# Assistant The Developer Center already includes the Docus assistant module, but the backend is not live on the public worker yet. The UI is configured in the app, and the assistant becomes active once the deployment provides `AI_GATEWAY_API_KEY`. ::note The assistant is planned for a future rollout. The current site configuration already enables the floating input UI and the "Explain with AI" action, but the server route stays disabled until the AI gateway key is present. :: ## Current Configuration The app config currently enables: | Feature | Status | | :----------------------- | :----------------------------------------- | | Floating input | Enabled in app config | | "Explain with AI" button | Enabled in app config | | Assistant API route | Disabled until `AI_GATEWAY_API_KEY` is set | ## Runtime Details When enabled, the assistant uses these Docus defaults: | Setting | Value | | :------------ | :---------------------- | | API route | `/__docus__/assistant` | | MCP server | `/mcp` | | Default model | `google/gemini-3-flash` | That means the assistant will use the same built-in MCP server documented in [/ai/mcp](https://nimiq.com/developers/ai/mcp). ## What The Assistant Supports Docus exposes configuration for: | Option | Purpose | | :--------------------- | :-------------------------------------------------------- | | `floatingInput` | Shows the floating prompt input on documentation pages | | `explainWithAi` | Shows the "Explain with AI" action in the docs sidebar | | `faqQuestions` | Seeds suggested questions for users | | `shortcuts.focusInput` | Controls the keyboard shortcut for focusing the assistant | | `icons.trigger` | Changes the trigger icon | | `icons.explain` | Changes the explain-action icon | ## Rollout Path To make the assistant live on the worker, the deployment needs an AI gateway key. Once that key is present, Docus mounts the assistant API route automatically and the configured UI starts using it. # AI Integrations Nimiq Developer Center ships AI-facing surfaces directly from the docs worker. That includes a built-in MCP server for tool-based retrieval, generated `llms.txt` files for model-friendly discovery, and a Docus assistant that can be enabled when the worker has an AI gateway key. ::u-page-section --- description: Use the integration that matches your assistant, IDE, or agent workflow. headline: Available Surfaces title: Build against the docs directly --- :::u-page-grid ::::u-page-card --- description: Connect Cursor, VS Code, or any MCP client to the built-in documentation server. icon: i-lucide-plug-zap title: MCP Server to: https://nimiq.com/developers/ai/mcp variant: outline --- :::: ::::u-page-card --- description: Give language models a compact or full-text index of the Developer Center. icon: i-lucide-file-text title: llms.txt to: https://nimiq.com/developers/ai/llms variant: outline --- :::: ::::u-page-card --- description: Prepare for the built-in docs assistant that will use the same MCP server when enabled. icon: i-lucide-sparkles title: Assistant to: https://nimiq.com/developers/ai/assistant variant: outline --- :::: ::: :: ## What ships today | Surface | Status | Route | | :---------------------- | :------------- | :---------------------------- | | MCP server | Live | `/mcp` | | Cursor deeplink | Live | `/mcp/deeplink` | | VS Code deeplink | Live | `/mcp/deeplink?ide=vscode` | | `llms.txt` | Live | `/llms.txt` | | `llms-full.txt` | Live | `/llms-full.txt` | | Docus assistant UI | Configured | App config enabled | | Docus assistant backend | Future rollout | Requires `AI_GATEWAY_API_KEY` | ## Deployed URLs On the public Developer Center deployment, these endpoints are available under `https://nimiq.com/developers`: - `https://nimiq.com/developers/mcp` - `https://nimiq.com/developers/llms.txt` - `https://nimiq.com/developers/llms-full.txt` The assistant will also run on the same deployment once the AI gateway key is configured. # llms.txt Docus publishes model-friendly text indexes for this site. They are generated from the live Developer Center content, so assistants can discover pages without scraping HTML. ::u-button --- class: mt-4 mr-3 rounded-full color: primary icon: i-tabler:file-text label: Open llms.txt to: https://nimiq.com/developers/llms.txt trailing-icon: i-tabler:arrow-up-right --- :: ::u-button --- class: mt-4 rounded-full color: neutral icon: i-tabler:file-text label: Open llms-full.txt to: https://nimiq.com/developers/llms-full.txt trailing-icon: i-tabler:arrow-up-right variant: outline --- :: ## Available Files | File | Purpose | | :--------------- | :----------------------------------------------------------- | | `/llms.txt` | Compact site index with page titles, descriptions, and URLs | | `/llms-full.txt` | Expanded export with full page content in a single text file | On the public deployment, these files are available at: - `https://nimiq.com/developers/llms.txt` - `https://nimiq.com/developers/llms-full.txt` ## When To Use Each One Use `llms.txt` when you want a lightweight overview of the site and page list. Use `llms-full.txt` when you want a single text export that includes the actual documentation content. ## Notes - `llms-full.md` redirects to `llms-full.txt` for compatibility. - The files are generated from site content, so they stay aligned with the published docs instead of a separate hand-maintained export. # MCP Server Connect AI tools directly to the Nimiq Developer Center MCP server that ships with this worker. This is the built-in Docus MCP server, and it is also the MCP backend the site assistant uses when that feature is enabled. ::u-button --- class: mt-4 mr-3 rounded-full color: primary icon: i-tabler:download label: Install in Cursor to: https://nimiq.com/developers/mcp/deeplink trailing-icon: i-tabler:arrow-up-right --- :: ::u-button --- class: mt-4 rounded-full color: neutral icon: i-tabler:download label: Install in VS Code to: https://nimiq.com/developers/mcp/deeplink?ide=vscode trailing-icon: i-tabler:arrow-up-right variant: outline --- :: ## Endpoint Point your MCP client to: ```text /mcp ``` On the public deployment, that resolves to: ```text https://nimiq.com/developers/mcp ``` ## Routes | Route | Purpose | | :------------------------- | :-------------------------------------- | | `/mcp` | MCP server endpoint | | `/mcp/deeplink` | One-click install for Cursor by default | | `/mcp/deeplink?ide=vscode` | One-click install for VS Code | | `/mcp/badge.svg` | Install badge image | ## Tools The current worker ships these Docus documentation tools: | Tool | Purpose | | :----------- | :-------------------------------------------------------------------------- | | `list-pages` | Discover available documentation pages with titles, descriptions, and paths | | `get-page` | Fetch the full markdown content of a specific page | Use `list-pages` when you need to browse the docs first. Use `get-page` once you know the exact path you want to read. ## Example Configuration ```json { "mcpServers": { "nimiq-developer-center": { "type": "http", "url": "https://nimiq.com/developers/mcp" } } } ``` ## What It Is For This MCP server is optimized for documentation retrieval. It lets assistants and agents discover Nimiq documentation pages and read their markdown directly from the live Developer Center worker. # Frequently Asked Questions about Nimiq PoS Migration #### Does every Nimiq user need to run the migration tools to transition to PoS? The migration process is only mandatory for those who want to be the first validators in the PoS chain or those who wish to have their nodes running from the very beginning. For regular users, no action is required. If you want to participate in the transition, you can find the appropriate guide [here](https://nimiq.com/developers/archive). #### I own a Nimiq Wallet. Do I need to participate in the migration? No, you don’t need to participate. Your balance and transaction history remains intact during the entire process. #### Can I access my wallet during the transition? Yes, you can access your wallet at any time during the transition. #### Can I log in to the Nimiq Wallet with the same Login File after the transition? Yes, you can. Since your data remains intact, your Login File will remain the same. If you log out for any reason, you can easily log back in using the same file and your password or the 24 recovery words. #### Do I need to be a miner to register as a validator? No, you don't. Any type of user can register as a validator, regardless of whether they are a miner or not. #### Do I need to register as a validator to participate actively in the migration? No, registration as a validator is optional. Users can choose to actively participate either as a validator or as an observer. Both options are available but participation in the migration is not mandatory for any Nimiq user. #### Can I deposit more than the minimum required as a pre-registered validator? Yes. Any NIM amount exceeding the validator deposit of 100 000 NIM will be considered stake, but only if it exceeds the minimum stake of 100 NIM. If the extra deposit does not meet this minimum, it will be burned. #### Will my balance remain intact during the transition? Yes, your balance and transaction history will remain intact throughout the transition. #### I don’t want to participate in the transition, but I want to earn rewards. How can I do it? You can participate in the pre-staking phase by delegating NIM to one of the pre-registered validators. Simply select a validator from the [provided list]() and pre-stake your NIM to earn rewards post-transition. #### Can I stake more than the minimum deposit of 100 NIM? Yes, you can. Any amount above the required 100 NIM minimum deposit will be added as additional stake to the validator of your choice. #### Can I pre-stake to a validator anytime during the transition? No, pre-staking is only available during the pre-staking phase. Your NIM will be added to the pre-registered validator’s deposit, contributing to the required threshold of stake needed for migration readiness. After the migration is complete, you can add more stake, re-stake to another validator, or unstake and recover your staked funds. #### What happens if the activation doesn’t collect 80% of readiness? The 80% readiness applies to the stake that has been pre-staked by pre-registered validators. There is no minimum amount of NIM that must be pre-staked, but 80% of the pre-staked NIM must signal readiness during an activation window. If this threshold is not met, a new activation window will start immediately after the current one ends. Each new activation window spans 1440 PoW blocks, equivalent to one day, and this process will continue until the required readiness threshold is reached. For more details, you can find more information [here](https://nimiq.com/developers/migration/migration-technical-details#activation-phase). #### I pre-registered as a validator but forgot to run the activation tool/send the readiness transaction within the activation window. Can I recover my validator? Your validator will still be included in the validator list and you can access to it once you migrate. However, if you are selected to produce a block and fail to do so because you didn't launch the tool in time, you will face penalties for the block you skipped to produce. Once you realize the oversight, you can run the activation tool to migrate the state and history and build the genesis block, and reactivate your validator via sending a transaction to the migrated PoS chain. #### Do I still need to run the activation tool after the PoS is running? No, the activation tool is specifically designed to migrate the PoW state and establish the genesis block for the PoS chain. Once this is done, the genesis block will be committed to the repository, making the migration tool no longer necessary. From this point on, you can simply follow the steps to run a validator. #### Can I withdraw my NIM deposit after pre-registration? Withdrawals are not possible until the PoS chain is operational. You can find more details on the withdrawal process for validators [here](https://nimiq.com/developers/protocol/validators/validators). #### Can I switch the validator I have pre-staked my NIM to? Yes, you can switch the validator you have pre-staked to. We support switching validators and increasing the NIM stake. You cannot remove or decrease the pre-stake; however, if you want to remove your NIM, you can do it after the transition. # Legacy PoW → PoS Migration ::callout{color="info" icon="i-tabler-info-circle"} This archive preserves the resources created for the Proof-of-Work to Proof-of-Stake transition. :: ::u-page-grid :::u-page-card --- description: How to be prepared to join the first epoch as a validator and earn rewards from the very beginning icon: i-nimiq:verified title: Pre-registration to: https://nimiq.com/developers/archive/validator-registration variant: outline --- ::: :::u-page-card --- description: Node Operators icon: i-lucide-server title: Be part of the migration to: https://nimiq.com/developers/archive/node-operators variant: outline --- ::: :::u-page-card --- description: Learn more icon: i-lucide-book-open title: Deep dive into the technical details to: https://nimiq.com/developers/migration/migration-technical-details variant: outline --- ::: :::u-page-card --- description: FAQ icon: i-lucide-help-circle title: Check our FAQs for more information to: https://nimiq.com/developers/archive/faqs variant: outline --- ::: :::u-page-card --- description: PoS icon: i-lucide-shield-check title: Curious about the new PoS? Check the protocol to: https://nimiq.com/developers/protocol variant: outline --- ::: :: ## Understanding the Migration Nimiq completed the transition from a Proof-of-Work to a Proof-of-Stake blockchain through a special hard fork. The transition process included several key phases: - **Pre-registration Phase**: Establishes the first list of validators for the PoS blockchain within the PoW chain - **Pre-Staking Phase**: Users pre-stake their NIM - **Activation Phase**: Selects candidate transition blocks from the PoW chain and executes the transition to the PoS chain if at least 80% of the stake is ready During the migration, the entire blockchain state—including accounts, balances, and transaction history—was captured so that users' balances moved intact to the PoS chain. **Participation was optional.** Those who wanted to contribute could [become one of the first validators](https://nimiq.com/developers/archive/validator-registration) or [migrate as observers](https://nimiq.com/developers/archive/node-operators). The captured state ensured no NIM was lost during the process, and the guides below document the steps that were available at the time. ## Most Asked Questions **Do I need to participate in the migration?** No, you don't need to participate unless you want to become one of our first validators or actively engage in the process as a node operator with zero downtime. Your NIM and transaction history will be automatically transferred to the new PoS chain. --- **Will my NIM be safe during the transition?** Yes, all NIM balances and transaction histories will be securely migrated to the PoS chain, and no NIM will be lost during this process. --- **Can I access my Wallet post-transition with the same Login File?** Yes, you can. Your address and data will be transferred to the PoS chain, so your Login File remains the same. # Nimiq PoW (Legacy) ::callout{color="warning" icon="i-tabler-alert-triangle"} **Deprecated Content** This content is for the legacy Nimiq 1.0 (Proof-of-Work) blockchain which has been deprecated. For current development, please use [Nimiq 2.0 (Proof-of-Stake)](https://nimiq.com/developers/web-client). :: Dive into the Nimiq Ecosystem documentation with links to resources, tutorials, and assets. ## Nimiq: the Blockchain for JS Devs! Nimiq is the first browser blockchain. That means apps based on Nimiq can run directly in the browser of the user, locally, installation-free, without the need of a server-side application. And if you have a server-side application, you can use the Nimiq Node.js client. This way, it can be easily integrated into any existing app. Syncing with Nimiq requires seconds, not hours and it works on low-bandwidth. Ideal for mobile and progressive web-apps. - You can create blockchain-enabled applications in JS without a third party to rely on - No dependencies on external services, your app is a full member of the Nimiq network - No service fees, terms of use, rules, and restrictions - Everything open source and licensed under MIT and Apache 2.0 license - Create a blockchain powered app and deploy it, or - Add NIM payments to any existing app Start building blockchain-enabled apps with your JS skills using the resources of Nimiq: - [Style guides and resources](https://www.nimiq.com/developers/#nimiq-style){rel=""nofollow""} - [Fresh tutorials](https://www.nimiq.com/developers/#tutorials){rel=""nofollow""} with step-by-step instructions - Community resources in the [Nimiq Forum](https://forum.nimiq.community/){rel=""nofollow""} - Run your own Nimiq Node [via Node.js](https://www.nimiq.com/developers/#run-node){rel=""nofollow""} - Source code [on GitHub](http://github.com/nimiq/){rel=""nofollow""} - Active community of fellow JS devs and the Nimiq team developers ready to help and brainstorm innovative project ideas; connect on [Telegram](https://t.me/joinchat/AAAAAEJW-ozFwo7Er9jpHw){rel=""nofollow""} and [Discord](https://discord.gg/cMHemg8){rel=""nofollow""} - [Additional APIs](https://api.nimiqx.com/docs/about){rel=""nofollow""} and extensions of the Nimiq Ecosystem provided by the community - [Nimiq Community Funding](https://forum.nimiq.community/t/nimiq-community-funding-board/61){rel=""nofollow""} initiative to support app developers with their projects This is a living document and will be updated as the Nimiq Ecosystem evolves. Make sure to to check back regularly and [join the developer community](https://nimiq.com/en/#community){rel=""nofollow""} to get the latest updates. # PoS Migration Guide for Node Operators Our migration guides are designed for users who want to actively participate in the transition process. This specific guide is for those who want to run the migration process without becoming validators (if you want to become one of the first validators from the start of the PoS chain, please refer to this [guide](https://nimiq.com/developers/archive/validator-registration)). It is suitable for: - Node Operators - Exchanges - Regular Users This guide provides instructions to run the Activation Tool, the final step of the migration to the Nimiq PoS. There is no requirement to run the migration as a node operator. You can simply start your PoS client once the migration process ends and build your own node. It's important to note that, as a node operator, your role is primarily as an observer during the activation process. The migration will only proceed if at least 80% of the allocated stake is ready to migrate. Since you have not pre-registered as a validator, running the activation tool does not contribute to meet the threshold requirement for the transition. Nonetheless, by running the migration tool, you will replicate the state migration and genesis block creation process. ## Activation Tool The Activation Tool facilitates the transition from the PoW chain to the PoS chain. We recommend running the activation tool before its window begins to ensure sufficient time for migrating the history, as this process can be time-consuming. Follow the appropriate guide based on whether you already have a PoW client running. ::collapsible{title="Users without an Existing PoW Client"} - Clone the [Nimiq CoreJS repository](https://github.com/nimiq/core-js?tab=readme-ov-file#quickstart){rel=""nofollow""} and follow the instructions - Refer to [this sample guide](https://github.com/nimiq/core-js/blob/master/clients/nodejs/sample.conf){rel=""nofollow""} to enable the PoW RPC server - Clone the [PoS blockchain repository](https://github.com/nimiq/core-rs-albatross?tab=readme-ov-file#installation){rel=""nofollow""} and follow the instructions to compile the code **Step 1: Set Up your PoS Configuration File** This step involves configuring your PoS client settings to prepare for the transition. You'll set parameters such as the network, sync mode, and RPC server. Once you have your client compiled in the **PoS chain**, you can: - Open the configuration file which is by default located in `$HOME/.nimiq/client.toml`. (see [example](https://github.com/nimiq/core-rs-albatross/blob/albatross/lib/src/config/config_file/client.example.toml){rel=""nofollow""}) - Set the `network` to `main-albatross` - Choose your `sync_mode` setting as `full` or `history` - Optionally, enable the PoS RPC server by uncommenting the section in the `[rpc-server]` configuration section if you need it - **Review all other sections** of the client.toml file and ensure that the parameters are configured according to your specific setup (paths, keys, and any optional features you want to enable). Adjust these settings as needed to fit your node's configuration. **Step 2: Download the PoW Chain Snapshot** If you are running the Activation Tool, a full database snapshot of the Nimiq PoW chain is available for download via IPFS or Torrent. While node operators primarily observe the migration process, downloading the snapshot is not required but can be helpful. Instead of syncing the entire chain from scratch, you will only need to sync the final portion after downloading the snapshot, enabling you to reach consensus more quickly. - IPFS is a decentralized file storage system that allows users to share and access files in a peer-to-peer network. You can find the ZIP file of the snapshot [here](https://ipfs.nimiq.io/ipfs/QmRKvFVpTdXagvgZG5cF9qdz13x9DkZhUvwXAS5YMaqTfu?filename=pow-main-full-consensus.zip){rel=""nofollow""}. It will start the download immediately. - BitTorrent File: An alternative method, you can download the Torrent file [here](https://repo.nimiq.com/torrents/nimiq-pow-main-full-consensus.torrent){rel=""nofollow""}. After downloading the snapshot, the database file must be placed in the directory from where you are running your PoW node. Once the database is in place, you can proceed by running the command from [step 3](https://nimiq.com/developers/#step-3-run-the-activation-tool). After your node has reached consensus, you can then move on to continue running the Activation Tool to complete the process. **Step 3: Check Client Sync Status** **In the PoW chain**, ensure you are fully synced and in consensus. Start the PoW client with an RPC server (this might take a while). Run the following command: ```bash node clients/nodejs/index.js --dumb --network=main --rpc=8648 ``` **Step 4: Run the Activation Tool** The Activation Tool establishes a connection with the PoW client via RPC, extracting data from your PoW client with the PoS client configuration. Ensure your PoW client is fully synced before running the Activation Tool on the PoS chain side. Before executing the Activation Tool, compile the **PoS chain** client by running `cargo build --release`. Once you are in consensus in the PoW chain, proceed to execute the Activation Tool by running the following command **in the PoS client repository** directory, including the path to the configuration file containing your validator data and specifying the PoW RPC server to be used. Note that this assumes the PoS client and PoW client (with RPC server enabled) are running on the same machine: ```bash cargo run --release --bin nimiq-pow-migration -- --url "http://127.0.0.1:8648" --config client.toml ``` :: ::collapsible{title="Users with an Existing PoW Client"} - Make sure you have your PoW RPC server enabled to allow your PoS client to connect to it - Clone the [PoS blockchain repository](https://github.com/nimiq/core-rs-albatross?tab=readme-ov-file#installation){rel=""nofollow""} and follow the instructions to compile the code **Step 1: Set Up your PoS Configuration File** This step involves configuring your PoS client settings to prepare for the transition. You'll set parameters such as the network, sync mode, and RPC server. Once you have your client compiled, you can: - Open the configuration file which is by default located at `$HOME/.nimiq/client.toml` (see [example](https://github.com/nimiq/core-rs-albatross/blob/albatross/lib/src/config/config_file/client.example.toml){rel=""nofollow""}) - Set the `network` to `main-albatross` - Choose your `sync_mode` setting as `full` or `history` - Optionally, enable the PoS RPC server by uncommenting the section in the `[rpc-server]` configuration section if you need it - **Review all other sections** of the client.toml file and ensure that the parameters are configured according to your specific setup (paths, keys, and any optional features you want to enable). Adjust these settings as needed to fit your node's configuration. **Step 2: Run the Activation Tool** The Activation Tool establishes a connection with the PoW chain via RPC, extracting data from your PoW client with the PoS client configuration. Ensure your PoW client is fully synced before running the Activation Tool on the PoS chain side. Before executing the Activation Tool, compile the **PoS chain** code by running `cargo build --release`. Once you are in consensus in the PoW chain, proceed to execute the Activation Tool by running the following command **in the PoS client repository** directory, including the path to the configuration file containing your validator data and specifying the RPC server to be used. Note that this assumes the PoS client and the PoW client (with the RPC server enabled at port `8648`) are running on the same machine: ```bash cargo run --release --bin nimiq-pow-migration -- --url "http://127.0.0.1:8648" --config client.toml ``` :: The Activation Tool connects with the PoW client via RPC to extract necessary data for the migration process. The tool: - Captures the state of the PoW chain at the candidate block for the transition to the PoS chain - Starts migrating the state from the PoW chain to the PoS state format - Generates the "genesis" block using a candidate transition block for the PoS chain - Monitors the readiness of validators, waiting for at least 80% of them to signal readiness Once the readiness threshold is met, the PoS client starts, marking the beginning of the PoS chain. Mind that as a non-validator, your role during this process is primarily observant, as your participation does not contribute to reach the 80% readiness threshold. # Activation Guide This guide is part of the Nimiq PoW to PoS migration process and is intended for users who have already registered as validators during the Validator Registration Phase by **October 6th, 2024**. If you missed the registration deadline, you can still participate in the activation as an observer by following [this guide](https://nimiq.com/developers/archive/node-operators). ## Validator Activation Tool This guide covers **Phase 3: Validator Activation**, which starts on **November 19th**. The Validator Activation Tool facilitates the transition from the PoW chain to the PoS chain. We recommend running the tool before the activation window begins to allow time for database synchronization, as this process can take some time. The tool will also automatically send online transactions every hour, signaling which validators are ready for the transition. Team Nimiq will fund all registered validator addresses with 100 Lunas before the activation window to cover these transactions. For more detailed information, click [here](https://nimiq.com/developers/migration/migration-technical-details#activation-phase). | **Phase** | **Start Date** | **End Date** | | ------------------------ | ----------------- | ------------- | | Validator Registration | 12th September | 6th October | | Pre-Stake Phase | 7th October | 10th November | | **Validator Activation** | **19th November** | - | The steps outlined in this guide are only applicable for the **Validator Activation Phase**. However, you can prepare by following these steps before that date. ### Prerequisites - **Validator Registration**: You must have already [registered as a validator](https://nimiq.com/developers/archive/validator-registration) - **PoW Full Node**: You need access to a fully synchronized Nimiq PoW full node with RPC access enabled. If you are not already running a full node, follow the instructions in the [core-js repository](https://github.com/nimiq/core-js){rel=""nofollow""}to set it up and sync with the main network - If you are running a PoW client, ensure it is fully synced and configured properly - Use this [sample configuration file](https://github.com/nimiq/core-js/blob/master/clients/nodejs/sample.conf){rel=""nofollow""} to enable RPC access on your PoW client - During this phase, you will need to run both the PoW and PoS clients. Ensure they are configured to run on **different RPC ports** to avoid conflicts if you are running both clients on the same machine. Alternatively, running them on separate servers is also possible. - **PoS Blockchain Repository**: Clone the [PoS blockchain repository](https://github.com/nimiq/core-rs-albatross?tab=readme-ov-file#installation){rel=""nofollow""} following the installation instructions ### **Step 1: Add Validator Data into the Configuration File** Once your PoS client is set up, follow these steps: 1. Check if the `$HOME/.nimiq`folder exists: 1. If it exists, open the configuration file in `$HOME/.nimiq/client.toml` and locate the dedicated section for validators at the end 2. If it doesn’t exist, create the `$HOME/.nimiq` folder and inside, create a `client.toml` file based on this [example](https://github.com/nimiq/core-rs-albatross/blob/albatross/lib/src/config/config_file/client.example.toml){rel=""nofollow""} 2. Paste your **validator data** into the validator section (public key, signing key, voting key) 3. Set the **network** is set to `main-albatross` and the `sync_mode` to `full` or `history`. Only full or history nodes are eligible to become validators 4. Review and adjust all the other sections of `client.toml` and ensure that the parameters are configured according to your specific setup (paths, keys, and any optional features you want to enable). Adjust these settings as needed to fit your node's configuration ### **Step 2: Download the PoW Chain Database Snapshot (Optional)** If your PoW client is not synced or you’re setting it up from scratch, you can download a database snapshot to accelerate the synchronization process. This snapshot is particularly useful before running the Activation Tool, as it eliminates the need to sync the entire PoW chain from scratch. After downloading the snapshot, only a small portion of the chain needs to be synced, allowing your node to reach consensus more quickly: - **IPFS**: Download the full PoW chain snapshot [here](https://ipfs.nimiq.io/ipfs/QmRKvFVpTdXagvgZG5cF9qdz13x9DkZhUvwXAS5YMaqTfu?filename=pow-main-full-consensus.zip){rel=""nofollow""} - **Torrent**: Alternatively, download the snapshot via Torrent [here](https://repo.nimiq.com/torrents/nimiq-pow-main-full-consensus.torrent){rel=""nofollow""} After downloading the snapshot, extract the file and place the database in the directory from where you are running your PoW client configuration. Once in place, follow steps [3](https://nimiq.com/developers/#step-3-prepare-the-pow-client-for-the-transition) and [4](https://nimiq.com/developers/#step-4-run-the-activation-tool). After your node reaches consensus, continue with the Activation Tool to complete the process. ### **Step 3: Prepare the PoW Client for the Transition** Ensure the **PoW client is running with RPC enabled** on a distinct port from the PoS client, as the following command both clients are running in the same machine. Configure the PoW client’s RPC settings in its configuration file by adding your validator address and key pair. Refer to [**this example**](https://github.com/nimiq/core-js/blob/master/clients/nodejs/sample.conf#L163){rel=""nofollow""}. Run the following command to start the PoW client: ```bash node clients/nodejs/index.js --dumb --network=main --rpc=8648 --wallet-seed=private_keypublic_key ``` The `private_keypublic_key` is the concatenation of your private key and public key in that order. It's necessary because the activation tool will use these keys to send and sign transactions on behalf of your validator, signaling readiness. ### **Step 4: Run the Activation Tool** Once your PoW client is synced and in consensus, you are ready to run the Validator Activation Tool. This tool establishes a connection with the PoW chain via RPC and sets your validator ready for the PoS transition. 1. Compile the PoS Client Ensure your PoS client is [properly configured](https://nimiq.com/developers/#step-1-add-validator-data-into-the-configuration-file) in the `client.toml` file, and your validator data is correctly set, and compile the PoS client: ```text cargo build --release ``` 2. **Run the Activation Tool** using the following command in the PoS client directory: ```text cargo run --release --bin nimiq-pow-migration -- --url "pow-rpc" --config client.toml ``` :brWhere `pow-rpc` is the **PoW client RPC url**. For example: `http://127.0.0.1:8648` The tool will monitor validator readiness by tracking readiness transactions sent by all the registered validators within 24 hour activation windows. Once 80% of the total stake has signaled readiness, the activation tool will automatically start the PoS client. Read more about the activation process [here](https://nimiq.com/developers/migration/migration-technical-details#activation-phase). ### PoS Activation On **November 19**, the network will initiate the transition from PoW to PoS. Once 80% of the total stake signals their readiness, PoS chain starts with the [candidate block](https://nimiq.com/developers/migration/migration-technical-details) as the genesis block. The transition block will be generated, and validators will officially start securing the PoS network. Ensure your validator is ready and synced before this date to avoid delays. # Registration Guide This document guides users through the registration process to become one of the first validators on the Nimiq PoS chain. It is part of the overall documentation for the transition from PoW to PoS. For more technical details on the migration, see [Migration Technical Details](https://nimiq.com/developers/migration/migration-technical-details). ## Validator Registration Tool This guide focuses on **Phase 1: Validator Registration** of the migration process, which takes place between **September 12 and October 6**. During this phase, you will create and register your validator on the PoW Mainnet, preparing it for the transition to PoS. Nimiq has developed a **Validator Registration Tool** specifically for this process. By using this tool, validators pre-register within the PoW chain, ensuring they are ready for the PoS transition. The tool operates in two modes: - **Key and Address Generation**: Generates the validator's keys and corresponding address - **Validator Registration**: Registers the validator by sending the necessary transactions on the PoW chain | **Phase** | **Start Date** | **End Date** | | -------------------------- | ------------------ | --------------- | | **Validator Registration** | **12th September** | **6th October** | | Pre-Stake Phase | 7th October | 10th November | | Validator Activation | 19th November | - | The steps outlined in this guide are only applicable during the **Validator Registration Phase**. ### Prerequisites - Ensure [Node.js](https://nodejs.org){rel=""nofollow""} ≥ v18.20.4 is installed - Clone the [Nimiq Validator Registration Tool repository](https://github.com/nimiq/validator-registration-tool){rel=""nofollow""} and move to the cloned directory - Install Yarn globally with `npm install -g yarn` - Install all dependencies by executing `yarn` inside the cloned repository ### Step 1: Generate the Validator Keys Execute the tool without parameters to generate a validator address, signing key, and voting key: ```bash node validator-registration.js ``` The tool generates fresh keys and stores them into the `validator-keys.json` file in your current directory. The screenshot demonstrates an example output of the script: ![Validator example keys](https://nimiq.com/developers/assets/images/migration/migration.png){.object-contain.max-h-[max(80vh,220px)]} ::callout{icon="i-tabler-bulb"} Save the private keys securely, especially the validator private key!  **There is no recovery mechanism for lost private keys** . Once lost, access to your validator and related NIM may be permanently lost. :: For detailed guidance through the scripts and their options, run `node validator-registration.js --help`. This will print out the usage instructions. **Using your own keys** You can of course also generate your own validator, signing, and/or voting keys using other methods. To do so, copy the `validator-keys.json` file generated in the previous step and replace the auto-generated address and keys with your own. Once you have added your keys, continue with the next step. ### Step 2: Fund your Validator Address To start the validator registration process, fund the validator address you just generated to cover the nominal transaction fees of 1 Luna each associated with the validator registration process. During the [Activation Phase](https://nimiq.com/developers/migration/migration-technical-details#readiness-and-activation-tool), you will also need to pay the readiness transaction, so ensure your address is funded with at least **1 NIM** for both the registration and activation transactions. You can use any Nimiq Wallet to send NIM to this address. ### Step 3: Run the Validator Registration Tool The Validator Registration Tool connects to the Nimiq PoW chain when executed. It registers your validator by importing the **generated keys** and then creates and sends **six transactions**, each with a **nominal fee of 1 Luna**. These transactions use your validator keys to sign and submit the necessary data to register your validator. Run the following command from the cloned `validator-registration-tool` repository. You must specify the arguments as follows: ```bash node validator-registration.js --validator validator-keys.json --network main ``` ### Step 4: Deposit Payment and Commit The final step involves committing to the registration and paying the validator's deposit of 100 000 NIM. This transaction can be sent from any address, but **you must include your validator address** in the transaction’s “public message” field. This allows the deposit to be linked to your validator. To send the transaction manually via **Nimiq Wallet**, you need the following data: | | | | --------------------- | -------------------------------------------------------------------- | | **Recipient Address** | `NQ07 0000 0000 0000 0000 0000 0000 0000 0000` | | **Value** | `100 000` NIM or more | | **Public Message** | Your validator address in human-readable format (starting with `NQ`) | ::callout{color="warning" icon="i-tabler-alert-triangle"} **We recommend using the Nimiq Wallet** to send the validator deposit, as it allows you to include the necessary public message. If you are using an exchange or another wallet, be aware that they often don’t allow public messages on-chain for withdrawals. To ensure everything works as expected, first send a small transaction (2 Lunas) between your own addresses with a simple message (like "hello world") to verify that the message is included properly. You can verify the address included the message with a block explorer like [nimiq.watch](https://nimiq.watch){rel=""nofollow""}. Ensure you follow these steps carefully, as failure to do so could result in permanent loss of your funds. Any value below 100 000 NIM will also result in permanent loss. Any amount above 100 000 NIM will be assigned as stake as long as the difference is greater than the minimum stake (100 NIM); otherwise, the excess will be burned. :: **Verify Registration and Deposit** After the command runs successfully and the deposit is sent, you can verify both on the network using our NIM block explorer [Nimiq Watch](https://nimiq.watch/#validator-registrations){rel=""nofollow""}. ### What’s Next? Congratulations! You have successfully registered your validator and paid the deposit. The next step is to prepare for the Activation Phase, which begins on **November 19**. You will need to follow the [Activation Tool](https://nimiq.com/developers/archive/validator-activation) guide, and we recommend running it before November 19, allowing your node to download the database snapshot early and speeding up the activation process. Click [here](https://nimiq.com/developers/migration/migration-technical-details#activation-phase) to learn more about the activation phase. # Design Kit Download official Nimiq logos and brand assets for your projects. ## Nimiq Logo The logo consists of the iconic hexagon mark and the wordmark. Use the hexagon alone as an icon or profile picture. Use the horizontal version when space allows. ### Hexagon ::div{.mt-6.mb-8.grid.gap-6.sm:grid-cols-2} :::design-kit-item --- label: Colored name: hexagon png: /logos/nimiq/hexagon.png svg: /logos/nimiq/hexagon.svg --- ::: :design-kit-item{label="Mono" name="hexagon-mono" svg="/logos/nimiq/hexagon-mono.svg"} :: ### Horizontal ::div{.mt-6.mb-8.grid.gap-6.lg:grid-cols-2} :::design-kit-item --- label: Colored name: horizontal png: /logos/nimiq/horizontal.png svg: /logos/nimiq/horizontal.svg --- ::: :::design-kit-item --- dark: true label: White name: horizontal-white png: /logos/nimiq/horizontal-white.png svg: /logos/nimiq/horizontal-white.svg --- ::: :design-kit-item{label="Mono" name="horizontal-mono" svg="/logos/nimiq/horizontal-mono.svg"} :: ## More Resources Explore our color palette and icon library for building Nimiq-branded applications. ::div{.mt-4.flex.flex-wrap.gap-3} :::u-button --- class: rounded-full color: neutral label: Color Palette target: _blank to: https://onmax.github.io/nimiq-ui/nimiq-css/palette.html trailing-icon: i-tabler:external-link variant: soft --- ::: :::u-button --- class: rounded-full color: neutral label: Icon Library target: _blank to: https://onmax.github.io/nimiq-ui/nimiq-icons/explorer.html trailing-icon: i-tabler:external-link variant: soft --- ::: :: # API Reference Complete reference for all Hub API methods, request types, and response formats. The Hub exposes a small set of methods to third-party origins (for example apps integrating the public Hub at `https://hub.nimiq.com`). Additional methods exist for the official Nimiq wallet and other privileged deployments, but those calls are blocked for regular origins. This page focuses on what you can use today and points you to the exact TypeScript definitions that ship with `@nimiq/hub-api`. ::callout{color="info" icon="i-tabler-info-circle"} **Check the types** The authoritative definitions live in `client/PublicRequestTypes.ts` inside the Hub repository and are bundled with the published npm package. Importing the library in a TypeScript project gives you auto-complete and compile-time safety. :: ## Public Methods ### checkout() Request a payment flow. For NIM-only payments (`version` omitted or set to `1`) the Hub returns a signed transaction and broadcasts it. Multi-currency requests (`version: 2`) always include a NIM option and can provide additional Bitcoin or Polygon payment options. ```ts interface NimiqCheckoutRequest extends BasicRequest { version?: 1 shopLogoUrl?: string sender?: string forceSender?: boolean recipient: string recipientType?: Nimiq.AccountType value: number fee?: number extraData?: string | Uint8Array flags?: number validityDuration?: number disableDisclaimer?: boolean // privileged origins only } interface MultiCurrencyCheckoutRequest extends BasicRequest { version: 2 shopLogoUrl: string callbackUrl?: string csrf?: string extraData?: string | Uint8Array // deprecated, use NIM option extraData instead time: number // seconds or milliseconds fiatCurrency: string // ISO 4217 code, e.g. "EUR" fiatAmount: number paymentOptions: AvailablePaymentOptions[] isPointOfSale?: boolean disableDisclaimer?: boolean // privileged origins only } type CheckoutRequest = NimiqCheckoutRequest | MultiCurrencyCheckoutRequest ``` Key points: - `AvailablePaymentOptions` lets you offer NIM, BTC, and Polygon USDC/USDT direct payments. Each currency can appear at most once and NIM is mandatory. - For popups you normally rely on the default behavior. Pass a second argument (`RedirectRequestBehavior`) for redirect-based flows. ### signTransaction() Sign a NIM transaction without broadcasting it. ```ts interface SignTransactionRequest extends BasicRequest { sender: string recipient: string recipientType?: Nimiq.AccountType recipientLabel?: string value: number fee?: number extraData?: string | Uint8Array flags?: number validityStartHeight: number } ``` Always obtain a current block height from a node and pass it as `validityStartHeight` so the transaction stays valid. ### signStaking() Sign one or multiple NIM staking transactions. You must prepare the raw transaction bytes yourself (for example with [`@nimiq/core`](https://nimiq.com/developers/web-client)) and hand them to the Hub for signing. ```ts interface SignStakingRequest extends BasicRequest { senderLabel?: string recipientLabel?: string transaction: Uint8Array | Uint8Array[] } ``` ### signMessage() Let the user sign an arbitrary message. Use it for authentication challenges. ```ts interface SignMessageRequest extends BasicRequest { signer?: string // optional human-readable address to pre-select message: string | Uint8Array } ``` ### chooseAddress() Ask the user to pick one of their addresses. Ideal for getting a destination account before sending funds. ```ts interface ChooseAddressRequest extends BasicRequest { returnBtcAddress?: boolean returnUsdcAddress?: boolean minBalance?: number disableContracts?: boolean disableLegacyAccounts?: boolean disableBip39Accounts?: boolean disableLedgerAccounts?: boolean ui?: number // internal flag for Hub UI variants } interface ChooseAddressResult extends Address { btcAddress?: string usdcAddress?: string meta: { account: { label: string color: string } } } ``` ### createCashlink() Create a shareable cashlink. The request extends `BasicRequest` and supports optional fields for value, theme, message, pre-selecting the funding address, and configuring redirect behaviour. ```ts // Simplified view — see CreateCashlinkRequest in PublicRequestTypes.ts for all combinations interface CreateCashlinkRequest extends BasicRequest { value?: number // Luna theme?: HubApi.CashlinkTheme message?: string autoTruncateMessage?: boolean senderAddress?: string senderBalance?: number returnLink?: boolean // when true you can skip the sharing screen via skipSharing skipSharing?: boolean fiatCurrency?: string } ``` ### manageCashlink() Retrieve the status of an existing cashlink (and allow the user to cancel if it is still unclaimed). ```ts interface ManageCashlinkRequest extends BasicRequest { cashlinkAddress: string } ``` ## Result Types ```ts interface SignedTransaction { transaction: Uint8Array serializedTx: string hash: string raw: { signerPublicKey: Uint8Array signature: Uint8Array sender: string senderType: Nimiq.AccountType recipient: string recipientType: Nimiq.AccountType value: number fee: number validityStartHeight: number extraData: Uint8Array flags: number networkId: number proof: Uint8Array } } interface SignedMessage { signer: string signerPublicKey: Uint8Array signature: Uint8Array } interface Cashlink { address: string message: string value: number status: CashlinkState theme: CashlinkTheme link?: string } ``` Use `HubApi.CashlinkState` and `HubApi.CashlinkTheme` enums to interpret cashlink details. ## Restricted Methods The following calls are **blocked** for regular origins on hub.nimiq.com. They require either the official Nimiq wallet origin or a self-hosted Hub configured with your domain in `privilegedOrigins`: - Account management: `onboard`, `signup`, `login`, `logout`, `export`, `rename`, `addAddress`, `addVestingContract`, `list`, `cashlinks`, `changePassword` - Multi-chain: `signBtcTransaction`, `addBtcAddresses`, `activateBitcoin`, `signPolygonTransaction`, `activatePolygon` - Swaps: `setupSwap`, `refundSwap` Attempting to call these from an unprivileged origin results in an "unauthorized" error response. ## Request Behaviors All methods accept an optional request behaviour. Popups are the default; use `new HubApi.RedirectRequestBehavior()` for mobile-friendly full-page flows and remember to call `hubApi.checkRedirectResponse()` on load. The Hub emits `HubApi.RequestType` events when a redirect returns — register handlers with `hubApi.on(...)`. ## Next Steps - [Getting Started](https://nimiq.com/developers/hub/getting-started) - [Integration Guide](https://nimiq.com/developers/hub/guide/integration) - [Transaction Methods](https://nimiq.com/developers/hub/guide/transactions) - [Cashlink and Advanced Features](https://nimiq.com/developers/hub/guide/advanced) - Type definitions in `@nimiq/hub-api/types` # Getting Started Get started with the Nimiq Hub API in three easy steps: install the client, initialize it, and make your first request. ## Quick Start **Try the live demo:** [hub-api-ts.vercel.app](https://hub-api-ts.vercel.app/){rel=""nofollow""} Or clone the starter template: ```bash npx degit onmax/nimiq-starter/starters/hub-api-ts my-nimiq-app cd my-nimiq-app && pnpm install && pnpm dev ``` [View source on GitHub](https://github.com/onmax/nimiq-starter/tree/main/starters/hub-api-ts){rel=""nofollow""} ## Installation ### CDN (Recommended for Prototyping) The fastest way to get started is using the CDN: ```html ``` For production, pin to a specific version for stability: ```html ``` ### NPM (Recommended for Production) For modern JavaScript projects: ::code-group ```bash [pnpm] pnpm add @nimiq/hub-api ``` ```bash [npm] npm install @nimiq/hub-api ``` ```bash [yarn] yarn add @nimiq/hub-api ``` :: Then import in your code: ```ts // ES Module import HubApi from '@nimiq/hub-api' // CommonJS const HubApi = require('@nimiq/hub-api') ``` ## Initialization Create a Hub API instance by specifying the Hub endpoint: ```ts // For mainnet const hubApi = new HubApi('https://hub.nimiq.com') // For testnet const hubApi = new HubApi('https://hub.nimiq-testnet.com') // For local development const hubApi = new HubApi('http://localhost:8080') ``` **Automatic endpoint selection:** If you don't provide an endpoint, the Hub API automatically selects based on your domain (`*.nimiq.com` → mainnet, `*.nimiq-testnet.com` → testnet, others → localhost). ## Making Your First Request All Hub API methods are asynchronous and return promises. They must be called within a user action (like a click) to avoid popup blockers. ### Example: Request a Payment ```ts document.getElementById('pay-button').addEventListener('click', async () => { try { const result = await hubApi.checkout({ appName: 'My Shop', recipient: 'NQ07 0000 0000 0000 0000 0000 0000 0000 0000', value: 1_000, // 0.01 NIM (value in Luna, 1 NIM = 100,000 Luna) }) console.log('Payment successful!') console.log('Transaction hash:', result.hash) } catch (error) { if (error.message === 'Request was cancelled') { console.log('User cancelled the payment') } else { console.error('Payment failed:', error) } } }) ``` **Important:** Call Hub methods **synchronously** within user actions (clicks, touches) to avoid popup blockers. Don't call Hub methods after `await` or inside `setTimeout`. ```ts // ✅ Good button.addEventListener('click', async () => { const result = await hubApi.checkout(options) }) // ❌ Bad - popup will be blocked button.addEventListener('click', async () => { await someAsyncFunction() const result = await hubApi.checkout(options) }) ``` ## COOP/COEP Headers Do not set `Cross-Origin-Embedder-Policy` or `Cross-Origin-Opener-Policy` headers — they break Hub popup communication. ## Network Selection The Hub API works on both **mainnet** and **testnet**: ::code-group ```ts [Mainnet] const hubApi = new HubApi('https://hub.nimiq.com') ``` ```ts [Testnet] const hubApi = new HubApi('https://hub.nimiq-testnet.com') ``` :: For testing and development, use **testnet** to avoid spending real NIM. ## Common Request Options Most Hub API methods accept an `appName` parameter to identify your application: ```ts const options = { appName: 'My App', // Short, descriptive name shown to users // ... other method-specific options } ``` The `appName` is displayed in the Hub UI so users know which application is requesting the action. ## Next Steps Now that you have the Hub API installed and initialized: - Learn about [Hub Architecture and Concepts](https://nimiq.com/developers/hub/guide/concepts) - Explore [Integration Patterns](https://nimiq.com/developers/hub/guide/integration) - See [Starter Template](https://github.com/onmax/nimiq-starter/tree/main/starters/hub-api-ts){rel=""nofollow""} - Check the complete [API Reference](https://nimiq.com/developers/hub/api-reference) ## Need Help? - Review [common integration issues](https://nimiq.com/developers/hub/guide/integration#troubleshooting) - Check out [starter template](https://github.com/onmax/nimiq-starter/tree/main/starters/hub-api-ts){rel=""nofollow""} - Ask questions in the [Nimiq Community Forum](https://forum.nimiq.community/){rel=""nofollow""} # Account Management The Hub API provides comprehensive account management methods to onboard new users, handle authentication, and manage addresses. Most of these methods are **restricted to privileged origins** (Nimiq domains only) for security. ::callout{color="warning" icon="i-tabler-alert-triangle"} **Restricted Methods** Account management methods like `onboard()`, `signup()`, `login()`, etc. are only accessible from **Nimiq domains** (`*.nimiq.com`) in the production Hub. Third-party apps should use: - `signMessage()` for authentication - `chooseAddress()` to get user addresses - `checkout()` / `signTransaction()` for payments If you're building a custom Hub instance, you can configure privileged origins in your Hub configuration. :: ## onboard() Guide new users through account creation with a friendly onboarding flow. This is the recommended method for user signup. ### Basic Usage ::code-group ```ts [onboard-user.ts] const accounts = await hubApi.onboard({ appName: 'My App', }) console.log('Created accounts:', accounts) ``` :: ### Request Options ```ts interface OnboardRequest { appName: string disableBack?: boolean // Disable back button during onboarding } ``` ### Response ```ts interface Account { accountId: string // Unique account ID label: string // Account name/label type: AccountType // Account type (BIP39, Ledger, etc.) addresses: Address[] // Associated addresses } interface Address { address: string // Human-readable address (NQ...) label: string // Address label } ``` ### Example: First-Time User Flow ::code-group ```ts [welcome-new-user.ts] async function welcomeNewUser() { try { const accounts = await hubApi.onboard({ appName: 'Welcome to My App', disableBack: true, }) // User created one or more accounts const defaultAccount = accounts[0] const defaultAddress = defaultAccount.addresses[0] // Store user information await saveUserProfile({ accountId: defaultAccount.accountId, address: defaultAddress.address, label: defaultAccount.label, }) showWelcomeMessage(`Welcome, ${defaultAccount.label}!`) navigateTo('/dashboard') } catch (error) { if (error.message === 'Request was cancelled') { showMessage('Onboarding cancelled') } else { showError('Onboarding failed') } } } ``` :: ## signup() Create a new account. Similar to `onboard()` but with less guidance. ### Basic Usage ::code-group ```ts [signup-user.ts] const accounts = await hubApi.signup({ appName: 'My App', }) ``` :: ### Request Options ```ts interface BasicRequest { appName: string } ``` ### Response Returns an array of `Account` objects (same as `onboard()`). ### Example ::code-group ```ts [create-new-account.ts] async function createNewAccount() { const accounts = await hubApi.signup({ appName: 'Account Manager', }) const newAccount = accounts[0] console.log('New account created:', newAccount.label) console.log('Address:', newAccount.addresses[0].address) } ``` :: ## login() Let users select an existing account to log in. ### Basic Usage ::code-group ```ts [login-user.ts] const accounts = await hubApi.login({ appName: 'My App', }) const selectedAccount = accounts[0] console.log('Logged in as:', selectedAccount.label) ``` :: ### Request Options ```ts interface BasicRequest { appName: string } ``` ### Response Returns an array of selected `Account` objects. ### Example: Login Flow ::code-group ```ts [handle-login.ts] async function handleLogin() { try { const accounts = await hubApi.login({ appName: 'My App', }) if (accounts.length === 0) { showError('No account selected') return } const account = accounts[0] const address = account.addresses[0].address // Authenticate with your backend const response = await fetch('/api/auth/login', { method: 'POST', headers: { 'Content-Type': 'application/json' }, body: JSON.stringify({ accountId: account.accountId, address, }), }) const { token } = await response.json() localStorage.setItem('authToken', token) showSuccess(`Welcome back, ${account.label}!`) navigateTo('/dashboard') } catch (error) { showError('Login failed') } } ``` :: ## logout() Log out a user (clears session in Hub). ### Basic Usage ::code-group ```ts [logout-user.ts] const result = await hubApi.logout({ appName: 'My App', }) console.log('Logged out successfully') ``` :: ### Request Options ```ts interface SimpleRequest { appName: string } ``` ### Response ```ts interface SimpleResult { success: boolean } ``` ### Example ::code-group ```ts [handle-logout.ts] async function handleLogout() { try { await hubApi.logout({ appName: 'My App', }) // Clear local session localStorage.removeItem('authToken') localStorage.removeItem('userAddress') showMessage('Logged out successfully') navigateTo('/login') } catch (error) { showError('Logout failed') } } ``` :: ## export() Allow users to export their account (backup words, keyfile, etc.). ### Basic Usage ::code-group ```ts [export-account.ts] const result = await hubApi.export({ appName: 'My App', accountId: 'account-id', }) console.log('Export complete') ``` :: ### Request Options ```ts interface ExportRequest { appName: string accountId: string // ID of account to export } ``` ### Response ```ts interface ExportResult { success: boolean } ``` ::callout{color="info" icon="i-tabler-info-circle"} **Security Note** The export operation is handled entirely within the secure Keyguard. Your application never receives the private keys or recovery words — users download them directly. :: ### Example ::code-group ```ts [export-account-backup.ts] async function exportAccountBackup(accountId: string) { try { await hubApi.export({ appName: 'Account Manager', accountId, }) showSuccess('Account exported successfully. Store your backup safely!') } catch (error) { if (error.message === 'Request was cancelled') { showMessage('Export cancelled') } else { showError('Export failed') } } } ``` :: ## rename() Change an account or address label. ### Basic Usage ::code-group ```ts [rename-account.ts] const account = await hubApi.rename({ appName: 'My App', accountId: 'account-id', address: 'NQ07 0000 0000 0000 0000 0000 0000 0000 0000', // Optional }) console.log('Renamed to:', account.label) ``` :: ### Request Options ```ts interface RenameRequest { appName: string accountId: string // Account to rename address?: string // If provided, renames address instead of account } ``` ### Response Returns the updated `Account` object. ### Example ::code-group ```ts [rename-account-or-address.ts] async function renameAccount(accountId: string) { try { const account = await hubApi.rename({ appName: 'Account Settings', accountId, }) showSuccess(`Renamed to "${account.label}"`) updateAccountDisplay(account) } catch (error) { if (error.message === 'Request was cancelled') { showMessage('Rename cancelled') } } } async function renameAddress(accountId: string, address: string) { try { const account = await hubApi.rename({ appName: 'Account Settings', accountId, address, }) // Find the renamed address const renamedAddr = account.addresses.find(a => a.address === address) showSuccess(`Address renamed to "${renamedAddr?.label}"`) } catch (error) { showError('Rename failed') } } ``` :: ## addAddress() Add a new address to an existing account. ### Basic Usage ::code-group ```ts [add-address.ts] const newAddress = await hubApi.addAddress({ appName: 'My App', }) console.log('New address:', newAddress.address) console.log('Label:', newAddress.label) ``` :: ### Request Options ```ts interface SimpleRequest { appName: string } ``` ### Response ```ts interface Address { address: string // Human-readable address label: string // Address label } ``` ### Example ::code-group ```ts [add-new-address.ts] async function addNewAddress() { try { const address = await hubApi.addAddress({ appName: 'Address Manager', }) showSuccess(`New address created: ${address.label}`) displayNewAddress(address) } catch (error) { showError('Failed to add address') } } ``` :: ## changePassword() Let users change their Keyguard password. ### Basic Usage ::code-group ```ts [change-password.ts] const result = await hubApi.changePassword({ appName: 'Security Settings', }) console.log('Password changed successfully') ``` :: ### Request Options ```ts interface SimpleRequest { appName: string } ``` ### Response ```ts interface SimpleResult { success: boolean } ``` ### Example ::code-group ```ts [update-password.ts] async function updatePassword() { try { await hubApi.changePassword({ appName: 'Account Security', }) showSuccess('Password changed successfully') } catch (error) { if (error.message === 'Request was cancelled') { showMessage('Password change cancelled') } else { showError('Password change failed') } } } ``` :: ## IFrame-Only Methods The following methods are only available via IFrame behavior from privileged origins: ### list() Get a list of all user accounts. ::code-group ```ts [list-accounts.ts] const accounts = await hubApi.list() console.log('User has', accounts.length, 'accounts') accounts.forEach((account) => { console.log(`${account.label}:`, account.addresses.length, 'addresses') }) ``` :: **Only available from Nimiq domains via IFrame.** ### cashlinks() Get all cashlinks associated with the user. ::code-group ```ts [list-cashlinks.ts] const cashlinks = await hubApi.cashlinks() console.log('User has', cashlinks.length, 'cashlinks') ``` :: **Only available from Nimiq domains via IFrame.** ## Account Types Accounts can be of different types: ```ts enum AccountType { BIP39 = 1, // Standard accounts (24-word recovery) LEGACY = 2, // Legacy accounts LEDGER = 3, // Ledger hardware wallet } ``` Check account type to provide appropriate features: ::code-group ```ts [check-account-type.ts] const account = accounts[0] if (account.type === HubApi.AccountType.LEDGER) { console.log('Ledger wallet detected') showMessage('Please confirm on your Ledger device') } ``` :: ## Account Lifecycle A typical account lifecycle in your app: ```text [lh-1] ┌─────────────────┐ │ Account Created │◄──── onboard ──── New User └────────┬────────┘ │◄──── login ──── Returning User │ ▼ ┌─────────────┐ │ Use App │ └──────┬──────┘ │ ┌──────────────────┼──────────────────┬──────────────┐ │ │ │ │ ▼ ▼ ▼ ▼ ┌──────────────┐ ┌──────────────┐ ┌──────────────┐ ┌────────────┐ │ More │ │ Update │ │ Backup │ │ Session │ │ Addresses │ │ Labels │ │ Account │ │ End │ └──────────────┘ └──────────────┘ └──────────────┘ └────────────┘ (addAddress) (rename) (export) (logout) ``` ## Best Practices ### 1. Graceful Onboarding Don't force onboarding immediately. Let users explore first: ::code-group ```ts [get-or-create-account.ts] async function getOrCreateAccount() { try { // Try login first (for returning users) const accounts = await hubApi.login({ appName: 'My App', }) return accounts[0] } catch (error) { // If login fails/cancelled, offer onboarding if (confirm('No account found. Create a new one?')) { const accounts = await hubApi.onboard({ appName: 'My App', }) return accounts[0] } } } ``` :: ### 2. Store Account References, Not Keys Never try to store private keys. Store account IDs and addresses: ::code-group ```ts [store-account-references.ts] // ✅ Good: Store references const userSession = { accountId: account.accountId, address: account.addresses[0].address, label: account.label, } localStorage.setItem('session', JSON.stringify(userSession)) // ❌ Bad: Never try to access private keys // Private keys never leave the Keyguard! ``` :: ### 3. Handle Multiple Addresses Users may have multiple addresses per account: ::code-group ```ts [display-account-addresses.ts] function displayAccountAddresses(account: Account) { return account.addresses.map(addr => ({ address: addr.address, label: addr.label || 'Unnamed Address', })) } ``` :: ### 4. Provide Export Reminders Remind users to backup their accounts: ::code-group ```ts [export-reminder.ts] // On first login after account creation if (isNewAccount && !hasExportedBefore) { showNotification( 'Backup Your Account', 'Export your recovery words to keep your account safe', () => hubApi.export({ appName: 'My App', accountId: account.accountId }) ) } ``` :: ## Alternative: signMessage() for Authentication For third-party apps, use `signMessage()` instead of `login()`: ::code-group ```ts [authenticate-user.ts] // Third-party apps should use this approach async function authenticateUser() { // 1. Get user's address const { address } = await hubApi.chooseAddress({ appName: 'My App', }) // 2. Request signature for authentication const challenge = await getAuthChallenge() // From your server const { signature, signerPublicKey } = await hubApi.signMessage({ appName: 'My App', message: `Sign in to My App\nChallenge: ${challenge}`, signer: address, // Use the chosen address }) // 3. Verify on server and get session token const token = await verifyAndLogin(address, signature, challenge) return token } ``` :: ## Next Steps - Explore [Advanced Features](https://nimiq.com/developers/hub/guide/advanced) (Cashlinks, Swaps, Multi-chain) - See [Starter Template](https://github.com/onmax/nimiq-starter/tree/main/starters/hub-api-ts){rel=""nofollow""} - Check the complete [API Reference](https://nimiq.com/developers/hub/api-reference) # Advanced Features Most third-party integrations focus on `checkout`, `signTransaction`, and `signMessage`. This page covers the extra functionality available through the Hub API and clarifies which features require privileged access. ## Cashlinks Cashlinks are shareable links that contain claimable value. Anyone with the link can redeem the funds via the Hub. The API exposes two public methods for working with cashlinks: `createCashlink()` and `manageCashlink()`. ### Creating a Cashlink ::code-group ```ts [create-cashlink.ts] const cashlink = await hubApi.createCashlink({ appName: 'Promo Campaign', value: 50_000, // 0.5 NIM (value is optional, defaults to user input) message: 'Thanks for trying our app!', theme: HubApi.CashlinkTheme.GENERIC, returnLink: true, // Show the result screen inside your app skipSharing: true, // Skip Hub sharing UI when returnLink is true }) console.log('Share this URL:', cashlink.link) ``` :: `CreateCashlinkRequest` extends `BasicRequest` and supports these options: | Field | Type | Notes | | --------------------- | ---------------------- | ------------------------------------------------------------------------------------------------------- | | `value` | `number` | Amount in Luna; omit to let the user enter an amount. | | `message` | `string` | Optional greeting shown to the recipient. Use `autoTruncateMessage` if you plan to send long text. | | `theme` | `HubApi.CashlinkTheme` | Controls the look of the Hub UI. | | `senderAddress` | `string` | Prefill the funding address when you know which account should pay. | | `senderBalance` | `number` | Optional balance hint for Hub optimisations. | | `fiatCurrency` | `string` | ISO 4217 code used for contextual pricing. | | `returnLink` | `boolean` | When `true`, the Hub redirects back to your app. Combine with `skipSharing` to bypass the share dialog. | | `skipSharing` | `boolean` | Only valid when `returnLink` is `true`. | | `autoTruncateMessage` | `boolean` | Automatically shortens long messages. | ### Managing a Cashlink ::code-group ```ts [manage-cashlink.ts] const cashlink = await hubApi.manageCashlink({ appName: 'Promo Campaign', cashlinkAddress: 'NQ30 F0O ...', }) if (cashlink.status === HubApi.CashlinkState.UNCLAIMED) { console.log('Cashlink still unclaimed — you may cancel it inside the Hub UI.') } ``` :: ### Result Format ```ts interface Cashlink { address: string message: string value: number status: HubApi.CashlinkState theme: HubApi.CashlinkTheme link?: string } ``` `HubApi.CashlinkState` enumerates the lifecycle: | State | Description | | ----------- | ---------------------------------------- | | `UNKNOWN` | Cashlink status could not be determined. | | `UNCHARGED` | Awaiting funding. | | `CHARGING` | Funding transaction in flight. | | `UNCLAIMED` | Ready to be claimed. | | `CLAIMING` | Claim transaction in flight. | | `CLAIMED` | Funds redeemed. | ### Tips - Pin cashlink values in Luna to avoid floating-point rounding issues. - Provide context (e.g. campaign or customer) using the `returnLink` state object when you call `new HubApi.RedirectRequestBehavior(returnUrl, state)`. - Use `HubApi.CashlinkTheme.GENERIC` for brand-neutral cashlinks or pick seasonal themes when appropriate. ## Atomic Swaps (privileged) `setupSwap()` and `refundSwap()` are exposed only to privileged origins (the official Nimiq wallet and self-hosted Hub instances that whitelist your domain). They orchestrate Hash Time-Locked Contracts for NIM, Bitcoin, Polygon, and fiat legs. If you maintain such an environment, consult `client/PublicRequestTypes.ts` in the Hub repository for the precise request structures. Public integrations on hub.nimiq.com should rely on external swap services instead. ## Multi-Chain Helpers (privileged) The Bitcoin and Polygon helpers—`activateBitcoin`, `signBtcTransaction`, `addBtcAddresses`, `activatePolygon`, and `signPolygonTransaction`—also require a privileged origin. Their payloads depend on detailed chain metadata (UTXO information for Bitcoin, OpenGSN relay objects for Polygon). Unless you operate a custom Hub deployment, focus on the NIM methods documented in the other guides. ## Chain Comparison | Feature | Nimiq | Bitcoin | Polygon | | ----------------- | ------------------------ | ------------------------ | -------------------- | | Address Format | `NQ...` | `bc1...`, `1...`, `3...` | `0x...` | | Unit | Luna (1 NIM = 100k Luna) | Satoshi (1 BTC = 100M) | Wei (1 MATIC = 1e18) | | Confirmation Time | \~1 second | \~10–60 minutes | \~2 seconds | | Transaction Fee | Very low/free | Variable (sat/vB) | Variable (Gwei) | | Smart Contracts | ✅ Yes | ❌ Limited | ✅ Yes (EVM) | Understanding these differences helps when you build dashboards or display balances from multiple chains. ## Next Steps - Review the [API Reference](https://nimiq.com/developers/hub/api-reference) for a method-by-method overview. - Follow the [Integration Guide](https://nimiq.com/developers/hub/guide/integration) for workflow best practices. - Check out the [Starter Template](https://github.com/onmax/nimiq-starter/tree/main/starters/hub-api-ts){rel=""nofollow""} for working examples. # Core Concepts Understanding how the Hub works will help you integrate it effectively and choose the right request behavior for your application. ## Architecture Overview The Nimiq Hub ecosystem consists of three main components: ```lh-1 ┌──────────────────┐ │ Your Application │ └────────┬─────────┘ │ Hub API Requests │ ▼ ┌────────┐ ┌───────┤ Hub │───────┐ │ └────────┘ │ Key Management Results │ │ ▼ │ ┌──────────┐ │ │ Keyguard │ │ └────┬─────┘ │ └─── Signatures ─────────┘ ┌──────────────────┐ │ Your Application │──── Transactions ────► Nimiq Blockchain └──────────────────┘ ``` - **Your Application**: The frontend application that integrates the Hub API to request wallet operations. This could be a dApp, payment platform, or any web application. - **Hub**: The user-facing interface that displays transaction details, manages accounts, and coordinates between your app and the Keyguard. The Hub validates requests and presents them to users in a friendly UI. - **Keyguard**: The secure, isolated component that holds private keys and performs all cryptographic operations. It's designed with maximum security in mind and never exposes private keys to the Hub or your application. ::callout{color="info" icon="i-tabler-info-circle"} **Security by Design** The Keyguard runs in a separate origin and iframe with strict security policies. Private keys are encrypted with user passwords and never leave the Keyguard environment. Even if the Hub or your app is compromised, private keys remain safe. :: ## Request Behaviors The Hub API supports three different request behaviors to accommodate different application needs: | Feature | Popup (Default) | Redirect | IFrame (Restricted) | | ---------------------- | --------------- | ------------------- | -------------------- | | **User stays on page** | ✅ Yes | ❌ No | ✅ Yes | | **Works on mobile** | ✅ Yes (new tab) | ✅ Yes | ✅ Yes | | **Requires HTTPS** | ❌ No | ⚠️ Yes (production) | ❌ No | | **Popup blocker risk** | ⚠️ Possible | ✅ Never | ✅ Never | | **State preservation** | ✅ Automatic | ⚠️ Manual | ✅ Automatic | | **Third-party access** | ✅ Yes | ✅ Yes | ❌ Nimiq domains only | | **Setup complexity** | 🟢 Low | 🟡 Medium | 🟢 Low | | **Best for** | Web apps, dApps | Mobile-first, PWAs | Official Nimiq apps | | **Recommended** | ⭐⭐⭐ | ⭐⭐ | ⭐ (restricted) | ### Popup (Default) Requests open in a centered popup window. Users stay on your page while the Hub opens in a separate window. ::code-group ```ts [popup-behavior.ts] const hubApi = new HubApi('https://hub.nimiq.com') // Or explicitly use popup behavior const popupBehavior = new HubApi.PopupRequestBehavior() const hubApi = new HubApi('https://hub.nimiq.com', popupBehavior) const result = await hubApi.checkout(options) ``` :: ::callout{icon="i-tabler-bulb"} **When to use** Use Popup for most web applications and dApps. It provides the best user experience by keeping users on your page while they complete Hub interactions. :: ### Redirect Redirects the entire browser tab to the Hub, then back to your app when complete. ::code-group ```ts [redirect-behavior.ts] const redirectBehavior = new HubApi.RedirectRequestBehavior() const hubApi = new HubApi('https://hub.nimiq.com', redirectBehavior) const result = await hubApi.checkout(options) // Will redirect ``` :: ::callout{icon="i-tabler-bulb"} **When to use** Use Redirect for mobile-first applications, PWAs, or when you encounter popup blocker issues. Works great on mobile devices with simpler navigation. :: ::callout{color="warning" icon="i-tabler-alert-triangle"} **HTTPS Required** Top-level redirects only work over HTTPS (except on localhost for development). Make sure your production app uses HTTPS before implementing redirect flows. :: ### IFrame (Restricted) Some methods can be called via iframe for privileged origins (Nimiq domains only). ::code-group ```ts [iframe-behavior.ts] const iframeBehavior = new HubApi.IFrameRequestBehavior() // Only available for specific methods from trusted origins const accounts = await hubApi.list(iframeBehavior) ``` :: ::callout{color="info" icon="i-tabler-info-circle"} **Restricted to Nimiq Domains** IFrame behavior is **only available from Nimiq domains** (e.g., `*.nimiq.com`) and limited to specific methods: `list()`, `cashlinks()`, `addBtcAddresses()`. Third-party applications should use **Popup** or **Redirect** behaviors. :: #### Handling Redirect Responses When using redirects, you need to listen for the Hub's return: ::code-group ```ts [setup-redirect-listeners.ts] // 1. Initialize Hub with redirect behavior const redirectBehavior = new HubApi.RedirectRequestBehavior('https://myapp.com/return') const hubApi = new HubApi('https://hub.nimiq.com', redirectBehavior) // 2. Set up listeners for each request type hubApi.on( HubApi.RequestType.CHECKOUT, result => console.log('Payment complete:', result), error => console.error('Payment failed:', error), ) // 3. Check for redirect response on page load hubApi.checkRedirectResponse() // 4. Later, trigger the request (will redirect) button.addEventListener('click', () => { hubApi.checkout({ appName: 'My App', /* ... */ }) }) ``` :: #### Preserving State Across Redirects You can pass state data that will be preserved across the redirect: ::code-group ```ts [preserve-redirect-state.ts] const storedData = { orderId: '12345', userId: 'user_abc', returnPath: '/checkout/complete', } const redirectBehavior = new HubApi.RedirectRequestBehavior('https://myapp.com/return', storedData) hubApi.on( HubApi.RequestType.CHECKOUT, (result, storedData) => { console.log('Order ID:', storedData.orderId) // '12345' console.log('Transaction:', result.hash) } ) ``` :: ## Request Lifecycle Understanding the request lifecycle helps you handle loading states and errors properly: ```text [lh-1] Your App Hub Keyguard Blockchain │ │ │ │ │──Request──────► │ │ │ (checkout) │ │ │ │ │──Validate── │ │ │ │ │ │ │ │──Display for──────► │ │ │ approval │ │ │ │ │──Review & │ │ │ │ Approve │ │ │ │ │ │ │ │──Sign with │ │ │ │ private key │ │ │ │ │ │ │◄──Signature───────│ │ │ │ │ │ │ │──(Optional)───────┼─────────────────► │ │ Broadcast tx │ │ │ │ │ │ │◄──Result──────│ │ │ │ │ │ │ │──(Optional)───┼───────────────────┼─────────────────► │ Verify/watch │ │ │ ``` 1. **Request**: Your app calls a Hub API method in response to a user action 2. **Validation**: Hub validates the request parameters 3. **User Review**: Hub presents the request to the user in a clear UI 4. **Keyguard**: If approved, Keyguard signs with the private key 5. **Response**: Hub returns the result (or error) to your app 6. **Broadcast**: For some methods like `checkout()`, the transaction is broadcast automatically ## Security Model ### Trust Boundaries ```text [lh-1] ┌──────────────┐ ┌──────────────┐ ┌──────────────┐ │ Your App │───────►│ Hub │───────►│ Keyguard │ │ (Untrusted) │ │(Semi-Trusted)│ │(Fully Trusted)│ └──────────────┘ └──────────────┘ └──────────────┘ ``` - **Your App (Untrusted)**: Can request operations but never access private keys - **Hub (Semi-Trusted)**: Validates and presents requests but never handles raw keys - **Keyguard (Fully Trusted)**: Holds encrypted keys and performs signing in isolation ### What the Hub Does NOT Know - Your users' private keys (only Keyguard has these, encrypted) - User passwords (only Keyguard handles these) - Keys are never transmitted to your app or the Hub ### What Your App Cannot Do - Access private keys directly - Sign transactions without user approval - Impersonate the user - Extract seeds or recovery phrases ::callout{icon="i-tabler-bulb"} **Security Best Practice** Always display transaction details to your users **before** calling Hub methods. While the Hub shows details again, informed users make better security decisions. :: ## Common Patterns ### Progressive Enhancement Start with popups and fallback to redirects if needed: ::code-group ```ts [progressive-enhancement.ts] let hubApi try { // Try popup first const popupBehavior = new HubApi.PopupRequestBehavior() hubApi = new HubApi('https://hub.nimiq.com', popupBehavior) await hubApi.checkout(options) } catch (error) { if (error.message.includes('popup')) { // Fallback to redirect const redirectBehavior = new HubApi.RedirectRequestBehavior() hubApi = new HubApi('https://hub.nimiq.com', redirectBehavior) await hubApi.checkout(options) } } ``` :: ### Mobile Detection Choose behavior based on device: ::code-group ```ts [mobile-detection.ts] const isMobile = /iPhone|iPad|iPod|Android/i.test(navigator.userAgent) const behavior = isMobile ? new HubApi.RedirectRequestBehavior() : new HubApi.PopupRequestBehavior() const hubApi = new HubApi('https://hub.nimiq.com', behavior) ``` :: ## Next Steps - Learn [Integration Best Practices](https://nimiq.com/developers/hub/guide/integration) - Explore [Transaction Methods](https://nimiq.com/developers/hub/guide/transactions) - See [Starter Template](https://github.com/onmax/nimiq-starter/tree/main/starters/hub-api-ts){rel=""nofollow""} # Integration Guide This guide distills the key practices that make Hub API integrations reliable and user-friendly. Cross-reference it with [Getting Started](https://nimiq.com/developers/hub/getting-started) and the [API Reference](https://nimiq.com/developers/hub/api-reference) for method details. ## 1. Centralise HubApi usage Create a single `HubApi` instance for your app and expose thin helpers. This keeps permissions, behaviours, and error handling in one place. ```ts [request-payment.ts] // hub.ts import HubApi, { CheckoutRequest, SignedTransaction } from '@nimiq/hub-api' const hubApi = new HubApi('https://hub.nimiq.com') export async function requestPayment(request: CheckoutRequest): Promise { try { return await hubApi.checkout(request) } catch (error) { handleHubError(error as Error) throw error } } ``` ## 2. Call methods synchronously inside user actions Browsers block popups opened outside direct interactions. Never await another promise before invoking a Hub method. ```ts [notify-success.ts] button.addEventListener('click', async () => { const result = await requestPayment({ appName: 'My Shop', recipient: 'NQ07 0000 0000 0000 0000 0000 0000 0000 0000', value: 1_000, // 0.01 NIM }) notifySuccess(result.hash) }) ``` ## 3. Handle success and failure explicitly Wrap calls in `try/catch` and branch on user cancellation versus genuine errors. ::code-group ```ts [handle-hub-error.ts] function handleHubError(error: Error) { if (error.message === 'Request was cancelled') showToast('Action cancelled by the user') else if (error.message.includes('popup')) showToast('Enable popups or switch to redirect mode') else console.error(error) showToast('Hub request failed') } ``` :: ## 4. Manage UI state - Disable the triggering button while the Hub popup is open. - Surface progress indicators ("Waiting for confirmation…"). - For checkout results, forward the signed transaction to your backend immediately if you need server-side confirmations. ## 5. Use redirects for mobile or kiosk setups Popups are convenient on desktop, but redirect flows avoid blocker dialogs on mobile. Instantiate the API with a redirect behaviour when needed: ::code-group ```ts [setup-redirect-behavior.ts] const redirectBehavior = new HubApi.RedirectRequestBehavior(window.location.href, { orderId }) const hubApi = new HubApi('https://hub.nimiq.com', redirectBehavior) hubApi.on(HubApi.RequestType.CHECKOUT, (result, state) => { completeOrder(state.orderId, result.hash) }) hubApi.checkRedirectResponse() ``` :: ## 6. Troubleshooting checklist - **Popup blocked:** ensure the call happens synchronously in the event handler; fall back to redirects if necessary. - **Hub not loading:** check network connectivity, CORS, and that no COOP/COEP headers are set. - **"Invalid request":** verify addresses, units (Luna), and required fields before sending the request. - **Stale validity heights:** fetch the latest block height from your [RPC endpoint](https://nimiq.com/developers/rpc) before calling `signTransaction`. ## 7. Testing strategy - Point your app at `https://hub.nimiq-testnet.com` during development. - Use the [testnet faucet](https://faucet.nimiq-testnet.com){rel=""nofollow""} to obtain NIM for testing. - Mock the Hub API in unit tests by stubbing the methods you use, returning realistic payloads. ## 8. Keep dependencies up to date Pin Hub API versions in production (`@nimiq/hub-api@1.10.0`) and upgrade periodically to benefit from bug fixes. The package includes TypeScript definitions—leverage them to catch integration mistakes during development. ## Further resources - [Quick Start](https://nimiq.com/developers/hub/getting-started) - [Transactions Guide](https://nimiq.com/developers/hub/guide/transactions) - [Cashlinks & Advanced Features](https://nimiq.com/developers/hub/guide/advanced) - [Starter Template](https://github.com/onmax/nimiq-starter/tree/main/starters/hub-api-ts){rel=""nofollow""} # Transaction Methods The Hub API provides several methods for transaction-related operations, from simple payments to complex staking operations. ## checkout() The `checkout()` method is the easiest way to request a payment from a user. It displays a friendly payment UI, signs the transaction, and automatically broadcasts it to the network. ### Basic Usage ::code-group ```ts [checkout-payment.ts] const result = await hubApi.checkout({ appName: 'My Shop', recipient: 'NQ07 0000 0000 0000 0000 0000 0000 0000 0000', value: 1_000, // 0.01 NIM (in Luna: 1 NIM = 100,000 Luna) }) console.log('Transaction hash:', result.hash) console.log('Transaction sent!') ``` :: ### Request Options ```ts interface CheckoutRequest { // Required appName: string // Name shown to user (keep it short) recipient: string // NIM address (human-readable: NQ...) value: number // Amount in Luna (1 NIM = 100,000 Luna) // Optional sender?: string // Pre-select sender address forceSender?: boolean // Require specific sender (throws if insufficient balance) fee?: number // Transaction fee in Luna (default: 0) extraData?: string | Uint8Array // Extra data to include validityDuration?: number // Validity in blocks (max/default: 120) shopLogoUrl?: string // Square logo, min 146x146px, same origin flags?: number // Transaction flags for contract creation recipientType?: number // Account type for contract creation } ``` ### Response ```ts interface SignedTransaction { hash: string // Transaction hash (hex) serializedTx: string // Serialized signed transaction (hex) raw: { signerPublicKey: Uint8Array signature: Uint8Array sender: string // Human-readable address senderType: number recipient: string recipientType: number value: number // Luna fee: number // Luna validityStartHeight: number extraData: Uint8Array flags: number networkId: number } } ``` ### Example: E-commerce Checkout ::code-group ```ts [process-checkout.ts] async function processCheckout(orderId: string, totalNim: number) { try { const result = await hubApi.checkout({ appName: 'Acme Store', recipient: 'NQ07 ACME STOR E000 0000 0000 0000 0000 0000', value: totalNim * 100000, // Convert NIM to Luna extraData: `Order #${orderId}`, // Include order reference shopLogoUrl: '/logo-square.png', }) // Transaction is already broadcast by Hub await confirmOrder(orderId, result.hash) showSuccessMessage('Payment complete!') return result } catch (error) { if (error.message === 'Request was cancelled') { showMessage('Payment cancelled') } else { showError('Payment failed') } throw error } } ``` :: ### Setting Fees ::code-group ```ts [checkout-with-fee.ts] // Standard transaction (no fee required on Nimiq) await hubApi.checkout({ appName: 'My App', recipient: recipientAddress, value: 1000000, fee: 0, // Default }) // Custom fee (optional, for faster processing) await hubApi.checkout({ appName: 'My App', recipient: recipientAddress, value: 1000000, fee: 1380, // Small fee for prioritization }) ``` :: ## signTransaction() Unlike `checkout()`, the `signTransaction()` method signs a transaction but does **not** broadcast it. Use this when you want to submit the transaction yourself or sign offline. ### Differences from checkout() - **Requires `sender` address** - Must specify who is sending - **Requires `validityStartHeight`** - Must specify starting block height - **Does not broadcast** - You handle submission to the network - **Different UI** - Focused on signing, not payment flow ### Basic Usage ::code-group ```ts [sign-transaction.ts] const currentHeight = await getCurrentBlockHeight() // Get from RPC or Web Client const result = await hubApi.signTransaction({ appName: 'My App', sender: 'NQ07 USER ADDR ESS0 0000 0000 0000 0000 0000', recipient: 'NQ07 DEST ADDR ESS0 0000 0000 0000 0000 0000', value: 1000000, validityStartHeight: currentHeight, }) // Now broadcast it yourself await client.sendRawTransaction(result.serializedTx) ``` :: ### Request Options ```ts interface SignTransactionRequest { // Required appName: string sender: string // Must specify sender address recipient: string value: number // Luna validityStartHeight: number // Current or future block height // Optional fee?: number extraData?: string | Uint8Array flags?: number recipientType?: number } ``` ::callout{color="warning" icon="i-tabler-alert-triangle"} **Validity Window** Transactions are only valid for **120 blocks** after `validityStartHeight`. A transaction with a future `validityStartHeight` will be rejected until that height is reached. Plan accordingly! :: ### Example: Offline Signing ::code-group ```ts [offline-signing.ts] import { Client } from '@nimiq/core' // 1. Prepare transaction details offline const txDetails = { appName: 'Offline Wallet', sender: userAddress, recipient: destinationAddress, value: 5000000, validityStartHeight: 123456, // Get from last known height } // 2. Sign with Hub (can be done offline if Hub is available locally) const signedTx = await hubApi.signTransaction(txDetails) // 3. Store or display serialized transaction console.log('Signed transaction:', signedTx.serializedTx) localStorage.setItem('pending-tx', signedTx.serializedTx) // 4. Later, when online, broadcast it const client = new Client() await client.waitForConsensus() await client.sendRawTransaction(signedTx.serializedTx) ``` :: > **Note:** This example uses the [Nimiq Web Client](https://nimiq.com/developers/web-client) (`@nimiq/core`) to broadcast the signed transaction. ## signStaking() `signStaking()` is a low-level helper: you prepare one or more staking transactions, the Hub has the user approve them, and the Keyguard returns signed transactions. The method does **not** build transactions for you — use [`@nimiq/core`](https://nimiq.com/developers/web-client)'s staking helpers or the [RPC client](https://nimiq.com/developers/rpc) to assemble the unsigned transactions first. ```ts interface SignStakingRequest extends BasicRequest { senderLabel?: string recipientLabel?: string transaction: Uint8Array | Uint8Array[] } ``` Workflow: 1. Build the desired staking transaction(s) with [`@nimiq/core`](https://nimiq.com/developers/web-client) (for example by creating an `Nimiq.ExtendedTransaction`). 2. Serialize each transaction to a `Uint8Array` via `.serialize()`. 3. Pass the bytes to `hubApi.signStaking({ appName, transaction })`. 4. Submit every signed transaction returned by the Hub to the network using your [JSON-RPC client](https://nimiq.com/developers/rpc). ::code-group ```ts [sign-staking.ts] const unsignedTx = buildStakeTransaction(/* staking payload */) // returns Uint8Array const signed = await hubApi.signStaking({ appName: 'Validator Console', transaction: unsignedTx, }) for (const tx of signed) { await client.sendRawTransaction(tx.serializedTx) } ``` :: Because staking operations can require multiple chained transactions, the Hub always returns an array. Many cases (like simple stake/unstake) contain a single item. ## signMessage() Sign arbitrary messages for authentication or proof-of-ownership. Perfect for login systems. ### Basic Usage ::code-group ```ts [sign-message.ts] const result = await hubApi.signMessage({ appName: 'My App', message: 'Sign in to My App', }) console.log('Signed by:', result.signer) console.log('Signature:', result.signature) console.log('Public key:', result.signerPublicKey) ``` :: ### Request Options ```ts interface SignMessageRequest { appName: string message: string | Uint8Array // UTF-8 string or binary data signer?: string // Pre-select address (optional) } ``` ### Response ```ts interface SignedMessage { signer: string // Human-readable address signerPublicKey: Uint8Array // Public key of signer signature: Uint8Array // Signature bytes } ``` ### Message Prefixing To prevent signing malicious transaction data, the Keyguard **automatically prefixes** all messages before signing: ```js // What actually gets signed: sign(sha256(`\x16Nimiq Signed Message:\n${message.length}${message}`)) ``` The prefix `\x16Nimiq Signed Message:\n` (23 bytes) and message length ensure the signed data can't be mistaken for a valid transaction. ### Verifying Signatures To verify a signed message using the [Nimiq Web Client](https://nimiq.com/developers/web-client): ::code-group ```ts [verify-with-web-client.ts] import { BufferUtils, Hash, PublicKey, Signature } from '@nimiq/core' function verifySignedMessage( message: string, signature: Uint8Array, publicKey: Uint8Array, ): boolean { const sig = new Signature(signature) const pubKey = new PublicKey(publicKey) // Recreate the prefixed message const prefix = '\x16Nimiq Signed Message:\n' const data = prefix + message.length + message const dataBytes = BufferUtils.fromUtf8(data) const hash = Hash.computeSha256(dataBytes) return sig.verify(pubKey, hash) } ``` ```ts [Custom Implementation] import { sha256 } from '@noble/hashes/sha256' function verifySignedMessage( message: string, signature: Uint8Array, publicKey: Uint8Array, ): boolean { const prefix = '\x16Nimiq Signed Message:\n' const data = prefix + message.length + message const encoder = new TextEncoder() const dataBytes = encoder.encode(data) const hash = sha256(dataBytes) // Use your signature verification library return verifyEd25519Signature(signature, hash, publicKey) } ``` :: ### Example: Authentication Flow ::code-group ```ts [sign-in-authentication.ts] // 1. User clicks "Sign In" async function signIn() { try { const challenge = generateRandomChallenge() // Server-provided nonce const result = await hubApi.signMessage({ appName: 'My App', message: `Sign in to My App\nChallenge: ${challenge}`, }) // 2. Send to server for verification const response = await fetch('/api/auth/verify', { method: 'POST', headers: { 'Content-Type': 'application/json' }, body: JSON.stringify({ address: result.signer, signature: Array.from(result.signature), publicKey: Array.from(result.signerPublicKey), challenge, }), }) const { token } = await response.json() // 3. Store auth token localStorage.setItem('authToken', token) navigateTo('/dashboard') } catch (error) { showError('Sign in failed') } } // Server-side verification (Node.js) app.post('/api/auth/verify', (req, res) => { const { address, signature, publicKey, challenge } = req.body const message = `Sign in to My App\nChallenge: ${challenge}` if (verifySignedMessage(message, signature, publicKey)) { const token = generateJWT({ address }) res.json({ token }) } else { res.status(401).json({ error: 'Invalid signature' }) } }) ``` :: ## chooseAddress() Let users select one of their addresses to provide to your app. **Not for authentication** (use `signMessage()` instead). ### Basic Usage ::code-group ```ts [choose-address.ts] const result = await hubApi.chooseAddress({ appName: 'My App', }) console.log('Address:', result.address) console.log('Label:', result.label) ``` :: ### Request Options ```ts interface ChooseAddressRequest { appName: string // Only required field } ``` ### Response ```ts interface ChooseAddressResult { address: string // Human-readable address (NQ...) label: string // Address label/name } ``` ::callout{color="warning" icon="i-tabler-alert-triangle"} **Not for Authentication** `chooseAddress()` does **not** prove the user owns the address. Anyone can provide any address. For authentication, use `signMessage()` instead. :: ### Example: Receiving Address ::code-group ```ts [get-receiving-address.ts] async function getReceivingAddress() { try { const result = await hubApi.chooseAddress({ appName: 'My Exchange', }) // Show deposit address to user showDepositAddress(result.address, result.label) return result.address } catch (error) { showError('No address selected') } } ``` :: ## Method Comparison | Method | Broadcasts? | Requires Sender? | Requires Height? | Use Case | | ------------------- | ----------- | ---------------- | ---------------- | ---------------------------------- | | `checkout()` | ✅ Yes | ❌ No | ❌ No | Simple payments, e-commerce | | `signTransaction()` | ❌ No | ✅ Yes | ✅ Yes | Offline signing, custom submission | | `signStaking()` | ❌ No | ✅ Yes | ✅ Yes | Validator operations | | `signMessage()` | N/A | ❌ No | N/A | Authentication, proof-of-ownership | | `chooseAddress()` | N/A | N/A | N/A | Get user's address (no proof) | ## Luna vs NIM All transaction values in the Hub API are specified in **Luna** (the smallest unit): ::code-group ```ts [convert-currency.ts] // Conversion helper function nimToLuna(nim: number): number { return Math.round(nim * 100000) } function lunaToNim(luna: number): number { return luna / 100000 } // Usage await hubApi.checkout({ appName: 'My App', recipient: address, value: nimToLuna(1.5), // 1.5 NIM = 150,000 Luna }) ``` :: ## Next Steps - Learn about [Account Management](https://nimiq.com/developers/hub/guide/accounts) - Explore [Advanced Features](https://nimiq.com/developers/hub/guide/advanced) (Cashlinks, Swaps, Multi-chain) - See [Starter Template](https://github.com/onmax/nimiq-starter/tree/main/starters/hub-api-ts){rel=""nofollow""} - Check the complete [API Reference](https://nimiq.com/developers/hub/api-reference) # Nimiq Hub ## Get started now Request a payment and get the signed transaction. ::code-group ```bash [pnpm] pnpm add @nimiq/hub-api ``` ```bash [npm] npm install @nimiq/hub-api ``` ```bash [yarn] yarn add @nimiq/hub-api ``` ```bash [CDN] ``` :: ::code-group ```js [Payment Example] import HubApi from '@nimiq/hub-api' const hubApi = new HubApi('https://hub.nimiq.com') const result = await hubApi.checkout({ appName: 'My Shop', recipient: 'NQ07 0000 0000 0000 0000 0000 0000 0000 0000', value: 1_000, // 0.01 NIM in Luna }) console.log('Payment complete:', result.hash) ``` ```js [Authentication] import HubApi from '@nimiq/hub-api' const hubApi = new HubApi('https://hub.nimiq.com') const result = await hubApi.signMessage({ appName: 'My App', message: 'Sign in to My App', }) console.log('Signed by:', result.signer) // Verify signature on your server ``` ```js [Address Selection] import HubApi from '@nimiq/hub-api' const hubApi = new HubApi('https://hub.nimiq.com') const result = await hubApi.chooseAddress({ appName: 'My App', }) console.log('Address:', result.address) console.log('Label:', result.label) ``` :: ::u-page-section --- description: The Hub provides a unified interface for all Nimiq wallet operations. Your users maintain full control of their keys while you get a simple, powerful API. headline: Why Use Hub API title: Secure Wallet Integration Made Simple --- :::u-page-grid ::::u-page-card --- description: Private keys never leave the secure Keyguard environment icon: i-tabler:key-off title: Zero Key Management variant: outline --- :::: ::::u-page-card --- description: Same interface across all Nimiq apps icon: i-tabler:users title: Trusted by Users variant: outline --- :::: ::::u-page-card --- description: Support for Nimiq today; Bitcoin and Polygon flows require a privileged Hub origin icon: i-tabler:timeline title: Multi-Chain Ready variant: outline --- :::: ::::u-page-card --- description: CDN or NPM — start in minutes icon: i-tabler:puzzle title: Simple Integration variant: outline --- :::: ::::u-page-card --- description: Full TypeScript definitions included icon: i-tabler:code title: Type-Safe API variant: outline --- :::: ::::u-page-card --- description: Popup or redirect flows for all devices icon: i-tabler:device-mobile title: Mobile Friendly variant: outline --- :::: ::: :: ::callout --- icon: i-tabler:bulb to: https://nimiq.com/developers/hub/guide/concepts --- **How the Hub Architecture Works** — Learn about the Hub-Keyguard relationship, request behaviors, and security model. :: ::u-page-section --- description: Choose your integration path and start building. headline: Quick Start title: Jump right in --- :::u-page-grid ::::u-page-card --- description: Install the Hub API and make your first request in 5 minutes icon: i-tabler:rocket title: Getting Started Guide to: https://nimiq.com/developers/hub/getting-started variant: outline --- :::: ::::u-page-card --- description: Complete documentation for all Hub methods and types icon: i-tabler:book-2 title: API Reference to: https://nimiq.com/developers/hub/api-reference variant: outline --- :::: ::::u-page-card --- description: Ready-to-use integration boilerplate icon: i-tabler:code-dots title: Starter Template to: https://github.com/onmax/nimiq-starter/tree/main/starters/hub-api-ts variant: outline --- :::: ::: :: ::callout{icon="i-tabler:arrows-exchange"} **Need Lower-Level Control?** — For advanced use cases requiring direct blockchain access, consider using the [Web Client](https://nimiq.com/developers/web-client) or [RPC API](https://nimiq.com/developers/rpc) . :: ## Hub Capabilities Flexible integration options. Choose your integration style, access powerful methods, and support multiple chains. ::callout{icon="i-tabler-bulb"} **Security First** The Hub uses a separate secure origin (Keyguard) to store and manage private keys. Your application **never** has access to user keys — all signing happens in the isolated Keyguard environment. :: ### Choose your integration style Select how the Hub appears to your users. ### Request behaviour ::u-page-grid :::u-page-card --- description: Opens in a centered popup window icon: i-tabler:window title: Popup (Default) variant: outline --- ::: :::u-page-card --- description: Full-page redirect for mobile-friendly flows icon: i-tabler:arrow-back-up title: Redirect variant: outline --- ::: :::u-page-card --- description: Seamless integration for privileged origins icon: i-tabler:layout-grid title: IFrame variant: outline --- ::: :: ### Core Methods ::u-page-grid :::u-page-card --- description: Accept NIM with checkout() and signTransaction() icon: i-tabler:coins title: Payments variant: outline --- ::: :::u-page-card --- description: Sign messages for secure user login with signMessage() icon: i-tabler:signature title: Authentication variant: outline --- ::: :::u-page-card --- description: Create shareable payment links with createCashlink() icon: i-nimiq:gift title: Cashlinks variant: outline --- ::: :: ### Multi-Chain Support ::u-page-grid :::u-page-card --- description: Sign Bitcoin transactions with signBtcTransaction() icon: i-nimiq:logos-bitcoin-mono title: Bitcoin variant: outline --- ::: :::u-page-card --- description: Sign EVM transactions with signPolygonTransaction() icon: i-tabler:hexagon-letter-p title: Polygon variant: outline --- ::: :::u-page-card --- description: Trustless cross-chain trading with setupSwap() icon: i-nimiq:btc-nim-swap title: Atomic Swaps variant: outline --- ::: :: # Best Practices Use this page when you already know what you need to change and want the repo conventions and guardrails in one place. For architecture, file map, and migration context, start with [Developer Center 101](https://nimiq.com/developers/maintainers). For page front matter and `_dir.yml` metadata, see [Front Matter Cheatsheet](https://nimiq.com/developers/maintainers/front-matter-cheatsheet). For landing-page ownership, module ordering, and sidebar file ownership, see [Navigation Map](https://nimiq.com/developers/maintainers/navigation-map). For step-by-step operational tasks, see [Maintenance Workflow](https://nimiq.com/developers/maintainers/maintenance-workflow). ## How To Use This Page Use this guide when you need conventions for: - comments and metadata - CSS comment syntax - validation before committing - deciding which layer should own a change - avoiding common maintenance mistakes If you need architecture, placement, or workflow steps, use the other maintainer pages linked above. ## Comment and Metadata Rules Use front matter for page metadata. Use HTML comments only when you intentionally need a hidden comment inside Markdown body content. Do not use `//` as Markdown comment syntax. ### Markdown Example ```md --- title: Example Page description: Example metadata in front matter. --- ``` ### Rule of Thumb - Use front matter for metadata such as `title`, `description`, `icon`, and `navigation.*` - Use HTML comments for hidden Markdown comments - Do not add new legacy metadata comments like ``, ``, or `` unless the team explicitly decides to keep using them For the exact page and section metadata shape, use [Front Matter Cheatsheet](https://nimiq.com/developers/maintainers/front-matter-cheatsheet). ## CSS Comment Conventions CSS comments use `/* ... */`. Do not use HTML comments in CSS. Do not use `//` comments in CSS files. ### CSS Example ```css /* Global typography tokens */ @theme { --font-sans: 'Mulish', sans-serif; } ``` ## What To Run Before Committing Before committing a meaningful change, use this baseline: ```bash pnpm lint pnpm typecheck pnpm build ``` Use these additional commands when relevant: - `pnpm dev` for visual checks, navigation checks, and content rendering checks - `pnpm build:rpc` when RPC-generated docs or OpenRPC-derived output changed - `pnpm build:web-client` when web-client reference docs changed For fast local iteration, `pnpm exec eslint path/to/file.md` is fine, but it is not the full final validation path. ### Also Know This The repo has a pre-commit hook via `lint-staged` that runs `eslint --fix` on staged `js`, `ts`, `vue`, and `md` files. That is helpful, but it is not a substitute for `pnpm lint`, `pnpm typecheck`, and `pnpm build` before you push important changes. ## Work In The Correct Layer Use these rules of thumb before you start editing: - `content/` is for authored docs and section metadata - `app/components/` is for reusable local Vue UI - `app/app.config.ts` is for shared app and component behavior - `app/assets/css/main.css` is for global CSS, design tokens, and font-family changes - `server/api/` is for remote-backed helpers and endpoints - `scripts/` is for generated-doc refresh logic and other maintenance scripts If the question is "which file owns placement or order?", use [Navigation Map](https://nimiq.com/developers/maintainers/navigation-map). If the question is "what steps should I follow to make this change?", use [Maintenance Workflow](https://nimiq.com/developers/maintainers/maintenance-workflow). ## Maintenance Habits Use these habits to avoid common mistakes: - Do not treat `.nuxt/`, `.output/`, `.data/`, and `.wrangler/` as primary edit targets - Decide whether the change belongs in `content/`, `app/`, `server/`, `scripts/`, or config before editing - Prefer source-of-truth files over generated artifacts - Verify navigation placement whenever you add docs - Verify styling changes both in CSS tokens and in real rendered pages - Run the baseline validation commands before finalizing non-trivial changes # Front Matter Cheatsheet Use this page when you are writing or editing docs content in the Developer Center and need the exact metadata shape for pages and sections. For page placement, landing-page cards, module order, and sidebar behavior, see [Navigation Map](https://nimiq.com/developers/maintainers/navigation-map). For the step-by-step workflow for adding pages, sections, or modules, see [Maintenance Workflow](https://nimiq.com/developers/maintainers/maintenance-workflow). ## Front Matter Cheatsheet These are the front-matter keys currently used in this repo. | Key | What it does | Typical use | Example | | ------------------------- | ------------------------------------------- | ----------------------------------------------------- | ------------------------------------------- | | `title` | Sets the page title | Most normal pages | `content/hub/index.md` | | `description` | Sets the page description | Most normal pages | `content/hub/index.md` | | `icon` | Sets the icon used in navigation or page UI | Most normal pages | `content/rpc/index.md` | | `layout` | Chooses a page layout | Maintainer or special pages | `content/maintainers/index.md` | | `navigation.title` | Overrides the sidebar label | When the sidebar label should be shorter or different | `content/hub/index.md` | | `navigation.order` | Orders the page inside its section | Pages that need explicit ordering | `content/hub/api-reference.md` | | `navigation: false` | Hides the page from generated navigation | Internal or landing pages | `content/index.md` | | `prose: false` | Disables default prose styling | Custom layout pages | `content/nodes/index.md` | | `prev: false` | Hides the previous-page link | Custom overview pages | `content/nodes/index.md` | | `next: false` | Hides the next-page link | Custom overview pages | `content/nodes/index.md` | | `aside: false` | Hides the main aside | Custom overview pages | `content/nodes/index.md` | | `footer: false` | Hides the page footer | Custom overview pages | `content/nodes/index.md` | | `secondarySidebar: false` | Disables secondary sidebar behavior | Special or overview pages | `content/rpc/methods/index.md` | | `pageFooterLeftText` | Sets custom left footer text | Attribution or page-note use cases | `content/web-client/integrations/NextJS.md` | | `changelog: false` | Hides the changelog block | Special reference pages | `content/rpc/methods/index.md` | ### Normal Docs Page ```yaml --- title: Example Page description: Explain what this page covers. icon: i-tabler:book navigation: title: Example order: 2 --- ``` ### Custom Overview Page ```yaml --- title: Example Overview description: Landing-style page for a docs area. icon: i-tabler:layout-grid prose: false prev: false next: false aside: false footer: false secondarySidebar: false navigation: title: Overview order: 1 --- ``` ### Hidden Internal Page ```yaml --- title: Internal Maintainer Page description: Hidden internal documentation. navigation: false layout: docs --- ``` ## How `title` and `description` Work The page title displayed in the header comes from the **H1 heading** in the markdown file, not from the frontmatter `title` field. A remark plugin (`remark-extract-title.mjs`) extracts the H1 text and removes it from the body so it renders once via `UPageHeader`. - **`title` in frontmatter** — used for the sidebar label and SEO. Does not appear as the page heading. - **`# H1` in markdown** — used as the visible page title in the header. - **`description` in frontmatter** — shown as the gray subtitle under the page title. If omitted, no subtitle is shown. ## Add a New Typed Front Matter Field If you want a front matter field to be part of the project's typed content schema, add it in `content.config.ts`. Today, the schema is permissive because it uses `.catchall(z.any())`. That means extra fields can still work even if they are not explicitly typed yet. To formalize a new field: 1. Add it to the `schema` object for the relevant collection. 2. Pick the right Zod type. 3. Keep it optional unless the project really requires it on every page. Example: ```ts schema: z.object({ icon: z.string().optional(), layout: z.string().optional(), description: z.string().optional(), }).catchall(z.any()) ``` Use this when you want stronger typing, clearer conventions, or better editor support for a field that is already becoming standard in the repo. ## Section Metadata With `_dir.yml` Use `_dir.yml` when you need to control metadata for a folder or section instead of a single page. Keys used here today: - `title` - `icon` - `navigation.order` Example: ```yaml title: Integrations icon: i-tabler-puzzle navigation.order: 5 ``` Real examples: - `content/web-client/integrations/_dir.yml` - `content/protocol/consensus/_dir.yml` - `content/rpc/methods/_dir.yml` # Developer Center 101 This page is the architecture and repo-understanding guide for maintainers of the Nimiq Developer Center. It explains how the repository is structured today, what changed in the Nuxt/Docus migration, and where the main source-of-truth files live. ## See Also For conventions, comments, validation, and guardrails, see [Best Practices](https://nimiq.com/developers/maintainers/best-practices). For page front matter and `_dir.yml` metadata, see [Front Matter Cheatsheet](https://nimiq.com/developers/maintainers/front-matter-cheatsheet). For landing-page ownership, module ordering, and sidebar file ownership, see [Navigation Map](https://nimiq.com/developers/maintainers/navigation-map). For the operational steps for running the site and making changes, see [Maintenance Workflow](https://nimiq.com/developers/maintainers/maintenance-workflow). For the current brand layer, visual ownership, asset locations, and external visual dependencies, see [Visual Language Cheatsheet](https://nimiq.com/developers/maintainers/visual-language-cheatsheet). ## What This Repository Is This repository is the source for the Nimiq Developer Center docs site. In the current architecture, it is a Nuxt application that uses Docus, Nuxt Content, Nuxt UI, and Nitro to serve documentation, dynamic docs features, and a small set of server endpoints. In practice, the repo contains five kinds of things: - Authored markdown content under `content/` - App-level UI customization and Vue components under `app/` - Server-side helper endpoints under `server/` - Generated/reference content and generated build artifacts - Runtime and deployment configuration for Cloudflare Workers ## Migration Context This branch is the large migration from the old VitePress-based Developer Center to a Nuxt/Docus-based one. The important architectural changes are: - The site framework moved from VitePress to Nuxt + Docus. - Authored docs were moved into `content/`, which is now the source of truth for most pages. - App customization moved into `app/`, which now contains Vue components, app config, styling, icons, and a small amount of local app logic. - Navigation is no longer driven by a single VitePress theme config file. It is now split across content metadata and app-level module definitions. - Nitro server routes now handle remote-backed or dynamic functionality such as RPC proxying and fetching remote JSON. - The branch also adds AI-facing docs surfaces like MCP and `llms.txt`. The diff looks much larger than the real maintainable change because it includes generated output and runtime artifacts such as `.nuxt/`, `.output/`, and `.data/content/contents.sqlite`. ### What To Care About If you are maintaining the repo, the files and folders that matter most are: - `content/` - `app/` - `server/` - `scripts/` - `nuxt.config.ts` - `content.config.ts` - `app/app.config.ts` ### What Not To Hand-Edit These are usually generated or runtime artifacts and should not be treated as source of truth: - `.nuxt/` - `.output/` - `.data/` - `.wrangler/` Even if these folders appear in the branch diff, they are not the primary place to make maintainable changes. ## Tech Stack ### Core Frameworks - `Nuxt`: the application framework. It owns the app shell, routing, module system, runtime config, and build/deploy pipeline. - `Nitro`: Nuxt's server runtime. It powers the API routes in `server/api/` and the Cloudflare Worker deployment target. - `Vue`: the component layer used for local custom UI in `app/components/`. ### Documentation Layer - `Nuxt Content`: the content engine. It loads markdown files, defines content collections, and powers the docs content model. - `Docus`: the documentation layer built on top of Nuxt and Nuxt Content. It provides the docs layouts, content rendering, assistant integration hooks, search/navigation primitives, and the overall documentation-site structure. - `Nuxt UI`: the UI component system and theme layer used across custom docs UI and MDC components. ### Tooling and Libraries - `pnpm`: package manager - `ESLint`: linting - `TypeScript`: types and app/tooling code - `Wrangler`: Cloudflare Worker tooling - `Iconify`: icon system and custom icon collections - `Typedoc` and `typedoc-plugin-markdown`: generate web-client reference docs - `@open-rpc/meta-schema` plus local scripts: power RPC docs and dynamic RPC method pages - `remark-math` and `rehype-katex`: math rendering in markdown - `ofetch`: server-side fetching in scripts and API handlers ### What Docus Is Docus is the documentation site layer used by this repo. It is not a replacement for Nuxt Content. It sits on top of Nuxt Content. The relationship is: - Nuxt Content provides the content model and markdown loading. - Docus provides the docs experience built on top of that content model. - Nuxt UI provides the component primitives and theming used by the docs experience. In this repo, `nuxt.config.ts` extends `docus`, and then the Developer Center customizes that Docus base with its own content, components, app config, CSS, and patches. ## Top-Level Folder Map The most important folders are: | Path | Purpose | Source of truth? | | -------------------- | ---------------------------------------------------------------------------------------------------- | ---------------------------------------------- | | `content/` | Authored docs pages, section metadata, and most maintainable content | Yes | | `app/` | Local Vue components, app config, icons, utilities, composables, and custom docs UI | Yes | | `server/` | Nitro API routes for remote-backed or helper endpoints | Yes | | `scripts/` | Generation scripts for RPC and web-client docs | Yes | | `data/` | Input data used by dynamic/generated docs, including OpenRPC and generated web-client reference data | Yes, but some files are generated from scripts | | `public/` | Static assets served as-is, such as favicons and public images | Yes | | `patches/` | pnpm patch files applied to dependencies, especially Docus | Yes | | `.pnpm-patch-docus/` | Local checked-in copy of the patched Docus source used to maintain the patch | Yes, for patch maintenance | | `.github/` | CI workflow configuration | Yes | | `.nuxt/` | Nuxt-generated dev/build artifacts and type output | No | | `.output/` | Built site/server output | No | | `.data/` | Generated content database and related runtime artifacts | No | | `.wrangler/` | Wrangler local runtime/deploy state | No | ### Where Key Things Live - Authored docs live in `content/` - Vue components live in `app/components/` - Global styling lives in `app/assets/css/main.css` - App-level theme configuration lives in `app/app.config.ts` - Remote fetch logic lives in `server/api/` - Generated RPC and web-client docs logic lives in `scripts/` ## Key Config Files ### `nuxt.config.ts` `nuxt.config.ts` is the main application and runtime configuration file. In this repo it controls: - app metadata in `app.head` - global CSS inclusion - Nuxt modules such as `@nuxt/eslint` - Nitro and Cloudflare Worker deployment settings - prerendering and route rules - markdown processing for Nuxt Content - icon configuration and custom icon collections - LLMS and MCP-related features It also includes custom logic for: - scanning `content/` to compute prerender routes - excluding dynamic-heavy routes from prerendering - deriving RPC method routes from `data/openrpc-document.json` ### `content.config.ts` `content.config.ts` defines the Nuxt Content collections and the typed content schema used by the app. Today it defines two collections: - `landing`: the landing-page collection, sourced from `index.md` - `docs`: the main documentation collection, sourced from `**/*.md` with selected exclusions The `docs` collection excludes: - `index.md` - `README.md` - `LICENSE.md` - `rpc/methods/[method].md` - files that start with `_` The typed schema currently models: - `icon` - `layout` Everything else is allowed through `catchall(z.any())`, which means the app uses more front matter than the schema strictly types today. ### `app/app.config.ts` `app/app.config.ts` is where the Developer Center customizes the Docus/Nuxt UI layer. It controls things like: - header branding - GitHub link - assistant settings - component slot styling - component variants - theme-level behavior for cards, buttons, page sections, header, navigation, and more If you need to change how shared UI primitives look or behave across the site, this is one of the first files to inspect. ### `app/assets/css/main.css` `app/assets/css/main.css` is the main global stylesheet for the current site. It defines: - CSS variables used to map the Nimiq design system to Nuxt UI tokens - color scales - shared design tokens - Tailwind v4-style `@theme` tokens - global theme-level styling overrides If you need to change colors, design tokens, or global docs styling behavior, start here. Font-family tokens also live here. In the current setup, `--font-sans` and `--font-mono` are defined in the `@theme` block. For working conventions around styling and comments, see [Best Practices](https://nimiq.com/developers/maintainers/best-practices). ### `package.json` `package.json` defines: - the package manager version - local scripts such as `dev`, `build`, `typecheck`, `build:rpc`, and `build:web-client` - runtime dependencies - development dependencies - pnpm patch configuration - lint-staged and git hook behavior It is also the fastest source of truth for how to run the project locally. ## Styling and UI System The current styling stack is: - global styling in `app/assets/css/main.css` - shared component theming in `app/app.config.ts` - utility-class usage in markdown and Vue templates - Nuxt UI as the component system There is no active repo-level `uno.config.ts` in the current architecture. This branch does still carry historical migration context from the old VitePress setup, but the current source-of-truth styling path is the Nuxt/Docus/Nuxt UI stack. ### Before vs Now The links in the "Now" column point to the current `nuxt` migration branch source files. | Area | Before | Now | | --------------------------------- | ----------------------------------------------------------------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | | Site framework | VitePress | [Nuxt + Docus](https://github.com/nimiq/developer-center/blob/nuxt/nuxt.config.ts){rel=""nofollow""} | | Content root | top-level docs folders like `hub/`, `rpc/`, `mini-apps/` | [`content/`](https://github.com/nimiq/developer-center/tree/nuxt/content){rel=""nofollow""} | | Global styling | `.vitepress/theme/main.css` | [`app/assets/css/main.css`](https://github.com/nimiq/developer-center/blob/nuxt/app/assets/css/main.css){rel=""nofollow""} | | Theme and shared UI customization | `.vitepress/theme.config.ts` and `.vitepress/theme/components/**` | [`app/app.config.ts`](https://github.com/nimiq/developer-center/blob/nuxt/app/app.config.ts){rel=""nofollow""} and [`app/components/**`](https://github.com/nimiq/developer-center/tree/nuxt/app/components){rel=""nofollow""} | | Top-level module navigation | `.vitepress/theme.config.ts` | [`app/utils/modules.ts`](https://github.com/nimiq/developer-center/blob/nuxt/app/utils/modules.ts){rel=""nofollow""} plus content metadata | | Content schema | VitePress front matter conventions | [`content.config.ts`](https://github.com/nimiq/developer-center/blob/nuxt/content.config.ts){rel=""nofollow""} | | Remote-backed docs helpers | VitePress/Nitro plugin glue | [`server/api/**`](https://github.com/nimiq/developer-center/tree/nuxt/server/api){rel=""nofollow""} | ## Content Model The current content model is defined in `content.config.ts`. At a high level: - `landing` contains only the homepage at `content/index.md` - `docs` contains the normal markdown docs pages - the schema explicitly types only `icon` and `layout` - other front-matter fields still work because the schema uses `catchall(z.any())` In practice, that means the repo is permissive today: pages use fields like `title`, `description`, and `navigation.*`, even though only a small subset is explicitly typed. For the actual metadata keys and examples, use [Front Matter Cheatsheet](https://nimiq.com/developers/maintainers/front-matter-cheatsheet). ## Navigation Architecture Navigation is now split across several layers. At a high level: - the global module bar comes from `app/utils/modules.ts` - the content tree comes from folder structure under `content/` - section metadata comes from `_dir.yml` - page metadata comes from front matter - the sidebar renderer filters the tree to the current module and special-cases RPC method expansion Use [Navigation Map](https://nimiq.com/developers/maintainers/navigation-map) for the exact file ownership and placement rules. ## Remote-backed and Generated Content Not everything in the site is hand-authored markdown. Two important patterns exist: - remote-backed content served through Nitro endpoints in `server/api/` - generated reference docs and input data maintained through scripts in `scripts/` and `data/` The architecture matters because the maintainable source of truth is usually the endpoint or script, not the generated output. Use [Maintenance Workflow](https://nimiq.com/developers/maintainers/maintenance-workflow) for the operational steps for refreshing or extending those pieces. ## Suggested Reading Order If you are new to the repo, start here: 1. [Developer Center 101](https://nimiq.com/developers/maintainers) 2. [Front Matter Cheatsheet](https://nimiq.com/developers/maintainers/front-matter-cheatsheet) 3. [Navigation Map](https://nimiq.com/developers/maintainers/navigation-map) 4. [Best Practices](https://nimiq.com/developers/maintainers/best-practices) 5. [Maintenance Workflow](https://nimiq.com/developers/maintainers/maintenance-workflow) Then read the actual source files that drive the repo: 1. `package.json` 2. `nuxt.config.ts` 3. `content.config.ts` 4. `app/app.config.ts` 5. `app/assets/css/main.css` 6. `app/utils/modules.ts` 7. a representative content module under `content/` 8. `server/api/` # Maintenance Workflow Use this page when you need the operational steps for working in the Developer Center repository. For conventions and guardrails, see [Best Practices](https://nimiq.com/developers/maintainers/best-practices). For page front matter and `_dir.yml` metadata, see [Front Matter Cheatsheet](https://nimiq.com/developers/maintainers/front-matter-cheatsheet). For page placement, landing-page ownership, module ordering, and sidebar file ownership, see [Navigation Map](https://nimiq.com/developers/maintainers/navigation-map). ## What This Page Is For Use this guide when you need to: - run the site locally - add or update docs pages - add hidden internal pages - add a new section or module - change UI in the correct layer - work with remote-backed data - refresh generated docs - prepare a change for merge ## Run the Site Locally 1. Use Node 22+. 2. Install dependencies: ```bash pnpm install ``` 3. Start the dev server: ```bash pnpm dev ``` 4. If port 3000 is already in use, run: ```bash PORT=3001 HOST=127.0.0.1 pnpm dev ``` `pnpm install` runs `nuxt prepare`, so it may regenerate local Nuxt artifacts before you start the dev server. ## Add a Normal Doc 1. Put the markdown file in the correct folder under `content/`. 2. Add front matter for the page. 3. Use `navigation.title` or `navigation.order` only when placement needs to be explicit. 4. If you are creating a new section, add `_dir.yml` as well. 5. Preview the page locally with `pnpm dev`. Use [Front Matter Cheatsheet](https://nimiq.com/developers/maintainers/front-matter-cheatsheet) for the metadata shape and [Navigation Map](https://nimiq.com/developers/maintainers/navigation-map) for where the page should live. ## Add a Hidden Internal Page 1. Create the markdown file under the correct folder. 2. Add normal page front matter. 3. Set: ```yaml navigation: false ``` That keeps the page routable without including it in generated navigation. ## Add a New Section 1. Create a nested folder under the correct module in `content/`. 2. Add `_dir.yml`. 3. Set `title`, `icon`, and `navigation.order` if label or order matters. 4. Add the section's pages. 5. Preview the sidebar locally and confirm the new section appears in the right place. Use [Navigation Map](https://nimiq.com/developers/maintainers/navigation-map) when you need to confirm which files control section order and sidebar behavior. ## Add a New Module 1. Create a new top-level folder under `content/`. 2. Add the module overview page at `content//index.md`. 3. Add `_dir.yml` if the module or its sections need folder metadata. 4. Add the module entry to `DOC_MODULES` in `app/utils/modules.ts`. 5. Preview the site locally and confirm the new module appears in the global module bar and has the expected sidebar. Use [Navigation Map](https://nimiq.com/developers/maintainers/navigation-map) for the exact ownership points and [Front Matter Cheatsheet](https://nimiq.com/developers/maintainers/front-matter-cheatsheet) for the metadata syntax. ## Add or Change UI 1. Decide which layer owns the change: - `content/` for authored content - `app/components/` for reusable local Vue UI - `app/app.config.ts` for shared app and component behavior - `app/assets/css/main.css` for global CSS, design tokens, and fonts 2. Reuse existing Nuxt UI and local components before creating a new pattern. 3. Add or update the component or styling in the correct layer. 4. Preview the affected pages locally. 5. Validate the change before you merge. Use [Best Practices](https://nimiq.com/developers/maintainers/best-practices) for the guardrails around comments, styling, and validation. ## Work with Remote-backed Data 1. Add or update a Nitro endpoint under `server/api/`. 2. Fetch the external data server-side with `$fetch`. 3. Cache the response in the endpoint instead of having docs pages fetch raw external data from the browser. 4. Point the UI or component at the local endpoint. Current examples: - `server/api/rpc-servers.get.ts` - `server/api/blockchain-explorers.get.ts` Both use `defineCachedEventHandler(...)` and fetch JSON from `nimiq/awesome`. ## Refresh Generated Docs Use these commands when generated docs or their inputs need to be refreshed: ```bash pnpm build:rpc pnpm build:web-client ``` - `pnpm build:rpc` refreshes `data/openrpc-document.json` using `scripts/build-rpc.ts` - `pnpm build:web-client` regenerates the web-client reference docs through Typedoc Treat the scripts and their input data as the source of truth. Do not hand-maintain generated output when the script should be updated instead. ## Before You Merge 1. Confirm you changed the correct source-of-truth files. 2. Run the baseline checks: ```bash pnpm lint pnpm typecheck pnpm build ``` 3. Run `pnpm dev` and visually verify the affected pages if you changed content, navigation, styling, or UI. 4. Run `pnpm build:rpc` or `pnpm build:web-client` only if your change touched those generated-doc flows. 5. Confirm metadata and page placement are correct. 6. Confirm generated files are intentional. Use [Best Practices](https://nimiq.com/developers/maintainers/best-practices) for the repo guardrails and [Navigation Map](https://nimiq.com/developers/maintainers/navigation-map) plus [Front Matter Cheatsheet](https://nimiq.com/developers/maintainers/front-matter-cheatsheet) for the supporting reference details. # Navigation Map Use this page when you need to know which file controls placement, ordering, or a visible navigation surface in the docs experience. For page front matter and `_dir.yml` metadata examples, see [Front Matter Cheatsheet](https://nimiq.com/developers/maintainers/front-matter-cheatsheet). For the step-by-step workflow for adding modules, sections, or pages, see [Maintenance Workflow](https://nimiq.com/developers/maintainers/maintenance-workflow). ## The Three Navigation Layers The Developer Center has three main navigation layers: 1. The landing page at `/`, including homepage sections and cards 2. The top module bar across docs pages, such as Web Client, RPC, AI, and Hub 3. The sidebar inside each module, built from content structure and page metadata Each layer is controlled differently. ## Where To Change What Use this as a fast map. | If you want to change... | Start here | | --------------------------------------------- | ------------------------------------------------------------------ | | Add or reorder landing-page cards | `content/index.md` | | Change homepage sections | `content/index.md` | | Reorder the module bar on every page | `app/utils/modules.ts` | | Change module labels, icons, or routes | `app/utils/modules.ts` | | Change desktop module-bar rendering | `app/components/app/AppHeaderBottom.vue` | | Change mobile module-bar rendering | `app/components/app/AppHeaderBody.vue` | | Reorder pages inside a section | Page front matter `navigation.order` | | Rename a page in the sidebar only | Page front matter `navigation.title` | | Hide a page from generated navigation | `navigation: false` in page front matter | | Reorder generated content sections or folders | `_dir.yml` with `navigation.order` | | Adapt the left sidebar order for a module | `app/components/docs/DocsAsideLeftBody.vue` | | Change sidebar filtering behavior | `app/components/docs/DocsAsideLeftBody.vue` | | Understand RPC methods sidebar special-case | `app/components/docs/DocsAsideLeftBody.vue` and `app/utils/rpc.ts` | ## Global Module Bar The top module bar comes from `DOC_MODULES` in `app/utils/modules.ts`. That array controls: - module label - module icon - module route - module order If you move one object higher or lower in the array, that changes the order everywhere the module bar is rendered. Current rendering files: - `app/components/app/AppHeaderBottom.vue` for desktop - `app/components/app/AppHeaderBody.vue` for mobile Example: ```ts export const DOC_MODULES = [ { label: 'RPC', icon: 'i-custom-nimiq-rpc', to: '/rpc', segment: 'rpc' }, { label: 'Web Client', icon: 'i-custom-nimiq-web-client', to: '/web-client', segment: 'web-client' }, ] ``` In that example, `RPC` would appear before `Web Client`. Write `to` without a trailing slash. `/rpc` and `/rpc/` are distinct routes to Nuxt, and only the canonical (slash-less) form is prerendered. ## Landing Page The homepage is `content/index.md`. That file controls: - the hero at the top - the "Choose your path" cards - quick-start cards - popular resource sections - all landing-page sections and their order Landing-page cards are authored inline using: - `u-page-section` - `u-page-grid` - `u-page-columns` - `u-page-card` Example landing-page card block: ```md ::::u-page-card --- title: RPC description: Build full-stack applications with the JSON-RPC API icon: i-lucide-terminal to: /rpc variant: outline --- :::: ``` If you want to add, remove, reorder, or rewrite homepage cards, `content/index.md` is the place. ## Sidebar Navigation The sidebar inside a docs module comes from Nuxt Content navigation data, which is shaped by: - folder structure under `content/` - `_dir.yml` files - page front matter The main keys that affect sidebar behavior are: - `navigation.title` - `navigation.order` - `navigation: false` The sidebar renderer is `app/components/docs/DocsAsideLeftBody.vue`. If you need to adapt the left sidebar order for a module, start in `app/components/docs/DocsAsideLeftBody.vue`. That component does two important things: 1. It filters the full content navigation down to the current top-level module. 2. It expands `/rpc/methods/` as a special case using generated RPC method groups. So if the question is "why is the sidebar structured this way?", the answer is usually: - content structure and metadata decide the raw navigation tree - `DocsAsideLeftBody.vue` decides how that tree is shown for the current module ## Add a New Module The ownership points for a new top-level module are: - a new top-level folder under `content/` - that module's `index.md` - `_dir.yml` if the module or its sections need folder metadata - the `DOC_MODULES` entry in `app/utils/modules.ts` If you do not add the module to `DOC_MODULES`, it will not appear in the global module bar. ## Add a New Section The ownership points for a new section inside an existing module are: - a nested folder under the module - `_dir.yml` for section metadata - `navigation.order` when section order matters - the pages inside that folder Example `_dir.yml`: ```yaml title: Integrations icon: i-tabler-puzzle navigation.order: 5 ``` ## Add a New Page The ownership points for a normal page are: - the markdown file under the correct folder in `content/` - page front matter for title, description, icon, and navigation metadata - `_dir.yml` if the surrounding section needs ordering or metadata Example: ```yaml --- title: My New Page description: Explain what this page is about. icon: i-tabler:book navigation: title: My Page order: 3 --- ``` ## `content.config.ts` in Navigation Terms `content.config.ts` explains which markdown files become content pages and how they are grouped. In practice: - the `landing` collection contains only `content/index.md` - the `docs` collection contains normal markdown docs pages The `docs` collection excludes: - `index.md` - `README.md` - `LICENSE.md` - `rpc/methods/[method].md` - files that start with `_` That matters because: - the homepage is handled separately from normal docs pages - helper or private underscore files do not show up as regular docs pages - the RPC methods detail route is handled dynamically rather than from a normal markdown page The schema is permissive because it uses `.catchall(z.any())`. That means many front-matter fields work even though only a small subset is explicitly typed there today. If you want stricter front-matter typing later, `content.config.ts` is the file to expand. # Visual Language Cheatsheet Use this page when you need a fast map of where the current Developer Center visual language comes from and which files own which parts of it. For architecture and repo structure, see [Developer Center 101](https://nimiq.com/developers/maintainers). For workflow and validation steps, see [Maintenance Workflow](https://nimiq.com/developers/maintainers/maintenance-workflow). ## Quick Answer The visual stack is layered: - `Docus` and `Nuxt UI` provide the docs shell, component system, and base theming primitives. - `app/assets/css/main.css` maps the Nimiq design language onto those primitives. - `app/app.config.ts` skins shared components such as the header, cards, buttons, sections, and navigation. - `public/` contains the main served brand assets such as logos, favicons, the OG image, and docs images. - a small set of visuals are remote-backed at runtime, most notably blockchain explorer logos fetched from `nimiq/awesome` If you only remember two files, remember these: - `app/assets/css/main.css` - `app/app.config.ts` ## Source Of Truth Map | If you want to change... | Start here | Notes | | -------------------------------------------------------------------- | --------------------------------------------------------------- | ------------------------------------------------------------------------- | | Global colors, design tokens, shadows, radius, and typography tokens | `app/assets/css/main.css` | Main Nimiq brand-layer styling | | Shared component appearance and behavior | `app/app.config.ts` | Header, cards, buttons, sections, navigation, and shared Nuxt UI skinning | | Header logo and main brand mark paths | `app/app.config.ts` plus `public/logos/nimiq/` | The header points to the served logo files | | Module icons in the top navigation | `app/assets/icons/` plus `app/utils/modules.ts` | Custom local Iconify collection with `i-custom-*` names | | Favicons and browser/share branding | `public/favicons/`, `public/og-image.png`, and `nuxt.config.ts` | `nuxt.config.ts` wires the assets into `app.head` | | Docs diagrams and page images | `public/assets/images/` | Pages use `/assets/images/...` paths | | Remote explorer logos shown in docs UI | `server/api/blockchain-explorers.get.ts` | Fetched from `nimiq/awesome` at runtime | ## What Is Framework And What Is Brand Layer Use this split when deciding where a change belongs. ### Framework Layer This is the generic docs and app foundation: - `nuxt.config.ts` extends `docus` - Docus provides the docs layouts and content experience - Nuxt UI provides shared components and theme slots - Nuxt Icon and Iconify provide the icon pipeline This layer explains why the site has a docs shell, cards, navigation menus, and content components. It does **not** define the final Nimiq visual language by itself. ### Nimiq Brand Layer This is the project-specific identity that sits on top of the framework: - Nimiq color scales and semantic token mapping in `app/assets/css/main.css` - shared component styling in `app/app.config.ts` - local logo files in `public/logos/nimiq/` - local module icons in `app/assets/icons/` - local favicons and social image assets in `public/` - docs imagery in `public/assets/images/` If a change is about the "look and feel" of the Developer Center, it usually belongs here. ## Colors And Tokens `app/assets/css/main.css` is the main global styling file for the site. It currently defines: - `Mulish` as the sans font token - `Fira Code` as the mono font token - Nimiq color scales for `primary`, `secondary`, `success`, `info`, `warning`, `error`, and `neutral` - semantic shortcuts such as `--ui-primary` - shared tokens such as radius, container width, shadows, and easing - Tailwind v4-style `@theme` tokens In practice, this is the strongest single file for the Nimiq visual identity. If the question is "where do our colors come from?" or "where does the global look come from?", start here. ## Shared Component Skinning `app/app.config.ts` customizes the Docus and Nuxt UI layer for this project. It currently owns things like: - header branding - the light and dark logo file paths - button shape and hover behavior - card, page-card, page-section, and page-feature styling - header and navigation appearance - content-search font behavior If `main.css` defines the brand tokens, `app/app.config.ts` is where those tokens get applied to the shared UI patterns. ## Typography The active typography is: - `Mulish` for sans text - `Fira Code` for monospace text The font-family tokens are defined in `app/assets/css/main.css`. The current runtime font loading is configured in `nuxt.config.ts` through Google Fonts. There are also local font files under `public/assets/fonts/`, but the current source wiring points at Google Fonts rather than those local files. If you change the site typography, inspect both: - `app/assets/css/main.css` - `nuxt.config.ts` ## Logos And Brand Assets The main served logo files live in: - `public/logos/nimiq/` That folder currently contains: - hexagon marks - horizontal wordmarks - mono variants - white variants - PNG and SVG versions The header logo configuration lives in `app/app.config.ts`. The public-facing design-kit page is: - `content/design-kit.md` That page exposes the official logo downloads and links out to other Nimiq design resources. ## Icons There are three icon sources in the current repo. ### Local Custom Module Icons These live in: - `app/assets/icons/` They are registered as a custom Iconify collection in `nuxt.config.ts` and used as `i-custom-*` icons in places like: - `app/utils/modules.ts` These are the clearest repo-owned icons for the top-level docs modules. ### Bundled Iconify Collections The repo also uses several packaged icon collections such as: - `tabler` - `lucide` - `simple-icons` - `logos` - `carbon` - `vscode-icons` These support many of the generic icons used across docs content and shared UI. ### `i-nimiq:*` Icons `i-nimiq:*` references resolve to the [`nimiq-icons`](https://www.npmjs.com/package/nimiq-icons){rel=""nofollow""} npm package — the Nimiq design system's icon set as an Iconify collection. It is installed as a dev dependency and registered in `nuxt.config.ts` as a custom collection (`prefix: nimiq`). The package ships \~323 icons. Browse the full set in [the Nimiq UI repository](https://github.com/onmax/nimiq-ui){rel=""nofollow""}. Notes for maintainers: - `customCollections` in `nuxt.config.ts` loads `nimiq-icons/icons.json` directly — no separate svg files in this repo. - Adding the collection bumped the client icon bundle past Nuxt Icon's default 256KB limit, so `clientBundle.sizeLimitKb` is set to `512`. - If an `i-nimiq:*` reference fails to render, first confirm the icon name exists in the package (its `icons.json` is the source of truth). Some legacy names from earlier `nimiq-css` versions may not exist (e.g. `wallet`, `duotone-send`) — use a Tabler alternative or a different nimiq icon in those cases. ## Images And Diagrams Docs pages currently reference image paths like: - `/assets/images/protocol/...` - `/assets/images/migration/...` - `/assets/images/learn/...` The served files for those paths live under: - `public/assets/images/` There is also a duplicate checked-in tree under: - `assets/images/` Today, the duplicate files appear to match, but the app code and markdown usage point at the served `public/` paths. If you update a docs image, verify whether both copies need to stay in sync. ## Runtime-Fetched Visuals Most of the visual identity is local, but a few visuals are fetched at runtime. The main example is blockchain explorer logos: - `server/api/blockchain-explorers.get.ts` fetches explorer data from `nimiq/awesome` - `app/components/BlockchainExplorers.vue` renders the returned `logo` fields In practice, those logos can come from: - inline SVG data URIs - remote image URLs from `raw.githubusercontent.com` This means the explorer cards are not fully repo-local brand assets. ## Rule Of Thumb Use this shortcut when deciding where to edit: - If the change is a global look-and-feel change, start in `app/assets/css/main.css`. - If the change is a shared UI pattern change, start in `app/app.config.ts`. - If the change is a logo or favicon swap, start in `public/`. - If the change is a module icon change, start in `app/assets/icons/` and `app/utils/modules.ts`. - If the change is a docs image change, start in `public/assets/images/` and verify the duplicate `assets/images/` tree. - If the change is an explorer-logo issue, inspect `server/api/blockchain-explorers.get.ts` before editing local assets. ## What To Inspect First When investigating visual issues, inspect these files in this order: 1. `app/assets/css/main.css` 2. `app/app.config.ts` 3. `nuxt.config.ts` 4. `public/logos/nimiq/` 5. `app/assets/icons/` 6. `public/assets/images/` 7. `server/api/blockchain-explorers.get.ts` # Legacy Migration Guide (PoW → PoS) ::callout{color="warning" icon="i-tabler-alert-triangle"} This content documents the completed transition from PoW to PoS and is retained for historical reference. :: ## Migration Resources - [Migration for Integrators](https://nimiq.com/developers/migration/migration-integrators) - Guide for integrators migrating to Nimiq 2.0 - [JSON-RPC Migration](https://nimiq.com/developers/migration/migration-json-rpc) - JSON-RPC API changes and migration guide - [Web Developers Migration](https://nimiq.com/developers/migration/migration-web-developers) - Guide for web developers - [Technical Details](https://nimiq.com/developers/migration/migration-technical-details) - Technical migration details and breaking changes # This Page No Longer Exists The transition from PoW to PoS is complete, and this section has been archived. - Learn more about the transition to Proof of Stake in our [blog post](https://www.nimiq.com/blog/nimiq-proof-of-stake-is-now-live/){rel=""nofollow""}. - For technical resources, visit the [Developer Center](https://www.nimiq.com/developers/){rel=""nofollow""}. # Guide for Integrators and Exchanges This guide outlines the key steps and requirements for integrators, such as exchanges, who want to set up and operate a Proof-of-Stake (PoS) node for the Nimiq blockchain. It provides detailed information on node types, hardware requirements and configuration options to facilitate an efficient integration. ### General Considerations for Different Node Options We have the following node types: - **History nodes** (recommend): Stores all transactions since genesis but **does not permanently retain all block data**. However, transactions are never pruned and remain retrievable by their hash and block number. - **Full nodes**: Holds all the blocks and transactions of only roughly the last 24 hours. The configuration of this duration is explained later in this document via the `client.toml`. - **Light nodes**: This node type is **not** suitable for integrators, as it lacks capabilities like a mempool, transaction inclusion and block bodies. It is meant to run on low-end devices like mobile phones and browsers. ### Hardware Requirements and Recommendations per Node Type | PoS Node Type | Memory | CPU | Storage | Network | Syncing Time | | ------------------- | ------------------------------------- | ------------------------------ | ---------------------------------------------------------------- | --------------------------------------------------------------------------------- | --------------------------------------------------- | | History (recommend) | Minimum 16GB RAM (higher recommended) | Minimum 4 vCPUs, 8 recommended | Starts from a few gigabytes, grows linearly with blockchain size | High-speed, reliable internet connection; Good I/O performance (SSDs required) | Sync time increases over the life of the blockchain | | Full | Minimum 8GB RAM | Minimum 4 vCPUs, 8 recommended | Minimum 80GB of storage, 160GB recommended | High-speed, reliable internet connection; Good I/O performance (SSDs recommended) | Sync time grows linearly but slowly | | Light | 1GB RAM recommended | 64-bit recommended | Works with minimal storage | Moderate-speed internet connection (e.g., 1 Mbps or higher) | Syncs in a few seconds | ### JSON-RPC Interface The JSON-RPC interface provides methods for generating addresses, creating/sending transactions, retrieving balances and much more. The full specification is available here: [PoS JSON-RPC Specification](https://nimiq.com/developers/rpc/methods). ### Key JSON-RPC Methods The following methods are particularly useful when interacting with the network: 1. [`getTransactionByHash`](https://nimiq.com/developers/rpc/methods/get-transaction-by-hash): Retrieve transaction details using a transaction hash. 2. [`getTransactionHashesByAddress`](https://nimiq.com/developers/rpc/methods/get-transaction-hashes-by-address): Fetch transaction hashes associated with a given address. 3. [`getBlockNumber`](https://nimiq.com/developers/rpc/methods/get-block-number): Returns the current head block of the node. 4. [`getBlockByNumber`](https://nimiq.com/developers/rpc/methods/get-block-by-number): Returns the block at the specified height 5. [`getRawTransactionInfo`](https://nimiq.com/developers/rpc/methods/get-raw-transaction-info): Get raw transaction details by decoding a serialized transaction. 6. [`isConsensusEstablished`](https://nimiq.com/developers/rpc/methods/is-consensus-established): Returns a boolean specifying if the node has established consensus with the network. 7. [`createBasicTransaction`](https://nimiq.com/developers/rpc/methods/create-basic-transaction): Create a signed transaction and returns a hex-encoded representation without broadcasting it. All `create*Transaction` RPC methods also have an equivalent `send*Transaction` version in order to create and broadcast the transaction one-go. 8. [`sendRawTransaction`](https://nimiq.com/developers/rpc/methods/send-raw-transaction): Sends the given serialized and signed transaction to the network. ### PoW Account and Transaction history Nimiq has transitioned from a PoW system to a PoS system. For those needing access to historical transaction data before the PoS genesis block, a read-only database of the PoW chain is available and can be queried using the [JSON-RPC interface](https://nimiq.com/developers/#json-rpc-interface). Pre-genesis transactions use a different format compared to PoS transactions. Instructions on how to handle and query these pre-genesis transactions will be provided in a future update. ## Getting Started with the PoS Node This section focuses on how to set up and configure your PoS node. The most important configuration settings are outlined below, but it is strongly recommended to review all the sections and apply them based on your requirements. Currently, two methods are supported for running a node: via Docker or by compiling from source code. ### The `nimiq-client` The `nimiq-client` is the central software for operating a PoS node and connecting to the blockchain. Written in Rust, it is completely [open source](https://github.com/nimiq/core-rs-albatross){rel=""nofollow""}. While we make no guarantees about the minimum supported Rust version, we currently test two versions older than the current Rust stable version. Releases follow [Semantic Versioning](https://semver.org/){rel=""nofollow""} rules, meaning patch releases are non-breaking. If you are compiling from source we therefore **recommend** to use the [Github releases](https://github.com/nimiq/core-rs-albatross/releases){rel=""nofollow""} rather than the main branch, as the latter may include breaking changes. A new Docker image is automatically uploaded to the [Github Container registry](https://github.com/nimiq/core-rs-albatross/pkgs/container/core-rs-albatross){rel=""nofollow""} with every new release. ### The `client.toml` The `client.toml` is the configuration file for the `nimiq-client`. It is divided into multiple sections, and most of the properties have default values. Upon running the `nimiq-client` for the first time, an example file is generated by the client and stored at `~/.nimiq/client.example.toml`. Rename this file to `client.toml`, as `~/.nimiq/client.toml` is the default location where the `nimiq-client` will look for configurations. The example file of the `client.toml` is available here: [GitHub](https://github.com/nimiq/core-rs-albatross/blob/albatross/lib/src/config/config_file/client.example.toml){rel=""nofollow""}. ### Important Configuration File Settings When setting up a node, ensure the following settings are properly configured in your `client.toml`. Every property has either a default value or accepted options. The following list highlights the most important ones to get your node up and running: - **network.seed\_nodes:** Depending on whether you are connecting to the PoS Testnet or Mainnet, the relevant seed nodes need to be provided. A list per network is provided [later](https://nimiq.com/developers/#mainnet-and-testnet-seed-nodes) in this document. - **network.tls:** TLS is **optional**; the client uses the [libp2p](https://libp2p.io){rel=""nofollow""} network stack under the hood which enforces encrypted connections between peers out-of-the-box. - **consensus.network**: Set to `main-albatross` in order to connect to the PoS Mainnet (default is Testnet). - **consensus.sync\_mode**: **Must** be `history` or `full` as outlined in [General Considerations](https://nimiq.com/developers/#general-considerations-for-different-node-options). - **consensus.max\_epochs\_stored:** Only applies if `consensus.sync_mode` is set to `full`; configures how long blocks and transactions are kept around before they get pruned (1 epoch translates roughly to 12 hours). - **rpc-server**: Uncomment the JSON-RPC server section (which it is by default) and configure the bind address and port for remote communication if desired. However, it is not recommended to allow communication outside of localhost unless TLS is used. ### Mainnet and Testnet Seed Nodes Both the PoS Mainnet and Testnet have their own seed nodes for initial connection and network discovery within the respective blockchain network. In the `client.toml`, apply the appropriate seed nodes in the `network.seed_nodes` section. **Testnet**: - `/dns4/seed1.pos.nimiq-testnet.com/tcp/8443/wss` - `/dns4/seed2.pos.nimiq-testnet.com/tcp/8443/wss` - `/dns4/seed3.pos.nimiq-testnet.com/tcp/8443/wss` - `/dns4/seed4.pos.nimiq-testnet.com/tcp/8443/wss` **Mainnet**: - `/dns4/aurora.seed.nimiq.com/tcp/443/wss` - `/dns4/catalyst.seed.nimiq.network/tcp/443/wss` - `/dns4/cipher.seed.nimiq-network.com/tcp/443/wss` - `/dns4/eclipse.seed.nimiq.cloud/tcp/443/wss` - `/dns4/lumina.seed.nimiq.systems/tcp/443/wss` - `/dns4/nebula.seed.nimiq.com/tcp/443/wss` - `/dns4/nexus.seed.nimiq.network/tcp/443/wss` - `/dns4/polaris.seed.nimiq-network.com/tcp/443/wss` - `/dns4/photon.seed.nimiq.cloud/tcp/443/wss` - `/dns4/pulsar.seed.nimiq.systems/tcp/443/wss` - `/dns4/quasar.seed.nimiq.com/tcp/443/wss` - `/dns4/solstice.seed.nimiq.network/tcp/443/wss` - `/dns4/vortex.seed.nimiq.cloud/tcp/443/wss` - `/dns4/zenith.seed.nimiq.systems/tcp/443/wss` ### Running the `nimiq-client` — Docker Setup (recommended) For history nodes on mainnet, the full genesis file is required. Follow these instructions to ensure proper setup. 1. Create a `data` folder in the $HOME directory: `mkdir ~/data`. 2. Pull the latest image from the container registry: `docker pull ghcr.io/nimiq/core-rs-albatross:latest`. 3. Create a `client.toml` in `~/data` and populate it with [the example](https://github.com/nimiq/core-rs-albatross/blob/albatross/lib/src/config/config_file/client.example.toml){rel=""nofollow""}. Adjust the configuration based on your requirements and [Important Configuration File Settings](https://nimiq.com/developers/#important-configuration-file-settings). 4. Run the client via Docker. - For history node on **mainnet**: - Make sure to have downloaded the full genesis file as explained in the [README](https://github.com/nimiq/core-rs-albatross?tab=readme-ov-file#history-nodes){rel=""nofollow""}. - Copy the full genesis file into the `data` folder: `cp /path/to/nimiq-genesis-main-albatross.toml ~/data`. - Run the client with the `NIMIQ_OVERRIDE_MAINNET_CONFIG` environment variable: ```text docker run -v $(pwd)/data:/home/nimiq/.nimiq -p 8443:8443 -p 8648:8648 -p 9100:9100 -e NIMIQ_OVERRIDE_MAINNET_CONFIG=/home/nimiq/.nimiq/nimiq-genesis-main-albatross.toml --name nimiq-rpc --rm ghcr.io/nimiq/core-rs-albatross:latest ``` - For other configurations (**non-history** nodes or **non-mainnet**): ```text docker run -v $(pwd)/data:/home/nimiq/.nimiq -p 8443:8443 -p 8648:8648 -p 9100:9100 --name nimiq-rpc --rm ghcr.io/nimiq/core-rs-albatross:latest ``` **Overview of Exposed Ports:** | Port | Description | | ---- | --------------------------------- | | 8443 | Incoming network connections port | | 8648 | RPC port | | 9100 | Metrics port | ### Running the `nimiq-client` — From Source Code (Ubuntu) - Install Rust stable via [Rustup](https://rustup.rs){rel=""nofollow""} - Install required build packages: `apt update && apt install clang cmake libssl-dev pkg-config` - Clone the [source code](https://github.com/nimiq/core-rs-albatross){rel=""nofollow""} and change directory into the repository directory - Checkout to the [latest release](https://github.com/nimiq/core-rs-albatross/releases){rel=""nofollow""} - Within the root of the source code repository, compile the binaries: `cargo build --release --bin nimiq-client` - Run the `nimiq-client`: `cargo run --release --bin nimiq-client` ## Blockchain Explorers For a visual representation of the activity on the PoS blockchain, the following blockchain explorers are available: **Mainnet**: - [NimiqHub](https://nimiqhub.com){rel=""nofollow""} - [Nimiq Watch](https://nimiq.watch){rel=""nofollow""} **Testnet**: - [NimiqHub](https://testnet.nimiqhub.com){rel=""nofollow""} - [Nimiq Watch](https://test.nimiq.watch){rel=""nofollow""} ## Useful Utility Binaries Besides the `nimiq-client` we provide a set of other binaries to facilitate interactions with the network and simplify key tasks. To run these binaries, you need to [compile them from source](https://nimiq.com/developers/#running-the-nimiq-client-%E2%80%94-from-source-code-ubuntu). - `nimiq-address`: Generates a Nimiq address and corresponding key pair. Outputs the user-friendly address, raw address, public key and private key. ```bash cargo run --release --bin nimiq-address -- --help cargo run --release --bin nimiq-address ``` - `nimiq-signtx`: Signs a transaction using key parameters such as sender address, recipient address, value and fee. Outputs the signed transaction in hexadecimal format. ```bash cargo run --release --bin nimiq-signtx -- --help cargo run --release --bin nimiq-signtx -- --secret-key --from --to --value --fee --validity-start-height --network ``` - `nimiq-rpc`: A CLI RPC client that can query all the supported JSON-RPC methods. ```bash cargo run --release --bin nimiq-rpc -- --help cargo run --release --bin nimiq-rpc -- -u URL -U username -P password ``` ## Important PoS Blockchain Properties ### Network Parameters | Parameter | Details | | ----------------------------------- | ----------------------------------------------- | | **Block frequency target** | 1 block per second | | **Maximum transactions per second** | \~700 transactions | | **Blocks per batch** | 60 blocks | | **Batches per epoch** | 720 batches | | **Blocks per epoch** | 43’200 blocks | | **Epoch duration** | \~12 hours | | **Transaction validity window** | 7’200 blocks (\~2 hours) | | **Transaction finality** | After the next macro block (end of every batch) | ### Transaction Validity Window The blockchain has a **\~2 hours** validity window, meaning that a transaction is valid to be included in a block within that timeframe after the transaction's validity start height. If a transaction is not included within this window, it becomes invalid and will be rejected by the network. ### **Transaction Failure** Transactions can fail for multiple reasons, such as missing information or invalid parameters. Before a transaction is added to the blockchain, it must meet all the conditions. If any of the following errors occur, the transaction will be rejected by the network and not be included in a block: - **NoSender**: The sender address is missing from the transaction. - **NoRecipient**: The recipient address is missing. A valid recipient must be provided. - **NoValue**: The transaction value (amount to be transferred) is missing. - **NoValidityStartHeight**: The transaction’s validity start height, which defines from when the transaction becomes valid, is not set. - **NoNetworkId**: The transaction’s network ID is missing. The ID identifies which network the transaction is intended, whether Testnet or Mainnet. ### Transaction Finality Once a valid transaction is included in a **micro block** (blocks containing user-generated transactions), finality is achieved through **macro blocks**. Macro blocks are produced after 59 micro blocks (\~1 minute) using the Tendermint consensus algorithm. Once a macro block is added to the chain, all the transactions from the previous 59 micro blocks are finalized and have become irreversible. ## Reference - Albatross White Paper: {rel=""nofollow""} - Protocol: {rel=""nofollow""} # PoS Migration Guide for JSON-RPC ## 1. General - **`params` property in requests is now required**:br While in PoW the `params` property in requests could be left out for requests that didn't take any parameters (or only optional ones), this is no longer the case in PoS. At least an empty array (`[]`) must now be passed. - **Most params are now required**:br In PoW many parameters could be left out, because they had a default in the server. In PoS most parameters are now required. For non-required parameters, `null` must still be passed in their place to use the server's default. - **The result of a JSON-RPC response is in `result.data`**:br In PoS, every RPC response contains `result: { data, metadata }`. The actual result of the request is in `result.data`, while `result.metadata` contains information about the current chainstate (only for chainstate-related requests, otherwise this is `null`). - **Timestamps are now in milliseconds**:br All timestamps (e.g. for blocks and transactions) are now specified in milliseconds since the Unix epoch. ## 2. Network ### 2.1 Network methods | Method | In Proof-of-Stake | | --------------- | ----------------------------------------------------------------------------------------------------------- | | `peerCount` | Now called `getPeerCount`. | | ~~`syncing`~~ | No equivalent method. | | `consensus` | Use `isConsensusEstablished` instead, which returns `true` when the node has consensus, `false` otherwise. | | `peerList` | Now called `getPeerList`. Only returns an array of IDs (`string[]`) instead of a list of peer info objects. | | ~~`peerState`~~ | No equivalent method. | ## 3. Transactions ### 3.1 Plain transaction objects - `from` & `to` are now the user-friendly addresses. The fields ~~`fromAddress`~~ & ~~`toAddress`~~ have been removed. - `data` has been renamed to `recipientData`. - `timestamp` is now in milliseconds. - ~~`blockHash`~~ has been removed. - ~~`transactionIndex`~~ has been removed. - The following fields have been added: ```ts { fromType: number toType: number senderData: string validityStartHeight: number proof: string networkId: number executionResult: boolean } ``` ### 3.2 Transaction methods | Method | In Proof-of-Stake | | ----------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ | | `sendRawTransaction` | This method doesn't push to the local mempool, it only broadcasts the transaction to all peers. To push the transaction to the local mempool (if available), use `pushTransaction`. | | `createRawTransaction` | Use separate transaction creation methods on the `Consensus` resolver instead. (TODO: link) | | `sendTransaction` | Use separate transaction sending methods on the `Consensus` resolver instad. (TODO: link) | | `getRawTransactionInfo` | No longer has the fields ~~`valid`~~ and ~~`inMempool`~~. See the plain transaction object changes above. | | ~~`getTransactionByBlockHashAndIndex`~~ | No equivalent method. | | ~~`getTransactionByBlockNumberAndIndex`~~ | No equivalent method. | | `getTransactionByHash` | See the plain transaction object changes above. Transactions in the mempool are not discovered. To search in the mempool (if available), use `getTransactionFromMempool`. | | ~~`getTransactionReceipt`~~ | No equivalent method. | | `getTransactionsByAddress` | The `max` parameter's maximum value is `65535` (this might get increased in the future). See the plain transaction object changes above. There is also `getTransactionHashesByAddress` to only receive a list of transaction hashes. | ## 4. Mempool Mempool methods are only available when the node has a mempool. ### 4.1 Mempool methods | Method | In Proof-of-Stake | | ---------------- | ----------------------------------------------------------------------------------------------------- | | `mempoolContent` | No change. See the plain transaction object changes above for when using `includeTransactions: true`. | | `mempool` | No change | | `minFeePerByte` | Now called `getMinFeePerByte` | ## 5. Miner All mining-related methods have been removed as they are no longer relevant. | Method | In Proof-of-Stake | | -------------------------- | ----------------- | | ~~`mining`~~ | Removed | | ~~`hashrate`~~ | Removed | | ~~`minerThreads`~~ | Removed | | ~~`minerAddress`~~ | Removed | | ~~`pool`~~ | Removed | | ~~`poolConnectionState`~~ | Removed | | ~~`poolConfirmedBalance`~~ | Removed | | ~~`getWork`~~ | Removed | | ~~`getBlockTemplate`~~ | Removed | | ~~`submitBlock`~~ | Removed | ## 6. Accounts ### 6.1 Plain account objects - The ~~`id`~~ field has been removed. - The `type` field is now one of these strings: `"basic" | "vesting" | "htlc" | "staking"`. - In vesting accounts, the `owner` field is now the address, the ~~`ownerAddress`~~ field has been removed. - In HTLC accounts, the `sender` & `recipient` fields are now the addresses, the ~~`senderAddress`~~ & ~~`recipientAddress`~~ have been removed. - In HTLC accounts, the `hashRoot` field is now an object containing a `algorithm: 'blake2b' | 'sha256' | 'sha512'` field (replacing the toplevel ~~`hashAlgorithm`~~ field) and a `hash: string` field. ### 6.2 Account methods | Method | In Proof-of-Stake | | --------------- | ------------------------------------------------------------------------------------ | | `accounts` | Renamed to `listAccounts`, only lists addresses (`string[]`). | | `createAccount` | The response no longer has an ~~`id`~~ field, but now includes `privateKey: string`. | | `getBalance` | Removed, use `getAccountByAddress` instead. | | `getAccount` | Renamed to `getAccountByAddress`. See the plain account object changes above. | ## 7. Blockchain ### 7.1. Plain block object Blocks in PoS are one of two types: a micro block or a macro block. Both types can include transactions, although macro blocks only include validator reward transactions from the coinbase (with an empty `proof`). Additionally, micro blocks can be skip blocks which don't include transactions. - `accountsHash` has been renamed to `stateHash`. - `timestamp` is now in milliseconds. - For changes to `transactions` plain objects, see [3.1 Plain transaction objects](https://nimiq.com/developers/#31-plain-transaction-objects). - ~~`difficulty`~~ has been removed. - ~~`nonce`~~ has been removed. - ~~`miner`~~ has been removed. - `minerAddress` for micro blocks is now `producer.validator`. Macro blocks do not have `producer`. - ~~`pow`~~ has been removed. - The following fields have been added: ```ts // All blocks { type: 'micro' | 'macro' batch: number epoch: number network: string version: number seed: string historyHash: string } // Micro blocks { producer: MicroProducer equivocationProofs: Array justification: MicroJustification } // Macro blocks { isElectionBlock: boolean parentElectionHash: string nextBatchInitialPunishedSet: Array justification: MacroJustification } ``` ### 7.2 Blockchain methods | Method | In Proof-of-Stake | | -------------------------------------- | ------------------------------------------------------------------------------------------------------ | | `blockNumber` | Renamed to `getBlockNumber`. To fetch the current block as a plain block object, use `getLatestBlock`. | | ~~`getBlockTransactionCountByHash`~~ | No equivalent method. | | ~~`getBlockTransactionCountByNumber`~~ | No equivalent method. | | `getBlockByHash` | No change. See above for plain block object changes. | | `getBlockByNumber` | No change. See above for plain block object changes. | ## 8. Miscellaneous ### 8.1 Miscellaneous methods | Method | In Proof-of-Stake | | -------------- | --------------------- | | ~~`constant`~~ | No equivalent method. | | ~~`log`~~ | No equivalent method. | # Migration Technical Details Nimiq is transitioning from a Proof-of-Work (PoW) to a Proof-of-Stake (PoS) blockchain. This transition is being carried out through a special hard fork, and will happen in three phases: validator registration, pre-staking, and activation. Each phase operates within a specified block window, enabling transactions to be sent to the network at specific points within the PoW chain. Our approach consists of targeting a specific block height within the PoW chain designated as the *transition block*. At this block height, the blockchain state will be captured and used to generate the "genesis block" for the PoS chain. Instead of starting from block height 0, the PoS chain will start from the same block number as the transition block, if the conditions covered in this document are met. ::callout{color="info" icon="i-tabler-info-circle"} Quotes are used around "genesis block" because it refers to the first block of the PoS chain, though not block 0, as is typical for a genesis block. It is also called the transition block since it marks the shift from PoW to PoS. :: ## Validator Registration Phase The transition begins by establishing the first validator list for the PoS blockchain within the PoW blockchain. This phase is open to all users, and being a miner is not a prerequisite for registering as a validator. Users must complete a series of transactions to indicate their willingness to become validators. To become a validator, users need a validator account, a signing key, and a voting key. Additionally, users must pay a minimum deposit of 100 000 NIM. Any amount exceeding the deposit contributes to the validator's stake as long as it exceeds the minimum deposit for stakers of 100 NIM. This phase involves a series of six transactions to register the validator keys and an additional one to confirm by paying the validator deposit. Users must complete the entire sequence of transactions to have their validator included in the PoS "genesis" block. NIM spent on incomplete registrations will be burned. Nimiq provides a two-mode tool to generate validator keys and send formatted registration transactions to the blockchain. Please refer to [our guide](https://nimiq.com/developers/archive/validator-registration) to learn how to use the tool and pre-register. ### Registration Transactions - **Validator Registration:** The first 6 transactions contain the encoded validator keys. Each transaction must be sent from the account of the registering validator, and have a value of 1 Luna each. - **Deposit Payment and Commitment:** The final step of this phase is to pay the validator deposit of 100 000 NIM and commit to the registration. Unlike the other six transactions, this one can be sent from any account, but the data field must include the registered validator's address to identify the validator. The validator generation transactions include the following data: | Type | Data | | --------- | --------------------------------------------- | | Sender | Validator address | | Recipient | Burn address | | Value | 0.00001 NIM | | Data | Validator keys encoded in 64 bytes, see below | | Validity | Registration block window | Due to the 64-byte data limit of a regular Nimiq transaction, validator keys are split across six transactions. The initial transaction transmits both the signing key and the validator's address. Subsequent transactions are used to progressively send the remainder of the data, particularly the voting key. In addition, each transaction is numbered (1-6). This process ensures the secure transmission and reconstruction of the complete validator keys. Mind that only the public keys are included in these transactions. The private key components are meant to be stored safely. The registration window takes place within a specific range of blocks. The count of validators and their deposits is made at the last block of this phase. ![Structure of validator registration transaction data](https://nimiq.com/developers/assets/images/protocol/migration-txs.png) ## Pre-staking Phase The Pre-Staking phase occurs within a specific range of blocks and is exclusive for staking. During this phase, validator registration transactions are no longer accepted. Users who wish to stake their NIM for the PoS chain launch can send a pre-stake transaction of a minimum of 100 NIM, specifying which pre-registered validator they want to stake with. Any attempt to stake with non-registered validators or incorrect transaction details will result in the loss of the sent NIM. It is critical to follow the instructions exactly to avoid losing funds. Please note that once NIMs are pre-staked for a pre-registered validator, unstaking is not possible in the PoW chain. The stake can only be accessed once the PoS chain begins. Pre-staking can be done through the [Nimiq Wallet](https://wallet.nimiq.com/){rel=""nofollow""}, which features an interface specifically designed to facilitate this. The Nimiq Wallet will provide users with a list of pre-registered validators and pools, allow them to select one, and send their pre-staking transaction. Every Address can only pre-stake for one pre-registered validator. After the pre-staking phase, a clear overview of the registered validators and the total allocated stake will be provided. ## Activation Phase Only pre-registered validators can participate in this phase. The activation phase serves the purpose of executing the transition, planned to start approximately on **November 19th, 2024**. At the first candidate block's height (block 3'456'000), if at least 80% of the total stake signals readiness for the transition, the candidate block becomes the transition block. A special activation tool captures and migrates the state of the PoW chain at the transition block, including the transaction history, to generate the "genesis block" for the new PoS chain. The activation phase follows a specific sequence of events, outlined in the following list. The overall process will be explained in more detail afterward. 1. **3 days** before November 19th, validators running the activation tool will begin sending automatic **online transactions** every hour before the first candidate block is mined to signal their online status. 2. The candidate block is mined at the block height 3'456'000, officially opening the first activation window. 3. The network waits for 10 confirmations after the candidate block to prevent block reversion. 4. After the 10 confirmations, pre-registered validators capture the state at block 3,456,000 and begin generating the PoS "genesis" block. Validators generate the "genesis" block deterministically. The block hash generated should be the same across all validators. 5. After generating the "genesis" block, validators send their readiness transactions, which include the block hash in the data field. 6. The activation tool monitors readiness transactions within a 24-hour window. 7. If 80% of the total stake (represented by registered validators) sends readiness transactions within 24 hours, the PoS chain starts at block height 3,456,000, disregarding any blocks mined after this point. 8. If the 80% readiness threshold is not met within the first 24 hours, a new activation window begins, starting with a new candidate block 1,440 PoW blocks (\~24 hours) after the first. 9. Validators who do not send readiness transactions by the **5th activation window** will no longer be considered part of the readiness voting process and will be deactivated from the first epoch of the PoS chain. This process ensures that inactive validators are removed from consideration to the required threshold. 10. The activation windows will continue every 24 hours until 80% readiness is achieved. Validators who fail to signal readiness in subsequent windows will be progressively removed until the required threshold is reached, ensuring that only active validators participate in the PoS chain when it starts. 11. Once 80% readiness is reached, the PoS client starts, and the once-candidate block becomes the transition block, marking the start of the Nimiq PoS blockchain. ### Online Transactions and Monitoring To ensure a smooth activation, pre-registered validators are encouraged to run the activation tool at least 3 days before November 19th. Once the tool is launched, it will send automatic online transactions every hour (costing 1 Luna each) starting 3 days before the first candidate block is mined to signal that the validator is online. These transactions continue until the validator sends the readiness transaction at block height 3'456'000. Validators who run the tool earlier will only start sending these automatic online transactions 3 days before activation. The purpose of these online transactions is to allow Team Nimiq to monitor which validators are online and ready for the transition. Validators will receive 100 Luna from Team Nimiq to cover the cost of these online and readiness transactions. These transactions help ensure all validators are ready and provide the team with a way to contact those who haven’t shown they are prepared. ### Readiness Transactions Once the first activation window opens, validators send a transaction signaling their readiness. Pre-registered validators are encouraged to run the activation tool before the phase begins, as migrating the entire transaction history is time-consuming. An activation tool has been developed to facilitate this process. The tool migrates the history and scans the PoW chain for readiness transactions, selecting the valid ones that come from pre-registered validators who have completed the registration process. The tool also verifies the `data` field to ensure the genesis hash that validators signaled readiness for matches the candidate transition block generated. The readiness transaction is as follows: | Type | Data | | --------- | ------------------------------------- | | Sender | Validator address | | Recipient | Burn address | | Value | 0.00001 NIM | | Data | Hash of the generated `GenesisConfig` | | Validity | Activation block window | ### Transition Block The `GenesisConfig` is generated after the candidate block is mined. If the pre-registered validators run the tool before the activation window starts, the tool will have already migrated most of the history by the time the candidate block is mined. After the candidate block is mined and the network reaches 80% readiness, the tool migrates the final part of the history and generates the "genesis" block, which becomes the candidate transition block for the PoS chain. The activation process activates at the candidate block. At this point, the tool scans and analyzes transactions sent to the PoW chain. The transition starts if at least 80% of the total stake is ready for the specified candidate transition block. ### Ensuring Migration Completion If the transition does not succeed in the initial activation window, a new window opens immediately, starting from the block after 1,440 PoW blocks (\~24 hours). This process repeats every 24 hours until the 80% readiness threshold is reached, or until the 5th window, at which point unready validators will be marked as inactive and will not count towards the 80% readiness threshold. #### Process Breakdown: - **First Activation Window**: The process begins on November 19th with the first activation window. This window lasts 24 hours, during which validators must send readiness transactions to reach the 80% readiness threshold. - **Subsequent Windows (2–5)**: If the 80% threshold is not met during the first window, new activation windows will open every 24 hours, starting with a new candidate block. This process continues for up to 5 windows. Readiness can be achieved in any of these windows, in which case the PoS chain will start immediately. - **Evaluation at the End of Window 5**: If readiness is still not achieved by the end of the 5th window, validators who have not sent their readiness transactions will be marked as inactive and won't be considered for the 80% readiness threshold. This ensures that only active validators are considered for the migration. - **Window 6 and Onward**: Starting from window 6, we expect to reach 80% readiness more quickly, as unready validators will have been marked as inactive. This allows the migration process to progress faster, ensuring the PoS chain can launch as soon as possible. This process guarantees the migration will succeed by excluding inactive validators, ensuring that only active participants contribute to the readiness threshold. By marking unready validators as inactive, the system ensures that the PoS chain can start efficiently. This mechanism is designed to secure completion of the migration, even if initial readiness is not achieved. ## Nimiq PoS Once 80% readiness is achieved, the PoS chain begins. Any subsequent transaction included in the PoW chain after the candidate transition block is not considered part of the PoS chain. From this point forward, the network operates entirely under the PoS consensus mechanism. # Migration Guide for Web Developers With our shift from Proof-of-Work (PoW) to Proof-of-Stake (PoS), the [Nimiq Web Client](https://nimiq.com/developers/web-client) has undergone significant updates. This comparison page is meticulously crafted to guide you through the enhancements implemented in the new version. We'll highlight critical changes in configuration, client instantiation, wallet creation, transaction handling, and more. ## Nimiq.Wallet The Wallet class has been removed and thus the following functions, too. Here is how you can now create and manage a KeyPair: ### Create a new wallet The *Wallet* class is no longer available. Now you generate a wallet by generating a key pair and use the address. #### Previous (PoW) ```JavaScript const wallet = Nimiq.Wallet.generate(); const address = wallet.address; ``` #### Now (PoS) ```JavaScript const keyPair = Nimiq.KeyPair.generate(); const address = keyPair.toAddress(); ``` ### Load a wallet from a plain private key Previously, loading a wallet from a plain private key involved using the `Wallet.loadPlain()` function. Now, you derive the key pair from the private key. #### Previous (PoW) ```JavaScript const wallet = Nimiq.Wallet.loadPlain(privateKeyHex); const address = wallet.address; ``` #### Now (PoS) ```JavaScript const privateKey = Nimiq.PrivateKey.fromHex(privateKeyHex); const keyPair = Nimiq.KeyPair.derive(privateKey); const address = keyPair.toAddress(); ``` ### Load a wallet from an encrypted private key Previously, you could use the `Wallet.loadEncrypted()` function to derive a wallet from an encrypted private key. This function is no longer available. #### Previous (PoW) ```JavaScript const wallet = await Wallet.loadEncrypted(encryptedHex, password); ``` #### Now (PoS) ```JavaScript // No equivalent yet ``` ### Export the key pair or private key as a plain `Uint8Array` To export the key pair or private key as a plain `Uint8Array`, you need to serialize the key pair or private key. #### Previous (PoW) ```JavaScript const keypairBytes = wallet.exportPlain(); // [privatekey, publickey] const privatekeyBytes = wallet.keyPair.privateKey.serialize(); ``` #### Now (PoS) ```JavaScript const keypairBytes = keyPair.serialize(); // [publickey, privatekey] - to be reversed in 0.22.0 const privatekeyBytes = keyPair.privateKey.serialize(); ``` ### Export the private key as an encrypted Uint8Array Previously, you could export the private key as an encrypted Uint8Array with the `Wallet.exportEncrypted()` function. This function is no longer available. #### Previous (PoW) ```JavaScript const encryptedKey = await wallet.exportEncrypted(password); ``` #### Now (PoS) ```JavaScript // No equivalent yet ``` ### Create and send transactions In order to send a transaction, you need to create a transaction builder and sign it with the key pair. #### Previous (PoW) ```JavaScript const transaction = wallet.createTransaction( Nimiq.Address.fromString(recipient), Nimiq.Policy.coinsToLunas(amount), // Convert from NIM to luna 0, // Fee, optional await client.getHeadHeight() // Current blockchain height ); const txDetails = await client.sendTransaction(transaction); ``` #### Now (PoS) ```JavaScript const transaction = Nimiq.TransactionBuilder.newBasic( keyPair.toAddress(), Nimiq.Address.fromString(recipient), BigInt(amount * 1e5), // Convert from NIM to luna BigInt(0), // Fee, optional await client.getHeadHeight(), await client.getNetworkId(), ); transaction.sign(keyPair); const txDetails = await client.sendTransaction(transaction); ``` ### Convert keys Convert the public and private keys to their hexadecimal string representations. #### Previous (PoW) ```JavaScript const publickeyHex = wallet.publicKey.toHex(); // or wallet.keyPair.publicKey.toHex() const privatekeyHex = wallet.keyPair.privateKey.toHex(); ``` #### Now (PoS) ```JavaScript const publickeyHex = keyPair.publicKey.toHex(); const privatekeyHex = keyPair.privateKey.toHex(); ``` ## Nimiq.Client The Client class is a central component of the Nimiq's new Web Client framework and is essential for interacting with the Nimiq blockchain network under the PoS consensus model. ### Initialization #### Previous (PoW) ```JavaScript import Nimiq from '@nimiq/core'; await Nimiq.init(); Nimiq.GenesisConfig.test(); // Select testnet const configBuilder = Nimiq.Client.Configuration.builder(); const client = configBuilder.instantiateClient(); ``` #### Now (PoS) When using the /web package export, you need to manually call the init function: ```JavaScript // When using the /web package export import init, * as Nimiq from '@nimiq/core/web'; await init(); ``` Then for all package exports, this is how you start a client: ```JavaScript // When using the /web package export const config = new Nimiq.ClientConfiguration(); config.network('TestAlbatross'); // Select testnet const client = await Nimiq.Client.create(config.build()); ``` ### Removed - `public resetConsensus()` - `public getBlockTemplate(minerAddress: Address | string, extraData?: Uint8Array | string)` - `public submitBlock(block: Block)` - `public getTransactionReceipt(hash: Hash | string)` - `public getTransactionReceiptsByHashes(hashes: Array)` - `public addBlockListener(listener: BlockListener)` ## Nimiq.Account In addition to the existing account types `basic (0)`, `vesting (1)`, and `htlc (2)`, Nimiq now has a fourth account type `staking (3)`. Only the staking contract can be type `staking`, no other account can have this type. ### User-friendly addresses The new library doesn’t yet support the `withSpaces` parameter. User-friendly addresses are always returned with spaces. #### Previous (PoW) ```JavaScript public toUserFriendlyAddress(withSpaces?: boolean): string; ``` #### Now (PoS) ```JavaScript toUserFriendlyAddress(): string; ``` ### Luna to NIM conversion #### Previous (PoW) ```JavaScript Nimiq.Policy.lunasToCoins(account.balance); ``` #### Now (PoS) You now have to manually divide any amount in luna by 10.000 to get NIM: ```JavaScript function lunasToCoins(lunas: number): number { return lunas / 1e5; } ``` ## Timestamps Timestamps of transactions and blocks are now in milliseconds, where they were in seconds (UNIX) before. That means you no longer have to multiply them by 1000 to use with `new Date()` in JavaScript: #### Previous (PoW) ```JavaScript const txDate = new Date(transaction.timestamp * 1000); ``` #### Now (PoS) ```JavaScript const txDate = new Date(transaction.timestamp); ``` ## Other ### Send transactions **New capability:** Can now handle `UintArray` ### Transaction state `MINED` is replace by `INCLUDED` # Ethereum Provider API This provider implements [EIP-1193](https://eips.ethereum.org/EIPS/eip-1193){rel=""nofollow""} and supports [EIP-6963](https://eips.ethereum.org/EIPS/eip-6963){rel=""nofollow""} provider discovery. It is injected into the mini app environment. ## Access ```javascript const provider = window.ethereum ``` ## Methods ### `eth_requestAccounts` / `requestAccounts` Requests the user's Ethereum accounts. **Parameters** - none **Returns** - `string[]` — Ethereum addresses. **User confirmation** - yes **Example** ```javascript const accounts = await provider.request({ method: 'eth_requestAccounts' }) ``` ### `personal_sign` / `signPersonalMessage` Signs a message with the user's Ethereum key. **Parameters** - `data` (string, required): message to sign, plain text or hex string (0x-prefixed). - `address` (string, required): Ethereum address to sign with. **Returns** - `string` — hex signature. **User confirmation** - yes **Example** ```javascript const signature = await provider.request({ method: 'personal_sign', params: ['hello', '0x1234567890abcdef1234567890abcdef12345678'], }) ``` ### `eth_sendTransaction` Submits a transaction for signing and broadcasting. **Parameters** - `from` (string, required): sender address. - `to` (string, required): recipient address or contract address. - `value` (string, optional): hex-encoded amount of native token to send (in wei). - `data` (string, optional): hex-encoded contract call data. - `gas` (string, optional): hex-encoded gas limit. **Returns** - `string` — transaction hash. **User confirmation** - yes **Example** ```javascript const txHash = await provider.request({ method: 'eth_sendTransaction', params: [{ from: '0x1234567890abcdef1234567890abcdef12345678', to: '0x1234567890abcdef1234567890abcdef12345678', value: '0x0', data: '0x', }], }) ``` ### `eth_signTypedData_v4` Signs typed structured data. Unlike `personal_sign`, this method presents the user with a readable breakdown of the data being signed, making it suitable for permits, order approvals, or login challenges. This is the current recommended signing method. The data structure follows the [EIP-712](https://eips.ethereum.org/EIPS/eip-712){rel=""nofollow""} standard. See the [MetaMask signing guide](https://docs.metamask.io/metamask-connect/evm/guides/sign-data){rel=""nofollow""} for more context on signing methods. **Parameters** - `address` (string, required): Ethereum address to sign with. - `typedData` (string, required): JSON-stringified object containing `domain`, `types`, `primaryType`, and `message`. **Returns** - `string` — hex signature. **User confirmation** - yes **Example** ```javascript const signature = await provider.request({ method: 'eth_signTypedData_v4', params: [ '0x1234567890abcdef1234567890abcdef12345678', JSON.stringify({ domain: { name: 'My App', version: '1', chainId: 137 }, types: { Message: [{ name: 'content', type: 'string' }] }, primaryType: 'Message', message: { content: 'Hello' }, }), ], }) ``` ### `wallet_switchEthereumChain` / `switchEthereumChain` Switches the active Ethereum network. **Parameters** - `chainId` (string, required): hex chain id. **Returns** - `null`. **Errors** - `4902` — chain not configured. **User confirmation** - yes **Example** ```javascript await provider.request({ method: 'wallet_switchEthereumChain', params: [{ chainId: '0x89' }], }) ``` ### `wallet_addEthereumChain` / `addEthereumChain` Adds a new chain configuration and switches to it. **Parameters** - `chainId` (string, required): hex chain id. - `chainName` (string, required): human-readable name. - `rpcUrls` (string [], required): RPC endpoints (first used). - `nativeCurrency` (object, optional): `{ name: string, symbol: string, decimals: number }`. - `blockExplorerUrls` (string [], optional): block explorer URLs. **Returns** - `null`. **User confirmation** - yes **Example** ```javascript await provider.request({ method: 'wallet_addEthereumChain', params: [{ chainId: '0x89', chainName: 'Polygon', rpcUrls: ['https://polygon-bor-rpc.publicnode.com'], nativeCurrency: { name: 'MATIC', symbol: 'MATIC', decimals: 18 }, blockExplorerUrls: ['https://polygonscan.com'], }], }) ``` ### `rpcCall` Proxies a JSON-RPC call through the host app. **Parameters** - `rpcUrl` (string, required): RPC endpoint URL. - `payload` (object, required): JSON-RPC request payload. **Returns** - JSON-RPC response. **User confirmation** - no **Example** ```javascript const response = await provider.request({ method: 'rpcCall', params: { rpcUrl: 'https://ethereum-rpc.publicnode.com', payload: { jsonrpc: '2.0', id: 1, method: 'eth_chainId', params: [] }, }, }) ``` ## Standard JSON-RPC Methods These methods are routed through `rpcCall`. ### `eth_chainId` Returns the current chain id. **Parameters** - none **Returns** - `string` — hex quantity. **User confirmation** - no **Example** ```javascript const chainId = await provider.request({ method: 'eth_chainId' }) ``` ### `eth_accounts` Returns the connected accounts. **Parameters** - none **Returns** - `string[]` — Ethereum addresses (empty if not connected). **User confirmation** - no **Example** ```javascript const accounts = await provider.request({ method: 'eth_accounts' }) ``` ### `eth_getBalance` Returns the balance for an address. **Parameters** - `address` (string, required): Ethereum address. - `block` (string, required): block tag or hex block number. **Returns** - `string` — hex quantity. **User confirmation** - no **Example** ```javascript const balance = await provider.request({ method: 'eth_getBalance', params: ['0x1234567890abcdef1234567890abcdef12345678', 'latest'], }) ``` ### `eth_call` Executes a read-only contract call. **Parameters** - `tx` (object, required): transaction call object. - `block` (string, required): block tag or hex block number. **Returns** - `string` — hex data. **User confirmation** - no **Example** ```javascript const data = await provider.request({ method: 'eth_call', params: [{ to: '0x1234567890abcdef1234567890abcdef12345678', data: '0x' }, 'latest'], }) ``` ### `eth_estimateGas` Estimates gas for a transaction. **Parameters** - `tx` (object, required): transaction call object. **Returns** - `string` — hex quantity. **User confirmation** - no **Example** ```javascript const gas = await provider.request({ method: 'eth_estimateGas', params: [{ to: '0x1234567890abcdef1234567890abcdef12345678', data: '0x' }], }) ``` ### `eth_gasPrice` Returns the current gas price. **Parameters** - none **Returns** - `string` — hex quantity. **User confirmation** - no **Example** ```javascript const gasPrice = await provider.request({ method: 'eth_gasPrice' }) ``` ### `eth_getTransactionCount` Returns the nonce for an address. **Parameters** - `address` (string, required): Ethereum address. - `block` (string, required): block tag or hex block number. **Returns** - `string` — hex quantity. **User confirmation** - no **Example** ```javascript const nonce = await provider.request({ method: 'eth_getTransactionCount', params: ['0x1234567890abcdef1234567890abcdef12345678', 'latest'], }) ``` ### `eth_getTransactionReceipt` Returns the transaction receipt. **Parameters** - `txHash` (string, required): 0x-prefixed 32-byte hash. **Returns** - `object | null` — `null` if not mined. **User confirmation** - no **Example** ```javascript const receipt = await provider.request({ method: 'eth_getTransactionReceipt', params: ['0x1234567890abcdef1234567890abcdef1234567890abcdef1234567890abcdef'], }) ``` ### `eth_blockNumber` Returns the latest block number. **Parameters** - none **Returns** - `string` — hex quantity. **User confirmation** - no **Example** ```javascript const blockNumber = await provider.request({ method: 'eth_blockNumber' }) ``` ### `eth_getBlockByNumber` Returns block information for a given block. **Parameters** - `block` (string, required): block tag or hex block number. - `includeTxs` (boolean, required): include full transaction objects. **Returns** - `object | null` — `null` if not found. **User confirmation** - no **Example** ```javascript const block = await provider.request({ method: 'eth_getBlockByNumber', params: ['latest', false], }) ``` ### `eth_getLogs` Returns logs matching a filter. **Parameters** - `filter` (object, required): log filter object. **Returns** - `object[]` — log objects. **User confirmation** - no **Example** ```javascript const logs = await provider.request({ method: 'eth_getLogs', params: [{ fromBlock: 'latest' }], }) ``` ### `net_version` Returns the current network id. **Parameters** - none **Returns** - `string` — decimal network id. **User confirmation** - no **Example** ```javascript const networkId = await provider.request({ method: 'net_version' }) ``` For a practical guide to reading ERC-20 token balances and sending token transfers through this provider, see [Using EVM Tokens in Mini Apps](https://nimiq.com/developers/mini-apps/features/evm-tokens). ## EIP-6963 Provider Discovery Nimiq Pay is EIP-6963 compatible and discoverable by wallet discovery flows that support EIP-6963. Mini app developers do not need to manually announce the provider. In most cases, using `window.ethereum` or a standard EIP-6963-compatible discovery library is sufficient. # API Reference This API is injected by the host app into the mini app environment. For Nimiq access, the recommended pattern is to use the Mini App SDK `init()` helper. This section is reference-only. ## Contents - [Nimiq provider](https://nimiq.com/developers/mini-apps/api-reference/nimiq-provider) - [Ethereum provider](https://nimiq.com/developers/mini-apps/api-reference/ethereum-provider) To load and build a mini app, see [Load a Local Mini App in Nimiq Pay](https://nimiq.com/developers/mini-apps/development/load-local-mini-app), the [Mini app tutorial](https://nimiq.com/developers/mini-apps/tutorials/mini-app-tutorial), and [Build a Dual-Chain Mini App with Nimiq Pay](https://nimiq.com/developers/mini-apps/tutorials/dual-chain-mini-app-tutorial). ## Quick Start Examples ### Nimiq Provider ```typescript import { init } from '@nimiq/mini-app-sdk' const nimiq = await init() const accounts = await nimiq.listAccounts() const signed = await nimiq.sign('hello') console.log({ accounts, signed }) ``` ### Ethereum dApp (EIP-1193) ```javascript const provider = window.ethereum const accounts = await provider.request({ method: 'eth_requestAccounts' }) const address = accounts[0] const balance = await provider.request({ method: 'eth_getBalance', params: [address, 'latest'], }) console.log({ address, balance }) ``` # Nimiq Provider API This provider exposes Nimiq blockchain operations and is injected into the mini app environment. ## Access Use the Mini App SDK `init()` helper to wait until Nimiq Pay injects the provider. ```ts import { init } from '@nimiq/mini-app-sdk' const nimiq = await init() ``` ## Methods ### `listAccounts` Returns the user's Nimiq account addresses. **Parameters** - none **Returns** - `string[]` — user-friendly addresses. **Errors** - `PermissionDeniedError` — user rejected the confirmation dialog. **User confirmation** - yes **Example** ```ts const accounts = await nimiq.listAccounts() ``` ### `sign` Signs a message with the user's Nimiq key. **Parameters** - `message` (string | object, required): plain text string or `{ message: string, isHex?: boolean }`. **Returns** - `{ publicKey: string, signature: string }` — hex strings. **Errors** - `PermissionDeniedError` — user rejected the confirmation dialog. **User confirmation** - yes **Example** ```ts const signed = await nimiq.sign('hello') ``` ### `isConsensusEstablished` Checks whether the Nimiq network consensus is established. **Parameters** - none **Returns** - `boolean`. **User confirmation** - no **Example** ```ts const ready = await nimiq.isConsensusEstablished() ``` ### `getBlockNumber` Returns the current Nimiq block height. **Parameters** - none **Returns** - `number`. **User confirmation** - no **Example** ```ts const height = await nimiq.getBlockNumber() ``` ### `sendBasicTransaction` Sends a basic NIM payment. **Parameters** - `recipient` (string, required): Nimiq user-friendly address. - `value` (number, required): amount in Luna (1 NIM = 100,000 Luna). - `fee` (number, optional): transaction fee in Luna. - `validityStartHeight` (number, optional): block height from which the transaction becomes valid. **Returns** - `string` — transaction hash. **Errors** - `PermissionDeniedError` — user rejected the confirmation dialog. - `InvalidTransactionError` — transaction data malformed. **User confirmation** - yes **Example** ```ts const txHash = await nimiq.sendBasicTransaction({ recipient: 'NQ07 0000 0000 0000 0000 0000 0000 0000 0000', value: 100000, // Optional. Nimiq Pay chooses a fee automatically, using 0 if possible. fee: 1000, // Optional. validityStartHeight: 123456, }) ``` ### `sendBasicTransactionWithData` Sends a NIM payment with an attached text message. **Parameters** - `recipient` (string, required): Nimiq user-friendly address. - `value` (number, required): amount in Luna (1 NIM = 100,000 Luna). - `fee` (number, optional): transaction fee in Luna. - `data` (string, required): text message to attach. - `validityStartHeight` (number, optional): block height from which the transaction becomes valid. **Returns** - `string` — transaction hash. **Errors** - `PermissionDeniedError` — user rejected the confirmation dialog. - `InvalidTransactionError` — transaction data malformed. **User confirmation** - yes **Example** ```ts const txHash = await nimiq.sendBasicTransactionWithData({ recipient: 'NQ07 0000 0000 0000 0000 0000 0000 0000 0000', value: 100000, data: 'mic check', // Optional. Nimiq Pay chooses a fee automatically, using 0 if possible. fee: 1000, // Optional. validityStartHeight: 123456, }) ``` ### `sendNewStakerTransaction` Creates a new staking transaction. **Parameters** - `delegation` (string, required): validator address or delegation target. - `value` (number, required): amount in Luna. - `fee` (number, optional): transaction fee in Luna. - `validityStartHeight` (number, optional): block height from which the transaction becomes valid. **Returns** - `string` — transaction hash. **Errors** - `PermissionDeniedError` — user rejected the confirmation dialog. - `InvalidTransactionError` — transaction data malformed. **User confirmation** - yes **Example** ```ts const txHash = await nimiq.sendNewStakerTransaction({ delegation: 'NQ07 0000 0000 0000 0000 0000 0000 0000 0000', value: 100000, // Optional. Nimiq Pay chooses a fee automatically, using 0 if possible. fee: 1000, // Optional. validityStartHeight: 123456, }) ``` ### `sendStakeTransaction` Adds stake to an existing staker. **Parameters** - `value` (number, required): amount in Luna. - `fee` (number, optional): transaction fee in Luna. - `validityStartHeight` (number, optional): block height from which the transaction becomes valid. **Returns** - `string` — transaction hash. **Errors** - `PermissionDeniedError` — user rejected the confirmation dialog. - `InvalidTransactionError` — transaction data malformed. **User confirmation** - yes **Example** ```ts const txHash = await nimiq.sendStakeTransaction({ value: 100000, // Optional. Nimiq Pay chooses a fee automatically, using 0 if possible. fee: 1000, // Optional. validityStartHeight: 123456, }) ``` ### `sendSetActiveStakeTransaction` Sets the active stake amount. **Parameters** - `newActiveBalance` (number, required): active stake amount in Luna. - `fee` (number, optional): transaction fee in Luna. - `validityStartHeight` (number, optional): block height from which the transaction becomes valid. **Returns** - `string` — transaction hash. **Errors** - `PermissionDeniedError` — user rejected the confirmation dialog. - `InvalidTransactionError` — transaction data malformed. **User confirmation** - yes **Example** ```ts const txHash = await nimiq.sendSetActiveStakeTransaction({ newActiveBalance: 100000, // Optional. Nimiq Pay chooses a fee automatically, using 0 if possible. fee: 1000, // Optional. validityStartHeight: 123456, }) ``` ### `sendUpdateStakerTransaction` Updates staker settings. **Parameters** - `newDelegation` (string, required): new validator address or delegation target. - `reactivateAllStake` (boolean, optional): whether to reactivate all stake. - `fee` (number, optional): transaction fee in Luna. - `validityStartHeight` (number, optional): block height from which the transaction becomes valid. **Returns** - `string` — transaction hash. **Errors** - `PermissionDeniedError` — user rejected the confirmation dialog. - `InvalidTransactionError` — transaction data malformed. **User confirmation** - yes **Example** ```ts const txHash = await nimiq.sendUpdateStakerTransaction({ newDelegation: 'NQ07 0000 0000 0000 0000 0000 0000 0000 0000', reactivateAllStake: true, // Optional. Nimiq Pay chooses a fee automatically, using 0 if possible. fee: 1000, // Optional. validityStartHeight: 123456, }) ``` ### `sendRetireStakeTransaction` Retires stake from a staker. **Parameters** - `retireStake` (number, required): amount in Luna to retire. - `fee` (number, optional): transaction fee in Luna. - `validityStartHeight` (number, optional): block height from which the transaction becomes valid. **Returns** - `string` — transaction hash. **Errors** - `PermissionDeniedError` — user rejected the confirmation dialog. - `InvalidTransactionError` — transaction data malformed. **User confirmation** - yes **Example** ```ts const txHash = await nimiq.sendRetireStakeTransaction({ retireStake: 100000, // Optional. Nimiq Pay chooses a fee automatically, using 0 if possible. fee: 1000, // Optional. validityStartHeight: 123456, }) ``` ### `sendRemoveStakeTransaction` Removes stake from a staker. **Parameters** - `value` (number, required): amount in Luna. - `fee` (number, optional): transaction fee in Luna. - `validityStartHeight` (number, optional): block height from which the transaction becomes valid. **Returns** - `string` — transaction hash. **Errors** - `PermissionDeniedError` — user rejected the confirmation dialog. - `InvalidTransactionError` — transaction data malformed. **User confirmation** - yes **Example** ```ts const txHash = await nimiq.sendRemoveStakeTransaction({ value: 100000, // Optional. Nimiq Pay chooses a fee automatically, using 0 if possible. fee: 1000, // Optional. validityStartHeight: 123456, }) ``` # Build with AI AI coding tools generate better code when they have accurate context about the framework you're using. Without it, the AI will suggest patterns that look correct but don't work inside Nimiq Pay. Nimiq provides an **AI skill** for the Mini Apps Framework. This skill gives your AI coding tool the rules, patterns, and API knowledge it needs to generate working mini app code from the start. ## What is a skill? A skill is a set of files with instructions written for AI, not for you. It gets installed into your project and is automatically loaded by your AI coding tool at the start of every session. The AI reads the skill and follows its rules in the background. Skills work with any tool that supports the [Agent Skills](https://skills.sh/){rel=""nofollow""} spec, including Claude Code, Cursor, VS Code Copilot, and others. ## How to install You need [Node.js](https://nodejs.org/){rel=""nofollow""} installed. Run this command in your project directory: ```bash npx skills add nimiq/developer-center --skill mini-apps ``` This pulls the skill from the Nimiq Developer Center GitHub repo and saves it to your project. The exact location depends on your tool (`.claude/skills/`, `.github/skills/`, etc.). The CLI detects which AI tools you have and installs the skill in the right place for each one. It doesn't modify your code, your dependencies, or your build. After installing, open your AI coding tool in the project directory and start working. The skill is picked up automatically by the AI, but you can also invoke it directly. Either way, the AI will have the Nimiq Mini Apps context available. To remove the skill: ```bash npx skills remove mini-apps ``` ## What the skill covers Once installed, the AI will ask how you want to proceed and present these options: | Your situation | What the AI does | | ----------------------------- | ---------------------------------------------------------------------------------------------------------------------------------------- | | Starting from scratch | Asks what you want to build, scaffolds the project, installs the SDK, configures the dev server, verifies the provider connects | | Converting an existing app | Audits your codebase, maps your existing functionality to Nimiq Pay's providers, assesses feasibility, plans and executes the conversion | | Checking if your app is ready | Runs a pre-ship checklist covering provider integration, mobile UI, security, error handling, token correctness, and chain usage | | Just building | Provides the rules, patterns, and API context as an ambient guardrail while you code | You don't need to pick upfront. The AI asks you when the skill activates. If you need inspiration first, check the [Mini App Ideas](https://nimiq.com/developers/mini-apps/ideas) page. The skill also includes local reference files with method signatures, supported chain IDs, and token contract addresses, so the AI has accurate data without needing to fetch external URLs. ## Reference - [Mini Apps Overview](https://nimiq.com/developers/mini-apps) - [Build Your First Mini App](https://nimiq.com/developers/mini-apps/tutorials/mini-app-tutorial) - [Using EVM Tokens](https://nimiq.com/developers/mini-apps/features/evm-tokens) - [Nimiq Provider API](https://nimiq.com/developers/mini-apps/api-reference/nimiq-provider) - [Ethereum Provider API](https://nimiq.com/developers/mini-apps/api-reference/ethereum-provider) - [Agent Skills spec](https://skills.sh/){rel=""nofollow""} # Load a Local Mini App Use this guide to load any locally running web app inside Nimiq Pay. ## Prerequisites - **Node.js** (version 22+, only if your mini app uses Node.js; the examples in this guide use it) - **Nimiq Pay** app installed on a mobile device (or emulator) - Phone and development machine on the same Wi-Fi network ## Start your local app The commands below assume you're using a Node.js mini app. Go to your project directory. ```bash cd my-mini-app ``` Install dependencies. ```bash npm install ``` Start the dev server with network access enabled. ```bash npm run dev -- --host ``` Note the **Network** URL in the terminal output, for example `http://192.168.1.42:5173`. ::callout{color="info" title="HMR over LAN with Docker"} If you're running the Vite dev server inside Docker, hot module reload (HMR) may fail silently when the app is opened on your phone. The HMR client tries to connect through container-internal addresses the phone cannot reach. To fix it, set `VITE_HMR_HOST` to your host machine's LAN IP and add an `hmr` block to your `vite.config`: ```ts const hmrHost = process.env.VITE_HMR_HOST export default defineConfig({ server: { host: true, port: 5173, hmr: hmrHost ? { host: hmrHost, protocol: 'ws', clientPort: 5173 } : undefined, }, }) ``` Then run with the env variable set: `VITE_HMR_HOST= npm run dev -- --host`. Outside Docker, the default Vite config works without this. :: ## Open your local app in Nimiq Pay 1. Open **Nimiq Pay** on your phone. 2. Go to **Mini Apps**. 3. Enter your network URL in the Custom URL field: `http://:5173`. ::callout{color="neutral" title="Secure-Context APIs"} `http://:5173` is not HTTPS, so secure-context-only Web APIs may be unavailable. For example, `crypto.randomUUID()` may work on `localhost` in a desktop browser but fail when the same app is opened from your phone inside a WebView. If your app uses one of these APIs, feature-detect it and add a fallback. For ID generation, use `crypto.getRandomValues()` or a UUID helper that falls back to it. If no fallback is practical, test over local HTTPS. :: Your app should load inside Nimiq Pay. You can also test [this demo](https://github.com/Eligioo/nimiq-mini-app-demo){rel=""nofollow""} to see a working mini app. ## Test on testnet Nimiq Pay has a hidden dev menu with a network switch for testing without real funds. To access it: open the app menu and long-press the settings button for 10 seconds. A dev menu appears with three network options: - **Default**: follows the build type (dev builds use testnet, production builds use mainnet) - **Mainnet**: force mainnet regardless of build type - **Testnet**: force testnet regardless of build type Switching clears transaction history and reloads the app. ::callout --- color: info icon: i-tabler-info-circle title: Testnet applies to Nimiq only --- The testnet switch only affects Nimiq provider operations (NIM payments, signing, staking). EVM mini apps continue running against mainnet chains. To add custom EVM chains for development, use [`wallet_addEthereumChain`](https://docs.metamask.io/metamask-connect/evm/reference/json-rpc-api/wallet_addEthereumChain/){rel=""nofollow""} . :: ### Get testnet NIM To test mini app flows that involve real transactions (payments, signing, staking), a testnet account can claim free NIM directly inside Nimiq Pay. After switching to testnet, the empty-state home screen shows a **Get free NIM** button. Tapping it credits the account with 110'000 testnet NIM per request. The same button is also available inside the **Top Up** modal. ## Tutorials - Build a first mini app: [Mini app tutorial](https://nimiq.com/developers/mini-apps/tutorials/mini-app-tutorial) - Build a dual-chain mini app: [Build a Dual-Chain Mini App with Nimiq Pay](https://nimiq.com/developers/mini-apps/tutorials/dual-chain-mini-app-tutorial) # FAQ Mini apps are web apps that run inside Nimiq Pay and connect to the user's Nimiq or Ethereum wallet through injected providers. This FAQ covers the questions developers most often ask, from what counts as a mini app to how to test, secure, and ship one. ## The basics ### What is a mini app? A mini app is a web application that runs inside Nimiq Pay. It uses injected providers to interact with the user's Nimiq or Ethereum wallet without ever accessing private keys directly. The wallet handles all cryptographic operations, and users approve every sensitive action through native confirmation dialogs. ### What's the difference between a mini app and a regular web app? The provider integration. A mini app must use the Nimiq provider, the Ethereum provider, or both to interact with the user's wallet. Without at least one provider connection, your app runs in Nimiq Pay's WebView, but it's not a mini app in any meaningful sense. The wallet integration is what defines a mini app. ### Does my mini app have to be about payments or crypto? No. Mini apps can be games, calculators, to-do lists, social tools, tipping jars, or productivity utilities. Almost anything. The requirement is that the mini app connects to at least one provider. That connection is what anchors it to the Nimiq Pay ecosystem. If you're looking for inspiration, check our [Mini App Ideas](https://nimiq.com/developers/mini-apps/ideas) page. ### I have no idea what to build. Where do I start? The [Mini App Ideas](https://nimiq.com/developers/mini-apps/ideas) page has a categorized list of mini app concepts, each with a description, which providers it needs, and any external APIs that could power it. Pick one, adapt it, or use it as a starting point for something entirely different. ### Do I need a Nimiq Pay account to use my mini app? Yes. Mini apps run inside Nimiq Pay, so users need the app installed. When your mini app requests wallet access, Nimiq Pay handles authentication and user approval natively. ### Which networks and tokens can my mini app use? Mini apps support NIM natively and all EVM-compatible chains available in Nimiq Pay, including Ethereum mainnet, Polygon, Arbitrum One, Optimism, Base, and BNB Smart Chain, as well as Sepolia for testing. ERC-20 tokens on any supported chain, including USDT on Polygon, are accessible through `window.ethereum` with no extra setup. ## Building ### Do I need to know blockchain development to build a mini app? Not deeply. The Mini Apps Framework abstracts most of the complexity. If you know basic web development, you can build a mini app. For Nimiq provider access, a single `init()` call sets up the connection. For Ethereum, you use standard Web3 patterns via `window.ethereum`. Blockchain knowledge helps when you want to go deeper, but it's not a prerequisite to get started. ### Can I use any frontend framework? Yes. Currently, our tutorials use Vue, React, and Svelte, but those are examples, not requirements. Any framework that runs in a WebView works. The Mini Apps Framework is framework-agnostic. If you're comfortable with a different stack, use it. ### Can my mini app have a backend or server? Yes. The Mini Apps Framework only governs how your app talks to the wallet, through the providers. Beyond that connection, you have full freedom over your stack: backend services, databases, APIs, authentication, business logic. ### Can I use external APIs and services? Yes. Your mini app can call any external API using `fetch()` or your HTTP client of choice. The [Mini App Ideas](https://nimiq.com/developers/mini-apps/ideas) page lists some external APIs that pair well with mini apps, like CoinGecko for prices or OpenWeatherMap for weather data, but you're free to use any API you want. If it needs a secret key, keep it on your own backend rather than in the mini app bundle. ### Can mini apps integrate external payment processors or fiat payment flows? Yes. Mini apps can integrate third-party payment services such as Stripe, fiat on-ramps, or other card payment providers. However, native Google Pay API payments can't be triggered from within a mini app. To qualify for the competition, your mini app must still meaningfully integrate with the Mini Apps Framework and supported providers. ### Can I use open-source libraries and templates? Yes. You can use any npm package, open-source template, or starter kit you like. Just respect the licenses of anything you depend on. ### Do I need to build a mini app from scratch, or can I reuse a project of mine? You don't have to start from scratch. If you already have a web app, you can adapt it. The main change is adding provider integration: connecting to the Nimiq or Ethereum provider and using it for at least one interaction. The `mini-apps` [AI skill](https://nimiq.com/developers/mini-apps/development/build-with-ai) can audit your codebase, map your existing functionality to Nimiq Pay's providers, assess feasibility, and plan the conversion before making any changes. If you don't want to use AI, install the [Mini App SDK](https://www.npmjs.com/package/@nimiq/mini-app-sdk){rel=""nofollow""} for Nimiq provider access or call `window.ethereum` directly for Ethereum, and wire up the interactions that make sense for your app. ### Do I need to use AI tools to build a mini app? No. AI tools are entirely optional. The [Build with AI](https://nimiq.com/developers/mini-apps/development/build-with-ai) page documents a skill that gives AI coding tools accurate context about the framework, which helps them generate working code. If you prefer to build without AI, the tutorials and API reference have everything you need. ## Testing, security, and deployment ### How do I test my mini app during development? Run your dev server with network access enabled, then open Nimiq Pay on a phone connected to the same Wi-Fi network. Go to Mini Apps and enter your local network URL in the Custom URL field. Nimiq Pay also has a hidden dev menu that lets you switch to testnet: open the app menu and long-press the settings button for 10 seconds. ### How do I test my mini app with NIM? You can claim free testnet NIM directly inside Nimiq Pay, which lets you test flows that involve real transactions like payments, signing, and staking. Switch your account to [testnet](https://nimiq.com/developers/#how-do-i-test-my-mini-app-during-development), and the empty-state home screen will show a **Get free NIM** button. Tapping it credits your account with 110'000 testnet NIM per request. The same button is also available inside the **Top Up** modal. ### Can I submit a mini app running on testnet? No. Testnet is for development: use it to test payment flows, signing, and how your mini app behaves. To qualify for the Mini Apps Competition, your mini app must be deployed and live on mainnet. ### How do I handle errors and edge cases when calling the provider? Provider calls can fail in several ways: the user cancels the confirmation dialog, the request times out, no accounts are available, the network is unreachable, or the transaction itself is invalid. Each surfaces as a thrown error your code can inspect. For example, the Nimiq provider throws `PermissionDeniedError` on user rejection, and the Ethereum provider follows the EIP-1193 error codes (for example, `4902` for an unconfigured chain). Treat the cancellation case as a normal outcome, not a bug. Show clear messages to inform the user of the error rather than letting the UI freeze. ### How do I keep API keys and secrets secure? Anything you ship in your mini app's frontend bundle is visible to anyone who opens the app. Treat the WebView like any other browser: never embed private API keys, signing secrets, or credentials directly in client code. If your mini app needs to call a third-party API that requires a secret, route the call through your own backend, which holds the key server-side and forwards the response to your mini app. ### How do I deploy my mini app? Anywhere a web app can be hosted. Vercel, Netlify, Cloudflare Pages, or your own server. Once your mini app is reachable over HTTPS, paste the URL into Nimiq Pay's Custom URL field to load it for testing, or submit it for listing in Nimiq Pay. # Device Identifier in Mini Apps 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. ## Requesting the identifier Call `requestDeviceIdentifier()` with a `reason` string. The reason is shown verbatim to the user in a consent prompt the first time your origin requests it. Subsequent calls from the same origin resolve silently. ```ts import { requestDeviceIdentifier } from '@nimiq/mini-app-sdk' try { const id = await requestDeviceIdentifier({ reason: 'Leaderboard ranking' }) // id: 64-char hex SHA-256, stable for this mini app on this device } catch (error) { // user denied, reason was empty, or not running inside Nimiq Pay } ``` ## How the value behaves | Property | Behaviour | | --------- | ----------------------------------------------------------------------------------------------------- | | Format | 64-character hex string (SHA-256 digest) | | Scope | One value per (device, origin). Different mini apps on the same device receive different identifiers | | Stability | Stable across Nimiq Pay reinstalls and across different user accounts on the same device | | Prompts | First call per origin shows a consent prompt with your `reason`. Later calls resolve without a prompt | The host derives the value by hashing a host-side device ID with your origin, so two mini apps cannot recognise the same device by comparing identifiers. ## What you should not use it for The identifier is for device-scoped state, not user identity. Do not use it for authentication or as a user ID: a shared device returns the same value to every user, and the same user on two devices receives two different identifiers. If you need a user identity, use the Nimiq provider to request the user's account address through [`listAccounts`](https://nimiq.com/developers/mini-apps/api-reference/nimiq-provider#listaccounts). ## Error handling `requestDeviceIdentifier()` rejects in three cases: - **User denied the consent prompt.** - **`reason` is empty.** - **Not running inside Nimiq Pay.** The host API is unavailable outside the Nimiq Pay app. # Using EVM Tokens in Mini Apps The Mini Apps Framework exposes a standard EVM provider through `window.ethereum`. This provider works with any EVM-compatible chain supported by Nimiq Pay, including Polygon, Arbitrum, Base, and others. Any ERC-20 token deployed on those chains is accessible through standard contract calls, with no extra setup. This page uses USDT on Polygon as a working example. The same pattern applies to any ERC-20 token on any supported chain. ## How it works Nimiq Pay generates an EVM wallet from the user's entropy. This wallet uses the same address across all EVM chains. Your Polygon address, Ethereum address, and Arbitrum address are all the same. What changes is which chain you interact with and which token contract you call. The model has three layers: | Layer | What it is | Example | | -------- | --------------------------------------- | ------------------------- | | Provider | The EVM interface injected by Nimiq Pay | `window.ethereum` | | Chain | An EVM-compatible network | Polygon (chain ID `0x89`) | | Token | A smart contract deployed on that chain | USDT (`0xc2132...8e8F`) | No custom provider is needed for Polygon or any other chain. The standard `window.ethereum` provider handles everything. ## Connect and get accounts Before interacting with any chain or token, request the user's accounts: ```javascript const accounts = await window.ethereum.request({ method: 'eth_requestAccounts', }) const userAddress = accounts[0] ``` This triggers a confirmation dialog in Nimiq Pay. The returned address works on all EVM chains. There is no separate "Polygon address" or "Arbitrum address." ## Switch to Polygon To interact with tokens on a specific chain, switch the active network: ```javascript await window.ethereum.request({ method: 'wallet_switchEthereumChain', params: [{ chainId: '0x89' }], // Polygon }) ``` This triggers a confirmation dialog. If the chain is not configured, the provider returns error `4902`. The same method works for any supported chain. Swap the chain ID for the target network. See [Other chains and tokens](https://nimiq.com/developers/#other-chains-and-tokens) for the full list. To add a chain that isn't in the default list, use [`wallet_addEthereumChain`](https://docs.metamask.io/metamask-connect/evm/reference/json-rpc-api/wallet_addEthereumChain/){rel=""nofollow""}. See the [Ethereum Provider API reference](https://nimiq.com/developers/mini-apps/api-reference/ethereum-provider) for parameters. ## Read a USDT balance USDT is an ERC-20 token, which means it is a smart contract that follows a standard interface. Every ERC-20 token has a `balanceOf` method that returns how many tokens an address holds. Calling a smart contract method requires encoding the function call. The examples on this page use [viem](https://viem.sh){rel=""nofollow""} for encoding: ```bash npm install viem ``` ```ts import { encodeFunctionData, formatUnits } from 'viem' // userAddress from eth_requestAccounts (see "Connect and get accounts") // USDT contract address on Polygon const USDT_ADDRESS = '0xc2132D05D31c914a87C6611C10748AEb04B58e8F' // Encode the balanceOf call const data = encodeFunctionData({ abi: [{ name: 'balanceOf', type: 'function', stateMutability: 'view', inputs: [{ name: 'account', type: 'address' }], outputs: [{ name: '', type: 'uint256' }], }], functionName: 'balanceOf', args: [userAddress], }) // Call the contract (read-only, no confirmation needed) const rawBalance = await window.ethereum.request({ method: 'eth_call', params: [{ to: USDT_ADDRESS, data }, 'latest'], }) // Convert from raw units to human-readable // USDT uses 6 decimals: 1 USDT = 1,000,000 raw units const balance = formatUnits(BigInt(rawBalance), 6) console.log(`USDT balance: ${balance}`) ``` **A note on decimals:** USDT and USDC use 6 decimal places, not the 18 used by most ERC-20 tokens. Always use the token's actual `decimals` value when parsing or formatting amounts. A 1 USDT balance displayed with 18 decimals would show as `0.000000000001` instead of `1.0`. ## Send a USDT transfer To send USDT, call the `transfer` method on the token contract. This triggers the native Nimiq Pay approval dialog. The user sees the transaction details and approves it. Keys never leave the wallet. When sending ERC-20 tokens through a mini app, the transaction goes through the EVM provider `window.ethereum`. This is different from sending USDT natively through Nimiq Pay, which uses gas abstraction. In a mini app, standard EVM gas rules apply. ::callout{color="warning" icon="i-tabler-alert-triangle" title="Gas fees"} The user must hold the native token of the chain to cover gas fees. On Polygon, this is POL (formerly MATIC). On Ethereum and Arbitrum, ETH. If the user has no native token balance, the transaction will fail. :: ```ts import { encodeFunctionData, parseUnits } from 'viem' // userAddress from eth_requestAccounts (see "Connect and get accounts") const USDT_ADDRESS = '0xc2132D05D31c914a87C6611C10748AEb04B58e8F' // Encode the transfer: send 10 USDT to a recipient const data = encodeFunctionData({ abi: [{ name: 'transfer', type: 'function', stateMutability: 'nonpayable', inputs: [ { name: 'to', type: 'address' }, { name: 'amount', type: 'uint256' }, ], outputs: [{ name: '', type: 'bool' }], }], functionName: 'transfer', args: [ '0x1234567890abcdef1234567890abcdef12345678', // recipient address parseUnits('10', 6), // 10 USDT (6 decimals) ], }) // Send the transaction const txHash = await window.ethereum.request({ method: 'eth_sendTransaction', params: [{ from: userAddress, to: USDT_ADDRESS, // the contract address, not the recipient data, value: '0x0', // no native token value; this is a contract call }], }) ``` Two things to notice: - The `to` field is the **token contract address**, not the recipient. The actual recipient is encoded in the `data` field as an argument to `transfer`. - The `value` is `0x0` because you are not sending native tokens (like MATIC). You are calling a contract method that moves USDT on your behalf. ## Other libraries The examples above use [viem](https://viem.sh){rel=""nofollow""} for ABI encoding. Any EVM library that accepts an [EIP-1193](https://eips.ethereum.org/EIPS/eip-1193){rel=""nofollow""} provider works with the Mini Apps provider: - **[ethers.js](https://docs.ethers.org){rel=""nofollow""}**: use `Contract` with the ERC-20 ABI and a `BrowserProvider` wrapping `window.ethereum` - **[wagmi](https://wagmi.sh){rel=""nofollow""}**: use `useSendTransaction` and `useReadContract` composables with the injected provider Pick whichever library your stack already uses. The underlying provider is the same. ## Full working example For a complete mini app that connects to Nimiq Pay's EVM wallet and handles sends, receives, and balance tracking across all supported chains, see the reference implementation: [github.com/Albermonte/evm-mini-wallet](https://github.com/Albermonte/evm-mini-wallet){rel=""nofollow""} Built with Vue, viem, and wagmi, it demonstrates wallet connection via EIP-6963, chain switching, ERC-20 balance reading with multicall, and token transfers with gas estimation. ## Other chains and tokens The same pattern applies to any EVM-compatible chain in the [supported list](https://nimiq.com/developers/mini-apps#supported-networks) and any ERC-20 token on those chains. Swap the chain ID and contract address: | Chain | Chain ID | USDT address | | ------------ | -------- | -------------------------------------------- | | Polygon | `0x89` | `0xc2132D05D31c914a87C6611C10748AEb04B58e8F` | | Ethereum | `0x1` | `0xdAC17F958D2ee523a2206206994597C13D831ec7` | | Arbitrum One | `0xa4b1` | `0xFd086bC7CD5C481DCC9C85ebE478A1C0b69FCbb9` | | Optimism | `0xa` | `0x94b008aA00579c1307B0EF2c499aD98a8ce58e58` | For tokens other than USDT, replace the contract address and check the token's `decimals` value. A list of well-known tokens per chain is available in the [reference implementation](https://github.com/Albermonte/evm-mini-wallet/blob/main/src/utils/well-known-tokens.ts){rel=""nofollow""}. For the full Ethereum provider API, see the [Ethereum Provider API reference](https://nimiq.com/developers/mini-apps/api-reference/ethereum-provider). # Localization in Mini Apps Nimiq Pay injects the user's selected language into every mini app before any script runs. The value is available at `window.nimiqPay.language` as an ISO 639-1 two-letter code (`en`, `es`, `de`, `fr`, `pt`). Use it instead of `navigator.language` so your app matches the user's Nimiq Pay language, not the device locale. Outside Nimiq Pay (e.g. during local development in a browser), `window.nimiqPay` is `undefined`. Always use optional chaining when reading it. For the full API details, see the [User Language section](https://nimiq.com/developers/mini-apps#user-language) on the overview page. ## Reading the value Use a three-level fallback: Nimiq Pay language, then device locale, then English. ```javascript function getLanguage() { const nimiqLang = window.nimiqPay?.language if (nimiqLang) return nimiqLang const deviceLang = navigator.language.split('-')[0] if (deviceLang) return deviceLang return 'en' } ``` `navigator.language` returns a BCP 47 tag like `en-US`. The `.split('-')[0]` extracts the two-letter language code. The final fallback to `'en'` covers the case where both are unavailable. ## Translations without a library For most mini apps, a plain object map is enough. No i18n library is needed. Define your translations as a record keyed by language code. Nimiq Pay currently supports five languages: ```javascript const translations = { en: { greeting: 'Hello', tagline: 'Nimiq Pay mini-app starter' }, es: { greeting: 'Hola', tagline: 'Plantilla de mini-app para Nimiq Pay' }, de: { greeting: 'Hallo', tagline: 'Nimiq Pay Mini-App Starter' }, fr: { greeting: 'Bonjour', tagline: 'Starter de mini-app Nimiq Pay' }, pt: { greeting: 'Olá', tagline: 'Modelo de mini-app para Nimiq Pay' }, } function getTranslations(lang) { return translations[lang] ?? translations[navigator.language.split('-')[0]] ?? translations.en } // Usage const lang = getLanguage() const text = t(lang) console.log(text.greeting) // "Hello", "Hola", etc. ``` ::callout{color="info" icon="i-tabler-info-circle" title="TypeScript"} If you're using TypeScript, indexing the translations object with an arbitrary string may cause a type error. Use the `in` operator to check if the key exists before accessing it: ```ts const nimiqPayLanguage = window.nimiqPay?.language const browserLanguage = navigator.language.split('-')[0] const t = (nimiqPayLanguage in translations ? translations[nimiqPayLanguage] : null) ?? (browserLanguage in translations ? translations[browserLanguage] : null) ?? translations.en ``` :: ## Framework examples The examples below show how to make the language value reactive in Vue, React, and Svelte. These are the frameworks covered in the [starter tutorials](https://nimiq.com/developers/mini-apps/tutorials/mini-app-tutorial). If you use a different framework, adapt the same pattern: read `window.nimiqPay?.language` once at init, apply the fallback chain, and use the result to index your translations. ::code-group ```vue [Vue (src/App.vue)] ``` ```js [React (src/App.jsx)] const translations = { en: { greeting: 'Hello', tagline: 'Nimiq Pay mini-app starter' }, es: { greeting: 'Hola', tagline: 'Plantilla de mini-app para Nimiq Pay' }, de: { greeting: 'Hallo', tagline: 'Nimiq Pay Mini-App Starter' }, fr: { greeting: 'Bonjour', tagline: 'Starter de mini-app Nimiq Pay' }, pt: { greeting: 'Olá', tagline: 'Modelo de mini-app para Nimiq Pay' }, } const t = translations[window.nimiqPay?.language] ?? translations[navigator.language.split('-')[0]] ?? translations.en export default function App() { return ( <>

{t.greeting}

{t.tagline}

) } ``` ```bash [Svelte (src/App.svelte)]

{t.greeting}

{t.tagline}

``` :: ## Using an i18n library For apps with many strings or complex pluralization, pass `window.nimiqPay?.language` as the locale to your i18n library of choice (e.g. [`vue-i18n`](https://vue-i18n.intlify.dev/){rel=""nofollow""}, [`react-i18next`](https://react.i18next.com/){rel=""nofollow""}, [`svelte-i18n`](https://github.com/kaisermann/svelte-i18n){rel=""nofollow""}) and set `'en'` as the fallback locale. # Mini App Ideas A collection of ideas for mini apps that run inside Nimiq Pay. Each idea lists what it does, which providers it needs, and any external APIs that could power it. Pick one, adapt it, or use it as a starting point for something entirely different. ## Payments and Commerce | Idea | What it does | Providers | External APIs | | ------------------ | ------------------------------------------------------------------ | --------- | ----------------------------- | | Tip Jar | Accept NIM tips with a shareable link and a live tip counter | Nimiq | | | Invoice Generator | Create and send NIM payment requests with memo text | Nimiq | | | Pay-per-Use Access | Unlock content or features with a one-time NIM payment | Nimiq | | | Split the Bill | Split a restaurant bill among friends, pay each share in NIM | Nimiq | | | Donation Page | Accept NIM or USDT donations with goal tracking and a progress bar | Both | | | Merchant Checkout | Accept USDT on Polygon for physical or digital goods | Ethereum | | | Freelancer Invoice | Send USDT invoices with a payment link, track paid/unpaid status | Ethereum | | | Gift Cards | Purchase and send digital gift cards paid with NIM or USDT | Both | Gift card API (e.g. Reloadly) | ## Finance and Portfolio | Idea | What it does | Providers | External APIs | | ------------------- | ------------------------------------------------------------------------------------------ | --------- | ------------------- | | Portfolio Tracker | Show NIM balance and ERC-20 token holdings across all supported chains | Both | CoinGecko | | Price Alerts | Notify the user when NIM or a token hits a target price | Ethereum | CoinGecko, Push API | | Savings Goal | Set a NIM savings target and track progress over time | Nimiq | | | Staking Dashboard | Stake NIM, view active stake, switch validators, track rewards | Nimiq | | | Multi-Chain Balance | Display native and token balances across Polygon, Arbitrum, Base, and Optimism in one view | Ethereum | | | Expense Tracker | Log transactions with categories and export monthly reports | Both | | ## Games and Entertainment | Idea | What it does | Providers | External APIs | | ------------------- | ----------------------------------------------------------------- | --------- | --------------------- | | Coin Flip | Two players bet NIM on a coin flip with on-chain randomness | Nimiq | | | Trivia Challenge | Answer trivia questions, bet NIM per round, winner takes the pot | Nimiq | Open Trivia DB | | Prediction Market | Bet USDT on outcomes of events (sports, crypto prices, elections) | Ethereum | Sports API, CoinGecko | | NFT Gallery | Browse and display NFTs from the user's EVM wallet | Ethereum | Alchemy, OpenSea API | | Music Jukebox | Pay a small NIM fee to queue songs in a shared playlist | Nimiq | Spotify API | | Meme Generator | Create memes, tip the best ones with NIM | Nimiq | Imgflip API, Giphy | | Rock Paper Scissors | Play against another user with NIM stakes | Nimiq | | ## Social and Community | Idea | What it does | Providers | External APIs | | ------------------- | ---------------------------------------------------------------------------------- | --------- | ------------- | | Proof of Attendance | Sign a message with your Nimiq or Ethereum identity to prove you attended an event | Both | | | Polls with Stakes | Create polls where voters stake NIM on their answer, majority wins the pool | Nimiq | | | Group Poll | Create polls where participants sign their vote with their Nimiq identity | Nimiq | | | Social Feed | Post short messages signed with your Nimiq identity, tip posts with NIM | Nimiq | | | Group Savings | Pool NIM with friends toward a shared goal, transparent balances | Nimiq | | ## Productivity and Utilities | Idea | What it does | Providers | External APIs | | ----------- | -------------------------------------------------------------------------- | --------- | ----------------- | | AI Chat | Chat with an AI model, pay per message or per session in NIM | Nimiq | OpenAI, Anthropic | | File Locker | Upload files to IPFS, pay for pinning with USDT | Ethereum | Pinata, IPFS | | Weather Bet | Bet NIM on tomorrow's weather in your city | Nimiq | OpenWeatherMap | | QR Pay | Generate QR codes that trigger NIM or USDT payments when scanned | Both | | | Pastebin | Create shareable text snippets, tip the author in NIM | Nimiq | | | Translator | Translate text using an AI model, pay per translation in NIM | Nimiq | DeepL, OpenAI | | Faucet | Distribute free testnet NIM to new users, gated by captcha and rate limits | Nimiq | Captcha API | # 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: ```javascript 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 1. Your mini app calls a provider method (for example, request accounts or sign a message) 2. The injected provider forwards a message to the Nimiq Pay app 3. The Nimiq Pay app validates the request and shows a native confirmation dialog (when required) 4. If approved, Nimiq Pay executes the wallet operation (keys never leave the wallet) 5. 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](https://nimiq.com/developers/mini-apps/features/evm-tokens) - 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](https://nimiq.com/developers/mini-apps/features/evm-tokens) 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. ```javascript 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](https://nimiq.com/developers/mini-apps/features/localization). ## 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. ```ts 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](https://nimiq.com/developers/mini-apps/features/device-identifier). ## 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** ```text 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** ```text https://nimpay.app/miniapps/open/your-app.com ``` Tapping this link opens the mini app the same way. It works with any domain. # Build a Dual-Chain Mini App with Nimiq Pay In this tutorial, you will build a mini app that uses both injected providers: - the Nimiq provider for Nimiq account and signing flows - the Ethereum provider for EIP-1193 account and signing flows You will implement methods that require user confirmations so you can test real wallet interactions end to end. ## What you'll build The mini app includes two action buttons: | Flow | Methods | User confirmation expected | | -------- | ---------------------------------------- | --------------------------------------- | | Nimiq | `listAccounts()` -> `sign()` | 2 prompts (account sharing, signing) | | Ethereum | `eth_requestAccounts` -> `personal_sign` | 2 prompts (account connection, signing) | ## Prerequisites - **Node.js** (version 22+ required) - **Nimiq Pay** app on a mobile device (or emulator) - Phone and dev machine on the same Wi-Fi network - At least one Ethereum account available in Nimiq Pay for the Ethereum success path ## 1. Create the project Use Vite with Vue + TypeScript for this tutorial: ```bash npm create vite@latest my-mini-app -- --template vue-ts cd my-mini-app npm install ``` ## 2. Configure the dev server Edit `vite.config.ts`: ```ts import vue from '@vitejs/plugin-vue' import { defineConfig } from 'vite' export default defineConfig({ plugins: [vue()], server: { port: 5173, host: true, }, }) ``` ## 3. Install the Nimiq Mini App SDK Install the published Nimiq Mini App SDK before editing `src/App.vue`. ```bash npm install @nimiq/mini-app-sdk ``` ## 4. Add the dual-chain mini app In `src/App.vue`, use separate script, template, and style blocks. ### 4.1 Add the script block ```vue ``` ### 4.2 Add the template block ```vue ``` ### 4.3 Add the style block (mobile-friendly) ```vue ``` ## 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, see [Localization in Mini Apps](https://nimiq.com/developers/mini-apps/features/localization). ## 6. Run the mini app ```bash npm run dev -- --host ``` Copy the **Network** URL from the terminal output, for example: ```bash 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://:5173` Open your mini app, tap **Run Nimiq flow**, then tap **Run Ethereum flow**. You should see: - Nimiq accounts and a Nimiq signature response. - Ethereum account(s) and an Ethereum signature response. ## Troubleshooting **No Ethereum account returned**:br The Ethereum success path requires at least one account available through Nimiq Pay. **Cannot open local URL from phone**:br Restart the dev server with `--host`, then use the terminal's Network URL. **Secure-context-only API missing**:br If your app uses APIs such as `crypto.randomUUID()`, they may be unavailable when the mini app is loaded from a local network URL like `http://:5173`. Add feature detection and a fallback, or use local HTTPS if the API is required. **Port 5173 is busy**:br Vite chooses another port automatically (for example `5174` or `5175`). Always use the exact Network URL shown in the terminal. # Build Your First Nimiq Mini App In this tutorial, you’ll build a minimal mini app that runs inside Nimiq Pay and calls three Nimiq provider methods: | Method | Description | | -------------------------- | --------------------------------------------- | | `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: ::code-group ```bash [Vue + Vite] npm create vite@latest my-mini-app -- --template vue-ts cd my-mini-app npm install ``` ```bash [React + JSX] npm create vite@latest my-mini-app -- --template react cd my-mini-app npm install ``` ```bash [Svelte] npm create vite@latest my-mini-app -- --template svelte 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`](https://www.npmjs.com/package/@nimiq/mini-app-sdk){rel=""nofollow""}. ```bash npm install @nimiq/mini-app-sdk ``` ## 3. Configure the dev server Enable network access so Nimiq Pay on your device can reach the app: ::code-group ```ts [Vue + Vite (vite.config.ts)] import vue from '@vitejs/plugin-vue' import { defineConfig } from 'vite' export default defineConfig({ plugins: [vue()], server: { port: 5173, host: true, }, }) ``` ```js [React + JSX (vite.config.js)] import react from '@vitejs/plugin-react' import { defineConfig } from 'vite' export default defineConfig({ plugins: [react()], server: { port: 5173, host: true, }, }) ``` ```js [Svelte (vite.config.js)] import { svelte } from '@sveltejs/vite-plugin-svelte' import { defineConfig } from 'vite' export default defineConfig({ plugins: [svelte()], server: { port: 5173, host: true, }, }) ``` :: ## 4. Add mini app logic and UI Replace the main app component with the variant for your framework: ::code-group ```vue [Vue + Vite (src/App.vue)] ``` ```jsx [React + JSX (src/App.jsx)] import { init } from '@nimiq/mini-app-sdk' import { useEffect, useRef, useState } from 'react' function getProviderErrorMessage(value) { if (typeof value !== 'object' || value === null || !('error' in value)) return null const maybeError = value.error if (maybeError && typeof maybeError.message === 'string') return maybeError.message return 'Provider request failed.' } function App() { const nimiqPromiseRef = useRef(null) const [isConnecting, setIsConnecting] = useState(true) const [isReady, setIsReady] = useState(false) const [accounts, setAccounts] = useState(null) const [consensus, setConsensus] = useState(null) const [blockNumber, setBlockNumber] = useState(null) const [errorMessage, setErrorMessage] = useState(null) useEffect(() => { let ignore = false async function connect() { try { nimiqPromiseRef.current = init({ timeout: 10000 }) await nimiqPromiseRef.current if (!ignore) setIsReady(true) } catch (error) { if (!ignore) setErrorMessage(error instanceof Error ? error.message : String(error)) } finally { if (!ignore) setIsConnecting(false) } } connect() return () => { ignore = true } }, []) async function runThreeRequests() { if (!nimiqPromiseRef.current) return setErrorMessage(null) try { const nimiq = await nimiqPromiseRef.current const [accountsResult, consensusResult, blockResult] = await Promise.all([ nimiq.listAccounts(), nimiq.isConsensusEstablished(), nimiq.getBlockNumber(), ]) const accountsError = getProviderErrorMessage(accountsResult) if (accountsError) throw new Error(accountsError) setAccounts(accountsResult) setConsensus(consensusResult) setBlockNumber(blockResult) } catch (error) { setErrorMessage(error instanceof Error ? error.message : String(error)) } } return (

Nimiq Mini App

{isConnecting && (

Waiting for Nimiq Pay to initialize the provider...

)} {!isConnecting && !isReady && (

Open this mini app inside Nimiq Pay to connect to the Nimiq provider.

)} {accounts && (
          Accounts:
          {JSON.stringify(accounts)}
        
)} {consensus !== null && (
          Consensus:
          {String(consensus)}
        
)} {blockNumber !== null && (
          Block:
          {String(blockNumber)}
        
)} {errorMessage &&

{errorMessage}

}
) } export default App ``` ```svelte [Svelte (src/App.svelte)]

Nimiq Mini App

{#if isConnecting}

Waiting for Nimiq Pay to initialize the provider...

{:else if !isReady}

Open this mini app inside Nimiq Pay to connect to the Nimiq provider.

{/if} {#if accounts}
Accounts: {JSON.stringify(accounts)}
{/if} {#if consensus !== null}
Consensus: {String(consensus)}
{/if} {#if blockNumber !== null}
Block: {String(blockNumber)}
{/if} {#if errorMessage}

{errorMessage}

{/if}
``` :: ## 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](https://nimiq.com/developers/mini-apps/features/localization). ## 6. Run the mini app Start the Vite dev server: ```bash npm run dev -- --host ``` Note the **Network** URL in the terminal, for example: ```bash 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://: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://:5173`. Add feature detection and a fallback. For the full list of available methods and events, see the [Nimiq Provider API](https://nimiq.com/developers/mini-apps/api-reference/nimiq-provider) and [Ethereum Provider API](https://nimiq.com/developers/mini-apps/api-reference/ethereum-provider). You can also check [this demo](https://github.com/Eligioo/nimiq-mini-app-demo){rel=""nofollow""} repository to see all supported methods. # Network upgrades Network upgrades, or hard forks, introduce coordinated changes to the Nimiq protocol. Upgrade implementations are released ahead of activation so validators and node operators can review the changes and decide whether to update their client. Activation follows the mechanism defined for each upgrade, such as validator stake signaling or a predetermined block height. The actions, timing, and activation method vary per upgrade. Track upcoming and past upgrades in the table below, and follow the page for the specific upgrade you are preparing for. ## Upgrades | Upgrade | Status | Who acts | Activation | What's changing | | --------------------------------------------------------------------------------- | --------- | -------------------------- | ------------------------------ | ----------------------------------------- | | [v2.0.0 hard fork](https://nimiq.com/developers/network-upgrades/upgrades/v2-0-0) | Completed | Validators, node operators | Stake signaling, 80% threshold | Security-relevant protocol improvements | | [PoS migration](https://nimiq.com/developers/migration) | Completed | Validators, node operators | Fixed block | Proof-of-Work to Proof-of-Stake consensus | Status is one of **Proposed** (published, no action yet), **In progress** (actions are live), or **Completed** (activated; the chain runs the upgraded rules). Each upgrade page carries its own detailed status and, where relevant, a live readiness dashboard. ## Where releases are announced - **Validators**: CERT Validators Telegram channel. - **Node operators**: Coders Dojo Telegram channel. ## Further reading - [Run a node](https://nimiq.com/developers/nodes): set up and operate a Nimiq node. - [Becoming a validator](https://nimiq.com/developers/nodes/validators/becoming-a-validator): validator setup. - [Protocol](https://nimiq.com/developers/protocol): how the protocol works, including consensus and block production. # v2.0.0 hard fork The v2.0.0 hard fork introduces security-relevant improvements to the Nimiq protocol. Its activation is coordinated through validator stake signaling rather than a predetermined block height. Validators independently decide whether to install the patch and signal readiness. The upgrade cannot be activated by the Nimiq team or any individual network participant. It becomes eligible for activation only after validators representing at least 80% of the active stake have signaled readiness. Installing the patch and signaling readiness are separate actions. The patch is backwards compatible: a patched client that has not sent a signaling transaction keeps operating under the current consensus rules and does not count toward the 80% threshold. **Phase 1, validators**: apply the security patch, restart your client, and manually send a signaling transaction. This happens before the hard fork. **Phase 2, node operators**: after activation, update to the public release to stay on the upgraded chain. Validators act in Phase 1 only. Node operators operate only in Phase 2. ## Phase 1: Validators Validators receive the security patch through the CERT channel. The patch contains the hard fork code. ### Before you start You will need: - The security patch from the CERT channel: the gist or the Docker image. - Your [validator cold key](https://nimiq.com/developers/protocol/validators/validator-keys): the private key of the Schnorr keypair your validator address is derived from, generated with `nimiq-address` when you [set up your validator](https://nimiq.com/developers/nodes/validators/becoming-a-validator#generating-your-validator-address-and-keys). The signaling transaction is signed with it. ### Step 1: Apply the patch and restart **From source** 1. Stop the running `nimiq-client`. 2. Apply the patch you received from the CERT channel. 3. Rebuild and restart: `cargo build --release --bin nimiq-client`, then run `cargo run --release --bin nimiq-client`. The run command loads the config file from its default location. If you keep your `client.toml` at a non-default path, point the client to it by appending `-- -c /path/to/client.toml` to the run command, as described under option B in [Configuration](https://github.com/nimiq/core-rs-albatross#configuration){rel=""nofollow""}. **Docker** 1. Stop the running container. 2. Pull the prebuilt image from the CERT channel. 3. Start a new container from the new image, reusing your existing data volume, ports, and config. Once restarted, your validator runs the patched client and is ready to signal. ### Step 2: Send the signaling transaction 1. Confirm you are running the patched client from Step 1; you can check the client version with the `get_client_version` RPC command. 2. Signal support after you update your client. The transaction must be signed with your validator cold key. To make this easier, we provide the `nimiq-mktx` tool to build and sign this specific transaction. The tool runs offline and does not broadcast the transaction; it prints the signed transaction as a hex string, which you send to the network in the next step. You can also build the signaling transaction with any other tooling you prefer. ```bash cargo run --release --bin nimiq-mktx validator signal-upgrade --validity-start ``` | Parameter | Description | | ------------------------------- | ----------------------------------------------------------------------------------------------------------------- | | `` | The network version to signal. Use `2`. | | `` | Secret key of the wallet that pays the transaction fee. | | `` | Your validator secret cold key. | | `` | The validity-start block. Use a recent block number, such as the current one; it should not be far in the future. | The command prints the signed transaction as a hex string. This transaction is not on the network yet. Broadcast it with the `sendRawTransaction` RPC method, passing the hex string as the `raw_tx` parameter. Using the RPC client: ```bash cargo run --release --bin nimiq-rpc send-raw-transaction ``` The call returns the transaction hash. Look it up in a blockchain explorer to confirm the transaction was included and confirmed. ### What happens after you signal The fork requires 80% of the stake represented by validators to signal readiness. Once readiness reaches 80%, the fork can activate at any subsequent election macro block. Whether a given election macro block triggers a fork depends on its proposer: the proposer must be willing to fork. If 80% is not reached, the chain continues to produce blocks under the current consensus rules. Unlike the PoS migration, which was activated at a fixed block, this fork has no fixed activation block. Readiness is re-evaluated at each election macro block until the threshold is met. If the threshold is never reached, you do not need to take any further action: the patched client keeps running as it does today. You can track readiness on the [dashboard](https://upgrade.nimiq.network/dashboard/){rel=""nofollow""} throughout this phase. ::callout{color="success" icon="i-tabler-circle-check"} Validators are finished with the upgrade after this phase. The Phase 2 public release is not required for validators, but keep your client up to date with subsequent public releases as you normally would. :: ## Phase 2: Node operators Phase 2 starts only after the chain has been upgraded, immediately following the fork. A public release is published at that point and announced in the Coders Dojo Telegram channel. Node operators who want to follow the upgraded chain must apply it. Validators are not required to, since they already applied the patch. Because the release ships after the fork, your node stays on the pre-fork client through activation and follows the upgraded chain once you apply the release. ### Update your client After the fork activates, stop your running client or container, then update to `v2.0.0` from source or Docker. ::code-group ```bash [From source] git fetch --tags git checkout v2.0.0 cargo build --release --bin nimiq-client cargo run --release --bin nimiq-client ``` ```bash [Docker] docker pull ghcr.io/nimiq/core-rs-albatross:v2.0.0 # Stop the old container and start a new one from the new image, # reusing your existing data volume, ports, and config. ``` :: When running from source, the run command loads the config file from its default location. If you keep your `client.toml` at a non-default path, point the client to it by appending `-- -c /path/to/client.toml` to the run command, as described under option B in [Configuration](https://github.com/nimiq/core-rs-albatross#configuration){rel=""nofollow""}. Once updated, your node follows the upgraded chain. Node operators are finished after this step. ## Support - **Validators**: CERT Validators Telegram channel. - **Node operators**: Coders Dojo Telegram channel. # Address Book Provides mapping of addresses to their corresponding labels for mainnet pools, services, and exchanges. ## Usage ### Get label for known address ```typescript import { AddressBook } from '@nimiq/utils/address-book' // Get label for known address const poolAddress = 'NQ48 8CKH BA24 2VR3 N249 N8MN J5XX 74DB 5XJ8' const label = AddressBook.getLabel(poolAddress) console.log(label) // 'Skypool' ``` ### Handle unknown addresses ```typescript // Unknown address returns null const unknownAddress = 'NQ01 2345 6789 0123 4567 8901 2345 6789 0123' const unknownLabel = AddressBook.getLabel(unknownAddress) console.log(unknownLabel) // null ``` ### Use in UI ```typescript // Use in UI function displayAddress(address) { const label = AddressBook.getLabel(address) return label ? `${label} (${address})` : address } ``` ## API | Method | Description | | --------------------------- | ----------------------------------------------- | | `getLabel(address: string)` | Returns label for address, or null if not found | # Albatross Policy Constants and utility functions for blockchain configuration, supply, and block calculations. ## Usage ### Basic usage ```typescript import { batchIndexAt, epochIndexAt, SLOTS_PER_EPOCH } from '@nimiq/utils/albatross-policy' const currentEpoch = epochIndexAt(blockNumber) const batch = batchIndexAt(blockNumber) console.log(`Block ${blockNumber} is in epoch ${currentEpoch}, batch ${batch}`) ``` ## API | Method | Description | | --------------------------- | ------------------------------------------ | | `epochIndexAt(blockNumber)` | Returns epoch index for given block number | | `batchIndexAt(blockNumber)` | Returns batch index for given block number | | `SLOTS_PER_EPOCH` | Number of slots in each epoch | | `BATCHES_PER_EPOCH` | Number of batches in each epoch | | `BLOCKS_PER_BATCH` | Number of blocks in each batch | | `TOTAL_SUPPLY` | Total supply in smallest units | # Browser Detection Utility for detecting browser details including type, version, private mode, and device information. ## Usage ### Detect browser type ```typescript import BrowserDetection from '@nimiq/utils/browser-detection' // Detect browser type if (BrowserDetection.isChrome()) { console.log('Chrome browser detected') } ``` ### Detect device type ```typescript // Detect device type if (BrowserDetection.isMobile()) { console.log('Mobile device') } ``` ### Get detailed info ```typescript // Get detailed info const info = BrowserDetection.getBrowserInfo() console.log(`${info.name} version ${info.version}`) ``` ### Check private mode ```typescript // Check private mode (async) const isPrivate = await BrowserDetection.isPrivateMode() if (isPrivate) { console.log('Private browsing detected') } ``` ## API | Method | Description | | ------------------ | ----------------------------------------------------- | | `isChrome()` | Returns true if Chrome browser | | `isFirefox()` | Returns true if Firefox browser | | `isSafari()` | Returns true if Safari browser | | `isEdge()` | Returns true if Edge browser | | `isMobile()` | Returns true if mobile device | | `isIOS()` | Returns true if iOS device | | `isPrivateMode()` | Returns promise that resolves to true if private mode | | `getBrowserInfo()` | Returns object with browser name and version | # Clipboard Utility for copying text to the clipboard with mobile compatibility. ## Usage ### Basic copy ```typescript import { Clipboard } from '@nimiq/utils/clipboard' // Basic copy const success = Clipboard.copy('Hello, World!') console.log(success) // true if successful ``` ### Copy address with feedback ```typescript // Copy address with feedback const address = 'NQ48 8CKH BA24 2VR3 N249 N8MN J5XX 74DB 5XJ8' if (Clipboard.copy(address)) { console.log('Address copied to clipboard!') } else { console.log('Copy failed - try again') } ``` ### Copy in click handler ```typescript // Copy in click handler button.addEventListener('click', () => { const text = button.dataset.copyText Clipboard.copy(text) }) ``` ## API | Method | Description | | -------------------- | ---------------------------------------------------- | | `copy(text: string)` | Copies text to clipboard, returns true if successful | # Cookie Utilities Utility functions for managing cookies including getting, setting, and unsetting. ## Usage ### Basic cookie operations ```typescript import { getCookie, setCookie, unsetCookie } from '@nimiq/utils/cookie' setCookie('theme', 'dark', { expires: 7 }) const theme = getCookie('theme') console.log(theme) // 'dark' ``` ## API | Method | Description | | ---------------------------------- | ---------------------------------------------------- | | `getCookie(name: string)` | Gets cookie value by name, returns null if not found | | `setCookie(name, value, options?)` | Sets cookie with optional expiration and path | | `unsetCookie(name: string)` | Removes cookie by setting expiration to past date | # Currency Info Provides currency information including code, symbol, name, and decimal precision. ## Usage ### Basic usage ```typescript import { CurrencyInfo } from '@nimiq/utils/currency-info' // Basic usage const usd = new CurrencyInfo('USD') console.log(usd.symbol) // '$' console.log(usd.name) // 'US Dollar' console.log(usd.decimals) // 2 ``` ### With custom locale ```typescript // With custom locale const eur = new CurrencyInfo('EUR', 'de-DE') console.log(eur.locale) // 'de-DE' ``` ### Multiple currencies ```typescript // Multiple currencies const currencies = ['USD', 'EUR', 'GBP'].map(code => new CurrencyInfo(code)) currencies.forEach((curr) => { console.log(`${curr.name}: ${curr.symbol}`) }) ``` ## API | Method | Description | | --------------------------------- | -------------------------------------------------------- | | `new CurrencyInfo(code, locale?)` | Creates currency info for given code and optional locale | | `code` | Three-letter currency code (e.g., 'USD') | | `symbol` | Currency symbol (e.g., '$') | | `name` | Full currency name (e.g., 'US Dollar') | | `decimals` | Number of decimal places for currency | | `locale` | Locale string for formatting | # Fiat API Provides unified interface for accessing fiat exchange rates from various APIs. ## Usage ### Get current rates ```typescript import { getExchangeRates, getHistoricExchangeRatesByRange } from '@nimiq/utils/fiat-api' // Get current rates const rates = await getExchangeRates('USD', ['EUR', 'GBP']) console.log(rates) // { EUR: 0.85, GBP: 0.73 } ``` ### Get single rate ```typescript // Get single rate const eurRate = await getExchangeRates('USD', 'EUR') console.log(eurRate) // 0.85 ``` ### Get historic rates ```typescript // Get historic rates const historic = await getHistoricExchangeRatesByRange( 'NIM', new Date('2024-01-01'), new Date('2024-01-31') ) console.log(historic) // Array of daily rates ``` ## API | Method | Description | | ----------------------------------------------------- | ------------------------------------------------------- | | `getExchangeRates(from, to)` | Gets current exchange rates from one currency to others | | `getHistoricExchangeRatesByRange(currency, from, to)` | Gets historic rates for date range | | `supportedFiatCurrencies` | Array of supported fiat currency codes | # Formattable Number Formats and converts numbers without precision loss with customizable formatting options. ## Usage ### Basic formatting ```typescript import { FormattableNumber, toNonScientificNumberString } from '@nimiq/utils/formattable-number' // Basic formatting const number = new FormattableNumber('12345.6789') const formatted = number.toString({ maxDecimals: 2, useGrouping: true }) console.log(formatted) // '12,345.68' ``` ### Math operations ```typescript // Math operations const a = new FormattableNumber('100.5') const b = new FormattableNumber('25.25') const sum = a.plus(b) console.log(sum.toString()) // '125.75' ``` ### Scientific notation conversion ```typescript // Scientific notation conversion const scientific = toNonScientificNumberString('1.23e4') console.log(scientific) // '12300' ``` ### Rounding ```typescript // Rounding const price = new FormattableNumber('123.456789') price.round(2) console.log(price.toString()) // '123.46' ``` ## API | Method | Description | | ---------------------------------- | -------------------------------------------------------------- | | `new FormattableNumber(value)` | Creates instance from number, string, or BigInt | | `toString(options?)` | Formats number with optional decimals, grouping, separators | | `round(decimals)` | Rounds to specified decimal places | | `equals(other)` | Compares equality with another FormattableNumber | | `plus(other)` | Adds another number and returns new instance | | `minus(other)` | Subtracts another number and returns new instance | | `multipliedBy(other)` | Multiplies by another number and returns new instance | | `dividedBy(other)` | Divides by another number and returns new instance | | `toNonScientificNumberString(num)` | Static method to convert scientific notation to regular string | # Nimiq Utils ::u-page-section --- description: Every utility has been battle-tested in production scenarios, from the official Nimiq Wallet to third-party integrations. headline: Why Nimiq Utils title: Built for real-world applications --- :::u-page-grid ::::u-page-card --- description: Optimized algorithms and minimal overhead icon: i-tabler:bolt title: Performance First variant: outline --- :::: ::::u-page-card --- description: Works with any JS framework & SSR safe icon: i-tabler:components title: Framework Agnostic variant: outline --- :::: ::::u-page-card --- description: Intuitive APIs designed for developer productivity icon: i-tabler:adjustments title: Flexible & Great DX variant: outline --- :::: ::::u-page-card --- description: Comprehensive docs with examples & real-world use cases icon: i-tabler:book title: Well-Documented variant: outline --- :::: ::::u-page-card --- description: Powers Nimiq Wallet & other official ecosystem apps icon: i-tabler:wallet title: Production Used variant: outline --- :::: ::::u-page-card --- description: 100% open source with community contributions welcome icon: i-tabler:heart title: Open Source variant: outline --- :::: ::: :: ::u-page-section --- description: See Nimiq Utils in action with real-world code snippets title: Quick Examples --- :::code-group ```ts [address-validation.ts] import { ValidationUtils } from '@nimiq/utils' // Validate Nimiq address format ValidationUtils.isValidAddress('NQ48 8CKH BA24...') // → true // Check if it's a user-friendly address ValidationUtils.isUserFriendlyAddress('NQ48 8CKH BA24...') // → true ``` ```ts [address-conversion.ts] import { AddressBook } from '@nimiq/utils' // Convert between address formats const userFriendly = 'NQ48 8CKH BA24 Y7R5 GXM9 PQ8R HHGJ' const hex = AddressBook.toHex(userFriendly) // → '84c8e...' // Convert back to user-friendly const address = AddressBook.fromHex(hex) // → 'NQ48 8CKH BA24 Y7R5 GXM9 PQ8R HHGJ' ``` ```ts [currency-formatting.ts] import { FormattableNumber } from '@nimiq/utils' // Format NIM amounts const amount = new FormattableNumber(1.5, 5) amount.toString() // → "1.50000" amount.toCurrency('NIM') // → "1.50 NIM" // Auto-format with locale amount.toLocaleString() // → "1.50000" ``` ```ts [fiat-rates.ts] import { getExchangeRates } from '@nimiq/utils' // Get current exchange rates const rates = await getExchangeRates(['nim'], ['usd', 'eur']) // → { nim: { usd: 0.012, eur: 0.011 } } // Calculate fiat value const nimValue = 100 const usdValue = nimValue * rates.nim.usd ``` ```ts [supply-calculator.ts] import { posSupplyAt } from '@nimiq/utils' // Get total supply at specific time const supply = posSupplyAt(Date.now()) // → 3000000000 (in smallest unit) // Get supply at block height const supplyAtBlock = posSupplyAt(1000000) ``` ::: :: ::u-page-section --- description: Browse all available utility modules by category title: All Modules --- :::u-page-grid :u-page-card{title="Address Book" to="https://nimiq.com/developers/nimiq-utils/address-book" variant="outline"} :u-page-card{title="Albatross Policy" to="https://nimiq.com/developers/nimiq-utils/albatross-policy" variant="outline"} :u-page-card{title="Browser Detection" to="https://nimiq.com/developers/nimiq-utils/browser-detection" variant="outline"} :u-page-card{title="Clipboard" to="https://nimiq.com/developers/nimiq-utils/clipboard" variant="outline"} :u-page-card{title="Cookie Utilities" to="https://nimiq.com/developers/nimiq-utils/cookie-utilities" variant="outline"} :u-page-card{title="Currency Info" to="https://nimiq.com/developers/nimiq-utils/currency-info" variant="outline"} :u-page-card{title="Fiat API" to="https://nimiq.com/developers/nimiq-utils/fiat-api" variant="outline"} :u-page-card{title="Formattable Number" to="https://nimiq.com/developers/nimiq-utils/formattable-number" variant="outline"} :u-page-card{title="Installation" to="https://nimiq.com/developers/nimiq-utils/installation" variant="outline"} :u-page-card{title="Rate Limit Scheduler" to="https://nimiq.com/developers/nimiq-utils/rate-limit-scheduler" variant="outline"} :u-page-card{title="Request Link Encoding" to="https://nimiq.com/developers/nimiq-utils/request-link-encoding" variant="outline"} :u-page-card{title="Staking Rewards Calculator" to="https://nimiq.com/developers/nimiq-utils/staking-rewards-calculator" variant="outline"} :u-page-card{title="Supply Calculator" to="https://nimiq.com/developers/nimiq-utils/supply-calculator" variant="outline"} :u-page-card{title="Tweenable" to="https://nimiq.com/developers/nimiq-utils/tweenable" variant="outline"} :u-page-card{title="UTF-8 Tools" to="https://nimiq.com/developers/nimiq-utils/utf8-tools" variant="outline"} :u-page-card{title="Validation Utils" to="https://nimiq.com/developers/nimiq-utils/validation-utils" variant="outline"} ::: :: # Install Nimiq Utils A comprehensive JavaScript/TypeScript utility library for the Nimiq blockchain ecosystem. ::code-group ```bash [pnpm] pnpm add @nimiq/utils ``` ```bash [npm] npm install @nimiq/utils ``` ```bash [yarn] yarn add @nimiq/utils ``` ```bash [bun] bun add @nimiq/utils ``` :: ## Basic Usage Nimiq Utils is designed with tree-shaking in mind. Import only the modules you need to keep your bundle size optimized. ```typescript import { AddressBook } from '@nimiq/utils/address-book' import { FormattableNumber } from '@nimiq/utils/formattable-number' import { calculateStakingRewards } from '@nimiq/utils/rewards-calculator' import { ValidationUtils } from '@nimiq/utils/validation-utils' // Use the utilities const address = 'NQ48 8CKH BA24 2VR3 N249 N8MN J5XX 74DB 5XJ8' const isValid = ValidationUtils.isValidAddress(address) const label = AddressBook.getLabel(address) const amount = new FormattableNumber('1234.56').toString({ maxDecimals: 2 }) // Calculate staking rewards const rewards = calculateStakingRewards({ stakedSupplyRatio: 0.5, amount: 100000, days: 365 }) console.log({ isValid, label, amount, rewards }) ``` ## TypeScript Support Nimiq Utils is written in TypeScript and includes full type definitions out of the box. No additional `@types` packages needed. ```typescript import type { CalculateStakingRewardsParams, CalculateStakingRewardsResult } from '@nimiq/utils/rewards-calculator' import { calculateStakingRewards } from '@nimiq/utils/rewards-calculator' const params: CalculateStakingRewardsParams = { stakedSupplyRatio: 0.5, amount: 100000, days: 365, autoRestake: true, network: 'main-albatross', fee: 0.02 } const result: CalculateStakingRewardsResult = calculateStakingRewards(params) ``` ## Framework Integration ::code-group ```typescript [Vue.js / Nuxt] // composables/useNimiqUtils.ts import { FormattableNumber } from '@nimiq/utils/formattable-number' import { ValidationUtils } from '@nimiq/utils/validation-utils' export function useNimiqUtils() { const validateAddress = (address: string) => { return ValidationUtils.isValidAddress(address) } const formatAmount = (amount: string | number, decimals: number = 2) => { return new FormattableNumber(amount).toString({ maxDecimals: decimals, useGrouping: true }) } return { validateAddress, formatAmount } } ``` ```typescript [React / Next.js] // hooks/useNimiqUtils.ts import { FormattableNumber } from '@nimiq/utils/formattable-number' import { ValidationUtils } from '@nimiq/utils/validation-utils' import { useCallback } from 'react' export function useNimiqUtils() { const validateAddress = useCallback((address: string) => { return ValidationUtils.isValidAddress(address) }, []) const formatAmount = useCallback((amount: string | number, decimals: number = 2) => { return new FormattableNumber(amount).toString({ maxDecimals: decimals, useGrouping: true }) }, []) return { validateAddress, formatAmount } } ``` ```html [Vanilla JavaScript] Nimiq Utils Example ``` ```html [CDN Usage] ``` :: ## Bundle Size Optimization Nimiq Utils is designed for optimal tree-shaking. Only import what you need: ```typescript // ❌ Avoid - Imports entire library import * as NimiqUtils from '@nimiq/utils' // ✅ Good - Import from specific modules for best tree-shaking import { FormattableNumber } from '@nimiq/utils/formattable-number' import { calculateStakingRewards } from '@nimiq/utils/rewards-calculator' import { ValidationUtils } from '@nimiq/utils/validation-utils' ``` # Rate Limit Scheduler Controls and limits task execution based on defined rate limits and parallel task limits. ## Usage ### Basic usage ```typescript import { Priority, RateLimitScheduler } from '@nimiq/utils/rate-limit-scheduler' const scheduler = new RateLimitScheduler({ maxParallel: 3, maxPerSecond: 10 }) await scheduler.schedule(() => fetch('/api/data'), Priority.HIGH) ``` ## API | Method | Description | | --------------------------------- | ----------------------------------------------- | | `new RateLimitScheduler(config)` | Creates scheduler with parallel and rate limits | | `schedule(task, priority?)` | Schedules task with optional priority | | `Priority.LOW/NORMAL/HIGH/URGENT` | Task priority levels | | `getStats()` | Returns scheduler statistics | | `clear()` | Clears all pending tasks | # Request Link Encoding Creates and parses request links for multiple cryptocurrencies including Nimiq, Bitcoin, and Ethereum. ## Usage ### Basic usage ```typescript import { createRequestLink, parseRequestLink } from '@nimiq/utils/request-link-encoding' const link = createRequestLink('nimiq:NQ48...5XJ8?amount=100&message=Payment') const parsed = parseRequestLink(link) console.log(parsed.recipient) // 'NQ48...5XJ8' ``` ## API | Method | Description | | --------------------------------- | ------------------------------------ | | `createRequestLink(uri)` | Creates request link from URI string | | `parseRequestLink(link)` | Parses request link into components | | `Currency.NIMIQ/BITCOIN/ETHEREUM` | Supported currency constants | # Staking Rewards Calculator Calculates potential wealth accumulation through staking with reward decay, compounding, and fees. ## Usage ### Basic calculation ```typescript import { calculateStakingRewards } from '@nimiq/utils/rewards-calculator' // Basic calculation const result = calculateStakingRewards({ amount: 100000, // 100k NIM days: 365, // 1 year stakedSupplyRatio: 0.5, // 50% of supply staked autoRestake: true // Compound rewards }) console.log(result.totalReward) // Total rewards earned console.log(result.finalBalance) // Final balance including rewards ``` ### With custom fee ```typescript // With custom fee const withFee = calculateStakingRewards({ amount: 50000, days: 180, stakedSupplyRatio: 0.6, fee: 0.05, // 5% validator fee autoRestake: false }) ``` ## API | Method | Description | | --------------------------------- | ------------------------------------------------------- | | `calculateStakingRewards(params)` | Calculates staking rewards for given parameters | | `StakingParams` | Input parameters: amount, days, stakedSupplyRatio, etc. | | `StakingResult` | Result object with totalReward, finalBalance, etc. | # Supply Calculator Calculates total Proof-of-Stake supply at specific times considering supply decay. ## Usage ### Basic usage ```typescript import { posSupplyAt } from '@nimiq/utils/supply-calculator' const timestamp = Date.now() const supply = posSupplyAt(timestamp) console.log(`Current PoS supply: ${supply}`) ``` ## API | Method | Description | | ------------------------ | ----------------------------------------------- | | `posSupplyAt(timestamp)` | Returns PoS supply at given timestamp | | `supplyAfter(blocks)` | Returns supply after specified number of blocks | # Tweenable Animation utility for handling tween animations with customizable easing functions. ## Usage ### Basic usage ```typescript import Tweenable from '@nimiq/utils/tweenable' const tween = new Tweenable({ from: { x: 0 }, to: { x: 100 }, duration: 1000 }) tween.start() ``` ## API | Method | Description | | ----------------------- | --------------------------------------------------------- | | `new Tweenable(config)` | Creates tween with from, to, duration, and easing options | | `start()` | Starts the animation | | `stop()` | Stops the animation | | `pause()` | Pauses the animation | | `resume()` | Resumes paused animation | | `seek(time)` | Jumps to specific time in animation | # Utf8 Tools Utility class for UTF-8 string and byte array conversions, validation, and truncation. ## Usage ### Basic usage ```typescript import { Utf8Tools } from '@nimiq/utils/utf8-tools' const bytes = Utf8Tools.stringToUtf8ByteArray('Hello, 世界!') const string = Utf8Tools.utf8ByteArrayToString(bytes) console.log(string) // 'Hello, 世界!' ``` ## API | Method | Description | | ----------------------------------------- | ------------------------------------------------ | | `stringToUtf8ByteArray(str)` | Converts string to UTF-8 byte array | | `utf8ByteArrayToString(bytes)` | Converts UTF-8 byte array to string | | `isValidUtf8(bytes)` | Checks if byte array is valid UTF-8 | | `truncateToUtf8ByteLength(str, maxBytes)` | Truncates string to fit in specified byte length | # Validation Utils Utility class for validating, normalizing, and checking Nimiq addresses and hashes. ## Usage ### Validate addresses ```typescript import { ValidationUtils } from '@nimiq/utils/validation-utils' // Validate addresses const address1 = 'NQ48 8CKH BA24 2VR3 N249 N8MN J5XX 74DB 5XJ8' const address2 = 'invalid-address' console.log(ValidationUtils.isValidAddress(address1)) // true console.log(ValidationUtils.isValidAddress(address2)) // false ``` ### Normalize formatting ```typescript // Normalize formatting const lowercase = 'nq48 8ckh ba24 2vr3 n249 n8mn j5xx 74db 5xj8' const normalized = ValidationUtils.normalizeAddress(lowercase) console.log(normalized) // 'NQ48 8CKH BA24 2VR3 N249 N8MN J5XX 74DB 5XJ8' ``` ### Check format validation ```typescript // Check format (throws if invalid) try { ValidationUtils.isUserFriendlyAddress(address1) console.log('Valid user-friendly format') } catch (error) { console.error('Invalid format:', error.message) } ``` ## API | Method | Description | | ---------------------------------------- | --------------------------------------------------- | | `isValidAddress(address: string)` | Returns true if address is valid | | `normalizeAddress(address: string)` | Returns normalized address with proper formatting | | `isUserFriendlyAddress(address: string)` | Throws error if address is not user-friendly format | # Nodes & Validators This hub helps you choose between being a validator or hosting your own RPC endpoint. ::u-page-grid :::u-page-card --- description: Deploy a full or history node that matches your infrastructure and security needs. icon: i-tabler:server-bolt title: Run a Node to: https://github.com/nimiq/core-rs-albatross?tab=readme-ov-file#configuration variant: outline --- ::: :::u-page-card --- description: Meet staking requirements, configure keys, and maintain uptime to earn rewards for securing the network. icon: i-nimiq:verified title: Become a Validator to: https://nimiq.com/developers/nodes/validators/becoming-a-validator variant: outline --- ::: :: ## Choose your path | Goal | Jump In | Outcome | | ------------------------- | --------------------------------------------------------------------------------------------------------------------- | --------------------------------------------------------------- | | Prototype quickly | [Explore the RPC](https://nimiq.com/developers/rpc) | Make JSON-RPC calls right away using hosted or local endpoints | | Control your own endpoint | [Run a node](https://github.com/nimiq/core-rs-albatross?tab=readme-ov-file#configuration){rel=""nofollow""} | Tune availability, security, and data retention to your needs | | Stake or pool NIM | [Become a validator](https://nimiq.com/developers/nodes/validators/becoming-a-validator) | Enter consensus and earn rewards from bonded or delegated stake | ## Helpful references - [Web Client vs RPC Client](https://nimiq.com/developers/web-client/concepts/web-client-vs-rpc) — decide when a hosted node is necessary. - [JSON-RPC Methods](https://nimiq.com/developers/rpc/methods) — integrate your applications once the endpoint is live. - [Protocol documentation](https://nimiq.com/developers/protocol) — understand how validators and staking fit into Albatross. # Becoming a Validator This guide will walk you through the process of setting up a Nimiq validator in the Albatross network. ## Setup This guide assumes the proof-of-stake network client (the node) has been compiled, or that you are running the node through other means, such as Docker. Check [this guide](https://github.com/nimiq/core-rs-albatross/blob/albatross/README.md#installation){rel=""nofollow""} for more information on compiling the code yourself. ::callout{color="info" icon="i-tabler-info-circle"} **Community Docker Image** An unofficial Docker image is available at [maestroi/nimiq-albatross](https://hub.docker.com/r/maestroi/nimiq-albatross){rel=""nofollow""} for those who prefer containerized deployment. This is a community-maintained image and not officially supported by the Nimiq team. :: This guide provides two methods for sending [JSON-RPC commands](https://nimiq.com/developers/rpc/methods) to your node: 1. [arpl](https://github.com/sisou/arpl){rel=""nofollow""}, an RPC client specific to Nimiq's PoS node 2. `curl`, a general-purpose network request tool ::collapsible{title="Install ARPL"} To install arpl, use `npm` or a compatible package manager: ```bash npm install -g @sisou/albatross-remote ``` :: ::collapsible{title="Install CURL"} If the `curl` command is not already installed on your machine, try installing it through your software center or check out {rel=""nofollow""} for installation instructions. :: ## Configure and run your node ### Generating your validator address and keys For running a validator you need the following items which we are generating now: - A validator address: Nimiq address, derived from your cold keypair (Schnorr) - A voting keypair: BLS keypair, also called the hot key - A signing keypair: Schnorr keypair, also called the warm key - Optionally a fee keypair: Schnorr keypair Note that we will use these in the following steps to configure your validator. For what each key does, and why validators hold separate cold, warm, and hot keys, see [Validator keys](https://nimiq.com/developers/protocol/validators/validator-keys). ::callout{icon="i-tabler-bulb"} Keep your public and private keys accessible by writing them down or saving them on your computer. Make sure you save the private keys securely, there is no way to recover them! :: We are generating these keys with utilities included in the `nimiq/core-rs-albatross` repository. Refer to [Setup](https://nimiq.com/developers/#setup) above for installation instructions. To generate the Schnorr keypairs and the validator address, you can use: ```bash cargo run --release --bin nimiq-address ``` ::callout{color="info" icon="i-tabler-info-circle"} Since we will need at least one Schnorr keypair and a Nimiq address, the command must be run 2 separate times and the output must be saved because it will be needed later in this guide. :: Run the command a third time, if you want to set a specific fee keypair - otherwise it will be auto-generated when you start your node, which will still work for sending control transactions without a fee. To generate a BLS keypair, you can use: ```bash cargo run --release --bin nimiq-bls ``` ::callout{color="info" icon="i-tabler-info-circle"} The output must be saved because it will be needed later in this guide. :: ### Configuration Run the node once. It will generate an example configuration file in the default config folder. On Linux, that's `~/.nimiq`. You need to copy `~/.nimiq/client.example.toml` to `~/.nimiq/client.toml`. You can leave most configuration options as they are for now to start a basic full node. To be able to control your node and to stake and validate, you need to enable the JSON-RPC server in your `client.toml`. Make sure the RPC section called `[rpc-server]` in the configuration file is enabled by uncommenting it. Note that you can also configure your node to use `history` as the `sync_mode`. For that, you could change the `consensus` section of your config file to set `sync_mode` like in the following example: ```toml [consensus] sync_mode = "history" ``` ::callout{color="info" icon="i-tabler-info-circle"} History sync mode uses much more storage (disk) space and can take very long to sync. As such, we recommend opting for a full node setup to get started quicker. :: The next step is to set up your validator address and keys in the `[validator]` section of your config file: ```toml [validator] validator_address = "NQXX XXXX XXXX XXXX XXXX XXXX XXXX XXXX XXXX" signing_key_file = "signing_key.dat" voting_key_file = "voting_key.dat" fee_key_file = "fee_key.dat" signing_key = "Schnorr Private Key" fee_key = "Schnorr Private Key" voting_key = "BLS Private Key" automatic_reactivate = true ``` Replace the validator address and keys generated accordingly: - The `validator_address` corresponds to the address output of a `nimiq-address` command. Paste your generated validator address here. - Ignore the three lines specifying file names. These files are automatically generated by the node and filled with the data from in the next settings. - The `signing_key` corresponds to the private key of a `nimiq-address` command. Paste your Schnorr secret key here. - The `fee_key` corresponds to the private key of a `nimiq-address` command. If you don't want to specify your own, comment that line out. - The `voting_key` in the config file corresponds to the secret key of the `nimiq-bls` command. Paste your BLS secret key here. - Leave `automatic_reactivate` as is. ::callout{color="info" icon="i-tabler-info-circle"} As previously mentioned, if you are creating a new validator from scratch, and you need to generate all those keys, then you will need to use the `nimiq-address` command three times and the `nimiq-bls` command one time. :br The `fee_key` is used to pay the fees for automatic reactivate transactions (if enabled). Since these fees default to 0 NIM, having the node auto-generate a fee key is safe. :: ### TLS Certificate It is strongly recommended to set up a TLS certificate for your node, because the browser-based Nimiq Wallet can only connect to it via secure connections. In order to maintain a healthy decentralization level within the network, it is advisable for the Nimiq Wallet to connect to as many diverse nodes as possible. There are different services where a TLS certificate can be obtained, such as [Let's Encrypt](https://letsencrypt.org/){rel=""nofollow""}. Once the certificate is obtained, it can be specified in the Network-TLS section within the config file: ```toml [network.tls] private_key = "/path/to/private_key_file.pem" certificates = "/path/to/full_certificates_file.pem" ``` ### Start your node and sync the blockchain After you finish your configuration, run the client from inside the `core-rs-albatross` directory with `cargo run --release --bin nimiq-client`. It will connect to the seed node(s), then to other nodes in the network, and start syncing the blockchain. Next, we will query your node for its status. ::callout{color="info" icon="i-tabler-info-circle"} When running your node through other means, such as a Docker container, refer to their respective documentation on how to start your node with your own config. :: ### Check your status with JSON-RPC If you enabled the JSON-RPC Server in your node’s configuration, you can query your node and send commands with `arpl` or `curl`, as installed in step 1. ::collapsible{title="ARPL"} To check the status of your client, first open an interactive session using the port set in your configuration. If you did not change it, the default `port` is `8648` and the `host` is `localhost`: ```bash arpl repl -u ws://:/ws # -u is short for --url # With default settings: arpl repl -u ws://localhost:8648/ws # You can also use other ways of specifying the connection parameters: arpl repl -h localhost -p 8648 # -h is short for --host, -p is short for --port # The defaults of the node configuration are also the defaults for # arpl, so just this would work, too: arpl repl ``` Once in the session, check the status with this command: ```text status ``` It will reply with a list of performance indicators, such as the consensus state, the current block height and number of connected peers. :: ::collapsible{title="CURL"} To check the status of your client with `curl`, send RPC requests to the port set in your configuration. If you did not change it, the default `port` is `8648` and the `host` is `localhost`: With `curl`, you need to query the various properties of your node individually: Query the consensus state: ```bash curl 'http://localhost:8648' -H 'Content-Type: application/json' \ --data-raw '{"method": "isConsensusEstablished", "params": [], "jsonrpc": "2.0", "id": 1}' ``` The result is the `result.data` value. Query the node's current block height: ```bash curl 'http://localhost:8648' -H 'Content-Type: application/json' \ --data-raw '{"method": "getBlockNumber", "params": [], "jsonrpc": "2.0", "id": 1}' ``` Query the number of connected peers: ```bash curl 'http://localhost:8648' -H 'Content-Type: application/json' \ --data-raw '{"method": "getPeerCount", "params": [], "jsonrpc": "2.0", "id": 1}' ``` :: ## Become a Validator To become a validator, you need to register it in the staking contract by sending a `create_validator` transaction. For that you need to have an account with at least the validator deposit fee (100 000 NIM). This guide assumes that this amount is already present in the validator address. To check if that is the case, use this command: ::collapsible{title="ARPL"} In the arpl session: ```text account:get ``` :: ::collapsible{title="CURL"} ```bash curl 'http://localhost:8648' -H 'Content-Type: application/json' \ --data-raw '{"method": "getAccountByAddress", "params": [""], "jsonrpc": "2.0", "id": 1}' ``` Note that the `balance` returned is in Luna. Devide by 100'000 to get NIM. :: ### Import your validator keypair To sign and send transactions from your validator account, you need to import its keypair. In the following commands, `validator_private_key` is the private key of the Schnorr keypair you generated for the validator address, that is, your cold key. ::collapsible{title="ARPL"} ```text account:import --unlock ``` Accounts are generally imported *locked*. The addition of the `--unlock` parameter to the above command unlocked the account for us already. If you forgot to add `--unlock` to the command above, or for any other reason, you can unlock your account in your node like this: ```text account:unlock
``` :: ::collapsible{title="CURL"} Import your validator private key: ```bash curl 'http://localhost:8648' -H 'Content-Type: application/json' \ --data-raw '{"method": "importRawKey", "params": ["", null], "jsonrpc": "2.0", "id": 1}' ``` Then unlock it: ```bash curl 'http://localhost:8648' -H 'Content-Type: application/json' \ --data-raw '{"method": "unlockAccount", "params": ["
", null, null], "jsonrpc": "2.0", "id": 1}' ``` :::callout{color="info" icon="i-tabler-info-circle"} In case you are wondering, the `null` as the second parameter is an optional password. You can set a password to lock the account when you import it, which you then need to provide during unlocking, too. The other `null` as the third parameter for unlocking is an unused duration parameter, that nontheless needs to be provided. ::: ### Send a validator-creation transaction Finally, to register your validator, run this with all the keys generated in the beginning: :::collapsible{title="ARPL"} ```text validator:new ``` Where `signing_private_key` is the private key of the Schnorr keypair generated for `signing_key`, and `voting_private_key` is the private key of the BLS keypair generated for `voting_key`. ::: :::collapsible{title="CURL"} The manual way with `curl` requires a few more parameters: 1. The address of the account you are sending from 2. The address of the validator you are creating 3. The private signing Schnorr key you generated 4. The private voting BLS key you generated 5. The reward payout address (can be the same as the validator address) 6. Signalling data (usually empty) 7. The fee for the transaction (can be zero) 8. The validity start height of the transaction (+0 means the node takes the current block height) ```bash curl 'http://localhost:8648' -H 'Content-Type: application/json' \ --data-raw '{"method": "sendNewValidatorTransaction", "params": ["", "", "", "", "", "", 0, "+0"], "jsonrpc": "2.0", "id": 1}' ``` ::: :::callout{color="info" icon="i-tabler-info-circle"} Your node must have established consensus and be up-to-date with the blockchain for the transaction to send successfully. Remember, you can check your node's status with the `status` command. ::: :::callout{icon="i-tabler-bulb"} When sending the create transaction, the validator deposit will be deducted from the wallet linked to the validator address. ::: :::callout{color="info" icon="i-tabler-info-circle"} Validators are only selected to produce blocks at the start of every epoch (every election block), so it may take some time for your validator to be elected to produce blocks. ::: ### Query your validator state You can now query the staking contract for your validator registration: :::collapsible{title="ARPL"} ```text validator:get ``` ::: :::collapsible{title="CURL"} ```bash curl 'http://localhost:8648' -H 'Content-Type: application/json' \ --data-raw '{"method": "getValidatorByAddress", "params": [""], "jsonrpc": "2.0", "id": 1}' ``` ::: It will tell your the public keys of your registered signing and voting keys, as well as which reward address is set to receive block rewards. It'll also tell you your validator's staking balance (which should be the same as the deposit for now), how many stakers are staking with your validator (none yet) and if the validator is inactive or retired (it should not be). :::callout{color="info" icon="i-tabler-info-circle"} If the command responds with an error, your validator creation transaction was likely not successfull. You can ask for support in our Telegram channels, in our Github, or in the community forum. ::: ## Add stake to your validator A validator itself can only maintain the validator deposit as stake. To stake more than that, you need to *add stake* to your validator as a staker. :::callout{icon="i-tabler-bulb"} **Note** You can stake your NIM on behalf of any registered validator. Your staked NIM then count towards that validator's stake, increasing their (randomly) assigned number of block production slots and thus rewards. Importantly, all staking rewards are received by the validator's reward address, not the stakers. The arrangement of distributing rewards among a validator's stakers is made off-chain and is usually handled by a pool operator or the people who are operating the validator themselves. ::: ### Stake from the Nimiq Wallet You can stake with your validator from the Nimiq Wallet. Go to the staking menu in your NIM address and search for and select your validator's address from the list of validators. Then assign as much NIM to it as you like. ### Stake from your node with JSON-RPC You can also send the staking transactions from your node with JSON-RPC. For that, you need to import and unlock the account that holds the NIM you want to stake. Then run the following command to start staking: :::collapsible{title="ARPL"} ```text stake:start ``` ::: :::collapsible{title="CURL"} The manual way with `curl` requires a few more parameters: 1. The address of the account you are sending from 2. The address of the staker you are creating 3. The address of the validator you are delegating to 4. the amount (in Luna) you want to stake 5. The fee for the transaction (can be zero) 6. The validity start height of the transaction (+0 means the node takes the current block height) ```bash curl 'http://localhost:8648' -H 'Content-Type: application/json' \ --data-raw '{"method": "sendNewStakerTransaction", "params": ["", "", "", , 0, "+0"], "jsonrpc": "2.0", "id": 1}' ``` ::: ## Remove your Validator Anyone can remove their validator when they no longer want to participate in block production. This process involves three transactions: `deactivate`, `retire`, and `delete` — and it may take up to 2 days to complete before the full 100'000 NIM deposit can be recovered. - `deactivate` marks the validator as inactive - `retire` confirms the validator is leaving permanently - `delete` removes the validator and returns the deposit The process may take up to 2 days due to the protocol’s requirement to allow time for reporting any potential misbehavior before the validator can be fully removed and the deposit returned. #### Disable Automatic Reactivation Before deactivating your validator, check whether the node is configured to automatically reactivate. If automatic reactivation is enabled, the node will detect the deactivation and reactivate itself, preventing a successful removal. **Check your configuration**: Open your [client.toml](https://github.com/nimiq/core-rs-albatross/blob/b1e8c0f26f55039861c1cc9a5112ad08ce87067c/lib/src/config/config_file/client.example.toml#L356){rel=""nofollow""} file and locate the `automatic_reactivate` setting. If this flag is already set to `false`, no further action is needed. If set to `true`, disable it using the following RPC method: :::collapsible{title="CURL"} ```bash curl 'http://localhost:8648' -H 'Content-Type: application/json' \ --data-raw '{"method": "setValidatorAutomaticReactivation", "params": [false], "jsonrpc": "2.0", "id": 1}' ``` ::: :::callout{icon="i-tabler-bulb"} **Note** This change is temporary. If you restart the node, it will fall back to the value defined in your configuration file. ::: ### Deactivate your Validator :::collapsible{title="ARPL"} ```text validator:deactivate ``` ::: :::collapsible{title="CURL"} The manual way with `curl` requires a few more parameters: 1. The address paying the transaction fee 2. The address of the validator you are deactivating 3. The signing key of the validator for validity and authorization 4. The fee for the transaction (can be zero) 5. The validity start height of the transaction (+0 means the node takes the current block height) ```bash curl 'http://localhost:8648' -H 'Content-Type: application/json' \ --data-raw '{"method": "sendDeactivateValidatorTransaction", "params": ["", "", "", 0, "+0"], "jsonrpc": "2.0", "id": 1}' ``` ::: ### Retire your Validator :::collapsible{title="ARPL"} ```text validator:retire ``` ::: :::collapsible{title="CURL"} The manual way with `curl` requires a few more parameters: 1. The address paying the transaction fee 2. The address of the validator you are retiring 3. The fee for the transaction (can be zero) 4. The validity start height of the transaction (+0 means the node takes the current block height) ```bash curl 'http://localhost:8648' -H 'Content-Type: application/json' \ --data-raw '{"method": "sendRetireValidatorTransaction", "params": ["", "", 0, "+0"], "jsonrpc": "2.0", "id": 1}' ``` ::: ### Delete your Validator :::collapsible{title="ARPL"} ```text validator:delete ``` ::: :::collapsible{title="CURL"} The manual way with `curl` requires a few more parameters: 1. The address of your validator wallet submitting the `delete` transaction 2. The address where the funds will be sent 3. The amount in NIM to withdraw 4. The fee for the transaction (can be zero) 5. The validity start height of the transaction (+0 means the node takes the current block height) ```bash curl 'http://localhost:8648' -H 'Content-Type: application/json' \ --data-raw '{"method": "sendDeleteValidatorTransaction", "params": ["", "", 0, 0, "+0"], "jsonrpc": "2.0", "id": 1}' ``` ::: :: # Comprehensive Staking FAQ Staking allows you to delegate your NIM to a validator, helping secure the network while earning rewards. Whether you're new to staking or looking for details about validators, rewards, or the Proof-of-Stake protocol, **this FAQ covers everything you need to know**. Explore topics such as unstaking periods, selecting a staking pool, and contributing to decentralization. ## General Staking Information ### What is Staking? Staking is the process of delegating tokens to a validator. The validator then uses these tokens to validate transactions and produce blocks on your behalf. ### What is a validator? A validator is the block producer of Proof-of-Stake blockchains, like a miner in Proof-of-Work blockchains. Validators produce blocks according to a consensus algorithm. ### What is a staking pool? While a validator is an individual entity, a staking pool combines the tokens of multiple participants into a single large entity, increasing their collective stake and chances of winning rewards. ### How does staking help the Nimiq network? Staking enhances the security and decentralization of the Nimiq network. Validators, backed by staked NIM, verify transactions and create new blocks. The network relies on this process to remain operational. Distributing stakes evenly across many validators reduces the risk of centralization, ensuring no single entity can control the network. This balance supports the network's reliability, resilience, and long-term sustainability. ### What happens if I don’t stake? You can choose not to stake and not earn any rewards. By not staking, you miss the opportunity to help maintain the network secure and decentralized. ### How long does it take to have my funds available after I un-stake? Once you un-stake your funds, it usually takes between 12 hours to 4 days for them to become available. The exact time frame depends on your validator's status. In rare cases, validators can be "jailed" for up to 4 days, which may delay access to your funds. ## Rewards ### How much can I earn by staking? The amount of NIM you will receive depends on multiple factors, such as the amount of NIM you have delegated to your validator or staking pool and the time you have been staking. You can use our [Staking Calculator](https://www.nimiq.com/staking-calculator/){rel=""nofollow""} to estimate the potential rewards you can earn. ### How do staking rewards work? When you delegate your NIM, your validator uses it to help secure the network. In return, it earns rewards, which are shared with its stakers. You don’t need any technical knowledge to start staking. ### How long does it take to start earning rewards after staking? The periodicity of reward distribution depends on your validator policies. These rewards are paid off-chain. Check your validator to understand the specific distribution schedules and earnings. ### Can I re-stake my rewards? Yes. If you are staking to a validator, you can manually re-stake your rewards. If you are staking with a staking pool, you can automatically set to re-stake once you earn rewards. ### I haven’t received my rewards in a while; what can I do? If you haven’t received your rewards when you were supposed to, you can contact your validator or staking pool. According to the Nimiq PoS protocol, validators who get jailed get their funds locked for a 4 day period, which may coincide with the day of the reward distribution. ## Staking Pool Selection ### How do I pick a Staking Pool? When selecting a Staking Pool, consider the following factors to make an informed decision: - **Pool Fee**: Pools charge a fee for maintaining and operating the validator infrastructure. Compare the fees of different pools to find one that aligns with your preferences. - **Decentralization**: A well-distributed stake ensures a healthy and secure Proof of Stake network. Each pool is assigned a score, indicating how staking with them contributes to the overall balance of the network. - **Pool-Specific Features**: Explore the unique features offered by each pool. Some pools may provide benefits like automatic re-staking, dynamic fees, or additional services. Check their websites or connect with their community on [Nimiq’s Discord](https://discord.gg/nimiq){rel=""nofollow""} to learn more. ### Can I switch the Staking Pool / Validator to which I have staked my NIM? Yes, you can change the Staking Pool or Validator to which you've staked your NIM at any time. To do this, you'll need to unstake your NIM from the current validator and then stake it with a new one. Please note that there is an unstaking period before your NIM becomes available again for staking with a different validator. This process involves two transactions: one to signal that you no longer want to stake and a second one to retrieve your funds once they are unstaked, which happens after the next macro block, a maximum of twelve hours later. ### Can I stake to multiple validators? You can only stake with one validator per wallet address. To stake with multiple validators, you’ll need to create additional wallet addresses. Simply create a new wallet, transfer funds to it, and stake with your chosen validator under that new wallet address. ### What happens if the validator I’m staking with goes offline? If the validator you're staking with goes offline, it will be deactivated and will not receive rewards during its inactivity. As a staker, this means you won't earn rewards from that validator while it's offline. However, you retain full control over your NIM and can choose to unstake and delegate to a different validator at any time. Keep in mind that unstaking involves a lock-up period before your funds become available for redelegation. ## Staking Requirements ### What is the minimum amount required to stake? To participate in staking Nimiq (NIM), a minimum of 100 NIM is required. ### I want to increase the amount I’m staking. Can I do that? You can always increase or decrease the amount of stake you have delegated to your validator; however, you must keep at least the minimum deposit at all times. ### Do I need to have a Nimiq Wallet? The Nimiq Wallet provides an easy, intuitive, and fully self-custodial staking experience. While third-party wallets may support NIM staking in the future, currently, the Nimiq Wallet is the primary platform for staking your NIM. ### Which wallets support staking? Currently, the Nimiq Wallet is the primary platform supporting NIM staking. It offers an intuitive, self-custodial experience, allowing you to stake your NIM directly. While third-party wallets may support NIM staking in the future, currently, the Nimiq Wallet is the main option for staking. ### Can I stake directly from an exchange? Currently, exchanges that support NIM do not offer direct staking functionality. However, they are participating in the migration to Proof-of-Stake, which lays the groundwork for potential future support. ## Proof-of-Stake Protocol ### How does the Nimiq Proof of Stake protocol ensure that all validators follow the rules? There is a system of rewards and punishments for validators. Validators are rewarded for validating transactions and producing blocks according to the consensus protocol, incentivizing good behavior. If a validator fails to follow the rules, they may face a punishment such as losing rewards or being temporarily “jailed” for up to 4 days, during which they cannot participate or earn rewards. This combination of rewards and punishments motivates validators to follow the rules. If you would like to learn more about validators, rewards, and punishments, you can refer to the [protocol documentation](https://nimiq.com/developers/protocol). ### Can I lose my funds when staking? You cannot lose your staked funds in Nimiq under normal circumstances, as they remain under your ownership. However, if your validator misbehaves or performs poorly, it may lose rewards or be jailed temporarily, impacting your earnings but not your staked funds. ## Miscellaneous ### Is staking taxable? The tax treatment of crypto staking rewards depends on your local regulations. We recommend consulting a local tax professional and reviewing the crypto tax guidelines in your jurisdiction to ensure compliance. Please note: Depositing and withdrawing your cryptocurrency from a staking pool is typically not considered a taxable event, similar to other wallet-to-wallet transfers. However, it is still important to confirm this with your local crypto tax guidelines. Another great way to find answers is by asking the Nimiq community. Try [Telegram](https://t.me/joinchat/AAAAAEJW-ozFwo7Er9jpHw){rel=""nofollow""} for general questions and [Discord](https://discord.gg/cMHemg8){rel=""nofollow""} for tech-related inquiries. ### Do I have to pay fees for staking? Staking with Nimiq is simple and cost-effective, with no fees for staking directly through Nimiq. However, you must select a third-party validator to stake with. Validators run staking pools that secure the network, similar to miners in a Proof of Work blockchain, and charge a small fee for their services, which varies by validator. Most validators provide details about their fees and services on their website or staking pool information page. Be sure to review these details and the terms of the staking provider before staking. # Staking Pools Handbook This handbook provides guidelines for the staking pools on the Nimiq network. It covers best practices, a code of conduct, and general standards required to ensure a fair and transparent experience for the stakers. The document outlines the requirements for staking pools, which are based on single validators, to integrate with the Nimiq Wallet. This integration helps stakers make informed decisions when choosing where to stake their funds. Pool operators are **fully responsible for setting up and maintaining their pools**, including creating the payout system and ensuring compliance with these guidelines. While validators can operate independently, staking pools allow multiple users to stake their funds with a single validator. This page is intended for those operating a staking pool who wish to be listed on the [Nimiq Wallet](https://wallet.nimiq.com/){rel=""nofollow""}. The [validators-API repository](https://github.com/nimiq/validators-api#add-your-validator-information){rel=""nofollow""} provides the tools and JSON schema for integrating staking pools with the wallet. By following these guidelines and submitting a complete JSON file via PR (pull request), pool operators can ensure their pool is displayed correctly in the wallet. ## General Rules To maintain trust and integrity for the stakers, pool operators must follow some basic rules. - **Transparency**: Communicate pool terms, including fees, reward timelines, and operational details. Pool operators are advised to maintain a website or any other accessible point of contact where their rules and terms are clearly outlined. - **Honesty**: Do not make misleading claims, such as advertising 0% fees while charging hidden fees. - **Compliance**: Submit a PR with your pool’s data in a JSON file following the guidelines outlined in the [README](https://github.com/nimiq/validators-api?tab=readme-ov-file#README){rel=""nofollow""}. - **Payout Commitments**: Ensure timely and accurate payouts to stakers. Clearly define and communicate any fees to stakers. Avoid ambiguous language in your terms. ## Code of Conduct All pool operators must comply with the following ethical and behavioral standards: - Do not engage in discriminatory behavior or harassment based on race, gender, sexual orientation, religion, or other personal characteristics. No hate speech, political messaging, pornography, child abuse, etc. - Avoid sharing or promoting illegal content. - Ensure all claims about the pool, such as fees and performance metrics, are accurate and verifiable. Failure to comply with this will result in immediate actions, including potential suspension or removal from the wallet. ## **Submitting your Pool via PR** Pool operators are required to submit a JSON file containing key details about their pool. Ensure the JSON file is complete and adheres to the guide to avoid delays in the review process. The JSON file includes fields such as: - Pool name and description - Address - Fee structure (fixed or dynamic) - Payout type and schedule - Contact information The review process consists of two steps: 1. **PR Review**: When a pool submits a PR with a JSON file describing its information, someone from the Nimiq team will review it within 3 business days. This step ensures the JSON file is complete, adheres to the guidelines, and accurately describes the pool's setup. If any required information is missing, the pool operator will be contacted to provide the details. The PR will be rejected if there is any misconduct or lack of transparency. Monitoring is currently manual, with plans to automate in the future. 2. **Fee Verification**: After the initial review and approval, the pool will undergo continuous monitoring to verify its fee structure and payout distributions. This is an ongoing process to ensure transparency and compliance with the stated terms. ### **Links and References** - [Validator Staking Pools README](https://github.com/nimiq/validators-api#add-your-validator-information){rel=""nofollow""} - [Become a Validator Guide](https://nimiq.com/developers/nodes/validators/becoming-a-validator) # Nimiq Validator Trustscore ::callout{color="warning" icon="i-tabler-alert-triangle"} The Validator Trustscore is still under development and we are open to discuss changes to the algorithm. :: The Validator Trustscore (VTS) helps users assess the reliability of validators in the Nimiq Wallet. This score ranges from 0 to 1, where 0 indicates a validator is not trustworthy, and 1 indicates a highly trustworthy validator. The VTS enables stakers to make informed decisions when selecting validators. The VTS score is calculated using three key factors: - **Dominance**: Ensures no validator has excessive influence by penalizing validators with a higher share of the total network stake. - **Reliability**: Measures how consistently a validator produces blocks over the past nine months. - **Availability**: Assesses how often a validator is online and actively selected to produce blocks. ::callout{color="info" icon="i-tabler-info-circle"} The VTS evaluates validators' performance and reliability during block production. It does not assess staking pool reliability or reward payment processes. For insights into staking pools, refer to the [Validators API](https://github.com/nimiq/validators-api){rel=""nofollow""} or the [Staking Pools Handbook](https://forum.nimiq.community/t/staking-pools-handbook/2169){rel=""nofollow""} . :: The algorithm is designed to promote decentralization, fairness, and consistent network participation. Below is an example of how the VTS might appear in the Nimiq Wallet: ![The Validator Score in the Wallet](https://nimiq.com/developers/assets/images/learn/validators-trustscore-wallet-preview.png){max-h-512="" object-contain=""} --- ## The VTS Technical Breakdown The VTS algorithm uses three factors: **D**ominance, **R**eliability, and **A**vailability. Each factor is calculated independently, with values ranging from 0 to 1, and their calculation determines the final score. [[[]{.katex-mathml}[[[]{.strut style="height:0.6833em;"}[T]{.mord.mathnormal style="margin-right:0.13889em;"}[]{.mspace style="margin-right:0.2778em;"}[=]{.mrel}[]{.mspace style="margin-right:0.2778em;"}]{.base}[[]{.strut style="height:0.7667em;vertical-align:-0.0833em;"}[D]{.mord.mathnormal style="margin-right:0.02778em;"}[]{.mspace style="margin-right:0.2222em;"}[×]{.mbin}[]{.mspace style="margin-right:0.2222em;"}]{.base}[[]{.strut style="height:0.7667em;vertical-align:-0.0833em;"}[R]{.mord.mathnormal style="margin-right:0.00773em;"}[]{.mspace style="margin-right:0.2222em;"}[×]{.mbin}[]{.mspace style="margin-right:0.2222em;"}]{.base}[[]{.strut style="height:0.6833em;"}[A]{.mord.mathnormal}]{.base}]{.katex-html ariaHidden="true"}]{.katex}]{.katex-display} The **dominance** factor is based on the dominance of the validator's stake relative to the total stake in the network. **Reliability** and **availability** are based on behavior over the last nine months. For these parameters, only completed epochs are considered, not the currently active one. Therefore, the score is not live and can have a delay of up to 12 hours (an epoch lasts 12 hours). #### Calculation of [[]{.katex-mathml}[[[]{.strut style="height:0.4306em;"}[m]{.mord.mathnormal}]{.base}]{.katex-html ariaHidden="true"}]{.katex} Because reliability and availability are based on the behavior of validators over the last 9 months, we need to define 𝑚 the number of epochs to consider within this timeframe. This value ensures that all calculations include only completed epochs for accuracy. Where: [[[]{.katex-mathml}[[[]{.strut style="height:0.4306em;"}[m]{.mord.mathnormal}[]{.mspace style="margin-right:0.2778em;"}[=]{.mrel}[]{.mspace style="margin-right:0.2778em;"}]{.base}[[]{.strut style="height:2.3904em;vertical-align:-0.996em;"}[[]{.mopen.nulldelimiter}[[[[[[]{.pstrut style="height:3em;"}[[[epoch\_duration]{.mord}]{.mord.text}]{.mord}]{style="top:-2.314em;"}[[]{.pstrut style="height:3em;"}[]{.frac-line style="border-bottom-width:0.04em;"}]{style="top:-3.23em;"}[[]{.pstrut style="height:3em;"}[[[window\_duration\_ms]{.mord}]{.mord.text}]{.mord}]{style="top:-3.7em;"}]{.vlist style="height:1.3944em;"}[​]{.vlist-s}]{.vlist-r}[[[]]{.vlist style="height:0.996em;"}]{.vlist-r}]{.vlist-t.vlist-t2}]{.mfrac}[]{.mclose.nulldelimiter}]{.mord}]{.base}]{.katex-html ariaHidden="true"}]{.katex}]{.katex-display}[[[]{.katex-mathml}[[[]{.strut style="height:1.0044em;vertical-align:-0.31em;"}[[window\_duration\_ms]{.mord}]{.mord.text}[]{.mspace style="margin-right:0.2778em;"}[=]{.mrel}[]{.mspace style="margin-right:0.2778em;"}]{.base}[[]{.strut style="height:0.7278em;vertical-align:-0.0833em;"}[9]{.mord}[]{.mspace style="margin-right:0.2222em;"}[×]{.mbin}[]{.mspace style="margin-right:0.2222em;"}]{.base}[[]{.strut style="height:0.7278em;vertical-align:-0.0833em;"}[30]{.mord}[]{.mspace style="margin-right:0.2222em;"}[×]{.mbin}[]{.mspace style="margin-right:0.2222em;"}]{.base}[[]{.strut style="height:0.7278em;vertical-align:-0.0833em;"}[24]{.mord}[]{.mspace style="margin-right:0.2222em;"}[×]{.mbin}[]{.mspace style="margin-right:0.2222em;"}]{.base}[[]{.strut style="height:0.7278em;vertical-align:-0.0833em;"}[60]{.mord}[]{.mspace style="margin-right:0.2222em;"}[×]{.mbin}[]{.mspace style="margin-right:0.2222em;"}]{.base}[[]{.strut style="height:0.7278em;vertical-align:-0.0833em;"}[60]{.mord}[]{.mspace style="margin-right:0.2222em;"}[×]{.mbin}[]{.mspace style="margin-right:0.2222em;"}]{.base}[[]{.strut style="height:0.6444em;"}[1000]{.mord}]{.base}]{.katex-html ariaHidden="true"}]{.katex}]{.katex-display}[[[]{.katex-mathml}[[[]{.strut style="height:1.0044em;vertical-align:-0.31em;"}[[epoch\_duration]{.mord}]{.mord.text}[]{.mspace style="margin-right:0.2778em;"}[=]{.mrel}[]{.mspace style="margin-right:0.2778em;"}]{.base}[[]{.strut style="height:1.0044em;vertical-align:-0.31em;"}[[block\_duration]{.mord}]{.mord.text}[]{.mspace style="margin-right:0.2222em;"}[×]{.mbin}[]{.mspace style="margin-right:0.2222em;"}]{.base}[[]{.strut style="height:1.0044em;vertical-align:-0.31em;"}[[blocks\_per\_epoch]{.mord}]{.mord.text}]{.base}]{.katex-html ariaHidden="true"}]{.katex}]{.katex-display}:br Block duration and blocks per epoch are constants defined in the [policy](https://github.com/nimiq/core-rs-albatross/blob/albatross/primitives/src/policy.rs){rel=""nofollow""}. ::callout{color="info" icon="i-tabler-info-circle"} The curves and constants presented in this document are subject to change at any time in the future. Any updates will be communicated to the community to ensure transparency. :: ### Dominance The dominance factor ensures that no single validator controls an excessive portion of the network's total stake. Validators with a larger stake receive a lower score to encourage a fairer distribution of control across the network. This approach penalizes disproportionately large stakes while promoting diversity in validator participation. #### Dominance Ratio The dominance ratio ( [[]{.katex-mathml}[[[]{.strut style="height:0.4306em;"}[s]{.mord.mathnormal}]{.base}]{.katex-html ariaHidden="true"}]{.katex} ) of a validator is calculated using one of two methods, depending on the epoch's state. However, due to technical limitations, only the **Active Epoch Method** is currently implemented and used. **Active Epoch Method**: During an active epoch, the dominance ratio is determined by dividing the validator's share by the total network share: [[[]{.katex-mathml}[[[]{.strut style="height:0.4306em;"}[s]{.mord.mathnormal}[]{.mspace style="margin-right:0.2778em;"}[=]{.mrel}[]{.mspace style="margin-right:0.2778em;"}]{.base}[[]{.strut style="height:1.7936em;vertical-align:-0.686em;"}[[]{.mopen.nulldelimiter}[[[[[[]{.pstrut style="height:3em;"}[[Z]{.mord.mathnormal style="margin-right:0.07153em;"}]{.mord}]{style="top:-2.314em;"}[[]{.pstrut style="height:3em;"}[]{.frac-line style="border-bottom-width:0.04em;"}]{style="top:-3.23em;"}[[]{.pstrut style="height:3em;"}[[v]{.mord.mathnormal style="margin-right:0.03588em;"}]{.mord}]{style="top:-3.677em;"}]{.vlist style="height:1.1076em;"}[​]{.vlist-s}]{.vlist-r}[[[]]{.vlist style="height:0.686em;"}]{.vlist-r}]{.vlist-t.vlist-t2}]{.mfrac}[]{.mclose.nulldelimiter}]{.mord}]{.base}]{.katex-html ariaHidden="true"}]{.katex}]{.katex-display} Where: - [[]{.katex-mathml}[[[]{.strut style="height:0.4306em;"}[v]{.mord.mathnormal style="margin-right:0.03588em;"}]{.base}]{.katex-html ariaHidden="true"}]{.katex}: The validator's share. - [[]{.katex-mathml}[[[]{.strut style="height:0.6833em;"}[Z]{.mord.mathnormal style="margin-right:0.07153em;"}]{.base}]{.katex-html ariaHidden="true"}]{.katex}: The total network share. This method relies on the `getActiveValidators` function from the [RPC](https://nimiq.com/developers/rpc/methods/get-active-validators), which provides real-time balances of each active validator. **Finished Epoch Method**: For a closed epoch, a less precise fallback method exists, but is not currently implemented. This approach calculates the dominance ratio based on slot distribution across voting blocks. The ratio is derived by dividing the number of slots allocated to a validator by the total slots in the epoch: [[[]{.katex-mathml}[[[]{.strut style="height:0.4306em;"}[s]{.mord.mathnormal}[]{.mspace style="margin-right:0.2778em;"}[=]{.mrel}[]{.mspace style="margin-right:0.2778em;"}]{.base}[[]{.strut style="height:2.0574em;vertical-align:-0.686em;"}[[]{.mopen.nulldelimiter}[[[[[[]{.pstrut style="height:3em;"}[[S]{.mord.mathnormal style="margin-right:0.05764em;"}[l]{.mord.mathnormal style="margin-right:0.01968em;"}]{.mord}]{style="top:-2.314em;"}[[]{.pstrut style="height:3em;"}[]{.frac-line style="border-bottom-width:0.04em;"}]{style="top:-3.23em;"}[[]{.pstrut style="height:3em;"}[[s]{.mord.mathnormal}[l]{.mord.mathnormal style="margin-right:0.01968em;"}]{.mord}]{style="top:-3.677em;"}]{.vlist style="height:1.3714em;"}[​]{.vlist-s}]{.vlist-r}[[[]]{.vlist style="height:0.686em;"}]{.vlist-r}]{.vlist-t.vlist-t2}]{.mfrac}[]{.mclose.nulldelimiter}]{.mord}]{.base}]{.katex-html ariaHidden="true"}]{.katex}]{.katex-display} Where: - [[]{.katex-mathml}[[[]{.strut style="height:0.6944em;"}[s]{.mord.mathnormal}[l]{.mord.mathnormal style="margin-right:0.01968em;"}]{.base}]{.katex-html ariaHidden="true"}]{.katex}: The number of slots allocated to the validator. - [[]{.katex-mathml}[[[]{.strut style="height:0.6944em;"}[S]{.mord.mathnormal style="margin-right:0.05764em;"}[l]{.mord.mathnormal style="margin-right:0.01968em;"}]{.base}]{.katex-html ariaHidden="true"}]{.katex}: The total number of slots in the epoch. While this method is defined in the code as `dominanceRatioViaSlots`, it is not actively used in practice. #### Curve adjustment After determining the dominance ratio, a curve is applied to calculate the dominance score [[]{.katex-mathml}[[[]{.strut style="height:0.6833em;"}[S]{.mord.mathnormal style="margin-right:0.05764em;"}]{.base}]{.katex-html ariaHidden="true"}]{.katex} : [[[]{.katex-mathml}[[[]{.strut style="height:0.6833em;"}[S]{.mord.mathnormal style="margin-right:0.05764em;"}[]{.mspace style="margin-right:0.2778em;"}[=]{.mrel}[]{.mspace style="margin-right:0.2778em;"}]{.base}[[]{.strut style="height:1.2491em;vertical-align:-0.35em;"}[max]{.mop}[]{.mspace style="margin-right:0.1667em;"}[[[(]{.delimsizing.size1}]{.mopen.delimcenter style="top:0em;"}[0]{.mord}[,]{.mpunct}[]{.mspace style="margin-right:0.1667em;"}[1]{.mord}[]{.mspace style="margin-right:0.2222em;"}[−]{.mbin}[]{.mspace style="margin-right:0.2222em;"}[[s]{.mord.mathnormal}[[[[[[]{.pstrut style="height:2.7em;"}[[[k]{.mord.mathnormal.mtight style="margin-right:0.03148em;"}]{.mord.mtight}]{.sizing.reset-size6.size3.mtight}]{style="top:-3.113em;margin-right:0.05em;"}]{.vlist style="height:0.8991em;"}]{.vlist-r}]{.vlist-t}]{.msupsub}]{.mord}[[)]{.delimsizing.size1}]{.mclose.delimcenter style="top:0em;"}]{.minner}[]{.mspace style="margin-right:0.1667em;"}[,]{.mpunct}[]{.mspace style="margin-right:1em;"}[]{.mspace style="margin-right:0.1667em;"}[[being ]{.mord}]{.mord.text}[t]{.mord.mathnormal}[]{.mspace style="margin-right:0.2778em;"}[=]{.mrel}[]{.mspace style="margin-right:0.2778em;"}]{.base}[[]{.strut style="height:0.6944em;"}[0.15]{.mord}[[ and ]{.mord}]{.mord.text}[k]{.mord.mathnormal style="margin-right:0.03148em;"}[]{.mspace style="margin-right:0.2778em;"}[=]{.mrel}[]{.mspace style="margin-right:0.2778em;"}]{.base}[[]{.strut style="height:0.6444em;"}[7.5]{.mord}]{.base}]{.katex-html ariaHidden="true"}]{.katex}]{.katex-display} Where: - [[]{.katex-mathml}[[[]{.strut style="height:0.6151em;"}[t]{.mord.mathnormal}[]{.mspace style="margin-right:0.2778em;"}[=]{.mrel}[]{.mspace style="margin-right:0.2778em;"}]{.base}[[]{.strut style="height:0.6444em;"}[0.15]{.mord}]{.base}]{.katex-html ariaHidden="true"}]{.katex} is the threshold. - [[]{.katex-mathml}[[[]{.strut style="height:0.6944em;"}[k]{.mord.mathnormal style="margin-right:0.03148em;"}[]{.mspace style="margin-right:0.2778em;"}[=]{.mrel}[]{.mspace style="margin-right:0.2778em;"}]{.base}[[]{.strut style="height:0.6444em;"}[7.5]{.mord}]{.base}]{.katex-html ariaHidden="true"}]{.katex} is the slope of the curve. :iframe{.aspect-video.w-full allowFullScreen="true" frameBorder="0" src="https://www.desmos.com/calculator/xynm6uphlq?embed"} Graph of the dominance factor. The x-axis represents the validator's dominance ratio, and the y-axis represents the dominance score. The following table illustrates how the dominance score varies with the stake percentage: | Stake Percentage | Dominance Score | | ---------------- | --------------- | | 0% | 1 | | 5% | 0.999 | | 7.5% | 0.994 | | 10% | 0.952 | | 12.5% | 0.745 | | >=15% | 0 | ### Reliability The Reliability factor measures how consistently a validator produces blocks when expected. Validators who reliably produce their assigned blocks will have a high score, while those who fail frequently will receive a lower score. The reliability score is calculated as a weighted moving average over multiple epochs, emphasizing recent performance. #### Calculating Reliability for an Epoch The reliability score for a single epoch [[]{.katex-mathml}[[[]{.strut style="height:0.5806em;vertical-align:-0.15em;"}[[r]{.mord.mathnormal style="margin-right:0.02778em;"}[[[[[[]{.pstrut style="height:2.7em;"}[[i]{.mord.mathnormal.mtight}]{.sizing.reset-size6.size3.mtight}]{style="top:-2.55em;margin-left:-0.0278em;margin-right:0.05em;"}]{.vlist style="height:0.3117em;"}[​]{.vlist-s}]{.vlist-r}[[[]]{.vlist style="height:0.15em;"}]{.vlist-r}]{.vlist-t.vlist-t2}]{.msupsub}]{.mord}]{.base}]{.katex-html ariaHidden="true"}]{.katex} is calculated as: [[[]{.katex-mathml}[[[]{.strut style="height:0.5806em;vertical-align:-0.15em;"}[[r]{.mord.mathnormal style="margin-right:0.02778em;"}[[[[[[]{.pstrut style="height:2.7em;"}[[i]{.mord.mathnormal.mtight}]{.sizing.reset-size6.size3.mtight}]{style="top:-2.55em;margin-left:-0.0278em;margin-right:0.05em;"}]{.vlist style="height:0.3117em;"}[​]{.vlist-s}]{.vlist-r}[[[]]{.vlist style="height:0.15em;"}]{.vlist-r}]{.vlist-t.vlist-t2}]{.msupsub}]{.mord}[]{.mspace style="margin-right:0.2778em;"}[=]{.mrel}[]{.mspace style="margin-right:0.2778em;"}]{.base}[[]{.strut style="height:2.1963em;vertical-align:-0.836em;"}[[]{.mopen.nulldelimiter}[[[[[[]{.pstrut style="height:3em;"}[[[H]{.mord.mathnormal style="margin-right:0.08125em;"}[[[[[[]{.pstrut style="height:2.7em;"}[[i]{.mord.mathnormal.mtight}]{.sizing.reset-size6.size3.mtight}]{style="top:-2.55em;margin-left:-0.0813em;margin-right:0.05em;"}]{.vlist style="height:0.3117em;"}[​]{.vlist-s}]{.vlist-r}[[[]]{.vlist style="height:0.15em;"}]{.vlist-r}]{.vlist-t.vlist-t2}]{.msupsub}]{.mord}]{.mord}]{style="top:-2.314em;"}[[]{.pstrut style="height:3em;"}[]{.frac-line style="border-bottom-width:0.04em;"}]{style="top:-3.23em;"}[[]{.pstrut style="height:3em;"}[[[C]{.mord.mathnormal style="margin-right:0.07153em;"}[[[[[[]{.pstrut style="height:2.7em;"}[[i]{.mord.mathnormal.mtight}]{.sizing.reset-size6.size3.mtight}]{style="top:-2.55em;margin-left:-0.0715em;margin-right:0.05em;"}]{.vlist style="height:0.3117em;"}[​]{.vlist-s}]{.vlist-r}[[[]]{.vlist style="height:0.15em;"}]{.vlist-r}]{.vlist-t.vlist-t2}]{.msupsub}]{.mord}]{.mord}]{style="top:-3.677em;"}]{.vlist style="height:1.3603em;"}[​]{.vlist-s}]{.vlist-r}[[[]]{.vlist style="height:0.836em;"}]{.vlist-r}]{.vlist-t.vlist-t2}]{.mfrac}[]{.mclose.nulldelimiter}]{.mord}[,]{.mpunct}[]{.mspace style="margin-right:1em;"}[]{.mspace style="margin-right:0.1667em;"}[[for ]{.mord}]{.mord.text}[i]{.mord.mathnormal}[]{.mspace style="margin-right:0.2778em;"}[=]{.mrel}[]{.mspace style="margin-right:0.2778em;"}]{.base}[[]{.strut style="height:0.8389em;vertical-align:-0.1944em;"}[0]{.mord}[,]{.mpunct}[]{.mspace style="margin-right:0.1667em;"}[1]{.mord}[,]{.mpunct}[]{.mspace style="margin-right:0.1667em;"}[2]{.mord}[,]{.mpunct}[]{.mspace style="margin-right:0.1667em;"}[…]{.minner}[]{.mspace style="margin-right:0.1667em;"}[,]{.mpunct}[]{.mspace style="margin-right:0.1667em;"}[m]{.mord.mathnormal}[]{.mspace style="margin-right:0.2222em;"}[−]{.mbin}[]{.mspace style="margin-right:0.2222em;"}]{.base}[[]{.strut style="height:0.6444em;"}[1]{.mord}]{.base}]{.katex-html ariaHidden="true"}]{.katex}]{.katex-display} Where: - [[]{.katex-mathml}[[[]{.strut style="height:0.8333em;vertical-align:-0.15em;"}[[C]{.mord.mathnormal style="margin-right:0.07153em;"}[[[[[[]{.pstrut style="height:2.7em;"}[[i]{.mord.mathnormal.mtight}]{.sizing.reset-size6.size3.mtight}]{style="top:-2.55em;margin-left:-0.0715em;margin-right:0.05em;"}]{.vlist style="height:0.3117em;"}[​]{.vlist-s}]{.vlist-r}[[[]]{.vlist style="height:0.15em;"}]{.vlist-r}]{.vlist-t.vlist-t2}]{.msupsub}]{.mord}]{.base}]{.katex-html ariaHidden="true"}]{.katex}: The number of blocks produced by the validator in epoch [[]{.katex-mathml}[[[]{.strut style="height:0.6595em;"}[i]{.mord.mathnormal}]{.base}]{.katex-html ariaHidden="true"}]{.katex} that received rewards. - [[]{.katex-mathml}[[[]{.strut style="height:0.8333em;vertical-align:-0.15em;"}[[H]{.mord.mathnormal style="margin-right:0.08125em;"}[[[[[[]{.pstrut style="height:2.7em;"}[[i]{.mord.mathnormal.mtight}]{.sizing.reset-size6.size3.mtight}]{style="top:-2.55em;margin-left:-0.0813em;margin-right:0.05em;"}]{.vlist style="height:0.3117em;"}[​]{.vlist-s}]{.vlist-r}[[[]]{.vlist style="height:0.15em;"}]{.vlist-r}]{.vlist-t.vlist-t2}]{.msupsub}]{.mord}]{.base}]{.katex-html ariaHidden="true"}]{.katex}: The expected number of blocks the validator was likely to produce in epoch [[]{.katex-mathml}[[[]{.strut style="height:0.6595em;"}[i]{.mord.mathnormal}]{.base}]{.katex-html ariaHidden="true"}]{.katex}. ##### **Calculating [[]{.katex-mathml}[[[]{.strut style="height:0.8333em;vertical-align:-0.15em;"}[[C]{.mord.mathnormal style="margin-right:0.07153em;"}[[[[[[]{.pstrut style="height:2.7em;"}[[i]{.mord.mathnormal.mtight}]{.sizing.reset-size6.size3.mtight}]{style="top:-2.55em;margin-left:-0.0715em;margin-right:0.05em;"}]{.vlist style="height:0.3117em;"}[​]{.vlist-s}]{.vlist-r}[[[]]{.vlist style="height:0.15em;"}]{.vlist-r}]{.vlist-t.vlist-t2}]{.msupsub}]{.mord}]{.base}]{.katex-html ariaHidden="true"}]{.katex}** [[]{.katex-mathml}[[[]{.strut style="height:0.8333em;vertical-align:-0.15em;"}[[C]{.mord.mathnormal style="margin-right:0.07153em;"}[[[[[[]{.pstrut style="height:2.7em;"}[[i]{.mord.mathnormal.mtight}]{.sizing.reset-size6.size3.mtight}]{style="top:-2.55em;margin-left:-0.0715em;margin-right:0.05em;"}]{.vlist style="height:0.3117em;"}[​]{.vlist-s}]{.vlist-r}[[[]]{.vlist style="height:0.15em;"}]{.vlist-r}]{.vlist-t.vlist-t2}]{.msupsub}]{.mord}]{.base}]{.katex-html ariaHidden="true"}]{.katex} represents the total blocks rewarded to the validator in epoch [[]{.katex-mathml}[[[]{.strut style="height:0.6595em;"}[i]{.mord.mathnormal}]{.base}]{.katex-html ariaHidden="true"}]{.katex} : [[[]{.katex-mathml}[[[]{.strut style="height:0.8333em;vertical-align:-0.15em;"}[[C]{.mord.mathnormal style="margin-right:0.07153em;"}[[[[[[]{.pstrut style="height:2.7em;"}[[i]{.mord.mathnormal.mtight}]{.sizing.reset-size6.size3.mtight}]{style="top:-2.55em;margin-left:-0.0715em;margin-right:0.05em;"}]{.vlist style="height:0.3117em;"}[​]{.vlist-s}]{.vlist-r}[[[]]{.vlist style="height:0.15em;"}]{.vlist-r}]{.vlist-t.vlist-t2}]{.msupsub}]{.mord}[]{.mspace style="margin-right:0.2778em;"}[=]{.mrel}[]{.mspace style="margin-right:0.2778em;"}]{.base}[[]{.strut style="height:3.2421em;vertical-align:-1.4138em;"}[[[[[[]{.pstrut style="height:3.05em;"}[[[j]{.mord.mathnormal.mtight style="margin-right:0.05724em;"}[=]{.mrel.mtight}[0]{.mord.mtight}]{.mord.mtight}]{.sizing.reset-size6.size3.mtight}]{style="top:-1.8723em;margin-left:0em;"}[[]{.pstrut style="height:3.05em;"}[[∑]{.mop.op-symbol.large-op}]]{style="top:-3.05em;"}[[]{.pstrut style="height:3.05em;"}[[[N]{.mord.mathnormal.mtight style="margin-right:0.10903em;"}[−]{.mbin.mtight}[1]{.mord.mtight}]{.mord.mtight}]{.sizing.reset-size6.size3.mtight}]{style="top:-4.3em;margin-left:0em;"}]{.vlist style="height:1.8283em;"}[​]{.vlist-s}]{.vlist-r}[[[]]{.vlist style="height:1.4138em;"}]{.vlist-r}]{.vlist-t.vlist-t2}]{.mop.op-limits}[]{.mspace style="margin-right:0.1667em;"}[[c]{.mord.mathnormal}[[[[[[]{.pstrut style="height:2.7em;"}[[j]{.mord.mathnormal.mtight style="margin-right:0.05724em;"}]{.sizing.reset-size6.size3.mtight}]{style="top:-2.55em;margin-left:0em;margin-right:0.05em;"}]{.vlist style="height:0.3117em;"}[​]{.vlist-s}]{.vlist-r}[[[]]{.vlist style="height:0.2861em;"}]{.vlist-r}]{.vlist-t.vlist-t2}]{.msupsub}]{.mord}[]{.mspace style="margin-right:1em;"}[[for ]{.mord}]{.mord.text}[i]{.mord.mathnormal}[]{.mspace style="margin-right:0.2778em;"}[=]{.mrel}[]{.mspace style="margin-right:0.2778em;"}]{.base}[[]{.strut style="height:0.8389em;vertical-align:-0.1944em;"}[0]{.mord}[,]{.mpunct}[]{.mspace style="margin-right:0.1667em;"}[1]{.mord}[,]{.mpunct}[]{.mspace style="margin-right:0.1667em;"}[2]{.mord}[,]{.mpunct}[]{.mspace style="margin-right:0.1667em;"}[…]{.minner}[]{.mspace style="margin-right:0.1667em;"}[,]{.mpunct}[]{.mspace style="margin-right:0.1667em;"}[m]{.mord.mathnormal}[]{.mspace style="margin-right:0.2222em;"}[−]{.mbin}[]{.mspace style="margin-right:0.2222em;"}]{.base}[[]{.strut style="height:0.6444em;"}[1]{.mord}]{.base}]{.katex-html ariaHidden="true"}]{.katex}]{.katex-display} Where: - [[]{.katex-mathml}[[[]{.strut style="height:0.7167em;vertical-align:-0.2861em;"}[[c]{.mord.mathnormal}[[[[[[]{.pstrut style="height:2.7em;"}[[j]{.mord.mathnormal.mtight style="margin-right:0.05724em;"}]{.sizing.reset-size6.size3.mtight}]{style="top:-2.55em;margin-left:0em;margin-right:0.05em;"}]{.vlist style="height:0.3117em;"}[​]{.vlist-s}]{.vlist-r}[[[]]{.vlist style="height:0.2861em;"}]{.vlist-r}]{.vlist-t.vlist-t2}]{.msupsub}]{.mord}]{.base}]{.katex-html ariaHidden="true"}]{.katex}: The number of blocks produced by the validator in batch [[]{.katex-mathml}[[[]{.strut style="height:0.854em;vertical-align:-0.1944em;"}[j]{.mord.mathnormal style="margin-right:0.05724em;"}]{.base}]{.katex-html ariaHidden="true"}]{.katex} of epoch [[]{.katex-mathml}[[[]{.strut style="height:0.6595em;"}[i]{.mord.mathnormal}]{.base}]{.katex-html ariaHidden="true"}]{.katex}. - [[]{.katex-mathml}[[[]{.strut style="height:0.6833em;"}[N]{.mord.mathnormal style="margin-right:0.10903em;"}]{.base}]{.katex-html ariaHidden="true"}]{.katex}: The total number of batches in the epoch (retrievable from the [policy](https://github.com/nimiq/core-rs-albatross/blob/albatross/primitives/src/policy.rs){rel=""nofollow""}). The number of blocks a validator produced can be retrieved from the blockchain via the rewarded inherent of each batch. ##### **Calculating [[]{.katex-mathml}[[[]{.strut style="height:0.8333em;vertical-align:-0.15em;"}[[H]{.mord.mathnormal style="margin-right:0.08125em;"}[[[[[[]{.pstrut style="height:2.7em;"}[[i]{.mord.mathnormal.mtight}]{.sizing.reset-size6.size3.mtight}]{style="top:-2.55em;margin-left:-0.0813em;margin-right:0.05em;"}]{.vlist style="height:0.3117em;"}[​]{.vlist-s}]{.vlist-r}[[[]]{.vlist style="height:0.15em;"}]{.vlist-r}]{.vlist-t.vlist-t2}]{.msupsub}]{.mord}]{.base}]{.katex-html ariaHidden="true"}]{.katex}** [[]{.katex-mathml}[[[]{.strut style="height:0.8333em;vertical-align:-0.15em;"}[[H]{.mord.mathnormal style="margin-right:0.08125em;"}[[[[[[]{.pstrut style="height:2.7em;"}[[i]{.mord.mathnormal.mtight}]{.sizing.reset-size6.size3.mtight}]{style="top:-2.55em;margin-left:-0.0813em;margin-right:0.05em;"}]{.vlist style="height:0.3117em;"}[​]{.vlist-s}]{.vlist-r}[[[]]{.vlist style="height:0.15em;"}]{.vlist-r}]{.vlist-t.vlist-t2}]{.msupsub}]{.mord}]{.base}]{.katex-html ariaHidden="true"}]{.katex} represents the expected likelihood of the validator producing blocks in epoch [[]{.katex-mathml}[[[]{.strut style="height:0.6595em;"}[i]{.mord.mathnormal}]{.base}]{.katex-html ariaHidden="true"}]{.katex} : [[[]{.katex-mathml}[[[]{.strut style="height:0.8333em;vertical-align:-0.15em;"}[[H]{.mord.mathnormal style="margin-right:0.08125em;"}[[[[[[]{.pstrut style="height:2.7em;"}[[i]{.mord.mathnormal.mtight}]{.sizing.reset-size6.size3.mtight}]{style="top:-2.55em;margin-left:-0.0813em;margin-right:0.05em;"}]{.vlist style="height:0.3117em;"}[​]{.vlist-s}]{.vlist-r}[[[]]{.vlist style="height:0.15em;"}]{.vlist-r}]{.vlist-t.vlist-t2}]{.msupsub}]{.mord}[]{.mspace style="margin-right:0.2778em;"}[=]{.mrel}[]{.mspace style="margin-right:0.2778em;"}]{.base}[[]{.strut style="height:2.5424em;vertical-align:-1.1709em;"}[[]{.mopen.nulldelimiter}[[[[[[]{.pstrut style="height:3em;"}[[[∑]{.mop.op-symbol.small-op style="position:relative;top:0em;"}[[[[[[]{.pstrut style="height:2.7em;"}[[[k]{.mord.mathnormal.mtight style="margin-right:0.03148em;"}[=]{.mrel.mtight}[0]{.mord.mtight}]{.mord.mtight}]{.sizing.reset-size6.size3.mtight}]{style="top:-2.4003em;margin-left:0em;margin-right:0.05em;"}[[]{.pstrut style="height:2.7em;"}[[[V]{.mord.mathnormal.mtight style="margin-right:0.22222em;"}[−]{.mbin.mtight}[1]{.mord.mtight}]{.mord.mtight}]{.sizing.reset-size6.size3.mtight}]{style="top:-3.2029em;margin-right:0.05em;"}]{.vlist style="height:0.9812em;"}[​]{.vlist-s}]{.vlist-r}[[[]]{.vlist style="height:0.2997em;"}]{.vlist-r}]{.vlist-t.vlist-t2}]{.msupsub}]{.mop}[]{.mspace style="margin-right:0.1667em;"}[[h]{.mord.mathnormal}[[[[[[]{.pstrut style="height:2.7em;"}[[[i]{.mord.mathnormal.mtight}[,]{.mpunct.mtight}[v]{.mord.mathnormal.mtight style="margin-right:0.03588em;"}]{.mord.mtight}]{.sizing.reset-size6.size3.mtight}]{style="top:-2.55em;margin-left:0em;margin-right:0.05em;"}]{.vlist style="height:0.3117em;"}[​]{.vlist-s}]{.vlist-r}[[[]]{.vlist style="height:0.2861em;"}]{.vlist-r}]{.vlist-t.vlist-t2}]{.msupsub}]{.mord}]{.mord}]{style="top:-2.1288em;"}[[]{.pstrut style="height:3em;"}[]{.frac-line style="border-bottom-width:0.04em;"}]{style="top:-3.23em;"}[[]{.pstrut style="height:3em;"}[[[h]{.mord.mathnormal}[[[[[[]{.pstrut style="height:2.7em;"}[[[i]{.mord.mathnormal.mtight}[,]{.mpunct.mtight}[v]{.mord.mathnormal.mtight style="margin-right:0.03588em;"}]{.mord.mtight}]{.sizing.reset-size6.size3.mtight}]{style="top:-2.55em;margin-left:0em;margin-right:0.05em;"}]{.vlist style="height:0.3117em;"}[​]{.vlist-s}]{.vlist-r}[[[]]{.vlist style="height:0.2861em;"}]{.vlist-r}]{.vlist-t.vlist-t2}]{.msupsub}]{.mord}]{.mord}]{style="top:-3.677em;"}]{.vlist style="height:1.3714em;"}[​]{.vlist-s}]{.vlist-r}[[[]]{.vlist style="height:1.1709em;"}]{.vlist-r}]{.vlist-t.vlist-t2}]{.mfrac}[]{.mclose.nulldelimiter}]{.mord}[]{.mspace style="margin-right:1em;"}[[for ]{.mord}]{.mord.text}[i]{.mord.mathnormal}[]{.mspace style="margin-right:0.2778em;"}[=]{.mrel}[]{.mspace style="margin-right:0.2778em;"}]{.base}[[]{.strut style="height:0.8389em;vertical-align:-0.1944em;"}[0]{.mord}[,]{.mpunct}[]{.mspace style="margin-right:0.1667em;"}[1]{.mord}[,]{.mpunct}[]{.mspace style="margin-right:0.1667em;"}[2]{.mord}[,]{.mpunct}[]{.mspace style="margin-right:0.1667em;"}[…]{.minner}[]{.mspace style="margin-right:0.1667em;"}[,]{.mpunct}[]{.mspace style="margin-right:0.1667em;"}[m]{.mord.mathnormal}[]{.mspace style="margin-right:0.2222em;"}[−]{.mbin}[]{.mspace style="margin-right:0.2222em;"}]{.base}[[]{.strut style="height:0.6444em;"}[1]{.mord}]{.base}]{.katex-html ariaHidden="true"}]{.katex}]{.katex-display} Where: - [[]{.katex-mathml}[[[]{.strut style="height:0.9805em;vertical-align:-0.2861em;"}[[h]{.mord.mathnormal}[[[[[[]{.pstrut style="height:2.7em;"}[[[i]{.mord.mathnormal.mtight}[,]{.mpunct.mtight}[v]{.mord.mathnormal.mtight style="margin-right:0.03588em;"}]{.mord.mtight}]{.sizing.reset-size6.size3.mtight}]{style="top:-2.55em;margin-left:0em;margin-right:0.05em;"}]{.vlist style="height:0.3117em;"}[​]{.vlist-s}]{.vlist-r}[[[]]{.vlist style="height:0.2861em;"}]{.vlist-r}]{.vlist-t.vlist-t2}]{.msupsub}]{.mord}]{.base}]{.katex-html ariaHidden="true"}]{.katex}: The total slots assigned to the validator [[]{.katex-mathml}[[[]{.strut style="height:0.4306em;"}[v]{.mord.mathnormal style="margin-right:0.03588em;"}]{.base}]{.katex-html ariaHidden="true"}]{.katex} in epoch [[]{.katex-mathml}[[[]{.strut style="height:0.6595em;"}[i]{.mord.mathnormal}]{.base}]{.katex-html ariaHidden="true"}]{.katex}. - [[]{.katex-mathml}[[[]{.strut style="height:0.6833em;"}[V]{.mord.mathnormal style="margin-right:0.22222em;"}]{.base}]{.katex-html ariaHidden="true"}]{.katex}: The total number of active validators in epoch [[]{.katex-mathml}[[[]{.strut style="height:0.6595em;"}[i]{.mord.mathnormal}]{.base}]{.katex-html ariaHidden="true"}]{.katex}. #### Combining Reliability Scores Across Epochs To calculate a validator's overall reliability score, we use a weighted moving average of scores across multiple epochs. More recent epochs are given higher weight: [[[]{.katex-mathml}[[[]{.strut style="height:0.8201em;"}[[[[[[]{.pstrut style="height:3em;"}[R]{.mord.mathnormal style="margin-right:0.00773em;"}]{style="top:-3em;"}[[]{.pstrut style="height:3em;"}[[ˉ]{.mord}]{.accent-body style="left:-0.1667em;"}]{style="top:-3.2523em;"}]{.vlist style="height:0.8201em;"}]{.vlist-r}]{.vlist-t}]{.mord.accent}[]{.mspace style="margin-right:0.2778em;"}[=]{.mrel}[]{.mspace style="margin-right:0.2778em;"}]{.base}[[]{.strut style="height:2.9947em;vertical-align:-1.2473em;"}[[]{.mopen.nulldelimiter}[[[[[[]{.pstrut style="height:3em;"}[[[∑]{.mop.op-symbol.small-op style="position:relative;top:0em;"}[[[[[[]{.pstrut style="height:2.7em;"}[[[i]{.mord.mathnormal.mtight}[=]{.mrel.mtight}[0]{.mord.mtight}]{.mord.mtight}]{.sizing.reset-size6.size3.mtight}]{style="top:-2.4003em;margin-left:0em;margin-right:0.05em;"}[[]{.pstrut style="height:2.7em;"}[[[m]{.mord.mathnormal.mtight}[−]{.mbin.mtight}[1]{.mord.mtight}]{.mord.mtight}]{.sizing.reset-size6.size3.mtight}]{style="top:-3.2029em;margin-right:0.05em;"}]{.vlist style="height:0.954em;"}[​]{.vlist-s}]{.vlist-r}[[[]]{.vlist style="height:0.2997em;"}]{.vlist-r}]{.vlist-t.vlist-t2}]{.msupsub}]{.mop}[]{.mspace style="margin-right:0.1667em;"}[[[(]{.delimsizing.size1}]{.mopen.delimcenter style="top:0em;"}[1]{.mord}[]{.mspace style="margin-right:0.2222em;"}[−]{.mbin}[]{.mspace style="margin-right:0.2222em;"}[a]{.mord.mathnormal}[[]{.mopen.nulldelimiter}[[[[[[]{.pstrut style="height:3em;"}[[[m]{.mord.mathnormal.mtight}[−]{.mbin.mtight}[1]{.mord.mtight}]{.mord.mtight}]{.sizing.reset-size6.size3.mtight}]{style="top:-2.655em;"}[[]{.pstrut style="height:3em;"}[]{.frac-line style="border-bottom-width:0.04em;"}]{style="top:-3.23em;"}[[]{.pstrut style="height:3em;"}[[[i]{.mord.mathnormal.mtight}]{.mord.mtight}]{.sizing.reset-size6.size3.mtight}]{style="top:-3.394em;"}]{.vlist style="height:0.8557em;"}[​]{.vlist-s}]{.vlist-r}[[[]]{.vlist style="height:0.4033em;"}]{.vlist-r}]{.vlist-t.vlist-t2}]{.mfrac}[]{.mclose.nulldelimiter}]{.mord}[[)]{.delimsizing.size1}]{.mclose.delimcenter style="top:0em;"}]{.minner}]{.mord}]{style="top:-2.156em;"}[[]{.pstrut style="height:3em;"}[]{.frac-line style="border-bottom-width:0.04em;"}]{style="top:-3.23em;"}[[]{.pstrut style="height:3em;"}[[[∑]{.mop.op-symbol.small-op style="position:relative;top:0em;"}[[[[[[]{.pstrut style="height:2.7em;"}[[[i]{.mord.mathnormal.mtight}[=]{.mrel.mtight}[0]{.mord.mtight}]{.mord.mtight}]{.sizing.reset-size6.size3.mtight}]{style="top:-2.4003em;margin-left:0em;margin-right:0.05em;"}[[]{.pstrut style="height:2.7em;"}[[[m]{.mord.mathnormal.mtight}[−]{.mbin.mtight}[1]{.mord.mtight}]{.mord.mtight}]{.sizing.reset-size6.size3.mtight}]{style="top:-3.2029em;margin-right:0.05em;"}]{.vlist style="height:0.954em;"}[​]{.vlist-s}]{.vlist-r}[[[]]{.vlist style="height:0.2997em;"}]{.vlist-r}]{.vlist-t.vlist-t2}]{.msupsub}]{.mop}[]{.mspace style="margin-right:0.1667em;"}[[[(]{.delimsizing.size1}]{.mopen.delimcenter style="top:0em;"}[1]{.mord}[]{.mspace style="margin-right:0.2222em;"}[−]{.mbin}[]{.mspace style="margin-right:0.2222em;"}[a]{.mord.mathnormal}[[]{.mopen.nulldelimiter}[[[[[[]{.pstrut style="height:3em;"}[[[m]{.mord.mathnormal.mtight}[−]{.mbin.mtight}[1]{.mord.mtight}]{.mord.mtight}]{.sizing.reset-size6.size3.mtight}]{style="top:-2.655em;"}[[]{.pstrut style="height:3em;"}[]{.frac-line style="border-bottom-width:0.04em;"}]{style="top:-3.23em;"}[[]{.pstrut style="height:3em;"}[[[i]{.mord.mathnormal.mtight}]{.mord.mtight}]{.sizing.reset-size6.size3.mtight}]{style="top:-3.394em;"}]{.vlist style="height:0.8557em;"}[​]{.vlist-s}]{.vlist-r}[[[]]{.vlist style="height:0.4033em;"}]{.vlist-r}]{.vlist-t.vlist-t2}]{.mfrac}[]{.mclose.nulldelimiter}]{.mord}[[)]{.delimsizing.size1}]{.mclose.delimcenter style="top:0em;"}]{.minner}[]{.mspace style="margin-right:0.1667em;"}[[r]{.mord.mathnormal style="margin-right:0.02778em;"}[[[[[[]{.pstrut style="height:2.7em;"}[[i]{.mord.mathnormal.mtight}]{.sizing.reset-size6.size3.mtight}]{style="top:-2.55em;margin-left:-0.0278em;margin-right:0.05em;"}]{.vlist style="height:0.3117em;"}[​]{.vlist-s}]{.vlist-r}[[[]]{.vlist style="height:0.15em;"}]{.vlist-r}]{.vlist-t.vlist-t2}]{.msupsub}]{.mord}]{.mord}]{style="top:-3.7933em;"}]{.vlist style="height:1.7473em;"}[​]{.vlist-s}]{.vlist-r}[[[]]{.vlist style="height:1.2473em;"}]{.vlist-r}]{.vlist-t.vlist-t2}]{.mfrac}[]{.mclose.nulldelimiter}]{.mord}[,]{.mpunct}[]{.mspace style="margin-right:1em;"}[]{.mspace style="margin-right:0.1667em;"}[a]{.mord.mathnormal}[]{.mspace style="margin-right:0.2778em;"}[=]{.mrel}[]{.mspace style="margin-right:0.2778em;"}]{.base}[[]{.strut style="height:0.6444em;"}[0.5]{.mord}]{.base}]{.katex-html ariaHidden="true"}]{.katex}]{.katex-display} Where: - [[]{.katex-mathml}[[[]{.strut style="height:0.4306em;"}[m]{.mord.mathnormal}]{.base}]{.katex-html ariaHidden="true"}]{.katex}: Total number of epochs considered. - [[]{.katex-mathml}[[[]{.strut style="height:0.4306em;"}[a]{.mord.mathnormal}]{.base}]{.katex-html ariaHidden="true"}]{.katex} = 0.5: Parameter determining how much weight the oldest epoch receives compared to the newest epoch, helping to balance the influence of recent versus older performance tendencies in the weighted moving average. #### Adjusting for High-Reliability Expectations The formula for the weighted moving average [[]{.katex-mathml}[[[]{.strut style="height:0.8201em;"}[[[[[[]{.pstrut style="height:3em;"}[R]{.mord.mathnormal style="margin-right:0.00773em;"}]{style="top:-3em;"}[[]{.pstrut style="height:3em;"}[[ˉ]{.mord}]{.accent-body style="left:-0.1667em;"}]{style="top:-3.2523em;"}]{.vlist style="height:0.8201em;"}]{.vlist-r}]{.vlist-t}]{.mord.accent}]{.base}]{.katex-html ariaHidden="true"}]{.katex} provides a baseline reliability score. However, to better reflect the high standards expected of validators, an additional adjustment is applied. This adjustment penalizes validators with lower reliability more severely, emphasizing the importance of consistent performance. The adjusted reliability score [[]{.katex-mathml}[[[]{.strut style="height:0.6833em;"}[R]{.mord.mathnormal style="margin-right:0.00773em;"}]{.base}]{.katex-html ariaHidden="true"}]{.katex} is calculated using the following formula: [[[]{.katex-mathml}[[[]{.strut style="height:0.6833em;"}[R]{.mord.mathnormal style="margin-right:0.00773em;"}[]{.mspace style="margin-right:0.2778em;"}[=]{.mrel}[]{.mspace style="margin-right:0.2778em;"}]{.base}[[]{.strut style="height:0.6667em;vertical-align:-0.0833em;"}[−]{.mord}[c]{.mord.mathnormal}[]{.mspace style="margin-right:0.2222em;"}[+]{.mbin}[]{.mspace style="margin-right:0.2222em;"}]{.base}[[]{.strut style="height:0.7278em;vertical-align:-0.0833em;"}[1]{.mord}[]{.mspace style="margin-right:0.2222em;"}[−]{.mbin}[]{.mspace style="margin-right:0.2222em;"}]{.base}[[]{.strut style="height:1.84em;vertical-align:-0.4541em;"}[[[[[[]{.pstrut style="height:3.8em;"}[[−]{.mord}[[[[[[[]{.pstrut style="height:3em;"}[R]{.mord.mathnormal style="margin-right:0.00773em;"}]{style="top:-3em;"}[[]{.pstrut style="height:3em;"}[[ˉ]{.mord}]{.accent-body style="left:-0.1667em;"}]{style="top:-3.2523em;"}]{.vlist style="height:0.8201em;"}]{.vlist-r}]{.vlist-t}]{.mord.accent}[[[[[[]{.pstrut style="height:2.7em;"}[[[2]{.mord.mtight}]{.mord.mtight}]{.sizing.reset-size6.size3.mtight}]{style="top:-2.989em;margin-right:0.05em;"}]{.vlist style="height:0.7401em;"}]{.vlist-r}]{.vlist-t}]{.msupsub}]{.mord}[]{.mspace style="margin-right:0.2222em;"}[+]{.mbin}[]{.mspace style="margin-right:0.2222em;"}[2]{.mord}[c]{.mord.mathnormal}[[[[[[]{.pstrut style="height:3em;"}[R]{.mord.mathnormal style="margin-right:0.00773em;"}]{style="top:-3em;"}[[]{.pstrut style="height:3em;"}[[ˉ]{.mord}]{.accent-body style="left:-0.1667em;"}]{style="top:-3.2523em;"}]{.vlist style="height:0.8201em;"}]{.vlist-r}]{.vlist-t}]{.mord.accent}[]{.mspace style="margin-right:0.2222em;"}[+]{.mbin}[]{.mspace style="margin-right:0.2222em;"}[[[(]{.mopen.delimcenter style="top:0em;"}[c]{.mord.mathnormal}[]{.mspace style="margin-right:0.2222em;"}[−]{.mbin}[]{.mspace style="margin-right:0.2222em;"}[1]{.mord}[)]{.mclose.delimcenter style="top:0em;"}]{.minner}[[[[[[]{.pstrut style="height:2.7em;"}[[[2]{.mord.mtight}]{.mord.mtight}]{.sizing.reset-size6.size3.mtight}]{style="top:-3.2029em;margin-right:0.05em;"}]{.vlist style="height:0.954em;"}]{.vlist-r}]{.vlist-t}]{.msupsub}]{.minner}]{.mord style="padding-left:1em;"}]{.svg-align style="top:-3.8em;"}[[]{.pstrut style="height:3.8em;"}[]{.hide-tail style="min-width:1.02em;height:1.88em;"}]{style="top:-3.3459em;"}]{.vlist style="height:1.3859em;"}[​]{.vlist-s}]{.vlist-r}[[[]]{.vlist style="height:0.4541em;"}]{.vlist-r}]{.vlist-t.vlist-t2}]{.mord.sqrt}]{.base}]{.katex-html ariaHidden="true"}]{.katex}]{.katex-display} Where: - [[]{.katex-mathml}[[[]{.strut style="height:0.4306em;"}[c]{.mord.mathnormal}[]{.mspace style="margin-right:0.2778em;"}[=]{.mrel}[]{.mspace style="margin-right:0.2778em;"}]{.base}[[]{.strut style="height:0.7278em;vertical-align:-0.0833em;"}[−]{.mord}[0.16]{.mord}]{.base}]{.katex-html ariaHidden="true"}]{.katex}: Defines the slope of the arc and determines the position of the curve. The adjustment formula is based on a circular arc, with the center of the circle at [[]{.katex-mathml}[[[]{.strut style="height:1em;vertical-align:-0.25em;"}[(]{.mopen}[c]{.mord.mathnormal}[,]{.mpunct}[]{.mspace style="margin-right:0.1667em;"}[−]{.mord}[c]{.mord.mathnormal}[]{.mspace style="margin-right:0.2222em;"}[+]{.mbin}[]{.mspace style="margin-right:0.2222em;"}]{.base}[[]{.strut style="height:1em;vertical-align:-0.25em;"}[1]{.mord}[)]{.mclose}]{.base}]{.katex-html ariaHidden="true"}]{.katex}. This adjustment maps the reliability score to a curve, making penalties for lower scores sharper while preserving high scores for reliable validators. :iframe{.aspect-video.w-full allowFullScreen="true" frameBorder="0" src="https://www.desmos.com/calculator/zqemsh7yay?embed"} Graph of the reliability score adjustment. The x-axis represents the reliability score, and the y-axis represents the adjusted reliability score. The adjustment curve is derived from a circular arc with a defined center. :br For example, a baseline reliability score of [[]{.katex-mathml}[[[]{.strut style="height:0.8201em;"}[[[[[[]{.pstrut style="height:3em;"}[R]{.mord.mathnormal style="margin-right:0.00773em;"}]{style="top:-3em;"}[[]{.pstrut style="height:3em;"}[[ˉ]{.mord}]{.accent-body style="left:-0.1667em;"}]{style="top:-3.2523em;"}]{.vlist style="height:0.8201em;"}]{.vlist-r}]{.vlist-t}]{.mord.accent}[]{.mspace style="margin-right:0.2778em;"}[=]{.mrel}[]{.mspace style="margin-right:0.2778em;"}]{.base}[[]{.strut style="height:0.6444em;"}[0.9]{.mord}]{.base}]{.katex-html ariaHidden="true"}]{.katex} may correspond approximately to 10% downtime, reflecting significant but not catastrophic validator underperformance. Validators with lower scores experience increasingly steep penalties, ensuring that unreliable validators are disincentivized. Note that using 10% is only a heavy approximation. The value of 0.9 could represent 10% downtime, but also 20% or 5%, depending on when the downtime occurred. We use 10% to provide a relatable scale for the reader. ### Availability The availability factor measures how often a validator is online and selected to produce blocks. Validators that are consistently selected and actively producing blocks receive a higher score, promoting reliable participation and network security. #### Why Availability Matters Without availability, a validator could have high dominance and reliability scores but still not actively contribute to the network. This would misrepresent their role in maintaining the network's operation. The availability factor ensures that only validators selected to produce blocks are evaluated, penalizing those that fail to participate effectively, whether due to inactivity, being jailed, or missing blocks when offline. In this context, we cannot measure how long a validator is online but can only determine when they are selected to produce blocks. A validator may be considered active yet fail to produce blocks. Availability focuses on participation in block production, regardless of online or offline status. For instance: - A validator might not produce blocks because it hasn’t been selected in a specific period. - In the other hand, a validator may be offline, causing it to miss block production when selected. Availability reflects how often a validator is selected to produce blocks, regardless of their online status. #### How to Calculate Availability The availability score for a single epoch [[]{.katex-mathml}[[[]{.strut style="height:0.8444em;vertical-align:-0.15em;"}[[l]{.mord.mathnormal style="margin-right:0.01968em;"}[[[[[[]{.pstrut style="height:2.7em;"}[[i]{.mord.mathnormal.mtight}]{.sizing.reset-size6.size3.mtight}]{style="top:-2.55em;margin-left:-0.0197em;margin-right:0.05em;"}]{.vlist style="height:0.3117em;"}[​]{.vlist-s}]{.vlist-r}[[[]]{.vlist style="height:0.15em;"}]{.vlist-r}]{.vlist-t.vlist-t2}]{.msupsub}]{.mord}]{.base}]{.katex-html ariaHidden="true"}]{.katex} is calculated as follows: [[[]{.katex-mathml}[[[]{.strut style="height:0.8444em;vertical-align:-0.15em;"}[[l]{.mord.mathnormal style="margin-right:0.01968em;"}[[[[[[]{.pstrut style="height:2.7em;"}[[i]{.mord.mathnormal.mtight}]{.sizing.reset-size6.size3.mtight}]{style="top:-2.55em;margin-left:-0.0197em;margin-right:0.05em;"}]{.vlist style="height:0.3117em;"}[​]{.vlist-s}]{.vlist-r}[[[]]{.vlist style="height:0.15em;"}]{.vlist-r}]{.vlist-t.vlist-t2}]{.msupsub}]{.mord}[]{.mspace style="margin-right:0.2778em;"}[=]{.mrel}[]{.mspace style="margin-right:0.2778em;"}]{.base}[[]{.strut style="height:3em;vertical-align:-1.25em;"}[[[{]{.delimsizing.size4}]{.mopen.delimcenter style="top:0em;"}[[[[[[[[]{.pstrut style="height:3.008em;"}[[1]{.mord}]{.mord}]{style="top:-3.69em;"}[[]{.pstrut style="height:3.008em;"}[[0]{.mord}]{.mord}]{style="top:-2.25em;"}]{.vlist style="height:1.69em;"}[​]{.vlist-s}]{.vlist-r}[[[]]{.vlist style="height:1.19em;"}]{.vlist-r}]{.vlist-t.vlist-t2}]{.col-align-l}[]{.arraycolsep style="width:1em;"}[[[[[[]{.pstrut style="height:3.008em;"}[[[if validator was selected in epoch ]{.mord}]{.mord.text}[i]{.mord.mathnormal}]{.mord}]{style="top:-3.69em;"}[[]{.pstrut style="height:3.008em;"}[[[otherwise]{.mord}]{.mord.text}]{.mord}]{style="top:-2.25em;"}]{.vlist style="height:1.69em;"}[​]{.vlist-s}]{.vlist-r}[[[]]{.vlist style="height:1.19em;"}]{.vlist-r}]{.vlist-t.vlist-t2}]{.col-align-l}]{.mtable}]{.mord}[]{.mclose.nulldelimiter}]{.minner}[]{.mspace style="margin-right:1em;"}[]{.mspace style="margin-right:0.1667em;"}[[for ]{.mord}]{.mord.text}[i]{.mord.mathnormal}[]{.mspace style="margin-right:0.2778em;"}[=]{.mrel}[]{.mspace style="margin-right:0.2778em;"}]{.base}[[]{.strut style="height:0.8389em;vertical-align:-0.1944em;"}[0]{.mord}[,]{.mpunct}[]{.mspace style="margin-right:0.1667em;"}[1]{.mord}[,]{.mpunct}[]{.mspace style="margin-right:0.1667em;"}[2]{.mord}[,]{.mpunct}[]{.mspace style="margin-right:0.1667em;"}[…]{.minner}[]{.mspace style="margin-right:0.1667em;"}[,]{.mpunct}[]{.mspace style="margin-right:0.1667em;"}[m]{.mord.mathnormal}[]{.mspace style="margin-right:0.2222em;"}[−]{.mbin}[]{.mspace style="margin-right:0.2222em;"}]{.base}[[]{.strut style="height:0.6444em;"}[1]{.mord}]{.base}]{.katex-html ariaHidden="true"}]{.katex}]{.katex-display} Where: - [[]{.katex-mathml}[[[]{.strut style="height:0.8444em;vertical-align:-0.15em;"}[[l]{.mord.mathnormal style="margin-right:0.01968em;"}[[[[[[]{.pstrut style="height:2.7em;"}[[0]{.mord.mtight}]{.sizing.reset-size6.size3.mtight}]{style="top:-2.55em;margin-left:-0.0197em;margin-right:0.05em;"}]{.vlist style="height:0.3011em;"}[​]{.vlist-s}]{.vlist-r}[[[]]{.vlist style="height:0.15em;"}]{.vlist-r}]{.vlist-t.vlist-t2}]{.msupsub}]{.mord}]{.base}]{.katex-html ariaHidden="true"}]{.katex}: The availability score for the most recent epoch. - [[]{.katex-mathml}[[[]{.strut style="height:0.9028em;vertical-align:-0.2083em;"}[[l]{.mord.mathnormal style="margin-right:0.01968em;"}[[[[[[]{.pstrut style="height:2.7em;"}[[[m]{.mord.mathnormal.mtight}[−]{.mbin.mtight}[1]{.mord.mtight}]{.mord.mtight}]{.sizing.reset-size6.size3.mtight}]{style="top:-2.55em;margin-left:-0.0197em;margin-right:0.05em;"}]{.vlist style="height:0.3011em;"}[​]{.vlist-s}]{.vlist-r}[[[]]{.vlist style="height:0.2083em;"}]{.vlist-r}]{.vlist-t.vlist-t2}]{.msupsub}]{.mord}]{.base}]{.katex-html ariaHidden="true"}]{.katex}: The availability score for the oldest epoch. To combine availability scores across epochs into a single value, we calculate a weighted moving average, where more recent epochs have higher weights: [[[]{.katex-mathml}[[[]{.strut style="height:0.8201em;"}[[[[[[]{.pstrut style="height:3em;"}[L]{.mord.mathnormal}]{style="top:-3em;"}[[]{.pstrut style="height:3em;"}[[ˉ]{.mord}]{.accent-body style="left:-0.2222em;"}]{style="top:-3.2523em;"}]{.vlist style="height:0.8201em;"}]{.vlist-r}]{.vlist-t}]{.mord.accent}[]{.mspace style="margin-right:0.2778em;"}[=]{.mrel}[]{.mspace style="margin-right:0.2778em;"}]{.base}[[]{.strut style="height:2.9947em;vertical-align:-1.2473em;"}[[]{.mopen.nulldelimiter}[[[[[[]{.pstrut style="height:3em;"}[[[∑]{.mop.op-symbol.small-op style="position:relative;top:0em;"}[[[[[[]{.pstrut style="height:2.7em;"}[[[i]{.mord.mathnormal.mtight}[=]{.mrel.mtight}[0]{.mord.mtight}]{.mord.mtight}]{.sizing.reset-size6.size3.mtight}]{style="top:-2.4003em;margin-left:0em;margin-right:0.05em;"}[[]{.pstrut style="height:2.7em;"}[[[m]{.mord.mathnormal.mtight}[−]{.mbin.mtight}[1]{.mord.mtight}]{.mord.mtight}]{.sizing.reset-size6.size3.mtight}]{style="top:-3.2029em;margin-right:0.05em;"}]{.vlist style="height:0.954em;"}[​]{.vlist-s}]{.vlist-r}[[[]]{.vlist style="height:0.2997em;"}]{.vlist-r}]{.vlist-t.vlist-t2}]{.msupsub}]{.mop}[]{.mspace style="margin-right:0.1667em;"}[[[(]{.delimsizing.size1}]{.mopen.delimcenter style="top:0em;"}[1]{.mord}[]{.mspace style="margin-right:0.2222em;"}[−]{.mbin}[]{.mspace style="margin-right:0.2222em;"}[a]{.mord.mathnormal}[[]{.mopen.nulldelimiter}[[[[[[]{.pstrut style="height:3em;"}[[[m]{.mord.mathnormal.mtight}[−]{.mbin.mtight}[1]{.mord.mtight}]{.mord.mtight}]{.sizing.reset-size6.size3.mtight}]{style="top:-2.655em;"}[[]{.pstrut style="height:3em;"}[]{.frac-line style="border-bottom-width:0.04em;"}]{style="top:-3.23em;"}[[]{.pstrut style="height:3em;"}[[[i]{.mord.mathnormal.mtight}]{.mord.mtight}]{.sizing.reset-size6.size3.mtight}]{style="top:-3.394em;"}]{.vlist style="height:0.8557em;"}[​]{.vlist-s}]{.vlist-r}[[[]]{.vlist style="height:0.4033em;"}]{.vlist-r}]{.vlist-t.vlist-t2}]{.mfrac}[]{.mclose.nulldelimiter}]{.mord}[[)]{.delimsizing.size1}]{.mclose.delimcenter style="top:0em;"}]{.minner}]{.mord}]{style="top:-2.156em;"}[[]{.pstrut style="height:3em;"}[]{.frac-line style="border-bottom-width:0.04em;"}]{style="top:-3.23em;"}[[]{.pstrut style="height:3em;"}[[[∑]{.mop.op-symbol.small-op style="position:relative;top:0em;"}[[[[[[]{.pstrut style="height:2.7em;"}[[[i]{.mord.mathnormal.mtight}[=]{.mrel.mtight}[0]{.mord.mtight}]{.mord.mtight}]{.sizing.reset-size6.size3.mtight}]{style="top:-2.4003em;margin-left:0em;margin-right:0.05em;"}[[]{.pstrut style="height:2.7em;"}[[[m]{.mord.mathnormal.mtight}[−]{.mbin.mtight}[1]{.mord.mtight}]{.mord.mtight}]{.sizing.reset-size6.size3.mtight}]{style="top:-3.2029em;margin-right:0.05em;"}]{.vlist style="height:0.954em;"}[​]{.vlist-s}]{.vlist-r}[[[]]{.vlist style="height:0.2997em;"}]{.vlist-r}]{.vlist-t.vlist-t2}]{.msupsub}]{.mop}[]{.mspace style="margin-right:0.1667em;"}[[[(]{.delimsizing.size1}]{.mopen.delimcenter style="top:0em;"}[1]{.mord}[]{.mspace style="margin-right:0.2222em;"}[−]{.mbin}[]{.mspace style="margin-right:0.2222em;"}[a]{.mord.mathnormal}[[]{.mopen.nulldelimiter}[[[[[[]{.pstrut style="height:3em;"}[[[m]{.mord.mathnormal.mtight}[−]{.mbin.mtight}[1]{.mord.mtight}]{.mord.mtight}]{.sizing.reset-size6.size3.mtight}]{style="top:-2.655em;"}[[]{.pstrut style="height:3em;"}[]{.frac-line style="border-bottom-width:0.04em;"}]{style="top:-3.23em;"}[[]{.pstrut style="height:3em;"}[[[i]{.mord.mathnormal.mtight}]{.mord.mtight}]{.sizing.reset-size6.size3.mtight}]{style="top:-3.394em;"}]{.vlist style="height:0.8557em;"}[​]{.vlist-s}]{.vlist-r}[[[]]{.vlist style="height:0.4033em;"}]{.vlist-r}]{.vlist-t.vlist-t2}]{.mfrac}[]{.mclose.nulldelimiter}]{.mord}[[)]{.delimsizing.size1}]{.mclose.delimcenter style="top:0em;"}]{.minner}[]{.mspace style="margin-right:0.1667em;"}[[l]{.mord.mathnormal style="margin-right:0.01968em;"}[[[[[[]{.pstrut style="height:2.7em;"}[[i]{.mord.mathnormal.mtight}]{.sizing.reset-size6.size3.mtight}]{style="top:-2.55em;margin-left:-0.0197em;margin-right:0.05em;"}]{.vlist style="height:0.3117em;"}[​]{.vlist-s}]{.vlist-r}[[[]]{.vlist style="height:0.15em;"}]{.vlist-r}]{.vlist-t.vlist-t2}]{.msupsub}]{.mord}]{.mord}]{style="top:-3.7933em;"}]{.vlist style="height:1.7473em;"}[​]{.vlist-s}]{.vlist-r}[[[]]{.vlist style="height:1.2473em;"}]{.vlist-r}]{.vlist-t.vlist-t2}]{.mfrac}[]{.mclose.nulldelimiter}]{.mord}[,]{.mpunct}[]{.mspace style="margin-right:1em;"}[]{.mspace style="margin-right:0.1667em;"}[a]{.mord.mathnormal}[]{.mspace style="margin-right:0.2778em;"}[=]{.mrel}[]{.mspace style="margin-right:0.2778em;"}]{.base}[[]{.strut style="height:0.6444em;"}[0.5]{.mord}]{.base}]{.katex-html ariaHidden="true"}]{.katex}]{.katex-display} Where: - [[]{.katex-mathml}[[[]{.strut style="height:0.4306em;"}[m]{.mord.mathnormal}]{.base}]{.katex-html ariaHidden="true"}]{.katex}: Total number of epochs considered. - [[]{.katex-mathml}[[[]{.strut style="height:0.4306em;"}[a]{.mord.mathnormal}[]{.mspace style="margin-right:0.2778em;"}[=]{.mrel}[]{.mspace style="margin-right:0.2778em;"}]{.base}[[]{.strut style="height:0.6444em;"}[0.5]{.mord}]{.base}]{.katex-html ariaHidden="true"}]{.katex}: Determines the relative weight of the oldest epoch compared to the most recent one. #### Adaptation to support smaller validators To support smaller validators in our PoS network, an adjustment curve is applied to the moving average. This reduces penalties for validators that are less frequently selected for block production, while still incentivizing active participation. This adjustment ensures fairness for smaller validators, encouraging them to stay active while maintaining accountability for all participants. The adjusted availability score [[]{.katex-mathml}[[[]{.strut style="height:0.6833em;"}[L]{.mord.mathnormal}]{.base}]{.katex-html ariaHidden="true"}]{.katex} is calculated as: [[[]{.katex-mathml}[[[]{.strut style="height:0.6833em;"}[L]{.mord.mathnormal}[]{.mspace style="margin-right:0.2778em;"}[=]{.mrel}[]{.mspace style="margin-right:0.2778em;"}]{.base}[[]{.strut style="height:0.9474em;vertical-align:-0.0833em;"}[−]{.mord}[[[[[[[]{.pstrut style="height:3em;"}[L]{.mord.mathnormal}]{style="top:-3em;"}[[]{.pstrut style="height:3em;"}[[ˉ]{.mord}]{.accent-body style="left:-0.2222em;"}]{style="top:-3.2523em;"}]{.vlist style="height:0.8201em;"}]{.vlist-r}]{.vlist-t}]{.mord.accent}[[[[[[]{.pstrut style="height:2.7em;"}[[[2]{.mord.mtight}]{.mord.mtight}]{.sizing.reset-size6.size3.mtight}]{style="top:-3.113em;margin-right:0.05em;"}]{.vlist style="height:0.8641em;"}]{.vlist-r}]{.vlist-t}]{.msupsub}]{.mord}[]{.mspace style="margin-right:0.2222em;"}[+]{.mbin}[]{.mspace style="margin-right:0.2222em;"}]{.base}[[]{.strut style="height:0.8201em;"}[2]{.mord}[[[[[[]{.pstrut style="height:3em;"}[L]{.mord.mathnormal}]{style="top:-3em;"}[[]{.pstrut style="height:3em;"}[[ˉ]{.mord}]{.accent-body style="left:-0.2222em;"}]{style="top:-3.2523em;"}]{.vlist style="height:0.8201em;"}]{.vlist-r}]{.vlist-t}]{.mord.accent}]{.base}]{.katex-html ariaHidden="true"}]{.katex}]{.katex-display} :iframe{.aspect-video.w-full allowFullScreen="true" frameBorder="0" src="https://www.desmos.com/calculator/oipaneynho?embed"} Graph of the availability score adjustment. The x-axis represents the availability score, and the y-axis represents the adjusted availability score. ## Suggestions & Feedback Like everything in Nimiq, this algorithm is designed with the people in mind. We always welcome feedback and suggestions to make it even better. If you’d like to share your thoughts, feel free to [open an issue](https://github.com/nimiq/developer-center/issues?q=is\:issue+is\:open+sort\:updated-desc){rel=""nofollow""} or join our [Telegram group](https://t.me/joinchat/AAAAAEJW-ozFwo7Er9jpHw){rel=""nofollow""}. # Accounts Nimiq has four account types, each with unique features and purposes. Each account has an individual address assigned, enabling users to interact with the blockchain. - Basic account - HTLC (Hashed Timelock Contract) - Vesting Contract - Staking Contract ## Basic Account With a basic account, users can send and receive NIM and have a balance. The account is controlled with a private key unique to the user. This type of account is similar to a bank account with an address, a balance, and a key. When a user sends or receives NIM, the corresponding balance is updated accordingly. A basic account is created when any user sends NIM to a non-existent address. ## HTLC An HTLC is a conditional payment implemented by a script in the blockchain. It is a smart contract that enables a party to transfer assets to another party without relying on a third party. The contract acts as the escrow party for both sender and recipient. | Data Field | Description | | :------------- | :--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | | `balance` | The amount of NIM at any given time. It can differ from the `total_amount` since it's possible to withdraw partial amounts at a time | | `sender` | The sender's address | | `recipient` | The recipient's address | | `hash_root` | The hash of the `pre_image` - secret key | | `hash_count` | The number of times the `pre_image` is hashed so the recipient can withdraw the funds entirely. If the `hash_count` is 2, the recipient can withdraw the funds in 2 portions | | `timeout` | The time, in Unix time with millisecond precision, when the contract elapses. The `timeout` is determined once the contract is created. If the time elapses, the sender can withdraw the funds | | `total_amount` | The initial amount decided in the contract creation | Anyone can create an HTLC whose structural values are static (determined by the contract owner) except for the balance, which changes every time NIM is withdrawn. Also, once the HTLC is created, no NIM can be added to the contract. There are three different transactions to unlock the funds, and each one results in a new balance on the HTLC: 1. **Timeout resolve**: After the timeout elapses, the sender can redeem the funds. 2. **Regular transfer**: The recipient can withdraw the funds entirely or partially before the `timeout` elapses. If the `hash_count` is three, the contract owner can present a hash that was rehashed two times resulting in the `hash_root` and then withdraw two-thirds of the funds. The owner can also present the `pre_image` and withdraw the `total_amount` immediately. 3. **Early resolve**: When both sender and recipient sign the transaction, the funds can be withdrawn at any time. ## Vesting Contract The vesting contract allows a user to lock funds for a period of time and unlock them in a predefined timetable. This contract locks the funds of a single user (the contract owner), and it can unlock the funds in predefined portions. | Data Field | Description | | :------------- | :-------------------------------------------------------------------------------------------------------------------------------------------------- | | `balance` | The amount of NIM at any given time. Whenever the funds are spent, the balance changes | | `owner` | The owner's address. The contract owner has a corresponding key to sign and withdraw the funds | | `start_time` | The time, in Unix time with millisecond precision, when the vesting schedule starts, decided by the contract owner | | `time_step` | The `step_amount` unlocks at each `time_step`. If the owner decides to unlock the funds every 24 hours, the `step_amount` unlocks at every 24 hours | | `step_amount` | The amount of NIM unlocked in every `time_step` | | `total_amount` | The initial amount decided in the contract creation | These values are static, except for the balance, which changes as the funds are withdrawn. The values are decided in the creation of the contract. The contract owner can interact with the contract whenever, but can only withdraw the partial amount of NIM decided when the `time_step` unlocks. The balance is then updated. Note that unlocking the funds is a predefined action, and it happens at every `step_amount`. However, withdrawing the funds is an owner's action. Also, once the vesting contract is created, no NIM can be added to the contract. ## Staking Contract The staking contract is a specific type of contract designed to track and manage functions regarding validators, stakers, and staking activities. For a detailed explanation about the staking contract, follow this [link](https://nimiq.com/developers/protocol/validators/staking-contract). # Block Format In the Nimiq blockchain, blocks are categorized into **microblocks** and **macroblocks**. Each type has a different role in maintaining the blockchain: - **Micro Blocks**: include user-generated transactions and are produced and signed by a validator according to the validator selection process. If a validator fails to produce a micro block on time, a [skip block](https://nimiq.com/developers/protocol/validators/skip-blocks) is produced instead. - **Macro Blocks**: these do not contain user transactions, ensure finality, and are produced using the Tendermint consensus algorithm. There are two types: election and checkpoint. ## Micro Blocks Micro blocks are the blocks for including transactions on the Nimiq blockchain. A validator, randomly selected through a [VRF-based process](https://nimiq.com/developers/protocol/consensus/verifiable-random-functions) which ensures randomness and decentralization, produces a new micro block. If a validator fails to produce a block, the remaining validators can agree on a skip block to maintain the blockchain's continuity. The structure of a micro block is divided into three parts: **header**, **body**, and **justification**. ### Micro Header | **Field** | **Data Type** | **Description** | | -------------- | ------------- | -------------------------------------------------------------------------------------------------------------------------------- | | `network` | `NetworkId` | The network ID associated with the block, such as Mainnet or Testnet | | `version` | `u16` | The block's version number. A change in the version number implies a hard fork. It can currently only be 1. | | `block_number` | `u32` | The number of the block, representing its height in the blockchain | | `timestamp` | `u64` | The block's Unix creation timestamp in milliseconds, indicating when the block was produced | | `parent_hash` | `Blake2bHash` | The hash of the preceding block's header (micro or macro). This ensures a direct link to its predecessor | | `seed` | `VrfSeed` | The output of the VxEdsa VRF function derived from the seed of the previous block, using the validator key of the block producer | | `extra_data` | `Vec` | Data that can be freely chosen by the producing validator, the default client leaves it empty | | `state_root` | `Blake2bHash` | The root of the Merkle tree representing the blockchain state, acting as a commitment to the current state | | `body_root` | `Blake2sHash` | The hash of the block's body, serving as a commitment to its content | | `diff_root` | `Blake2bHash` | The root of the trie diff tree proof, authenticating the state changes between blocks | | `history_root` | `Blake2bHash` | The root of a Merkle Mountain Range covering all transactions in the current epoch up until the current block | ### Micro Body | **Field** | **Data Type** | **Description** | | --------------------- | -------------------------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | | `equivocation_proofs` | `Vec` | A vector containing equivocation proofs for this block. This field may be empty if no such proofs exist or if the block producer chooses not to include any | | `transactions` | `Vec` | A vector containing the transactions for this block. It may be empty if there are no transactions available for inclusion or if the block producer chooses not to include any | ### Micro Justification | **Field** | **Data Type** | **Description** | | ------------------------- | ------------------ | --------------------------------------------------------------------------------------------------------------------------------------------------- | | `Micro(Ed25519Signature)` | `Ed25519Signature` | The block producer's signature. This is used as the justification when the block is produced within the expected time | | `Skip(SkipBlockProof)` | `SkipBlockProof` | Contains the aggregated BLS signatures of validators for a skip block. Used as justification when the block isn't produced within the expected time | Only one of these fields is used at a time as justification, depending on whether the block is produced within the expected timeframe or not. ### Skip Blocks When a micro block is not produced within the expected timeframe, the remaining elected validators step in and create a skip block in the expected micro block’s place. Unlike a regular micro block, a skip block does not include transactions and is agreed and signed by over two-thirds of the validators of the current epoch. This block replaces the micro block, thus ‘skipping’ past it. For detailed information, refer to the [skip blocks](https://nimiq.com/developers/protocol/validators/skip-blocks) documentation. ## Macro Blocks There are two types of macro blocks: **election** and **checkpoint**, each serving a specific role. Election macro blocks update the validator list, defining which validators will participate in the next epoch; these blocks also close epochs. Checkpoint macro blocks finalize transactions and close batches but do not change the validator list. Macro blocks need consensus of 2/3 of the validator [slots](https://nimiq.com/developers/protocol/validators/slots) to be confirmed, ensuring finality and cementing the state of the blockchain at regular intervals. The structure of a macro block is divided into three parts: **header**, **body**, and **justification**. ### Macro Header | **Field** | **Data Type** | **Description** | | --------------------------------- | -------------------------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | | `network` | `NetworkId` | The network ID associated with the block, such as Mainnet or Testnet | | `version` | `u16` | The block's version number. Changing this implies a hard fork | | `block_number` | `u32` | The number of the block, representing its height in the blockchain | | `round` | `u32` | The specific Tendermint round in which this block was proposed | | `timestamp` | `u64` | The Unix creation timestamp (in milliseconds) indicating when the block was produced | | `parent_hash` | `Blake2bHash` | The hash of the preceding block's header (can only be a micro block) | | `parent_election_hash` | `Blake2bHash` | The hash of the header from the previous election macro block | | `interlink` | `Option>` | A vector of hashes linking to previous election blocks with epoch numbers ending in *n* zeros in binary representation. This allows nodes to verify past blocks efficiently without needing to traverse the entire chain | | `seed` | `VrfSeed` | The output of the VxEdsa VRF function derived from the seed of the previous block, using the validator key of the block producer | | `extra_data` | `Vec` | Data that can be freely chosen by the producing validator, the default client leaves it empty | | `state_root` | `Blake2bHash` | The Merkle root representing the blockchain state, acting as a commitment to the current state | | `body_root` | `Blake2sHash` | The hash of the block body, serving as a commitment to its content | | `diff_root` | `Blake2bHash` | The root of the trie diff tree proof, which authenticates the state transitions or changes between blocks | | `history_root` | `Blake2bHash` | The root of a Merkle Mountain Range covering all transactions that occurred in the current epoch up until this block | | `validators` | `Option` | Information about the upcoming validator list. Present only in election macro blocks. The `Validators` struct contains a list of validators ordered by their slots and a mapping of validator addresses to their slot range. | | `next_batch_initial_punished_set` | `BitSet` | A bitset representing validator slots that are banned from producing blocks in the next batch due to misbehavior | ### Macro Body | **Field** | **Data Type** | **Description** | | -------------- | ------------------------ | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | | `transactions` | `Vec` | Contains the reward transactions of this block, distributing block rewards and transaction fees of the current batch to validators. Macro blocks do not include user-generated transactions. | ### Macro Justification | **Field** | **Data Type** | **Description** | | --------- | ---------------- | ----------------------------------------------------------------------------------------------------------------------------------------- | | `round` | `u32` | The specific tendermint round in which the block was accepted. This is used to verify that the signature corresponds to the correct round | | `sig` | `MultiSignature` | The aggregated BLS signature of the validators’ precommit votes for the block, confirming validator consensus | ## Relation Between Micro and Macro Blocks Micro and macro blocks are interconnected. This connection ensures blockchain continuity and finality. The following section focuses on how these block types interact. **Block Connections** All blocks are sequentially linked by the parent hash, forming a continuous chain, and every checkpoint macro block points to its election macro block by the parent election hash. The following diagram illustrates the connection between micro and macro blocks. Each block is directly connected to its predecessor through the parent hash. ![macro and micro block connection](https://nimiq.com/developers/assets/images/protocol/macro-micro.png){.object-contain.max-h-[max(80vh,220px)]} *Note: This diagram is a simplified representation. The actual blockchain includes a fixed number of blocks per batch and epoch, which this diagram does not reflect.* - **Parent Hash**: Links each block to its direct predecessor. - **Election Parent Hash**: Connects checkpoint macro blocks to their preceding election macro block. ## Blockchain Format The Nimiq blockchain is structured into several subsets of blocks called epochs and batches. - **Batches**: A batch consists of 59 **micro blocks** produced one after another. Each batch ends with a **checkpoint** macro block, which finalizes the transactions included in the preceding micro blocks. Since the micro blocks are supposed to be spaced 1 second apart, a batch is expected to take 1 minute. - **Epochs**: An epoch is a set of 1440 batches. Each epoch ends with an **election** macro block, which not only finalizes the transactions in the preceding batch but also updates the validator list of the entire epoch. Since a batch is expected to take about 1 minute, 1440 batches are expected to take 12 hours. ![blockchain structure](https://nimiq.com/developers/assets/images/protocol/block-struct-3.png){.object-contain.max-h-[max(300px)]} ## Block Finality Block finality in the Nimiq PoS blockchain ensures that all transactions within the finalized blocks are permanent and cannot be reversed. This is achieved through a balance of micro block production and periodic macro block consensus. While micro blocks add transactions to the chain, these transactions only reach finality when confirmed by a macro block. Macro blocks, produced at regular intervals using Tendermint consensus, finalize the state of all preceding micro blocks in a batch. # Equivocation Proofs An equivocation refers to malicious behavior by a validator that contradicts the consensus, such as producing two blocks at the same block height or signing two different proposals within the same Tendermint aggregation. An equivocation proof proves that a validator misbehaved. The offending validator is automatically jailed as soon as the equivocation proof is added to the blockchain. Validators enter an 8-epoch jail, lose their rewards, and the ability to produce blocks during the jail period. Honest validators refrain from any misbehavior, as it is not in their interest to lose rewards or be restrained from block production. Validators can submit proofs attesting to malicious behavior. While submitting these proofs is considered good practice, it is optional for validators. They can submit any proof from the moment they witness an offense up to the last micro block at the end of the next epoch. The reporting window, spanning almost two epochs, provides sufficient time for validators to identify, address, and submit proofs of malicious behavior to be included in the blockchain. Validators can misbehave in three ways: - Fork the chain - Proposing different macro blocks in the same round - Voting twice in the same round and step ### Fork Proofs A fork occurs when a malicious validator generates two micro blocks at the same block height, aiming to create a chain split or attempt double spending. The fork concludes once an honest validator is chosen as the subsequent block producer. Block production then resumes according to the consensus (one micro block per block height), and any validator can submit a fork proof attesting to the malicious behavior of the previous validator. Forks may also end if the next block is a macro block. Although a malicious validator may attempt to propose 2 blocks at the same block height (refer to the double proposal proof below), the consensus requirement dictates that more than 2/3 of validators must agree on a block proposal before it is added to the blockchain; thus, there is no way to continue a fork. ```rust pub struct ForkProof { validator_address: Address, header1: MicroHeader, header2: MicroHeader, justification1: SchnorrSignature, justification2: SchnorrSignature, } ``` The offending validator address, two micro headers from the same block height and the respective signatures are enough to prove the malicious behavior. ### Double Proposal Proofs Macro blocks are produced using the Tendermint algorithm. A validator, selected as the round leader, proposes a macro block and gossips its proposal. Malicious validators may attempt to propose two different macro headers at the same block height, round and step. Honest validators vote for one proposal per round; therefore, receiving more than one proposal from the same validator for the same block indicates misbehavior from a malicious validator. Double proposal proofs serve to identify and punish a validator if it attempts to sign conflicting blocks, demonstrating malicious behavior. ```rust pub struct DoubleProposalProof { validator_address: Address, header1: MacroHeader, header2: MacroHeader, justification1: SchnorrSignature, justification2: SchnorrSignature, } ``` The offending validator address, two macro headers from the same round and the respective signatures are enough to prove the malicious behavior. ### Double Vote Proofs Validators are expected to vote block or *nil* for a single Tendermint proposal per round and step. Voting for different proposals at the same block height, round, and step is considered a double vote, disrupting Tendermint's voting principle. The double vote proof is used to identify and punish validators for their misbehavior. ```rust pub struct DoubleVoteProof { validator_address: Address, tendermint_id: TendermintIdentifier, proposal_hash1: Option, proposal_hash2: Option, signature1: AggregateSignature, signature2: AggregateSignature, signers1: BitSet, signers2: BitSet, } ``` The proof serves to identify the malicious validator, pointing the block height, round, and step at which the double voting occurred, along with the two proposal hashes. Validators combine their signatures into a single aggregate signature. However, aggregate signatures cannot be verified without knowing who voted. To verify the signature, the bitset of signers is included. This bitset identifies the validators who participated in signing the specific proposals, thus also pinpointing and confirming instances of double voting by a malicious validator. # Punishments Validators are responsible for ensuring the security and stability of a blockchain network. They are rewarded for participating and punished if they fail to contribute according to the consensus. Misbehaving always results in either losing the rewards or going to jail, where the validator gets locked up for a period and loses the rewards. The types of punishment are divided based on the severity of the misbehavior. The blockchain deals with misbehavior based on the nature of the offense: - A delay in block production constitutes a minor offense. In such cases, the associated slot is deactivated, and the rewards are burned. - For more severe offenses like forking, double voting, or double proposals, the validator is jailed. All validator slots are deactivated for a set period, and rewards for these slots are burned. ::callout{color="info" icon="i-tabler-info-circle"} Burned rewards are sent to the burned address: `NQ07 0000 0000 0000 0000 0000 0000 0000 0000` . Note that no one can or will use the funds sent to this address. :: ## Block production delay A delay in block production is categorized as a minor offense. Such delays can occur due to intentional or unintentional circumstances, such as unexpected internet connectivity issues. Determining the intent behind the delay can be challenging. Validators hold multiple slots and produce micro blocks with one slot at a time. As a consequence of delaying the block production, rewards for the corresponding slot are burned. The slot is added to the `punished_slots` set, which remains for the current batch and the next one, to account for reward distribution at the next batch. This set ensures accurate reward distribution during the upcoming batch. The misbehaving slot gets deactivated but can reactivate itself one block after committing the offense. While delaying block production is not considered a severe misbehavior due to replacing the missing block with a skip block, the rewards for the misbehaving slot are burned regardless as a penalty. ## Jail When a validator acts maliciously on purpose, it gets jailed. Getting jailed can happen for a variety of malicious behaviors, including: - Creating a fork or continuing to produce on a fork - Making a double proposal on Tendermint - Casting more than one vote per slot on Tendermint proposals Any rational validator that witnesses one of these behaviors can report it by including a proof in a micro block. Once the proof that attests to the misbehavior is submitted, the validator is immediately jailed. As these are more severe offenses that interfere with the blockchain, the consequences are also more severe. When a validator is jailed: - It is immediately removed from the `active_validators` set, and all its slots are marked as punished in the `punished_slots` set in the staking contract. - It gets locked for 8 epochs. However, it is required to continue block production until the end of the current batch and vote for Tendermint blocks until the end of the epoch; from thereafter, it is not considered for block production until the locking period ends. The withdrawal lock takes effect immediately upon getting jailed. - It loses its rewards for the jail period. The `active_validators` and `punished_slots` sets are updated at every block in the [staking contract](https://nimiq.com/developers/protocol/validators/staking-contract). However, if a validator shifts from active to inactive or jailed, it is required to produce blocks until the current batch concludes, as it remains included in the validator slot list for that batch. However, it is no longer considered to produce blocks for further batches starting at the next checkpoint block. In the context of Tendermint votes, a validator that shifts to inactive or jailed mid-epoch must vote until the end of the epoch. This is because there are no mid-epoch elections to replace the slots of the inactive or jailed validator. Thus, it must participate in the entire epoch's voting process to maintain the necessary validator count for consensus. Once the validator is out of jail, it moves to the inactive state. Validators with the `automatic_reactivate` feature set to `true` within their configuration will reactivate upon release. Furthermore, even if the validator activates itself right after being released, it will only be considered again to participate in the consensus at the next epoch upon election. If a validator wants to withdraw its deposit after being released, it can do so immediately if it does not reactivate. If the validator becomes active again, it must be inactive for a predetermined time to account for possible new misbehaviors. ### Reporting window There is a reporting window for when validators can submit such proofs. From the block after the offense up to the end of the epoch after the next election block. The reporting window corresponds to the period a validator must be in the inactive state to be able to delete its account and withdraw its funds. ### Impact on stakers Punishments also affect the validator's stakers, as the locking period for the staker's stake aligns with the validator's locking period. Stakers can either maintain their stake with their validator or remove it once the jail period ends if their stake remains inactive. # Verifiable Random Functions A verifiable random function is a pseudo-random function that generates a random value and allows anyone to verify if it was correctly calculated. It combines a proving function, a verifying function, and an extracting function. A key pair is used to operate these functions. - **Prove function**: Given a message and a user's private key as input to the function, a proof is generated. - **Verify function**: By running this function, anyone can verify the proof's correctness. The corresponding public key, the proof, and the previous message are taken as input to verify if the proof was correctly computed. - **Extract function**: The function takes as input the proof and outputs a random value. This random value is the entropy that was extracted from the proof. Thus, the entropy randomly takes a piece of the proof and generates a random value. VRFs have three security properties: - **Pseudorandomness**: Despite the output appearing to be random, it is generated with deterministic computation. The same input always results in the same output. - **Uniqueness**: Only one output is possible for each input and private key. - **Public verifiability**: Anyone that holds the corresponding public key can verify the correctness of the output. ## VRF implementation Elected validators produce random seeds implementing VRFs with the [VXEdDSA](https://www.signal.org/docs/specifications/xeddsa/#vxeddsa){rel=""nofollow""} algorithm. Both micro block producers and macro block proposers generate random seeds. These are stored in the header of every block. The elected validator selected to produce a random seed takes as input the entropy from the previous random seed as the message of the proof function along with its own private key. This outputs a proof that is the new random seed. Then, any node can run the verify function with the corresponding public key to check the proof's correctness. Lastly, any node can run the extract function on the random seed to extract its entropy, which is used to generate a random value. A random value is generated by extracting the entropy from the proof. The random seed cannot be used directly since it is a controllable value that the elected validator could change. Extracting the entropy from the proof is essential as it ensures security and prevents any node from controlling this value. The prove and extract functions allow a chain of seeds since generating a new random seed occurs using data from the previous random seed. Every random seed is intrinsically related to the previous one. Random seeds are used in three cases: - **Validator slot selection:** A new [validator slot list](https://nimiq.com/developers/protocol/validators/slots) is selected at the end of each epoch. The entropy extracted from the random seed is used to select this new list. The block's proposer takes the active validator set along with the entropy and creates the list. - **Slot owner selection:** A new slot owner list is created at every block. The block's producer extracts the entropy from the random seed to shuffle the validator slot list resulting in the view slot list for the block. - **Rewards distribution:** Elected validators are rewarded at the end of every batch. The rewards are distributed among the elected validators. In every batch, the validator slot list has 512 validator slots. Due to the potential inability to evenly divide the batch reward among 512 slots, entropy from the random seed is utilized to determine which elected validator receives the remainder. # Rewards Validators stake a minimum deposit to participate in block production. Following consensus rules yields rewards; failing to do so results in [punishments](https://nimiq.com/developers/protocol/consensus/punishments) and loss of rewards. Validators receive rewards under these conditions: - Producing a micro block on time - Avoiding creating or building on forks - Voting once per slot for each Tendermint proposal - Broadcasting Tendermint proposals on time Validators receive rewards proportional to their total stake. Validators with a higher total stake earn higher rewards. Users who cannot become validators can delegate their NIM to a validator, increasing the validator's total stake and potential rewards. While validators receive their rewards on-chain, they distribute rewards to stakers off-chain. Validators handle the distribution of these rewards according to their arrangements with their stakers. ### Reward distribution Validators receive rewards to their reward address every batch. However, the distribution of rewards for a batch occurs at the end of the following batch. This delay is necessary to prevent malicious validators from attempting an offense in the last block of a batch. With this delay, there is sufficient time to submit an equivocation proof on the malicious validator. For minor offenses, such as delaying block production, validators lose the rewards for the affected slot. For severe misbehavior, like equivocations, the rewards for all slots are burned. This also affects stakers, as the validator does not receive rewards for at least 8 epochs if jailed, regardless of any arrangements made with their stakers. The reward distribution is proportional to the total stake and is evenly distributed per slot. This means a validator with 15 slots receives fewer rewards than one with 50 slots. Also, if a validator with 15 slots delays block production, it will only receive rewards for 14 of its 15 slots, but if it attempts to broadcast a double proposal, it does not receive any rewards for at least 8 epochs. ### Reward calculation The rewards comprise the coinbase and transaction fees. The coinbase represents the coins printed at the end of each batch, while transaction fees encompass the total fees from transactions within the batch. In Albatross, both the coinbase and transaction fees fluctuate. In contrast to Bitcoin's fixed coinbase, which decreases by around 50% every four years, our coinbase varies over time as new coins are printed per batch rather than per block. To calculate the coinbase, we have a formula that predicts the supply at any given time, given three parameters: - **Initial supply**: the supply that Nimiq will start with, denoted by *S₀* - **Initial velocity**: a constant parameter that determines the number of NIM created initially per unit of time represented by *V₀* - **Decay**: a constant that dictates the percentage by which the velocity decreases, denoted by *β* The supply formula is the following: [[]{.katex-mathml}[[[]{.strut style="height:1em;vertical-align:-0.25em;"}[S]{.mord.mathnormal style="margin-right:0.05764em;"}[(]{.mopen}[t]{.mord.mathnormal}[)]{.mclose}[]{.mspace style="margin-right:0.2778em;"}[=]{.mrel}[]{.mspace style="margin-right:0.2778em;"}]{.base}[[]{.strut style="height:0.8333em;vertical-align:-0.15em;"}[[S]{.mord.mathnormal style="margin-right:0.05764em;"}[[[[[[]{.pstrut style="height:2.7em;"}[[0]{.mord.mtight}]{.sizing.reset-size6.size3.mtight}]{style="top:-2.55em;margin-left:-0.0576em;margin-right:0.05em;"}]{.vlist style="height:0.3011em;"}[​]{.vlist-s}]{.vlist-r}[[[]]{.vlist style="height:0.15em;"}]{.vlist-r}]{.vlist-t.vlist-t2}]{.msupsub}]{.mord}[]{.mspace style="margin-right:0.2222em;"}[+]{.mbin}[]{.mspace style="margin-right:0.2222em;"}]{.base}[[]{.strut style="height:1.3695em;vertical-align:-0.4811em;"}[[]{.mopen.nulldelimiter}[[[[[[]{.pstrut style="height:3em;"}[[[β]{.mord.mathnormal.mtight style="margin-right:0.05278em;"}]{.mord.mtight}]{.sizing.reset-size6.size3.mtight}]{style="top:-2.655em;"}[[]{.pstrut style="height:3em;"}[]{.frac-line style="border-bottom-width:0.04em;"}]{style="top:-3.23em;"}[[]{.pstrut style="height:3em;"}[[[[V]{.mord.mathnormal.mtight style="margin-right:0.22222em;"}[[[[[[]{.pstrut style="height:2.5em;"}[[0]{.mord.mtight}]{.sizing.reset-size3.size1.mtight}]{style="top:-2.357em;margin-left:-0.2222em;margin-right:0.0714em;"}]{.vlist style="height:0.3173em;"}[​]{.vlist-s}]{.vlist-r}[[[]]{.vlist style="height:0.143em;"}]{.vlist-r}]{.vlist-t.vlist-t2}]{.msupsub}]{.mord.mtight}]{.mord.mtight}]{.sizing.reset-size6.size3.mtight}]{style="top:-3.4101em;"}]{.vlist style="height:0.8884em;"}[​]{.vlist-s}]{.vlist-r}[[[]]{.vlist style="height:0.4811em;"}]{.vlist-r}]{.vlist-t.vlist-t2}]{.mfrac}[]{.mclose.nulldelimiter}]{.mord}[(]{.mopen}[1]{.mord}[]{.mspace style="margin-right:0.2222em;"}[−]{.mbin}[]{.mspace style="margin-right:0.2222em;"}]{.base}[[]{.strut style="height:1.0991em;vertical-align:-0.25em;"}[[2]{.mord}[[[[[[]{.pstrut style="height:2.7em;"}[[[−]{.mord.mtight}[β]{.mord.mathnormal.mtight style="margin-right:0.05278em;"}[t]{.mord.mathnormal.mtight}]{.mord.mtight}]{.sizing.reset-size6.size3.mtight}]{style="top:-3.063em;margin-right:0.05em;"}]{.vlist style="height:0.8491em;"}]{.vlist-r}]{.vlist-t}]{.msupsub}]{.mord}[)]{.mclose}]{.base}]{.katex-html ariaHidden="true"}]{.katex} Additionally, t is the time elapsed since the genesis block. The formula is hard-coded and returns the supply of the coinbase at any given time in seconds, and it is distributed in Lunas (1 NIM = 100'000 Lunas). Essentially, the coinbase is calculated by subtracting the supply calculated in the blockchain at any given time from the previous supply, which is the total amount of NIM at the end of the last batch. # Glossary Nimiq PoS ## Account An account consists of a unique address and the respective balance. Our blockchain offers 4 types of accounts: basic accounts, vesting accounts, HTLC accounts, and staking accounts. Each account has a corresponding key. ## Address The identifier of an account. ## Aggregated Signature The outcome of calculating multiple signatures into a single signature. Aggregating signatures reduces the amount of data that several single signatures hold. Signature aggregation is used for signing [skip blocks](https://nimiq.com/developers/#skip-block) and aggregating votes for [Tendermint](https://nimiq.com/developers/#tendermint) voting. ## Albatross Nimiq Proof-of-Stake algorithm. It is an algorithm inspired by the BFT protocol, assuming that 3*f*+1 validators, at maximum *f*, are malicious. Nimiq PoS protocol achieves probabilistic finality by combining [micro blocks](https://nimiq.com/developers/#micro-block) and [macro blocks](https://nimiq.com/developers/#macro-block). Micro blocks are produced and signed by a single validator, while macro blocks mark the end of an epoch and are produced using Tendermint, which ensures finality as they are agreed upon by at least 2f+1 validators. ## BLS Signature The BLS signature scheme uses bilinear pairing and elliptic curve cryptography and has many valuable features. In Nimiq PoS, BLS is used for signature aggregation, allowing *n* signatures to be combined into a single signature, significantly decreasing the required data. Validators generate a public and private key, and each validator uses their private key to produce a signature. BLS signatures allow for efficient signature aggregation, resulting in substantial space savings. ## Batch The interval between two macro blocks, [election](https://nimiq.com/developers/#election-block) or [checkpoint](https://nimiq.com/developers/#checkpoint-block) macro blocks. A batch consists of several micro blocks, closing on a macro block. ## Block A block contains a set of transactions and data attesting to the transactions' validity. Our blockchain holds 2 types of blocks: micro blocks and macro blocks. Validators are responsible for gathering and adding data to a block based on consensus rules. The block's validity is determined by the data contained within it, and it is added to the blockchain once the network verifies it. ## Block Number Block number and block height can be used interchangeably. The block number refers to the block's position relative to the blockchain, starting at block 0 - the [genesis block](https://nimiq.com/developers/#genesis-block). The block number of 9 is the ninth block after the genesis block. ## Body Part of the structure of a block. The body contains the block's transactions and fork proofs in a micro block, but it can be empty if no transactions or [equivocation proofs](https://nimiq.com/developers/#equivocation-proof) have occurred. In a macro block, the body stores rewards related data. ## Checkpoint Block A type of macro block that marks the end of a batch. Checkpoint blocks maintain the same list of validators that was selected in the previous election macro block and serve as a finality point for the blockchain state between epochs. ## Coinbase Given our supply formula, the coinbase is the number of new coins printed at the end of a batch. ## Commitment A commitment is a cryptographic primitive that enables a node to commit to a value without revealing it, resulting in less data to the endpoint. The value on which the node committed remains private, but its accuracy can be proven without revealing the value itself. The value is part of the proof, and nodes can verify that the value matches the commitment. In our consensus algorithm, the blockchain uses commitments in two areas: commitments to specific parts of the blockchain, such as transactions in a block and accounts in the current state, and commitments to secret values in our multi-sig scheme. Ultimately, using commitments enables data compaction by using hashes and Merkle trees. For instance, it allows light clients to sync without downloading the entire blockchain while preserving the integrity of the blockchain. ## Compressed Signature A compressed signature is a compacted version of a typical digital signature generated from a full signature. The compressed signature provides the same level of security as a full signature while decreasing the storage space of one. ## Consensus Algorithm A type of algorithm used to reach an agreement between nodes in a shared state. Nimiq PoS uses the Albatross consensus algorithm, which combines micro blocks for fast transaction processing with macro blocks for finality. Validators work together to follow the consensus rules, ensuring network security and maintaining a consistent blockchain state. ## Deposit The initial amount of NIM that a validator must lock in the staking contract to become eligible for validator selection, which is 100'000 NIM. This is different from the stake amount and serves as a security deposit. ## Double Proposal The act of submitting two different Tendermint proposals in the same round. ## Double Vote The act of voting twice for the same block height, at the same round and step of Tendermint. ## Election Block A type of macro block that marks the end of an epoch. Election blocks are where a new validator list is selected from the potential validator set and integrated into the staking contract for the upcoming epoch. ## Entropy The measure of unpredictability of a random value. Using the entropy of the random seed present in a block, the process involves hashing and generating a new random seed. The more random the value, the higher the entropy. Thus, by using the entropy of a random seed, a random, unpredictable, and secure value can be produced. ## Epoch The time between two election macro blocks marks an epoch. An epoch starts with a micro block after an election macro block and ends at an election macro block, including all the micro blocks and checkpoint macro blocks in between. ## Equivocation An equivocation is when a validator acts maliciously against the consensus protocol. This can involve creating two blocks at the same height, proposing two Tendermint blocks for the same block height, or even voting twice for a proposal during the same round and step. ## Equivocation Proof An equivocation proof provides evidence of a validator's misbehavior, leading to [jail](https://nimiq.com/developers/#jail) upon proof submission by any honest validator. ## Fork A split in the blockchain produced by a malicious validator. A malicious validator can fork the chain by producing two blocks at the same block height, attempting for a double-spend attack. ## Fork Proof Evidence that a validator has attempted to create a fork by producing multiple blocks at the same height. This proof is used to punish malicious validators. ## Genesis Block The designation of the first block in the blockchain - also known as block 0. Developers code it, and validators produce the following blocks. The genesis block determines the initial state of the blockchain, and it's hardcoded by developers. Validators produce the subsequent blocks following it according to the rules hardcoded in the genesis block. ## Header Part of the structure of a block. The block's header contains general data about the block, such as the block number, the timestamp, and the version. Headers include required data to the consensus and commitments to the block. It also connects the current block to the previous one. ## Inherent An inherent is a type of data that is intrinsic to the block and automatically generated by the protocol rather than submitted by users. Unlike transactions, inherents are applied at specific times and serve different purposes, depending on their type. Examples include finalizing an epoch, validator set changes, and other protocol-specific data that helps maintain the blockchain's state and consensus rules. ## Jail Going to jail refers to the validator's state characterized by incurring severe misbehavior for actions such as forking or continuing on a fork. When a validator is in a jailed state, it is locked for 8 epochs and cannot be re-elected during this lockup. Additionally, all the validator's rewards are burned. ## Justification Part of the structure of a block. In micro blocks, the justification contains the information and signature of the validator who produced the block. Whereas in macro blocks, the justification consists of a round of signatures produced through the Tendermint protocol. ## Leader The proposer selected to make a Tendermint proposal. ## Luna The smallest unit of NIM. ## Macro Block There are two types of macro blocks: checkpoint macro blocks and election macro blocks. A checkpoint macro block marks the end of a batch, while an election macro block marks the end of an epoch, where validators are chosen from the validator set. Macro blocks are produced using Tendermint and provide finality as they are build upon the agreement of at least 2f+1 validators. ## Malicious Validator A validator that intentionally misbehaves, attempting to interfere with the standard consensus of the blockchain. ## Mempool A database where transactions are kept on hold until a validator includes them in a block. Once a validator includes it in a block, a transaction is considered verified and valid. ## Merkle Tree A tree data structure where each leaf node is a hash of a data block and each non-leaf node is a hash of its children. Merkle trees are used in Nimiq to efficiently verify data integrity and provide compact proofs that specific data is included in a larger dataset. Nimiq uses [Merkle Mountain Ranges](https://nimiq.com/developers/protocol/storage/merkle-trees#merkle-mountain-range) (MMRs) for transaction history and [Merkle Radix](https://nimiq.com/developers/protocol/storage/merkle-trees) tries for account state management. ## Micro Block A type of block produced by one validator at a time. Micro blocks include transactions but may also include equivocation proofs and skip block proofs. ## NIM Nimiq's native cryptocurrency. ## Pinned Election Block A recent election macro block, identified by its block number and hash, that is hardcoded into the client release. It speeds up the [light macro sync](https://nimiq.com/developers/protocol/node-sync/macro-sync/light-macro-sync) fallback: a Pico node that falls back uses it as a trusted anchor, seeding its chain to the pinned election block and verifying forward instead of re-syncing the election chain from genesis. Other node types (light, full, history) do not sync from it. They only cross-check it against their own chain and log a mismatch. When no pinned election block is set for a network, clients behave as if the feature were absent. Distinct from a [checkpoint block](https://nimiq.com/developers/#checkpoint-block) (a macro block ending a batch) and from the transient checkpoint message used during macro sync. ## Potential Validator A validator who has staked coins to participate in the consensus but has not yet been included in the block production. ## Proof-of-Stake A blockchain model where nodes put their tokens as a deposit and get allowed to validate transactions in the blockchain. Nodes are elected proportionally by their stake. A higher deposit increases the probability of a node being selected as a validator. ## Random Seed A seed is present in every block. Random seeds are used in the validator selection to create a random and secure value. The initial random seed is generated at the genesis block, and the subsequent random seeds are generated by implementing the VXEDdSA algorithm instantiated as a verifiable random function. ## Signature A digital signature that authenticates a message by comprising three functions: generate, sign and verify. A node's private key and a particular message generate a signature. The signature is then verified, given the signature and the node's public key. ## Slot A validator receives *x* slots when selected to participate in the consensus, distributed in a range. Validators use their slots to produce, propose and sign blocks. The number of slots a validator gets depends on the amount of stake they have deposited in the staking contract. ## Slot Owner The slot selected to produce the current micro block. ## Slot Range The continuous range of slot numbers assigned to a validator. Validators receive slots in sequential ranges, and the size of the range corresponds to their stake amount. ## Skip Block A type of micro block that doesn't include the standard micro block data (doesn't contain transactions) and that is produced in place of a micro block when the slot owner delays the production of the block. Any validator from the validator list can add this block to the chain, which must include a skip block proof. ## Skip Block Proof Evidence that a skip block is legitimate and was produced due to a validator's failure to produce a block on time. This proof is required to validate skip blocks and must contain signatures from at least 2*f*+1 validators to be considered valid. ## Staker A node that doesn't have the time or resources to be a validator, or chooses not to, can delegate its coins to a validator. Validators then validate blocks on behalf of the staker by using the staker's coins as joined collateral. ## Staking To lock a deposit in the staking contract. Either a validator stakes its deposit to the staking contract, or a staker does. ## Staking Contract A special contract that deals with functions regarding validators, stakers, and staking. The staking contract gathers all the contract data in a single location, keeping track of the validators' balance, validators' list, punishments, and rewards. ## Supermajority Supermajority means that at least 2/3 of the total validator voting power must agree on a decision for it to be considered final and valid. ## Supply Based on the supply formula, the supply is the number of coins in the blockchain at any given moment. The blockchain has a maximum supply of 21 Billion NIM. ## Tendermint Tendermint is a Byzantine Fault Tolerant (BFT) consensus algorithm used to produce macro blocks. It operates in rounds where validators are selected as proposers based on VRF-based slot assignment. Each round consists of three phases: Propose, Prevote, and Precommit. Validators must reach 2*f*+1 consensus ([supermajority](https://nimiq.com/developers/#supermajority)) at each phase. If consensus isn't reached, the round times out and a new round begins with a new proposer. The algorithm includes a locking mechanism to ensure safety and liveness even with network partitions. ## Transaction A data structure that represents an activity or request recorded in the blockchain that alters its state. Most transactions transfer NIM from a sender to a recipient, which can be another account, a validator, or a smart contract. Transactions are user-generated included in micro blocks. ## Transaction Fees A small fee charged in transactions. The transaction fees of a batch are calculated at the end of the batch and divided among the validators as part of the rewards. ## Validator An active validator is a node that has been selected to participate in the consensus for each epoch based on the stake deposited in the staking contract. The higher the stake, the greater the likelihood of being selected as a validator for the upcoming epoch. Once selected, validators can produce micro blocks, participate in macro block consensus, and receive rewards for their efforts. ## Validator List List of the active validators for the current epoch. ## Validator Set List of all the active and potential validators. # Nimiq Proof-of-Stake Welcome to the Nimiq Proof-of-Stake documentation! This section introduces our consensus protocol, Albatross, and provides a comprehensive overview of our protocol's unique features. ::u-page-grid :::u-page-card --- description: Everything about micro and macro blocks icon: i-nimiq:cubes title: Blockchain Structure to: https://nimiq.com/developers/protocol/consensus/block-format variant: outline --- ::: :::u-page-card --- description: The repository of data for validators, stakers, and staking icon: i-tabler:settings title: Staking Contract to: https://nimiq.com/developers/protocol/validators/staking-contract variant: outline --- ::: :::u-page-card --- description: Explore the pillars of Albatross PoS icon: i-nimiq:verified title: Validators to: https://nimiq.com/developers/protocol/validators/validators variant: outline --- ::: :::u-page-card --- description: Learn how slots are assigned to validators icon: i-tabler:settings title: Slots to: https://nimiq.com/developers/protocol/validators/slots variant: outline --- ::: :::u-page-card --- description: Learn about delegation and staking participation icon: i-lucide-users title: Stakers to: https://nimiq.com/developers/protocol/validators/stakers variant: outline --- ::: :: ## What is Albatross? Albatross is Nimiq's innovative Proof-of-Stake consensus algorithm designed for speed, security, and efficiency. Unlike traditional PoS systems, Albatross combines the best of Byzantine Fault Tolerance (BFT) protocols with probabilistic finality, achieving thousands of transactions per second while maintaining robust security guarantees. ::u-page-grid :::u-page-card --- description: Achieve 1000+ TPS with lightning-fast 1-second block separation for optimal performance icon: i-nimiq:bolt title: High Throughput variant: outline --- ::: :::u-page-card --- description: Reduced power consumption compared to traditional Proof-of-Work blockchain systems icon: i-nimiq:eco title: Energy Efficient variant: outline --- ::: :::u-page-card --- description: Robust Byzantine fault tolerance with proven 3f+1 assumption for maximum security icon: i-nimiq:verified title: Secure variant: outline --- ::: :::u-page-card --- description: Dynamic validator set with periodic rotation maintains active validator participation icon: i-nimiq:cycle title: Scalable variant: outline --- ::: :: ## Validators and Stakers [Validators](https://nimiq.com/developers/protocol/validators/validators) play a crucial role in the Proof-of-Stake consensus mechanism as block producers. In our algorithm, we assume that out of 3*f*+1 validators, at most *f* are malicious. This assumption ensures valid and accurate performance of the blockchain, even if up to *f* validators fail to respond or act maliciously. Validators signal their participation by allocating stake, which increases their chances of being elected. The stake amount influences the number of slots assigned to a validator. [Slots](https://nimiq.com/developers/protocol/validators/slots) determine block producers, with random selection ensuring fairness. Any node in Nimiq's network can propose to become a validator by staking coins as a deposit. The higher the stake a node has, the higher the chances of being selected to produce blocks and joining the validator list. Validators are selected according to the validator selection rules. We have 512 slots per batch ready to produce blocks. Participants lacking the resources or expertise to become validators can delegate funds as [stakers](https://nimiq.com/developers/protocol/validators/stakers). Validators produce and validate blocks on behalf of stakers, who receive rewards even when offline. Validator rewards for stakers are processed off-chain. Stakers face the same punishment as their validator in case of misbehavior. ## Blockchain Structure ### Epochs and Batches The Nimiq PoS blockchain is organized into [epochs and batches](https://nimiq.com/developers/protocol/consensus/block-format#blockchain-format). An epoch, comprising multiple batches, ends with a closing election macro block. While validators remain constant within an epoch, the election macro block selects new validators for the next epoch. ### Micro Blocks Produced by selected validators, [micro blocks](https://nimiq.com/developers/protocol/consensus/block-format#micro-blocks) contain user transactions. A [skip block](https://nimiq.com/developers/protocol/validators/skip-blocks) may replace a delayed micro block, signed by over two-thirds of validators in the current epoch. ### Macro Blocks After a set number of micro blocks, a [macro block](https://nimiq.com/developers/protocol/consensus/block-format#macro-blocks) finalizes the batch. Randomly proposed by a leader, macro blocks undergo a two-step voting process. Election blocks provide periodic finality, renewing the validator set, while checkpoint blocks retain the validator set. ## Consensus Mechanism ### Tendermint Integration Albatross uses Tendermint for macro block consensus, ensuring Byzantine fault tolerance. The process involves: 1. **Proposal Phase**: A leader validator proposes a macro block 2. **Pre-vote Phase**: Validators vote on the proposal 3. **Pre-commit Phase**: Validators commit to the final decision 4. **Finality**: 2f+1 validators must agree for consensus out of a maximum of 512 available slots ### Skip Block Protocol When a validator fails to produce a micro block on time, any validator can produce a skip block. This ensures network continuity and prevents malicious validators from halting the network. ## Dealing with Malicious Behavior Validators earn rewards for contributions and face [punishments](https://nimiq.com/developers/protocol/consensus/punishments) for consensus violations, with severity varying by offense type. Minor offenses lead to deactivation of the responsible slot and burned rewards. Severe offenses result in a [jail](https://nimiq.com/developers/protocol/consensus/punishments#jail) state, where the validator, including all slots, is locked for an extended period, with burned rewards and an inability to be re-elected. The jailing period also affects stakers, as their stake is locked for the duration of the jailing period. ### Punishment Types | Offense Type | Consequence | Duration | Validator Status | | ---------------- | ---------------------------------- | --------- | ---------------- | | **Block Delay** | Slot deactivation + reward burning | Temporary | Slot suspended | | **Equivocation** | Jail state + all rewards burned | 8 epochs | Fully locked | ## Network Security ::u-page-grid :::u-page-card --- description: Network continues operating even with f faulty validators icon: i-nimiq:nodes title: Liveness variant: outline --- ::: :::u-page-card --- description: Consensus cannot be reached on conflicting blocks icon: i-nimiq:verified title: Safety variant: outline --- ::: :::u-page-card --- description: Once consensus is reached, it cannot be reversed icon: i-tabler:lock title: Finality variant: outline --- ::: :: ## Getting Started Ready to dive deeper into the Nimiq protocol? Explore these key areas: - **[Block Format](https://nimiq.com/developers/protocol/consensus/block-format)**: Understand how blocks are structured - **[Validators](https://nimiq.com/developers/protocol/validators/validators)**: Learn about becoming a validator - **[Staking Contract](https://nimiq.com/developers/protocol/validators/staking-contract)**: The central hub for validator and staker data - **[Network Sync](https://nimiq.com/developers/protocol/node-sync)**: Learn about different synchronization methods ## Technical Resources - **[RPC](https://nimiq.com/developers/rpc)**: Integrate with the blockchain - **[Web Client](https://nimiq.com/developers/web-client)**: Build browser-based applications # Architecture Nimiq's consensus architecture centers on a **two-phase synchronization model** that separates epoch-level state synchronization from real-time block processing. This design enables efficient sync strategies tailored to different node capabilities while maintaining cryptographic security guarantees. ## Two-Phase Sync Architecture **Macro Sync Phase**: Establishes current network state efficiently by downloading and verifying macro blocks (epoch and checkpoint blocks). Different strategies optimize for various resource constraints: - [History Macro Sync](https://nimiq.com/developers/protocol/node-sync/macro-sync/history-macro-sync): Complete historical verification for history nodes - [Light Macro Sync](https://nimiq.com/developers/protocol/node-sync/macro-sync/light-macro-sync): Signature-verified macro sync for full and light nodes - [Pico Macro Sync](https://nimiq.com/developers/protocol/node-sync/macro-sync/pico-macro-sync): Trust-based approach with automatic security fallback **Live Sync Phase**: Maintains real-time synchronization with ongoing micro block production: - [State Live Sync](https://nimiq.com/developers/protocol/node-sync/live-sync/state-live-sync): Complete state maintenance for full nodes - [Block Live Sync](https://nimiq.com/developers/protocol/node-sync/live-sync/block-live-sync): Header-only sync for light clients ```text ┌─────────────────┐ ┌─────────────────┐ │ Application │ │ Network │ │ Layer │ │ Layer │ └─────────┬───────┘ └─────────┬───────┘ │ │ v v ┌─────────────────────────────────────────┐ │ Consensus Component │ │ ┌─────────────┐ ┌─────────────────┐ │ │ │ Consensus │ │ ConsensusProxy │ │ │ │ (Core) │ │ (Async Access) │ │ │ └─────────────┘ └─────────────────┘ │ └─────────┬───────────────────────────────┘ │ v ┌─────────────────────────────────────────┐ │ Syncer Component │ │ ┌─────────────┐ ┌─────────────────┐ │ │ │ Syncer │ │ SyncerProxy │ │ │ │ (Strategy) │ │ (Multi-variant) │ │ │ └─────────────┘ └─────────────────┘ │ └─────────┬───────────────────────────────┘ │ v ┌─────────────────────────────────────────┐ │ Sync Strategies │ │ ┌─────────┐ ┌──────────┐ ┌──────────┐ │ │ │ History │ │ Light │ │ Pico │ │ │ │ Macro │ │ Macro │ │ Macro │ │ │ └─────────┘ └──────────┘ └──────────┘ │ │ ┌─────────┐ ┌──────────┐ │ │ │ Block │ │ State │ │ │ │ Live │ │ Live │ │ │ └─────────┘ └──────────┘ │ └─────────────────────────────────────────┘ ``` ## System Components ### Coordination Layer **Consensus Component**: Acts as the central orchestrator, analyzing peer agreement and sync progress to determine network consensus state. Emits `ConsensusEvent::Established` and `ConsensusEvent::Lost` to coordinate system behavior. **Syncer Component**: Manages the macro sync → live sync lifecycle, selecting appropriate strategies based on node configuration and coordinating peer state transitions. **Proxy Architecture**: Both components use proxy patterns (`ConsensusProxy`, `SyncerProxy`) to provide thread-safe async interfaces while maintaining clear separation between coordination logic and external access. **`RemoteDataStore` and Event Dispatcher**: Supporting components such as `RemoteDataStore` and `RemoteEventDispatcher` provide remote access to account, validator, and staker data, and enable address-based event subscriptions. ### Strategy Implementation Layer **Sync Strategies**: Implement `MacroSync` and `LiveSync` traits to enable different verification approaches and resource optimization patterns. See [Traits and Abstractions](https://nimiq.com/developers/protocol/node-sync/traits-and-abstractions) for detailed interface specifications. **Trait-Based Design**: The sync system is built around trait-based abstractions, such as `MacroSync`, `LiveSync`, and `LiveSyncQueue`. This approach allows for pluggable sync strategies, making it straightforward to extend or adapt the system for new node types or future requirements. **Queue Architecture**: The core of peer request coordination is the generic `SyncQueue` abstraction, which manages requests, retries, and peer rotation for all sync strategies. ## Communication Architecture **Peer Classification Systems**: Different sync phases use specialized peer classification approaches. **Macro Sync Classification**: - **Good**: Successfully synchronized to peer's macro state - **Outdated**: Peer is behind local chain or provided outdated information - **Incompatible**: Peer does not provide required services for synchronization; *Example: full node cannot serve a syncing history node* - **Conflicting**: Peer provided conflicting blockchain data (triggers fallback in Pico Sync) **Live Sync Classification**: - **Behind**: Peer is too far behind our current blockchain position (exceeds tolerance threshold) - **Ahead**: Peer is too far ahead of our current blockchain position (exceeds window limit) **Peer Management**: Peer management is handled by the `PeerList` abstraction, which tracks active peers, supports efficient peer rotation, and notifies components when peers join or leave the network. ### Event-Driven Coordination **Structured Event System**: All major components communicate through asynchronous event streams, implementing the `Stream` trait. This enables the system to respond promptly to network changes, peer events, and sync progress: - `ConsensusEvent`: System-wide consensus state changes (`Established`, `Lost`) - `LiveSyncPushEvent`: Block processing outcomes (`AcceptedAnnouncedBlock`, `AcceptedBufferedBlock`, `ReceivedMissingBlocks`, `RejectedBlock`, `AcceptedChunks`) - `LiveSyncPeerEvent`: Peer classification (`Behind`, `Ahead`) - `NetworkEvent`: Peer lifecycle management (`PeerJoined`, `PeerLeft`) - `BlockchainEvent`: State transition coordination (`Extended`, `Rebranched`, `Finalized`, `EpochFinalized`, `HistoryAdopted`, `Stored`) - `RemoteEvent`: Inter-peer notifications (`InterestingReceipts`) **Cross-Node Communication**: `RemoteEventDispatcher` enables selective subscriptions between different node types, supporting efficient address-based notifications without full chain monitoring. ## Performance **Async Stream Processing**: All major components implement `Stream` trait for non-blocking, event-driven processing that maintains responsiveness under load. **Concurrency and Parallel Requests**: The sync system frequently needs to communicate with multiple peers at once, such as when requesting blocks. To handle this efficiently, it uses Rust’s `FuturesUnordered` collection. This allows the system to manage many asynchronous tasks in parallel and process each result as soon as it becomes available, regardless of the order they were started. By doing so, the node can take advantage of the fastest responses, keep the synchronization pipeline full, and avoid delays caused by slower peers. This approach ensures high throughput and responsiveness during all phases of synchronization. **Parallel Request Management**: Multi-peer concurrent request coordination with automatic load balancing and failure recovery ensures optimal network utilization. **Resource Management**: Configurable buffer sizes and connection limits enable tuning for different deployment environments and resource constraints. ## Security **Cryptographic Verification**: History and full nodes perform complete cryptographic validation of all received data. **Macro Chain Verification**: Light and full nodes verify each election and checkpoint block against the current validator set, extending a chain of trust without storing the full history. **Trust-Based Operation**: Pico nodes use optimistic trust with automatic fallback to trustless sync when conflicts are detected. ## Error Handling **Automatic Peer Rotation**: Network request failures trigger immediate peer failover with exponential backoff to prevent cascading failures. **Peer Banning**: Peers that provide invalid data or misbehave are subject to banning or disconnection. This mechanism protects the node from malicious actors and helps maintain the network's integrity and security. **State Recovery**: When errors occur pushing blocks or chunks, the system discards pending chunks and requests chunks again starting from the earliest missing key in the local accounts tree state. **`EitherSyncer`**: This abstraction enables seamless runtime fallback between sync strategies, such as automatically switching from Pico Macro Sync to Light Macro Sync when conflicts are detected, without disrupting the overall sync process. ## Consensus Establishment A node establishes consensus when it achieves both **peer connectivity** (minimum 3 peers) and **state synchronization** (complete required data), plus one of: - **Network Activity**: Accepted 5+ block announcements extending the local chain - **Peer Agreement**: Knowledge of head blocks from 2/3+ of connected peers **Head Consensus:** - Poll multiple peers simultaneously for chain head - Require 2/3+ agreement on current blockchain state - Disconnect from peers with significantly different state **Multi-Peer Verification:** - Request data from multiple peers for cross-validation - Compare responses to detect inconsistencies - Build consensus from majority agreement - Ban peers providing invalid data # Sync and Network Consensus Nimiq implements a **two-phase synchronization architecture** that separates epoch-level state synchronization from real-time block processing. This design enables efficient sync strategies tailored to different node capabilities. All nodes follow a **two-phase synchronization pattern**: **macro sync** followed by **live sync**. During macro sync, nodes download and verify macro blocks (checkpoints/epochs) to reach the current network state efficiently. Once macro sync completes, nodes transition to live sync to receive and validate the latest micro blocks in real-time. This modular approach allows each node type to optimize for its specific use case. ## Sync Comparison Table | | **History Node** | **Full Node** | **Light Node** | **Pico Node** | | --------------------- | --------------------------------------------------------------------------------------------------- | ----------------------------------------------------------------------------------------------- | ----------------------------------------------------------------------------------------------- | --------------------------------------------------------------------------------------------------------------- | | **Verification** | Entire chain + full history | Full blocks and state | Election-header chain (validator BLS signatures) | Trust-based (peer-reported state) | | **Macro Sync Method** | [History Macro Sync](https://nimiq.com/developers/protocol/node-sync/macro-sync/history-macro-sync) | [Light Macro Sync](https://nimiq.com/developers/protocol/node-sync/macro-sync/light-macro-sync) | [Light Macro Sync](https://nimiq.com/developers/protocol/node-sync/macro-sync/light-macro-sync) | [Pico Macro Sync](https://nimiq.com/developers/protocol/node-sync/macro-sync/pico-macro-sync)\* | | **Live Sync Method** | [Block Live Sync](https://nimiq.com/developers/protocol/node-sync/live-sync/block-live-sync) | [State Live Sync](https://nimiq.com/developers/protocol/node-sync/live-sync/state-live-sync) | [Block Live Sync](https://nimiq.com/developers/protocol/node-sync/live-sync/block-live-sync) | [Block Live Sync](https://nimiq.com/developers/protocol/node-sync/live-sync/block-live-sync) | | **Consensus Level** | Fully verified | Verified | Verified | Trust-based | | **Fallback** | N/A | N/A | N/A | \*Falls back to [Light Macro Sync](https://nimiq.com/developers/protocol/node-sync/macro-sync/light-macro-sync) | | **Sync Speed** | Slower, full chain from genesis | Efficient, grows with chain length | Fast, election headers only | Fastest, based on peer responses | | **Web Client** | Not supported | Not supported | Supported | Supported | ### History Nodes - Complete blockchain history from genesis - Deep chain queries, historical analysis, and serving data to other nodes - Can act as validators and provide historical data to the network - Serve data to other nodes, validate transactions and produce blocks (if validator) - Rely on other history nodes for initial sync ### Full Nodes - Complete current state with pruned history - maintains full validation capability - Serve data to other nodes, validate transactions and produce blocks (if validator) - Rely on full or history nodes for initial sync ### Light Nodes - Election block headers (verified via validator BLS signatures) and subsequent micro block headers only - Transaction verification and sending with cryptographic security guarantees - Browser/mobile deployment, web client integration (WASM support) - Rely on full or history nodes for data availability ### Pico Nodes - Sync with the latest election block only (no historical data; trust-based) - Ultra-fast startup with trust-based consensus and automatic fallback to trustless sync - Development environments, testing, and trusted network scenarios - Rely on full or history nodes for data availability and fallback verification ### Service Nodes **[Validator Nodes](https://nimiq.com/developers/protocol/validators/validators)**: Produce blocks and participate in consensus. Any node with a minimum of 100'000 NIM deposit that runs a full or history client can become a validator. ## Architecture Components **Coordination Layer**: `Consensus` and `Syncer` components manage sync lifecycle and peer relationships, enabling seamless transitions between sync phases. **Pluggable Strategies**: `MacroSync` and `LiveSync` trait implementations allow optimization for different resource constraints. **Network Layer**: Request/response and gossip protocols with async streams for efficient concurrent peer processing. **Queue Architecture**: Automatic peer rotation, retry logic, and backpressure control ensure reliable data retrieval. ::u-page-grid :::u-page-card --- description: Core components, data flow, and design patterns that enable efficient sync coordination. icon: i-lucide-layout-dashboard title: Architecture to: https://nimiq.com/developers/protocol/node-sync/architecture variant: outline --- ::: :::u-page-card --- description: Core traits, components, and architectural patterns in the sync system. icon: i-lucide-puzzle title: Traits & Abstractions to: https://nimiq.com/developers/protocol/node-sync/traits-and-abstractions variant: outline --- ::: :::u-page-card --- description: Node requests and responses for syncing. icon: i-lucide-network title: Network Protocol to: https://nimiq.com/developers/protocol/node-sync/network-protocol variant: outline --- ::: :: ## Further Reading **Understanding the System** - [Architecture](https://nimiq.com/developers/protocol/node-sync/architecture) - Core components, data flow, and design patterns - [Node Sync System](https://nimiq.com/developers/#node-sync-system) - Node lifecycles and sync mode selection **Implementation Details** - [Traits and Abstractions](https://nimiq.com/developers/protocol/node-sync/traits-and-abstractions) - System design and component coordination - [Network Protocol](https://nimiq.com/developers/protocol/node-sync/network-protocol) - Message specifications and communication patterns **Sync Strategy Deep Dives** *Macro Sync Strategies:* - [History Macro Sync](https://nimiq.com/developers/protocol/node-sync/macro-sync/history-macro-sync) - Full chain download for history nodes - [Light Macro Sync](https://nimiq.com/developers/protocol/node-sync/macro-sync/light-macro-sync) - Trustless macro sync for full and light nodes - [Pico Macro Sync](https://nimiq.com/developers/protocol/node-sync/macro-sync/pico-macro-sync) - Optimistic sync with automatic fallback *Live Sync Strategies:* - [Block Live Sync](https://nimiq.com/developers/protocol/node-sync/live-sync/block-live-sync) - Real-time block synchronization - [State Live Sync](https://nimiq.com/developers/protocol/node-sync/live-sync/state-live-sync) - Complete state maintenance for full nodes ## Sync Lifecycle When a node starts, it follows this coordination pattern: 1. **Peer Discovery** through the network layer 2. **Macro Sync Strategy Sync** based on node configuration 3. **Live Sync Transition** to maintain real-time synchronization 4. **Consensus Detection** through peer agreement analysis The `Consensus` component orchestrates this process, while the `Syncer` manages strategy-specific implementations through pluggable trait interfaces. ::callout{icon="i-tabler-bulb"} **Developer Focus** This documentation targets developers working on sync logic and node implementations. For node operation, see the [Node Setup Guide](https://github.com/nimiq/core-rs-albatross?tab=readme-ov-file#README){rel=""nofollow""}. :: # Block Live Sync **Block Live Sync** is the real-time block synchronization mechanism, used as the second phase of synchronization after macro sync completes. It enables nodes to follow the chain tip by processing micro blocks as they are produced. This mode targets nodes that do not require state synchronization. Block Live Sync is used by: - **History nodes** – Download full block bodies (including transactions) - **Light and Pico nodes** – Download block headers only Full nodes do not use Block Live Sync. Instead, they transition to **[State Live Sync](https://nimiq.com/developers/protocol/node-sync/live-sync/state-live-sync)** to synchronize both blocks and complete account state simultaneously. ## **Key Characteristics** - **Real-Time Micro Block Synchronization**: Continuously follows the latest micro blocks after macro sync. - **Peer-Independent Processing**: The system processes each peer independently for block announcements and missing block detection. - **Flexible Download Modes**: Supports both full block bodies and header-only modes. - **Stream-Based**: Implements asynchronous processing via the `Stream` trait. ## **How It Works** The `BlockLiveSync` manages real-time blockchain synchronization by processing incoming block announcements, buffering out-of-order blocks, and proactively requesting missing blocks from peers. It ensures the node maintains synchronization with the network's current state through continuous block processing. The `BlockLiveSync` follows a reactive request pattern: - **Block Announcements** → Process incoming blocks via gossipsub - **RequestMissingBlocks** → Request missing blocks when gaps are detected (see Network Messages) - **Block Buffering** → Buffer out-of-order blocks until predecessors arrive ## **Architecture Overview** ```rust pub type BlockLiveSync = LiveSyncer>; pub struct LiveSyncer> { blockchain: BlockchainProxy, network: Arc, queue: Q, /// Vector of pending push operations. pending: VecDeque>, /// Cache for BLS public keys to avoid repetitive uncompressing. bls_cache: Arc>, /// Channel used to communicate additional blocks to the queue. /// We use this to wake up the queue and pass in new, unknown blocks /// received in the consensus as part of the head requests. block_tx: mpsc::Sender>, } ``` **Key components:** | **Component** | **Purpose** | | ----------------------- | ---------------------------------------------------- | | `LiveSyncer` | Main sync controller implementing `Stream` | | `BlockQueue` | Manages block buffering, ordering, and gap detection | | `BlockRequestComponent` | Handles network requests for missing blocks | ## **Step-by-Step Process** ### **1. Block Reception** The node receives blocks from two sources: - **Announced blocks**: Via gossipsub block announcements from peers - **Requested blocks**: Responses to missing block requests Each block is classified with its source for proper validation and peer management. ### **2. Block Classification** Each incoming block is classified by the queue as: - **Head** – Parent known, block processed immediately - **Buffered** – Block ahead of current state, stored temporarily - **Missing** – Block cannot be processed due to gaps; predecessor requested ### **3. Missing Block Resolution** When the system detects chain gaps: - Generate block locators from current head to last macro block - Send `RequestMissingBlocks` with target hash and locators - Track pending requests to avoid duplicates - Once the gaps are filled, the node processes all buffered blocks in order ### **4. Blockchain Integration** - Validate block signatures and intrinsic properties - Push accepted blocks to blockchain using `push()` or `push_with_chunks()` - Process buffered blocks that become applicable - Update BLS cache with new validator keys ## **Configuration Differences** The behavior of Block Live Sync depends on the QueueConfig: ```rust pub struct QueueConfig { /// Buffer size limit pub buffer_max: usize, /// How many blocks ahead we will buffer. pub window_ahead_max: u32, /// How many blocks back into the past we tolerate without returning a peer as Outdated. pub tolerate_past_max: u32, /// Flag to indicate if blocks should carry a body. pub include_body: bool, } ``` - **History Nodes** → Download full transaction data for archival purposes - **Light/Pico Nodes** → Download headers only for efficient operation ## Event Processing Block Live Sync emits structured events for different scenarios: - `AcceptedAnnouncedBlock(hash)` - Live block accepted - `AcceptedBufferedBlock(hash, buffer_size)` - Buffered block applied - `ReceivedMissingBlocks(hashes)` - Missing blocks successfully received - `RejectedBlock(hash)` - Block validation failed ### **Peer Events** - `Behind(peer_id)` - Peer is behind our blockchain state - `Ahead(peer_id)` - Peer is ahead of our blockchain state **Peer Classification Logic:** Peers are classified based on the block height difference and tolerance configuration: - **Behind**: Peer's announced block is more than `tolerate_past_max` blocks behind our current head - **Ahead**: Peer's announced block is more than `window_ahead_max` blocks ahead of our current head **System Actions:** - **Behind peers**: Excluded from missing block requests but remain connected for potential catch-up - **Ahead peers**: May trigger missing block requests if the gap is bridgeable, otherwise marked for potential disconnection - **Excessive drift**: Peers too far ahead or behind may be disconnected to maintain sync efficiency This event-driven approach enables the consensus layer to track synchronization progress and make informed decisions about peer management and sync strategy. # State Live Sync State Live Sync is a comprehensive real-time synchronization mechanism designed exclusively for full blockchain instances. The State Live Sync simultaneously maintains both the latest blockchain state and complete account data through parallel block and state synchronization. Every other node type does not use State Live Sync. Instead, they transition to **[Block Live Sync](https://nimiq.com/developers/protocol/node-sync/live-sync/block-live-sync)** to synchronize both blocks and complete account state simultaneously. ## Key Characteristics - **Peer-to-Peer Operation**: Each peer is handled independently with separate request queues - **Full State Synchronization**: Maintains complete account state through parallel chunk downloads - **Full Blockchain Exclusive**: Compatible only with full blockchain instances - **Multi-Layered Architecture**: Combines `BlockQueue`, `DiffQueue`, and `StateQueue` for comprehensive sync - **Partial Trie Reconstruction**: Builds complete state without requiring transaction history - **State Completion Tracking**: Monitors blockchain state completeness and triggers chunk requests as needed - **Stream-Based**: Implements the `Stream` trait for asynchronous event processing ## How It Works The `StateLiveSync` manages both block and state synchronization through a layered queue system. It processes incoming blocks while simultaneously requesting and applying state chunks in order to eventually reach a complete blockchain state. The sync monitors account tree completeness and automatically triggers state synchronization when gaps are detected. The `StateLiveSync` follows a dual-request pattern combining block and state synchronization: 1. **RequestMissingBlocks** → Request missing blocks when gaps are detected 2. **RequestTrieDiff** → Request trie diffs for efficient state updates 3. **RequestChunk** → Request state chunks to fill account tree gaps The complete message specifications are documented in the [Network Protocol](https://nimiq.com/developers/protocol/node-sync/network-protocol) document. ## Partial Trie Construction The State Live Sync does not download the entire state trie at once. Instead, nodes request and apply small chunks of the trie incrementally. This approach is necessary because blocks continue to be produced while a node is syncing. By the time the full trie was downloaded, it would already be outdated. Instead, nodes construct a **partial trie** by: - Requesting one chunk at a time - Using the `end_key` from the previous response as the `start_key` for the next request - Repeating this process until the full trie is reconstructed and matches the current state At the end of the process, the node compares its computed **state root** against the expected root in the latest block to verify correctness. This approach eliminates the need for transaction history while maintaining complete account state. ## Architecture Overview ::collapsible{title="State Live Sync Struct (click to expand)"} ```rust pub type StateLiveSync = LiveSyncer>; pub struct LiveSyncer> { blockchain: BlockchainProxy, network: Arc, queue: Q, /// Vector of pending push operations. pending: VecDeque>, /// Cache for BLS public keys to avoid repetitive uncompressing. bls_cache: Arc>, /// Channel used to communicate additional blocks to the queue. /// We use this to wake up the queue and pass in new, unknown blocks /// received in the consensus as part of the head requests. block_tx: mpsc::Sender>, } pub struct StateQueue { /// Configuration for the block queue. config: QueueConfig, /// Reference to the blockchain. blockchain: Arc>, /// Reference to the network. network: Arc, /// The queue from which we receive blocks and tree diffs. diff_queue: DiffQueue, /// The chunk request component. /// We use it to request chunks from up-to-date peers chunk_request_component: ChunkRequestComponent, /// Buffered chunks - `block_height -> block_hash -> BlockAndId`. /// There can be multiple blocks at a height if there are forks. /// For each block, we can store multiple chunks. buffer: BTreeMap>>>, buffer_size: usize, /// The block number of the latest macro block. We prune the block buffer when it changes. current_macro_height: u32, /// The starting point for the next chunk to be requested. We reset it to `None` when the /// chain of chunks is invalidated, which will force the component to request the next /// chunk starting from the missing range of the blockchain state. /// Invalidation of the chain may happen by an invalid chunk or block, a discarded chunk, /// or a rebranch event. start_key: ChunkRequestState, /// The blockchain event stream. blockchain_rx: BoxStream<'static, BlockchainEvent>, /// Waiter for the peer list to become nonempty. /// /// Since we only want to dispatch requests from the /// `ChunkRequestComponent` when its peer list is nonempty, we need some /// notification mechanism to wake us up once the list becomes nonempty if /// we find it empty. peers_became_nonempty: Option>, } ``` :: **Key components:** | **Component** | **Purpose** | | ----------------------- | -------------------------------------------------------------------- | | `LiveSyncer` | Main sync controller implementing `Stream` | | `StateQueue` | Manages state chunk requests and buffering for trie reconstruction | | `DiffQueue` | Handles tree diff processing and application for incremental updates | | `BlockQueue` | Manages block buffering, ordering, and gap detection | | `ChunkRequestComponent` | Handles network requests for state chunks | ## Buffer Configuration State Live Sync uses multiple buffer systems to manage concurrent block and state processing: ```rust pub struct QueueConfig { /// Buffer size limit pub buffer_max: usize, /// How many blocks ahead we will buffer. pub window_ahead_max: u32, /// How many blocks back into the past we tolerate without returning a peer as Outdated. pub tolerate_past_max: u32, /// Flag to indicate if blocks should carry a body. pub include_body: bool, } ``` ## Step-by-Step Process ### 1. Dual Stream Processing The node processes two parallel streams: - **Block Announcements**: Via gossipsub block announcements from peers - **State Monitoring**: Via blockchain events tracking account tree completeness ### 2. Block Reception & Buffering Incoming blocks are processed through the layered queue system: - **StateQueue**: Requests corresponding state chunks for each block to maintain trie completeness - **DiffQueue**: Applies tree diffs for efficient state updates without full reconstruction - **BlockQueue**: Handles block ordering and gap detection for continuous sync ### 3. Partial Trie Reconstruction When the account tree is incomplete, the node initiates chunk-based reconstruction: - **Gap Discovery**: Use `get_missing_accounts_range()` to identify missing trie sections - **Sequential Requests**: Request chunks starting from missing key ranges with up to 5,000 nodes each - **Progressive Building**: Apply chunks sequentially using `start_key` from previous response as next `start_key` - **Chunk Buffering**: Buffer chunks by block height and hash for ordered application ### 4. Block & State Application Process blocks and chunks in the following order: - **Block Validation**: Standard block signature and intrinsic validation - **Block Push**: Apply validated blocks to the blockchain - **Chunk Push**: Apply state chunks via `commit_chunks()` to rebuild account trie - **BLS Cache Updates**: Update validator key cache for performance optimization ### 5. State Completion Tracking & Diff Mode Monitor blockchain state completeness and optimize sync strategy: - **Completion Detection**: Mark state sync complete when `accounts_complete()` returns true - **Diff Mode Switch**: Disable chunk requests and enable diff-only processing for efficiency - **Reset Triggers**: Restart chunk-based reconstruction on rebranch or state reinitialization - **Buffer Pruning**: Clean outdated chunks when passing macro blocks to manage memory - **Progress Reporting**: Emit events for state sync progress and completion ### 6. Rebranch Recovery Handle blockchain reorganizations gracefully: - **State Validation**: Check if rebranch caused state incompleteness - **Reset Strategy**: If incomplete, reset to chunk request mode and re-enable diffs - **Buffer Cleanup**: Clear invalid chunks and restart trie reconstruction from detected gaps ## Event Processing State Live Sync emits structured events for different synchronization scenarios: **Block and State Events:** - `AcceptedAnnouncedBlock(hash)` - Real-time block accepted - `AcceptedBufferedBlock(hash, buffer_size)` - Buffered block applied - `ReceivedMissingBlocks(hashes)` - Missing blocks successfully received - `RejectedBlock(hash)` - Block validation failed - `AcceptedChunks(hash)` - State chunks applied for head block **Peer Events:** - `Behind(peer_id)` - Peer is behind our blockchain state - `Ahead(peer_id)` - Peer is ahead of our blockchain state **Peer Classification Logic:** Peers are classified based on the block height difference and tolerance configuration: - **Behind**: Peer's announced block is more than `tolerate_past_max` blocks behind our current head - **Ahead**: Peer's announced block is more than `window_ahead_max` blocks ahead of our current head # History Macro Sync History Macro Sync is a full history synchronization mechanism designed exclusively for history nodes. It downloads the complete blockchain transaction history from genesis. The History Macro Sync is required for nodes that need to serve historical queries or verify the full transaction history. ## Key Characteristics - **Peer-to-Peer Operation**: Each peer is handled independently with separate request queues - **Full History Reconstruction**: Retrieves and validates complete transaction history since genesis - **Full Blockchain Exclusive**: Compatible only with full blockchain instance - **Parallel Sync Clusters**: Organizes downloads into concurrent clusters for maximum efficiency - **Stream-Based**: Implements the `Stream` trait for asynchronous event processing ## How It Works The `HistoryMacroSync` manages blockchain synchronization through parallel cluster operations. It downloads complete macro block history with transaction data, organizing work into efficient parallel streams for maximum throughput. The `HistoryMacroSync` follows a cluster-based parallel request pattern: 1. **RequestMacroChain** → Discover available election macro block chains and epoch information 2. **RequestBatchSet** → Download macro blocks with validation metadata and history proofs 3. **RequestHistoryChunk** → Retrieve complete transaction history chunks in parallel The complete message specifications are documented in the [Network Protocol](https://nimiq.com/developers/protocol/node-sync/network-protocol) document. ## Architecture Overview ```rust pub struct HistoryMacroSync { pub(crate) blockchain: Arc>, pub(crate) network: Arc, pub(crate) network_event_rx: SubscribeEvents, pub(crate) peers: HashMap, pub(crate) epoch_ids_stream: FuturesUnordered>>>, pub(crate) epoch_clusters: VecDeque>, pub(crate) checkpoint_clusters: VecDeque>, pub(crate) active_cluster: Option>, pub(crate) job_queue: VecDeque>, pub(crate) waker: Option, } ``` ## Step-by-Step Process ### 1. Macro Chain Discovery - The node sends `RequestMacroChain` to peers to discover epoch IDs and identify checkpoint blocks - Block locators help find the highest common block between the node and its peers ### 2. Parallel Batch Set Downloads per Cluster - The node creates one or more `SyncCluster`s instances responsible for specific epoch ranges - It sends `RequestBatchSet` messages to retrieve macro blocks along with metadata - Macro blocks are stored but not yet applied until their history is complete ### 3. History Chunks Downloads - The node sends `RequestHistoryChunk` messages to download transaction history in manageable chunks - Each `SyncCluster` manages its own queue, allowing multiple history chunks to be retrieved in parallel - History chunks are verified using Merkle proofs against the macro block's history root ### 4. Block Application - Once all required history is downloaded and verified, the node applies macro blocks using `push_history_sync()` - This process updates the blockchain state without replaying every transaction ### 5. Sync Completion - If the peer has no new epochs → Emit as `Good` - If missing epochs are found → Continue processing - If validation fails → Emit as `Outdated` or `Incompatible` This cycle continues until all clusters complete and peers are fully synchronized. ## **Concurrency Management** History Macro Sync uses multiple levels of parallelism to improve performance: - **Cluster-Level**: Multiple clusters process different epoch ranges simultaneously - **Request-Level**: Batch set and history chunk requests proceed independently - **Chunk-Level**: Multiple history chunks are downloaded in parallel per cluster ### Cluster Architecture ```rust pub struct SyncCluster { pub id: usize, pub epoch_ids: Vec, pub first_epoch_number: usize, pub first_block_number: usize, // Both batch_set_queue and the history_queue share the same peers. pub(crate) batch_set_queue: SyncQueue, history_queue: SyncQueue< TNetwork, HistoryChunkRequest, (HistoryChunkRequest, HistoryTreeChunk), HistoryRequestError, (), >, pending_batch_sets: VecDeque, num_epochs_finished: usize, blockchain: Arc>, network: Arc, } ``` ### Parallel Processing Limits - **Batch Sets**: 5 concurrent downloads per cluster - **History Chunks**: 12 concurrent downloads per cluster - **Max Clusters**: 100 total active clusters - **Job Queue**: 4 maximum queued completion jobs ## Event Processing History Macro Sync emits structured events for different peer synchronization scenarios: **Sync Events:** - `MacroSyncReturn::Good(peer_id)` - Peer successfully synchronized, no new epochs available - `MacroSyncReturn::Outdated(peer_id)` - Peer validation failed or provided outdated information - `MacroSyncReturn::Incompatible(peer_id)` - Peer does not provide required services for synchronization; *Example: A full node cannot serve a history node because it does not store the full transaction history from genesis, making it incompatible for history sync requests* **Progress Events:** - Cluster completion notifications for parallel download tracking - Batch set download completion per epoch range - History chunk application progress within clusters This event system enables the consensus layer to track synchronization progress across multiple peers and make informed decisions about when sufficient peers have achieved macro sync completion. ## **Transition to Live Sync** When History Macro Sync emits `MacroSyncReturn::Good` for sufficient peers, the consensus layer initiates the transition to **Live Sync**. The node transitions to [Block Live Sync](https://nimiq.com/developers/protocol/node-sync/live-sync/block-live-sync) to follow new micro blocks in real time. This two-phase approach (macro sync → live sync) ensures nodes can quickly reach consensus state then maintain real-time synchronization with minimal overhead. # Light Macro Sync Light Macro Sync is the macro block synchronization mechanism for full and light nodes, and the trustless fallback for [Pico Macro Sync](https://nimiq.com/developers/protocol/node-sync/macro-sync/pico-macro-sync). It brings a node to the current macro state by requesting and verifying the chain of election and checkpoint blocks, without the full block history. Macro block requests run through a bounded, ordered **`SyncQueue`**, which prevents a node that is many epochs behind from flooding its peers with requests. ## Key Characteristics - **Multi-Peer Fetching**: Macro blocks are fetched from multiple peers through a shared, bounded queue with per-block failover - **Signature-Verified**: Each election and checkpoint block is verified against the current validator set before it is applied - **Dual Blockchain Support**: Compatible with both full and light blockchain instances - **Validity Window Sync**: Full nodes perform additional history chunk validation - **Trustless Fallback**: Serves as the fallback mechanism for Pico Macro Sync - **Stream-Based**: Implements the `Stream` trait for asynchronous event processing ## How It Works The `LightMacroSync` discovers the macro chain from its peers, then fetches and applies the missing election and checkpoint blocks in epoch order. Block fetches are routed through the `macro_block_queue` so that requests stay bounded and responses are applied in order. The `LightMacroSync` follows this request pattern: 1. **RequestMacroChain** → Request epoch IDs using known block locators 2. **RequestBlock** → Fetch the missing macro blocks by hash, through the `macro_block_queue` 3. **RequestHistoryChunk** → Validate transaction history within the validity window (full nodes only) When Light Macro Sync runs as the [Pico Macro Sync](https://nimiq.com/developers/protocol/node-sync/macro-sync/pico-macro-sync) fallback, it is given a [pinned election block](https://nimiq.com/developers/protocol/glossary#pinned-election-block) to bootstrap from: instead of syncing the election chain from genesis, it seeds the chain to that block and verifies forward. Full and light nodes do not bootstrap this way. They sync the election chain from genesis and only verify the pinned election block against their own chain. The complete message specifications are documented in the [Network Protocol](https://nimiq.com/developers/protocol/node-sync/network-protocol) document. ## Architecture Overview ::collapsible{title="Light Macro Sync Struct (click to expand)"} ```rust pub struct LightMacroSync { /// The blockchain pub(crate) blockchain: BlockchainProxy, /// Reference to the network pub(crate) network: Arc, /// Stream for peer joined and peer left events pub(crate) network_event_rx: SubscribeEvents, /// The stream for epoch ids requests pub(crate) epoch_ids_stream: FuturesUnordered>>>, /// Hardcoded election block to bootstrap from on the pico sync fallback path; `None` for /// light/full sync (which sync the election chain from genesis and only verify the checkpoint). /// When set and the chain is still behind it, the checkpoint election block is fetched through /// `macro_block_queue` and seeded via `apply_macro_block` (see `add_peer`). pub(crate) bootstrap_checkpoint: Option, /// Bounded, ordered, failover queue for fetching macro (election) block headers: /// the checkpoint seed, the forward catch-up after it, and the full-node `previous_slots` /// recovery block all go through here. Requests are bounded, responses applied in epoch /// order, and a timed-out block is re-requested from another peer instead of stalling. pub(crate) macro_block_queue: SyncQueue< TNetwork, Blake2bHash, (Blake2bHash, Result, TNetwork::PeerId), MacroBlockError, (), >, /// Macro block hashes currently queued or in flight in `macro_block_queue`. Deduplicates /// overlapping `epoch_ids` (and seed requests) from multiple peers; entries are removed /// once the block is applied or its request is exhausted. pub(crate) in_flight_macro_blocks: HashSet, /// Peers waiting for `macro_block_queue` to advance our head to their reported target block /// number. Once reached they are re-queried for epoch ids (emitting `Good` when nothing is /// left, or enqueuing the next epochs if the tip moved). Drives the checkpoint seed and /// forward catch-up. pub(crate) waiting_macro_peers: HashMap, /// Peers to re-query once a specific queued block resolves, keyed by that block's hash. Used /// for the full-node `previous_slots` recovery fetch, whose `update_previous_slots` apply does /// not advance the head (so `waiting_macro_peers` can't drive it). pub(crate) pending_followup_requests: HashMap>, #[cfg(feature = "full")] /// The validity (history chunks) queue pub(crate) validity_queue: SyncQueue< TNetwork, RequestHistoryChunk, ( RequestHistoryChunk, Result, TNetwork::PeerId, ), RequestError, (), >, #[cfg(feature = "full")] /// Used to track the validity chunks we are requesting pub(crate) validity_requests: Option, #[cfg(feature = "full")] /// The peers we are currently syncing with pub(crate) syncing_peers: HashSet, #[cfg(feature = "full")] /// A vec of all the peers that we successfully synced with pub(crate) synced_validity_peers: Vec, #[cfg(feature = "full")] /// Minimum distance to light sync in #blocks from the peers head. pub(crate) full_sync_threshold: u32, } ``` :: ## Step-by-Step Process ### 1. Epoch Discovery - Send a `RequestMacroChain` with known block locators - Peer responds with epoch IDs and, when applicable, the metadata of the last checkpoint block ### 2. Block Retrieval - Request the missing macro blocks by hash through the `macro_block_queue` - The queue bounds the number of in-flight requests, applies blocks in epoch order, and re-requests a timed-out block from another peer instead of stalling - A block whose hash does not match the request is rejected, and the responding peer is disconnected ### 3. Validity Window Sync (Full Nodes Only) For full nodes, the Light Macro Sync includes an additional step to synchronize and validate historical transaction data within the blockchain's **validity window**. - The node requests history chunks associated with recently applied macro blocks. These chunks include the historical transactions necessary to maintain full state validity without storing the entire chain history - Chunks are applied to the local blockchain to ensure that transaction history within the validity window is complete and consistent ### 4. Sync Completion 1. **Macro State Synchronized**: All election and checkpoint blocks up to the network's current state have been applied: - If the peer has no new blocks → Emit as `Good` - If missing blocks are found → Emit as `Outdated` 2. **Validity Window Satisfied** (full nodes only): Transaction history within the validity window has been downloaded and validated ## Verification Light Macro Sync builds trust forward from a known block rather than from a single proof: - **Macro chain verification**: Each election and checkpoint block is verified against the current validator set before it is applied. Because each election block determines the next set of validators, the node extends a chain of trust block by block. - **Pinned election block check**: When the network defines a [pinned election block](https://nimiq.com/developers/protocol/glossary#pinned-election-block), every node verifies the committed election block at that height against it. A mismatch is logged and surfaced through the `checkpoint_mismatch` metric, but it does not stop the node. Pico nodes additionally use the pinned election block as the bootstrap anchor on this fallback path. ## Validity Window Synchronization Full nodes perform additional validation through validity window chunks: - **History Verification**: Downloads and validates transaction history chunks within the validity window - **Chunk Processing**: Verifies Merkle proofs for history integrity - **Recent History Integrity**: Ensures complete transaction history within the validity window ### Validity Request Tracking ```rust /// Struct used to track the progress of the validity window chunk process. pub struct ValidityChunkRequest { /// This corresponds to the block that should be used to verify the proof. pub verifier_block_number: u32, /// The root hash that should be used to verify the proof. pub root_hash: Blake2bHash, /// The chunk index that was requested. pub chunk_index: u32, /// Flag to indicate if there is an election block within the validity window pub election_in_window: bool, /// Number of items in the previous requested chunk (for cases where we adopt a new macro head) pub last_chunk_items: Option, } ``` ## Event Processing Light Macro Sync emits structured events for different synchronization scenarios: **Sync Events:** - `MacroSyncReturn::Good(peer_id)` - Peer successfully synchronized and reached the most recent macro block - `MacroSyncReturn::Outdated(peer_id)` - Peer provided outdated blocks or failed validation - `MacroSyncReturn::Incompatible(peer_id)` - Peer does not provide required services for synchronization; *Example: A light node cannot serve a full node because it does not store the validity window, making it incompatible for full nodes sync requests* ## **Transition to Live Sync** When Light Macro Sync emits `MacroSyncReturn::Good` for sufficient peers, the consensus layer transitions the node to **Live Sync** for ongoing micro block synchronization and real-time state updates. Full nodes follow the [State Live Sync](https://nimiq.com/developers/protocol/node-sync/live-sync/state-live-sync) and light nodes follow the [Block Live Sync](https://nimiq.com/developers/protocol/node-sync/live-sync/block-live-sync). The node maintains synchronization through live micro block announcements and continuous state updates. This two-phase approach (macro sync → live sync) ensures nodes can quickly reach consensus state then maintain real-time synchronization with minimal overhead. # Pico Macro Sync Pico Macro Sync is a lightweight sync mechanism designed for resource-constrained environments. It operates exclusively with light blockchain instances and provides fast initial synchronization by requesting only essential macro blocks (election and checkpoint blocks) from peers on a per-peer basis. Pico Macro Sync takes an optimistic approach by accepting macro blocks with minimal validation, then falling back to a more robust sync method if conflicts are detected. ## Key Characteristics - **Peer-to-Peer Operation**: Each peer is handled independently with separate request queues - **Optimistic Approach**: Accepts blocks with minimal validation - **Minimal State**: Only tracks essential information needed for the sync process - **Fast Fallback**: Can quickly transition to Light Macro Sync when conflicts are detected - **Stream-Based**: Implements the `Stream` trait for asynchronous event processing ## How It Works The `PicoMacroSync` manages macro block synchronization for each peer individually using a two-step process optimized for speed and efficiency. The `PicoMacroSync` follows a minimal request pattern: 1. **RequestHead** → Request the peer's head which returns the peer's election hash and the peer's latest macro block hash 2. **RequestBlock** → Use those hashes to request the respective blocks and apply them to the blockchain 3. **Then either:**:br 3.1 **First-time sync (at genesis block):** The blocks are simply applied to the blockchain, or :br 3.2 **Subsequent peer syncs:** The node compares the peer's head hashes to what it already has. If they are equal, the peer is marked as `Good`. If the hashes are different, there's a conflict and the node falls back to the regular macro sync mechanism. The complete message specifications are documented in the [Network Protocol](https://nimiq.com/developers/protocol/node-sync/network-protocol) document. ## Architecture Overview ::collapsible{title="Pico Macro Sync Struct (click to expand)"} ```rust pub struct PicoMacroSync { /// The blockchain pub(crate) blockchain: BlockchainProxy, /// Reference to the network pub(crate) network: Arc, /// Stream for peer joined and peer left events pub(crate) network_event_rx: SubscribeEvents, /// Used to track the macro requests on a per peer basis pub(crate) peer_requests: HashMap, /// The stream for head requests pub(crate) head_stream: FuturesUnordered>>, /// Block requests pub(crate) block_headers: FuturesUnordered< BoxFuture< 'static, ( Result, RequestError>, TNetwork::PeerId, ), >, >, /// Collection of peers we are currently pico macro syncing with pub(crate) syncing_peers: HashSet, } ``` :: ## Step-by-Step Process ### 1. Head Request The node sends a RequestHead message to the peer to obtain its current macro and election block hashes. Then, it extracts the macro and election block hashes to determine the peer's macro state and guide the next request. ### 2. State Comparison Compare peer's head with local blockchain state: - **Match** → Mark as `Good` - **Different hashes** → Continue to block requests ### 3. Targeted Block Requests Request only the specific blocks needed: - **Starting from genesis** → Request peer's latest election block (trusted) - **Have election block** → Request only the next macro block in sequence ### 4. Optimistic Block Application Apply blocks with simple validation rules: - **Election block**: Only accepted if local blockchain is at genesis - **Macro block**: Only accepted if it is the immediate next epoch - **Any other case**: Mark peer as `Conflicting`, fall back to Light Macro Sync ### 5. Verify Completion Re-request the peer's head to check if more blocks are needed: - **Hashes match** → Mark peer as `Good`, sync complete - **Still different** → Repeat from step 3 - **Validation failed** → Fallback to `LightMacroSync` ## Fallback Mechanism ### Conflicting Peer The Pico Macro Sync operates with minimal validation, accepting blocks optimistically to maximize speed. It only accepts a new election block if the local chain is at genesis, since it cannot fully validate election blocks without full history. If the node is not at genesis and receives an unknown election block, it cannot verify its validity. Accepting such a block could allow a malicious or faulty peer to inject an alternate chain or fork, risking the node’s security and consensus. When a peer provides a block that cannot be optimistically and safely applied, the node marks the peer as **conflicting**. This triggers a fallback to Light Macro Sync, which securely re-syncs and verifies the chain state to resolve discrepancies. Fallback to `LightMacroSync` is triggered when: - Block validation fails during push operations - Peer provides blocks from wrong epoch - Network errors or malicious peer behavior detected - Peer state differs from current local state The `EitherSyncer` enum allows transitions between sync mechanisms: ```rust pub enum EitherSyncer { Normal(PicoMacroSync), // Fast optimistic sync Fallback(LightMacroSync), // Trustless fallback sync } ``` ## Event Processing Pico Macro Sync emits structured events for different synchronization scenarios: **Sync Events:** - `MacroSyncReturn::Good(peer_id)` - Peer successfully synchronized with optimistic validation - `MacroSyncReturn::Outdated(peer_id)` - Peer provided outdated blocks or failed basic validation - `MacroSyncReturn::Incompatible(peer_id)` - Peer does not provide required services for synchronization; *Example: A pico node cannot serve another pico node because it does not provide fully verifiable or authenticated data, making it incompatible for pico sync requests* - `MacroSyncReturn::Conflicting(peer_id)` - Peer provided conflicting blocks, triggering fallback to Light Macro Sync **Fallback Events:** - Fallback trigger detection when block validation fails - Transition from `PicoMacroSync` to `LightMacroSync` via `EitherSyncer` - Peer transfer to Light Macro Sync (trustless sync) ## Transition to Live Sync When the Pico Macro Sync emits `MacroSyncReturn::Good` for sufficient peers, the consensus layer initiates the transition to **Live Sync**. The node transitions to [Block Live Sync](https://nimiq.com/developers/protocol/node-sync/live-sync/block-live-sync) to follow new micro blocks in real time. This two-phase approach (macro sync → live sync) ensures nodes can quickly reach consensus state then maintain real-time synchronization with minimal overhead. # Network Messages The consensus crate implements a comprehensive network protocol enabling nodes to synchronize with the blockchain and exchange data efficiently. Communication follows two primary patterns: **Request/Response**: Direct peer-to-peer queries with guaranteed responses, used for targeted data retrieval and sync coordination. **Gossip/Broadcast**: One-to-many real-time propagation for block headers, bodies, and notifications. All messages implement the `RequestCommon` trait with unique `TYPE_ID` identifiers and follow standardized error handling patterns. The following requests implement this multi-peer coordination through standardized message types: ## Request Summary | TYPE\_ID | Request | Purpose | Response Type | Primary Use | | -------- | ---------------------------------------------------------------------------------------------------------- | -------------------------------------- | -------------------------------------- | -------------------------- | | **200** | [`RequestMacroChain`](https://nimiq.com/developers/#requestmacrochain) | Get macro block hashes from locators | `MacroChain` | Macro sync | | **202** | [`RequestBatchSet`](https://nimiq.com/developers/#requestbatchset) | Get macro block batch information | `BatchSetInfo` | History sync setup | | **204** | [`RequestHistoryChunk`](https://nimiq.com/developers/#requesthistorychunk) | Get history chunk by epoch/index | `HistoryChunk` | History download | | **207** | [`RequestBlock`](https://nimiq.com/developers/#requestblock) | Get specific block by hash | `Block` | Individual block retrieval | | **209** | [`RequestMissingBlocks`](https://nimiq.com/developers/#requestmissingblocks) | Get blocks between locators and target | `ResponseBlocks` | Chain gap filling | | **210** | [`RequestHead`](https://nimiq.com/developers/#requesthead) | Get peer's current chain tip | `ResponseHead` | Sync coordination | | **212** | [`RequestChunk`](https://nimiq.com/developers/#requestchunk) | Get accounts trie chunk | `ResponseChunk` | State live sync | | **213** | [`RequestTransactionsProof`](https://nimiq.com/developers/#requesttransactionsproof) | Get transaction inclusion proof | `ResponseTransactionsProof` | Transaction verification | | **214** | [`RequestTransactionReceiptsByAddress`](https://nimiq.com/developers/#requesttransactionreceiptsbyaddress) | Get receipts for address | `ResponseTransactionReceiptsByAddress` | Address queries | | **215** | [`RequestTrieProof`](https://nimiq.com/developers/#requesttrieproof) | Get accounts trie proof | `ResponseTrieProof` | State verification | | **216** | [`RequestBlocksProof`](https://nimiq.com/developers/#requestblocksproof) | Get block inclusion proof | `ResponseBlocksProof` | Block verification | | **217** | [`RequestSubscribeToAddress`](https://nimiq.com/developers/#requestsubscribetoaddress) | Subscribe to address notifications | Success/Error | Live monitoring | | **218** | [`RequestTrieDiff`](https://nimiq.com/developers/#requesttriediff) | Get trie difference for block | `ResponseTrieDiff` | State live sync | --- ### RequestMacroChain Primary mechanism for macro sync phase across all node types. Gets a sequence of macro block hashes for epoch-based sync by providing known macro block hashes (newest to oldest). The responder finds the best-known locator and returns subsequent epochs. Uses `max_epochs` to avoid overwhelming peers. ```rust pub struct RequestMacroChain { /// Blocks known by the requester. pub locators: Vec, /// Limit of epochs to send in response. pub max_epochs: u16, } pub struct MacroChain { /// The hashes of the macro blocks starting at one of the locators of the request. pub epochs: Vec, /// Under certain circumstances, the metadata about the last checkpoint block. pub checkpoint: Option, } ``` **Error handling**: - `UnknownLocators` (try different peer) - `TooManyLocators` (reduce locator count) ### RequestBatchSet Retrieves macro block metadata and history length information for a specific macro block hash. This provides the foundation for subsequent history chunk downloads by telling the requester how much history exists and how it's organized into batches. ```rust pub struct RequestBatchSet { /// The hash of the macro block. pub hash: Blake2bHash, } pub struct BatchSetInfo { pub election_macro_block: Option, pub batch_sets: Vec, } pub struct BatchSet { /// Verifying macro block pub macro_block: MacroBlock, /// Total history length at the height of the specified macro block pub history_len: SizeProof, } ``` Each `BatchSet` provides cumulative history length through `history_len`, enabling calculation of chunk ranges for subsequent `RequestHistoryChunk` calls. **Error handling**: - `TargetHashNotFound` (try different hash or peer) - `MicroBlockGiven` (must use macro block hash) ### RequestHistoryChunk Downloads incremental ranges of historical data using coordinates provided by `RequestBatchSet`. The coordinates specify which portion of the history to retrieve, allowing nodes to download historical transaction data in manageable chunks in parallel from multiple peers to maximize throughput. ```rust pub struct RequestHistoryChunk { pub epoch_number: u32, pub block_number: u32, pub chunk_index: u64, } /// This message contains a chunk of the history. pub struct HistoryChunk { pub chunk: HistoryTreeChunk, } ``` **Error handling**: - `CouldntProduceProof` (chunk data unavailable or corrupted) ### RequestBlock Direct block retrieval by hash with optional body inclusion. The `include_body` flag allows downloading headers-only for light verification or full blocks for complete validation. This is for targeted retrieval when the node knows exactly which block it needs. ```rust pub struct RequestBlock { /// The hash of the block that is requested. pub hash: Blake2bHash, /// Whether to include the body. pub include_body: bool, } ``` Uses `include_body: false` for quick verification, `include_body: true` for full validation or transaction processing. Body inclusion depends on node type specifications and sync requirements. **Error handling**: - `TargetHashNotFound` (block unknown to peer) - `ResponseHashMismatch` (response does not match requested hash) ### RequestMissingBlocks Fills gaps in the blockchain by requesting blocks between known points. Uses locators (newest first) to help peers find the best starting point, then retrieves blocks toward the target hash. ```rust pub struct RequestMissingBlocks { /// Target block hash. pub target_hash: Blake2bHash, /// Whether to include block bodies. pub include_body: bool, /// List of known block hashes, ordered from newest to oldest. /// The responder uses the most recent matching locator to build the response. /// For `Forward` requests, incorrect ordering may lead to unnecessary blocks being returned. pub locators: Vec, /// Search direction for the response: /// - `Forward`: from the first matching locator to the target, always on the main chain. /// - `Backward`: from the target backwards until a locator or macro block is found. /// `Backward` allows retrieving forks but is less efficient for large responses. pub direction: Direction, } ``` Direction determines search strategy. Uses Forward for normal sync, Backward for fork resolution or when retrieving inferior chains. - **Forward**: Searches from best locator to target on main chain only - **Backward**: Searches from target backwards, can include fork blocks **Error handling**: - `TargetBlockNotOnMainChain` (target not on peer's main chain) - `TargetHashNotFound` (target unknown to peer) - `UnknownLocators` (try different peer) - `TooManyLocators` (reduce locator count) - `FailedToGetBlocks` (peer internal error) ### RequestHead Queries a peer's current chain state to determine sync status and consensus alignment. Returns blockchain tip information including block number, hashes, and election state. Primary mechanism for consensus establishment and peer capability assessment. ```rust pub struct RequestHead {} pub struct ResponseHead { pub block_number: u32, pub block_hash: Blake2bHash, pub macro_hash: Blake2bHash, pub election_hash: Blake2bHash, } ``` Polls multiple peers simultaneously to establish network consensus. If 2/3+ peers agree on the same head, consensus is likely established. ### RequestChunk Downloads state trie chunks during live sync to reconstruct the current accounts state. Node specifies a starting key and limit to control chunk size. Used for state live sync to incrementally build the complete state tree from multiple peers in parallel. ```rust pub struct RequestChunk { pub start_key: KeyNibbles, pub limit: u32, } /// The response for trie chunk requests. /// In addition to the chunk, we also return the block hash and number. pub struct Chunk { pub block_number: u32, pub block_hash: Blake2bHash, pub chunk: TrieChunk, } pub enum ResponseChunk { Chunk(Chunk), IncompleteState, } ``` Node requests chunks sequentially using the end key of previous chunk as `start_key` for next request. Use reasonable limits to balance throughput with memory usage. **Error handling**: `IncompleteState` built in the response `enum` ### RequestTransactionsProof Requests cryptographic proofs for specific transactions within a block. Provides transaction hashes and optionally specifies which block to search. Returns proofs that can be verified independently without requiring the full block data. ```rust pub struct RequestTransactionsProof { pub hashes: Vec, pub block_number: Option, } pub struct ResponseTransactionsProof { pub proof: HistoryTreeProof, pub block: Block, } ``` **Error handling**: - `NoTransactionsProvided` (empty hash list) - `TooManyTransactionsProvided` (reduce hash list size) - `RequestedTxnProofFromFuture` (block does not exist yet) - `RequestedTxnProofFromFinalizedEpoch` (use election block instead) - `RequestedTxnProofFromFinalizedBatch` (use checkpoint block instead) - `BlockNotFound` (specified block unknown) - `CouldntProveInclusion` (proof generation failed) - `TransactionNotFound` (transaction not in block) ### RequestTransactionReceiptsByAddress Returns the latest transactions for a given address where the address appears as sender, recipient, or in reward transactions. Supports pagination and result limiting. Transactions are returned in descending order (latest first). ```rust pub struct RequestTransactionReceiptsByAddress { pub address: Address, pub max: Option, pub start_at: Option, } pub struct ResponseTransactionReceiptsByAddress { /// Tuples of `(transaction_hash, block_number)` pub receipts: Vec<(Blake2bHash, u32)>, } ``` Uses `max` to limit response size. Use `start_at` with a transaction hash to retrieve transactions that occurred before that hash. If the `start_at` hash is not found or does not belong to the address, returns an empty list. Results are ordered newest to oldest. **Error handling**: No specific errors (always returns response, potentially empty) ### RequestTrieProof Requests cryptographic proofs for specific account addresses in the accounts trie. Node provides key nibbles (account addresses) and receives a proof that can verify account states without requiring the full trie data. ```rust pub struct RequestTrieProof { /// Addresses for which the accounts trie proof is requested for pub keys: Vec, //-> Accounts } pub struct ResponseTrieProof { // The accounts proof pub proof: TrieProof, // The hash of the block that was used to create the proof pub block_hash: Blake2bHash, } ``` Requests proofs for multiple addresses simultaneously to batch verification. Use reasonable key limits to avoid overwhelming peers with large proof generation tasks. **Error handling**: - `TooManyKeys` (reduce number of addresses requested) - `IncompleteTrie` (peer does not have complete trie state) ### RequestBlocksProof Requests inclusion proofs for specific blocks within an election period. Node provides an election head and list of block numbers, receiving cryptographic proof that those blocks are part of the canonical chain for that election period. Uses `election_head` as the trusted reference point for proof verification. ```rust pub struct RequestBlocksProof { pub election_head: u32, pub blocks: Vec, } pub struct ResponseBlocksProof { pub proof: BlockInclusionProof, } ``` **Strategy**: Only works for finalized epochs (election\_head must be election block). Batch multiple blocks for efficiency. **Error handling**: - `BadBlockNumber` (invalid block number provided) - `TooManyBlocks` (reduce number of blocks requested) ### RequestSubscribeToAddress Manages address subscriptions for real-time transaction notifications. Node can subscribe or unsubscribe from specific addresses to receive notifications when transactions involve those addresses. ```rust pub enum AddressSubscriptionOperation { /// Subscribe to some interesting addresses, to start receiving notifications about those addresses. Subscribe, /// Unsubscribe from some specific addresses, to stop receiving notifications from those addresses Unsubscribe, } pub struct RequestSubscribeToAddress { /// The type of operation that is needed by the peer pub operation: AddressSubscriptionOperation, /// The addresses which are interesting to the peer pub addresses: Vec
, } ``` **Error handling**: - `TooManyPeers` (node is already serving too many subscription peers) - `TooManyAddresses` (node is already monitoring too many addresses) - `InvalidOperation` (invalid subscription operation or parameters) ### RequestTrieDiff Requests state changes (diffs) for a specific block to enable efficient state synchronization. Node provides a block hash and receives only the account changes needed to transition to that block's state, avoiding the need to download complete state trees. ```rust pub struct RequestTrieDiff { pub block_hash: Blake2bHash, } pub enum ResponseTrieDiff { PartialDiff(TrieDiff), UnknownBlockHash, IncompleteState, } ``` Applies diffs sequentially to build state incrementally rather than downloading complete state trees. Enables efficient rollbacks during fork resolution by unapplying diffs in reverse order. **Error handling**: Built into response `enum` (`UnknownBlockHash`, `IncompleteState`) # Traits and Abstractions **Three core traits** form the foundation of the consensus system, creating a pluggable synchronization architecture: - **`MacroSync`** - Gets nodes caught up to current network state - **`LiveSync`** - Keeps nodes synchronized with real-time blocks - **`LiveSyncQueue`** - Defines how the system processes and applies blocks These traits enable the same consensus engine to work with different sync strategies while maintaining consistent coordination patterns. ## Core Trait Hierarchy ### `MacroSync` Different node types need fundamentally different approaches to reach current state. The Macro Sync gets nodes to the latest macro block state using different strategies based on node capabilities. It feeds into `LiveSync` once the system establishes macro state. Coordinated by `Syncer` component. **Key Implementations**: - `HistoryMacroSync` - Downloads complete blockchain history for history nodes - `LightMacroSync` - Trustless macro sync for full and light nodes - `PicoMacroSync` - Optimistic sync with automatic fallback to Light Macro Sync - `EitherSyncer` - Flexible wrapper enabling transition between Pico and Light macro sync strategies, automatically falling back to LightMacroSync when conflicts or limitations are detected during Pico Sync ### `LiveSync` Once caught up with the macro state, all node types need to stay current, but with different data requirements. The `LiveSync` trait manages continuous block announcements and any missing blocks after the macro sync is complete. **Key Implementations**: - `LiveSyncer` - Generic coordinator that delegates to queue strategies. It uses `LiveSyncQueue` implementations to define processing behavior. ### `LiveSyncQueue` Defines how the system processes, buffers, and applies incoming blocks to the blockchain for different node requirements. The same block coordination logic works for all node types, but each node type needs to process and apply the data differently. The `LiveSyncQueue` trait allows the same `LiveSyncer` coordinator to work with different processing strategies. The queue component plugs into `LiveSyncer` to define processing behavior. Determines what data gets requested and how it is applied. **Key Implementations**: - `BlockQueue` - Basic block processing for light/history nodes - `StateQueue` - State chunk coordination for full nodes - `DiffQueue` - Efficient incremental state updates ## Component Map ### Components **`Consensus`** - The central coordinator that determines when the system establishes consensus - Uses `Syncer` for sync coordination, emits `ConsensusEvent` for system state **`ConsensusProxy`** - Thread-safe, cloneable interface to consensus functionality - Provides transaction sending, state querying, and block resolution capabilities **`Syncer`** - Manages macro sync → live sync transitions and peer compatibility - Bridges between different sync phases and handles peer state tracking - Contains `macro_sync` and `live_sync` trait objects for different strategies **`SyncerProxy`** - Enum wrapper that abstracts over different node sync combinations: History/Full/Light/Pico - Each variant contains a `Syncer` with specific `MacroSync` and `LiveSync` implementations **`SyncQueue`** - Generic request coordinator with peer rotation, retry logic, and response verification - Used by all sync implementations for network requests - Maintains ordered response processing with custom verification callbacks **Request Components** - `BlockRequestComponent` - Missing block requests - `ChunkRequestComponent` - State chunk requests - `DiffRequestComponent` - Trie diff requests ### Blockchain Services | Component | Purpose | Key Features | | -------------------------- | ------------------------------- | ------------------------------------------------ | | `RemoteDataStore` | Remote staking contract queries | Merkle proof verification, validator/staker data | | `RemoteEventDispatcher` | Address-based event routing | Client subscriptions, event notifications | | `BlsCache` | BLS key optimization | LRU cache, validator voting key storage | | `HeadRequests` | Consensus peer analysis | Head state tracking, missing block detection | ## Component Interactions ### Event-Driven Communication Components coordinate through event streams rather than direct method calls. The consensus system emits `ConsensusEvent::Established` and `ConsensusEvent::Lost` to signal state changes, while sync components emit `LiveSyncEvent` for block processing and peer status. ### Request Coordination Pattern All sync strategies use `SyncQueue` for reliable peer coordination. When data is needed, sync implementations coordinate requests across multiple peers with automatic retry, peer rotation, and response verification. ### Proxy Pattern Architecture `ConsensusProxy` provides thread-safe access via channels, `SyncerProxy` is an enum wrapper for different sync strategies (History/Full/Light/Pico). ### Stream-Based Processing Key coordination components implement `Stream` trait for async coordination: `MacroSync`, `LiveSync`, `LiveSyncQueue`, and `LiveSyncer`. ### Generic Queue Architecture Same live sync coordination logic works with different processing strategies: `LiveSyncQueue` trait lets `BlockQueue`, `StateQueue`, and `DiffQueue` plug into `LiveSyncer`. ### Fallback Mechanisms `EitherSyncer` enables `PicoMacroSync` → `LightMacroSync` transitions when conflicts are detected. ## TL;DR 1. **`MacroSync`** → Node-specific strategies to reach the latest macro block 2. **`LiveSync`** → Real-time synchronization phase: coordination with specialized queues (`LiveSyncQueue`) for different data requirements 3. **`Consensus`** → Analyzes peer agreement patterns and determines when the node has reached a consistent view of the network state 4. **Request Components** → Network request coordination: manages peer rotation, and retry logic for reliable data retrieval # History Store The History Store is a component of the blockchain that is responsible for recording and maintaining all transactions that have occurred on the blockchain. This system ensures the integrity and traceability of transactions, serving as both a record-keeping and indexing tool. It allows easy retrieval of transactions, such as locating all transactions associated with a specific address. ### Transaction Lifecycle 1. **Transaction submission:** A user creates a transaction and sends it to the network. The transaction is then placed into the validator’s [mempool](https://nimiq.com/developers/protocol/storage/mempool). The mempool temporarily holds pending transactions before they are included in a block. 2. **Transaction validation:** Validators check the validity store to ensure the transaction has not already been included in a block within the validity window. This prevents duplicate transactions. 3. **Block inclusion:** If the transaction is valid, a validator includes it in a new block. Once the block is validated, it is added to the blockchain, officially recording the transaction. 4. **Recording in the History Store:** After a block is added to the blockchain, its transactions are moved to the History Store, becoming historic transactions. These transactions are stored in [MMR](https://nimiq.com/developers/protocol/storage/merkle-trees#merkle-mountain-range) trees, allowing for efficient inclusion proofs. ### History Store The History Store is responsible for keeping track of all transactions that have occurred on the blockchain. It ensures that these transactions are stored to enable efficient proof and retrieval. The History Store includes: 1. **History trees (MMRs):** These trees store the hashes of transactions for each epoch in an MMR structure. They provide a way to prove that a transaction has been included in the blockchain. 2. **Historic transactions:** These are detailed records of transactions, indexed by their epoch number and leaf index. They include additional data, such as block numbers and timestamps, that enable efficient retrieval. 3. **Last leaf index table:** This table keeps track of the last leaf index for each block number, facilitating efficient updates to the MMR. 4. **Validity store:** This component tracks transactions within the validity window and prevents duplicates. Both full and history nodes use it to manage transactions' validity before they are recorded as historic transactions. 5. **Indexing system:** When combined with the indexing system (see below), the History Store enables fast retrieval of specific transactions, allowing nodes to easily query transactions by details such as transaction hash, sender, or recipient. A historic transaction is a representation of a transaction that has already been included in a block. It contains additional information such as the block number, timestamp, and data about the transaction, providing a clear record of when and where each transaction occurred. This distinction is important for tracking and verifying the transaction history accurately. The History Store is connected to each new block through the history tree root, which is updated with every new block. This root can be verified to ensure the integrity of the transaction history. ### Validity Store and Validity Window The validity store is a subcomponent of the History Store used by both full and history nodes to track transactions within the validity window. The validity window is a range of blocks within which a transaction must be included to be considered valid. This mechanism prevents duplicate transactions by ensuring that any given transaction can only be included once within the validity window. ### History Store Index The History Store indexing system was created to enable fast and efficient retrieval of specific transactions from the History Store. While the History Store itself is responsible for recording and maintaining all transactions on the blockchain, the indexing component allows history nodes quick access to this data. Unlike history nodes, full nodes store only one epoch of blockchain data at a time by default, so they do not require the complex indexing functionality that history nodes use. The indexing system maps transaction hashes to their corresponding locations in the History Store, linking them to specific epoch numbers and leaf indices within the MMR trees. This structure allows for the swift identification and retrieval of transactions, even within large datasets. History nodes use this indexing system mainly to serve clients seeking their transaction history, providing efficient retrieval and accurate proof of inclusion. Thanks to the transaction history and indexes maintained by these nodes, the system also supports detailed queries, such as retrieving transactions by sender or recipient address. ### Syncing and Building the History When a node syncs with the network using the [History Macro Sync](https://nimiq.com/developers/protocol/node-sync/macro-sync/history-macro-sync) protocol, it downloads the history for each epoch, which is essential for reconstructing the transaction history up to the blockchain's current state. As the node processes and verifies each macro block, it builds its local History Store by storing historic transactions, organizing them into MMR trees, and updating relevant records. After syncing, the node compares the root of its constructed history tree with the root provided by the current block in the blockchain. If the roots match, it confirms that the node's History Store is accurate and fully synchronized with the network. # Mempool ## What is a mempool? A mempool is a waiting list that keeps [transactions](https://nimiq.com/developers/protocol/transactions) on hold until validators add them to the blockchain. Transactions, once filtered, are gathered in the mempool before being selected by validators for inclusion in the next block. Transactions are broadcasted among the network, and each validator maintains its own mempool. Upon a validator adding a transaction to the blockchain, other validators must remove that transaction from their respective mempools. Every block has a predetermined storage capacity for transactions. Validators are motivated to maximize the number of transactions in a block, as they seek to receive transaction fees. However, validators also have the option to produce empty blocks or blocks with fewer transactions than the storage allows. Our protocol imposes no restriction on the quantity of transactions a block can contain, only that it has a ceiling. Users are encouraged to offer higher fees to accelerate the addition of their transactions to the blockchain. The result of a transaction being added to the mempool is to be then added to the block. The mempool serves the dual purpose of filtering transactions and enabling validators to disregard invalid ones. The blockchain mempool is divided into two groups that hold different types of transactions: - Transactions from the [staking contract](https://nimiq.com/developers/protocol/validators/staking-contract) are added to a **control mempool** - Transactions from basic, HTLC, and vesting [accounts](https://nimiq.com/developers/protocol/accounts) are added to a **regular mempool** Control transactions have priority over regular transactions, so they are first added to the block, followed by regular transactions. ## How is a transaction added to the mempool? A verification process filters transactions before they are added to the mempool. This verification is made orderly, and validators follow this order: - **Signature:** This serves as proof of the sender’s identity. If the signature is not valid, the transaction is disregarded. - **Validity Window:** A specific range of blocks during which a transaction remains valid. After this validity window, the transaction becomes invalid, and validators can disregard it. The starting block height of this window is determined by the specified range. - **Known Transaction:** - In the event of a validator being offline for a period, there's a possibility that upon return, they may attempt to add a transaction to a block that has already been added. To address this, when the validator comes back online, they must download the history sync to receive all transactions from the moment they went offline to the present. Only then can they verify if the transaction they want to include in the block hasn’t already been added. - Another scenario involves a transaction *x* being made, received by all validators, and one validator includes it in a block. The transaction *x* is now considered a known transaction, requiring the other validators to remove it from their individual mempools. - **Balance:** After verifying all necessary steps, the validator checks the user’s balance and all pending transactions for that user in the mempool. The mempool must ensure that the sender has adequate funds to cover at least the transaction fees. Note that if the first step returns an invalid signature, the transaction is immediately discarded, and verifying the following steps is unnecessary as the first was already invalid. This means that if, for example, the signature is not valid, the rest of the steps do not need to be verified, and the transaction is immediately discarded. After the two mempools are fed with transactions respecting the verification process, they are kept on hold and will be added to a block by the elected block producer in the following way: - Control transactions have priority over regular transactions. - Transactions with higher fees have priority over transactions with lower fees (note that this is not the rule. While high fees encourage validators to add the transaction to the block, nothing in the protocol prevents the validator from adding a transaction with low fees) - New transactions have priority over older ones. ![mempool](https://nimiq.com/developers/assets/images/protocol/mempool.png) ::callout{color="info" icon="i-tabler-info-circle"} Note that once the transactions are added to the micro block, they aren’t ordered. The order is made in the mempool. :: After a transaction is added, the user's balance is updated, and the validators must update their mempool accordingly. Note that each validator owns a mempool and broadcasts and verifies transactions constantly. Adding and removing transactions from each mempool is a continuous process. Also, two validators may attempt to add the same transaction to different blocks. In this case, the first transaction to be added is the valid one, and the other validator must discard the respective transaction in their mempool. ## How do transactions become invalid in the mempool? Even after the verification process has been completed and after the transactions have been added to the mempool, transactions may not succeed in being included in a block, as they can become invalid when in the mempool. As transactions are included in the blockchain, validators first verify if: 1. There are **expired transactions**. Similar to the verification step of the validity window, when adding a transaction to the mempool, transactions can expire when on hold. In this case, validators must discard the respective transaction. 2. There is any **transaction already included** in a block. A validator might have included a transaction in a block that other validators haven't detected, or a validator might disconnect from the network, and once reconnecting and downloading the history sync, other validators could already have included that transaction. In this case, as soon as a validator notices the respective transaction, they must discard the one already added. 3. A **fork occurred** somewhere in the chain. Suppose a malicious validator forks the chain, and the following elected block producer is also malicious and produces on top of the fork. Eventually, a rational validator will be selected, and the blocks produced maliciously must be reverted. Based on this, as soon as a rational validator notices the fork, the blocks produced maliciously are no longer valid. There are two ways to fix this: (1) transactions are adopted by other validators, and they include them in a block in the longest chain; validators with the respective transaction in their mempool can discard it, and (2) transactions are reverted and must be re-added to the mempool as they were added in the block produced maliciously. 4. The user's **account balance** has changed between the time the transaction was added to the mempool and the time the transaction was about to be added to the block. Similar to verifying the user's balance before the transaction is added to the mempool, if the user's balance changes in this period, the transaction becomes invalid as the user's balance is insufficient. Validators must update the user's balance in their mempool. # Merkle Trees In the context of blockchain, ensuring data security is paramount. Our blockchain uses a tree-like structure known as [Merkle Trees](https://en.wikipedia.org/wiki/Merkle_tree){rel=""nofollow""} to store accounts and transactions. This approach guarantees that every piece of data is encoded within these trees, ultimately resulting in a single value called the "root." This root value represents the entire dataset and acts as a commitment to the data being stored in the blocks. We use two types of trees in our blockchain system: - **Merkle Radix Tree**: stores accounts and balances - **Merkle Mountain Range**: stores transactions ## Merkle Radix Tree The Merkle Radix Tree is a data structure used in our blockchain system to store and manage accounts and balances efficiently. This tree organizes accounts and their corresponding balances within its leaf nodes, where each leaf node holds the hash of a single account. Merkle Radix Trees are significantly different from standard Merkle Trees. Leaf nodes with similar prefixes are paired up, while leaf nodes with unique prefixes are called “only child” nodes. Parent nodes in the tree can have multiple children or just one child. When a parent node has only one child, it merges with that child node, optimizing space within the tree. Likewise, as parent nodes can have an only child node, parent nodes can also have up to 16 children. Below is a simplified illustration of a Merkle Radix Tree. ![Diagram of a Merkle Radix Tree showing merged branches](https://nimiq.com/developers/assets/images/protocol/merkle.png) When constructing the tree, nodes with similar prefixes are paired to form parent nodes, optimizing space by reducing the number of intermediate nodes. If a node does not have a sibling with a similar prefix, it becomes an "only child" node and is merged with its parent node, further optimizing space within the tree. The process of merging adjacent nodes and creating parent nodes continues iteratively until a single hash value remains at the topmost layer of the tree. This hash value, known as the state root, represents the entire tree's integrity and serves as proof of the accounts' validity when stored in every block header. ## Merkle Mountain Range A Merkle Mountain Range (MMR) is another type of Merkle Tree used in our blockchain, specifically for storing transactions. MMRs are optimized to handle large datasets by organizing transactions into a hierarchical set of trees, collectively forming what is referred to as a "mountain range.” In Nimiq, the root hash of the MMR, known as the "history root," is stored in every block header and is the cryptographic proof of the transaction history up to that point, providing an immutable record of transactions. Transactions are hashed and stored as leaf nodes. As transactions are appended to the MMR, their hashes are combined and hashed together with adjacent leaf nodes to form intermediate hashes. These intermediate hashes are then recursively combined and hashed with other intermediate hashes and adjacent leaf nodes until reaching the topmost level of the tree structure. MMRs are designed to efficiently append new transactions without restructuring the entire tree. When a new transaction occurs, its hash is appended to the MMR as a new leaf node, always added to the tree's rightmost part. As MMRs include a set of trees within, each tree hash root is called a “peak”. To calculate the final root of the tree, the peaks are hashed from the right, combining their hash values to construct the root hash. These peaks, representing the root hash values of individual trees within the MMR, also serve as reference points for subsets of transaction data. Note that due to the nature of the MMR, it is possible to have a sub-tree consisting of just one node. Below is a simplified illustration of an MMR with 3 sub-trees. ![Diagram of a Merkle Mountain Range with three peaks](https://nimiq.com/developers/assets/images/protocol/mmr.png) Unlike Merkle Radix Trees where accounts and balances undergo constant updates, MMRs do not require direct data updates. In case a block is reverted, transactions are deleted from the transaction history, and new transactions are appended as new blocks come in. ### Peaks-only Merkle Mountain Ranges The "peaks-only MMR" is a special MMR variant in our blockchain that is exclusive to full nodes. Only the peaks of the MMR are stored, while all other intermediate nodes and leaf nodes are removed. This approach allows full nodes to store only the necessary data to prove the history root, significantly reducing storage requirements. They do not need to store the entire transaction history represented by the MMR, which is computationally heavy. This special MMR serves as a lightweight and efficient solution for verifying the integrity of transaction data. By storing only the peak nodes, full nodes can significantly reduce the amount of data they need to retain while still being able to prove the correctness of transaction computations. Full nodes can compare the computed history root against the current block history root to verify the blockchain's integrity. # Transactions Transactions modify the state of the Nimiq blockchain according to protocol rules and enable value transfers and contract interactions. These transactions are stored in the micro block's body. This document provides a technical overview of transaction structure, common transaction issues, transaction finality, and system operations known as inherents in the Nimiq blockchain. ## Types of Accounts Nimiq supports four types of accounts, each designed for different purposes: - **Basic Account**: The most commonly used account for standard transactions between individuals or entities - **Hashed Time-Locked Contract (HTLC)**: Handles conditional transfers, such as atomic swaps, based on cryptographic conditions and time constraints - **Vesting Contract**: Manages funds released gradually over time, often used to lock funds with a defined release schedule - **Staking Contract**: Enables validators to lock their NIM, participate in network consensus, and earn rewards Each account type processes transactions differently to meet its specific use case. For more details, refer to the [accounts](https://nimiq.com/developers/protocol/accounts) documentation. ## Transaction Prioritization and Mempool Transactions are first placed in the mempool, waiting for validation. Nimiq has two mempools: - **Regular Mempool**: For basic, HTLC, and vesting transactions - **Control Mempool**: For staking transactions, which are prioritized Once selected by a validator, transactions are validated and included in a block if they meet the protocol’s requirements. For more details on how the mempool operates, refer to the [mempool](https://nimiq.com/developers/protocol/storage/mempool) documentation. ## Transaction Structure | **Field** | **Data Type** | **Description** | | ----------------------- | ------------------ | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | | `sender` | `Address` | The sender’s address | | `sender_type` | `AccountType` | Specifies the [type](https://nimiq.com/developers/#types-of-accounts) of the sender account | | `sender_data` | `Vec` | Additional data specific to the sender account’s type, primarily used for extra info in transactions from the [staking contract](https://nimiq.com/developers/protocol/validators/staking-contract) | | `recipient` | `Address` | The recipient’s address | | `recipient_type` | `AccountType` | Specifies the type of the recipient account | | `recipient_data` | `Vec` | Additional data specific to the recipient account. Used in transactions involving contracts such as staking, HTLCs, and vesting contracts. | | `value` | `Coin` | The amount of NIM to transfer. This field can be zero for transactions that do not transfer value but interact with the staking contract | | `fee` | `Coin` | The fee paid by the sender for the transaction. Validators earn this fee as part of the block rewards for including the transaction in the blockchain as an incentive | | `validity_start_height` | `u32` | The block height from which the transaction becomes valid. A transaction can be submitted before this height, but will only be eligible for inclusion once the blockchain reaches this height. If not included in a block within the window of 120 blocks after, the transaction will expire | | `network_id` | `NetworkId` | Specifies the network (Mainnet, Testnet) on which the transaction is valid to ensure the transaction is only processed on the correct network | | `flags` | `TransactionFlags` | Flags that indicate special transaction types, such as contract creation or signaling | | `proof` | `Vec` | A cryptographic proof, generated by signing the transaction data with the sender’s private key, which authenticates the sender | **Additional Considerations** - **Variations in Transaction Structure**: Different account types (basic, HTLC, vesting, staking) may have variations in their transaction structure. These variations ensure that each account type processes transactions according to its specific purpose and function within the protocol - **Incoming and Outgoing Transactions**: The network distinguishes between incoming and outgoing transactions. **Incoming transactions** are related to operations within an account, such as adding stake or creating an account. **Outgoing transactions** involve external account operations that affect the network state, such as deleting a validator or removing stake - **Zero-Value Transactions**: Staking transactions can have a zero `value` field for contract interaction without fund transfer - **Serialization and Deserialization**: Transactions are **serialized** to reduce size for transmission and **deserialized** by nodes for validation and processing across the network For a deeper dive into the transactions and serialization specifics, refer to the document [Albatross Transaction Serialization](https://gist.github.com/sisou/33ece69190cf38f884b1781ad9d5a106){rel=""nofollow""}. ## Transaction Flow and Potential Issues Transactions go through multiple stages of verification before being added to a block, and there are potential issues that might arise at each stage: 1. **Transaction Builder Errors**: These occur when creating a transaction and required fields (such as the sender, recipient, or value) are missing or invalid 2. **Transaction Errors**: These errors happen when the transaction is submitted to the network, where the transaction fails checks like invalid proof, wrong network, or serialization errors 3. **Failed Transactions**: Even after the previous steps have been successfully verified with no errors, a transaction can fail if the sender lacks sufficient funds to cover the transaction value or the fees ### Transaction Builder Errors Deals with missing or invalid fields when creating transactions. If any of the following errors occur, the transaction will not even be sent: - **No Sender**: The sender address is missing from the transaction - **No Recipient**: The recipient address is missing. A valid recipient must be provided - **No Value**: The transaction value (amount to be transferred) is missing - **No Validity Start Height**: The transaction’s validity start height, which defines from when the transaction becomes valid, is not set - **No Network ID**: The transaction’s network ID is missing. The ID identifies which network the transaction is intended, whether Testnet or Mainnet - **Invalid Sender**: The sender is not valid for the recipient - **Invalid Value**: For signaling transactions, the value must be zero, whereas other transactions require a non-zero value. This error is triggered when the value does not match the requirements for the specific transaction type ### Transaction Error Deals with transaction execution issues when it is submitted to the network: - **Foreign Network**: The transaction is intended for a network other than the one it was submitted to (a transaction for the Testnet being submitted to the Mainnet) - **Zero Value**: The transaction’s value is set to zero when it’s not allowed. Transactions that transfer funds must have a non-zero value unless they are specific contract interactions that permit zero-value transactions - **Invalid Value**: The value of the transaction is not valid for the specific operation being attempted (incorrect value for contract-related transactions) - **Overflow**: The transaction causes an overflow in calculations, due to large values that cannot be processed - **Sender Equals Recipient**: The sender and recipient of the transaction are the same which is not allowed - **Invalid For Sender**: The transaction is not valid for the sender’s account type or current state - **Invalid Proof**: The cryptographic proof for the transaction is incorrect, meaning the transaction was not correctly signed by the sender - **Invalid For Recipient**: The transaction is not valid for the recipient’s account type or current state - **Invalid Data**: The transaction contains invalid data, which could refer to incorrect parameters or malformed data fields - **Invalid Serialization**: There is an issue with the serialization of the transaction, typically occurring during the encoding or decoding process ### Failed Transactions The final verification of a transaction occurs before it enters the mempool. Even if it passes earlier stages, it can fail if the sender lacks sufficient funds. Validators ensure the sender can cover the transaction fees before adding it to the mempool. If the sender does not even have enough for the fees, the transaction is deemed invalid and not processed. Including a transaction in a block may succeed or fail: - **Successful**: The sender has enough funds to cover both the transaction value and fees, and the user's balance is updated - **Failed**: The sender has insufficient funds to pay out the transaction value but transaction fees can be deducted **Example Scenario** Consider a scenario where Alice has 100 NIM in her balance. She sends 3 transactions: - **Transaction 1**: Alice sends 80 NIM to Bob. Since she has sufficient funds (80 NIM + fees), this transaction succeeds, and both the value and fees are deducted from her account - **Transaction 2**: Alice attempts to send 50 NIM to Charlie immediately after. Since her remaining balance is insufficient to cover both the value and fees, this transaction fails, but the transaction fees are still deducted - **Transaction 3**: Alice tries to send another transaction but does not have enough NIM to cover the fee. In this case, the transaction is deemed **invalid** and is not processed by the network. Neither the value nor the fees are deducted ## Transaction Finality Finality is periodically reinforced through the Tendermint protocol, which ensures that blocks and the transactions within them cannot be reversed once they are finalized by a macro block. For more details on how finality is achieved through the block structure, please refer to the [block format](https://nimiq.com/developers/protocol/consensus/block-format) documentation. ## Inherents In addition to user-initiated transactions, Nimiq also processes **inherents**—system-generated operations that modify the blockchain’s state without requiring a transaction from a user. These are used for tasks like distributing rewards and enforcing punishments, ensuring network stability. **Key Characteristics of Inherents:** - **No Account Interaction**: Inherents don’t originate from user accounts or affect balances - **System-Driven**: These operations are generated by the protocol itself based on network rules and conditions - **No Signature Requirement**: Inherents don’t require digital signatures for validation. There are 5 types of inherents in the Nimiq protocol: - **Reward**: Automatically issued to validators who successfully fulfill their assigned slots without misbehavior - **Penalty**: Applied to validators who delay block production. The penalty removes their reward for the slot, and the validator can be deactivated - **Jail**: Enforced when validators are involved in severe misbehavior, such as double voting or creating forks. In this case, all of their slots are punished, and the validator is jailed, preventing further participation in the network for 8 epochs - **Finalize Batch**: Triggered at the end of each batch of micro blocks, marking its completion - **Finalize Epoch**: Occurs at the end of an epoch, marking a significant period in the blockchain's state updates. This ensures that all transactions and state changes for the epoch are finalized and the validator list is updated # Skip Blocks Skip blocks are a special type of [micro block](https://nimiq.com/developers/protocol/consensus/block-format#micro-blocks) in the consensus protocol. When a validator fails to produce a block within the expected timeframe, the remaining elected validators can collectively agree to add a skip block instead of the missing micro block. This prevents delays and ensures the blockchain progresses smoothly. Once a supermajority of elected validators agrees to add the skip block, the chain resumes its regular progression. The primary purpose of skip blocks is to ensure blockchain continuity by serving a structural role rather than a transactional one. Unlike micro blocks, which process transactions, skip blocks are like placeholders that prevent interruptions when a validator fails to produce a block. Skip blocks are canonical, meaning their structure is strictly determined by the protocol. For any given block, the skip block that follows is determined by the protocol rules. Once a skip block is added, the chain resumes regular micro block production with one validator per block. There is no maximum limit on the number of skip blocks, as skip blocks adapt to the chain’s continuity. ### Skip Block and Micro Block Differences Skip blocks are a special type of micro block, but because they do not hold transactions, there are some key differences. Below are the main differences between a skip block and a regular micro block: | **Feature** | **Skip Block** | **Micro Block** | | ----------------- | --------------------------------------------------------------------------------- | ------------------------------------------------------------------------------------------------ | | **Body** | Empty - skip blocks have no transactions or equivocation proof data | Contains transaction data and possibly equivocation proofs | | **Body Root** | The `body_root` field in the block header is the hash of the empty body | The `body_root` is the hash of the body, which includes the transactions and equivocation proofs | | **Timestamp** | Derived from the previous block’s timestamp plus a fixed duration (4 seconds) | Generated based on the block’s production time by the assigned producer | | **Extra Data** | Must be empty to ensure the skip block is canonical | Can include additional data as required by the transactions or block producer | | **VRF Seed** | Inherits the VRF from the previous micro block without introducing new randomness | A new VRF seed is generated by the block producer introducing new randomness | | **Justification** | Aggregated signatures from multiple validators | Single signature from the assigned producer | | **Producer** | No specific producer; multiple validators attest to the skip block | Block producer selected to produce the block | ![skip block comparison to micro blocks](https://nimiq.com/developers/assets/images/protocol/skip-micro.png){.object-contain.max-h-[max(80vh,220px)]} ### How is the Skip Block Added? A skip block is an agreement among validators to confirm they did not see a micro block in the expected timeframe. The block’s justification consists of the aggregated signatures from the validators. The process goes as follows: 1. The elected validator fails to produce a micro block within the expected timeframe 2. Upon noticing the missing block, any validator can create a skip block locally 3. Validators each create and sign their skip block, then share their signatures with peers 4. When at least 2*f*+1 signatures are collected, they are aggregated into the skip block proof 5. The skip block is added and the chain resumes regular block production with the next validator. If the next validator fails, the process above repeats **There are only two outcomes for a delayed micro block:** - Receive 2*f*+1 signatures to a skip block, add it to the chain, and resume block production - Wait to receive a micro block; if a validator does not receive a skip block, it means that at least 2*f*+1 validators saw the expected micro block, and the remainder should receive it shortly ### Validator Penalty for Misbehavior A delay in block production is considered a minor offense. When a validator fails to produce a micro block in time, the associated slot is marked to not receive rewards, which are burned as a penalty. This delay also results in the deactivation of the validator slot, although it can reactivate itself after one block. For more information on this misbehavior, see the [punishments](https://nimiq.com/developers/protocol/consensus/punishments#block-production-delay) document. # Slots Validators are selected from the validator set to integrate the following validator list based on their initial stake. Validators that have deposited a higher stake increase their chances of being selected for the upcoming epoch. At the end of an epoch, the block leader proposes a new validator list in the election macro block, including the group of validators eligible to participate in the consensus. Upon selection, validators are assigned a certain number of slots, which serve as the means to produce blocks. The allocation of slots to a validator depends on the NIM they have deposited in the staking contract. Validators participate in the consensus process by producing micro blocks, proposing and voting for macro blocks, attesting to malicious behavior from other validators, and thus ensuring an agreement on the current blockchain state. Validators use their slots in the following way: - One slot is used to produce one micro block - One slot is used to propose a macro block - All validators’ slots are used to vote for a macro block proposal or a [skip block](https://nimiq.com/developers/protocol/validators/skip-blocks) | Validator address | Validator pubkey | Range of slots | | ----------------- | ---------------- | -------------- | | Validator 1 | pubkey 1 | (0, 24) | | Validator 2 | pubkey 2 | (25, 84) | | Validator 3 | pubkey 3 | (85, 149) | | Validator 4 | pubkey 4 | (150, 254) | | Validator 5 | pubkey 5 | (255, 304) | | Validator 6 | pubkey 6 | (305, 321) | | Validator 7 | pubkey 7 | (322, 361) | | Validator 8 | pubkey 8 | (362, 436) | | Validator 9 | pubkey 9 | (437, 481) | | Validator 10 | pubkey 10 | (482, 512) | Due to the redistribution of the slot owner list with every micro block, it is impossible to anticipate which validator will be responsible for producing the next block. The same validator may end up producing three consecutive blocks if the range is extensive. For instance, based on the above figure, if slots 151, 170, and 237 were chosen to produce the following three blocks, the resulting range would correspond to validator 4. Note that whether a validator signs a block with slot x or y, it uses its validator key. Validators do not have keys per slot but keys per validator. ## Validators List Selection The list of validators for the next epoch is initially chosen in the election block that closes the previous epoch. The block leader generates this list using entropy from the VRF seed of the previous block. The new list contains the validators for the new epoch, along with the distribution of slots for each validator, given a range. ## Slot Owner Selection Subsequently, to select the producer of the first block of the epoch, the entropy of the VRF seed of the previous block is used to shuffle the validator list. This slot owner list is randomly generated for every micro block, determining the producer of the upcoming micro block. ## Random Seed Generation The VRF seed serves two purposes for validator selection: providing the randomness needed to select validators based on their stake and determining the slot owners for block production. The initial random seed is generated from an external source at the genesis block. Subsequently, for generating random seeds for subsequent blocks, the protocol relies on the [VXEDdSA](https://www.signal.org/docs/specifications/xeddsa/#vxeddsa){rel=""nofollow""} algorithm implemented as a verifiable random function. In addition to producing and proposing blocks, validators are also responsible for generating the random seed included in every block. The random seed from the election macro block is used to generate the validator list for the epoch, while the random seed from the previous block is used to reallocate slots and elect the slot owner for each micro block. # Stakers A staker delegates its NIM to a validator, which validates blocks on its behalf. Validators handle the reward distribution off-chain. This document explains how the staking process works, the functions available to stakers, and the conditions and rules that govern these states. ::div{.columns} :::div ### Stake States **Active**: Funds actively participating in staking **Inactive**: Funds temporarily inactive, not actively participating, awaiting either reactivation or retirement **Retired**: Funds permanently marked for withdrawal, not participating in staking anymore **Removed**: Funds completely withdrawn from the staking contract ::: :::div ### Balances **Active balance**: The portion of the staker's funds currently used by the validator as stake **Inactive balance**: The portion of the staker's funds that is not currently being used as stake and is locked for a period or inactive **Retired balance**: The portion of the staker's funds that exists but is ready to be removed from the staking contract **Non-retired balance**: The sum of the active and inactive balances **Total balance**: The sum of the active, inactive, and retired balances ::: :: ### State Transitions | From State | To State | Conditions/Notes | | ---------- | -------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ | | Active | Inactive | During this period, funds are locked and cannot be moved or withdrawn. The lock-up period accounts for any potential misbehavior by a validator. The released block is the block at which this period ends, and the staker funds are fully released if no jailing occurs | | Inactive | Active | Immediate transition | | Inactive | Retired | Can retire a specific amount if leaving a balance greater than the minimum stake in active + inactive. To retire all, move all active + inactive to retired | | Retired | Removed | Remove all funds in the retired balance; partial removal is not allowed. Funds can only be removed after they have been retired | Stakers must wait through the reporting window or the remaining jail period of the validator, whichever is longer, to inactivate their funds. The inactive balance can only be released after the lock-up period or the validator's jail period has passed. If the validator is not jailed, stakers must wait for one epoch of reporting window counting from the next election block. **Examples** - Suppose a validator has a remaining jail period of 3 epochs and the reporting window is 2 epochs. In that case, the staker must wait for 3 epochs (the longer period) before the funds are released. - If 1 epoch remains of the jailing period while the reporting window can last up to 2 epochs, the staker must wait for the full reporting window period before the funds are released, as the longest release block prevails. ### Transactions **Create Staker** Creates a new staker with a specified address and optional delegation. If no validator is added, the staker is not actively delegating its stake to a validator and thus is not eligible to receive rewards. The initial stake (minimum 100 NIM) is placed in the active balance. **Add Stake** Adds coins to the staker’s active balance from any external address. The resulting non-retired funds must meet the minimum stake requirements. **Set Active Stake** Sets the desired active stake, which automatically adjusts the inactive balance accordingly. For example, if a staker has 500 NIM and sets the active stake to 300 NIM, the inactive stake will be adjusted to 200 NIM. The inactive balance then becomes locked to account for potential validator misbehavior. **Update Staker** Updates the validator address to which the stake is delegated. This process involves several steps: 1. The staker must set the active stake to 0, making all non-retired funds inactive 2. The staker must wait for the inactive balance to be released, which involves waiting for one epoch + the blocks left in the current epoch 3. Once the inactive funds are released, the staker can update the validator address 4. Finally, the staker needs to return the inactive stake to active as desired Alternatively, stakers have an option in their configuration to activate a setting that automatically reactivates their stake after the reporting window time when executing this transaction. **Retire Stake** Moves funds from inactive to retired balance, making them eligible for withdrawal. Only inactive funds released (post lock-up period) can be retired. A staker can either retire all the non-retired stake or leave at least the minimum stake in the non-retired balance; otherwise, the transaction fails. **Remove Stake** Withdraws the retired balance from a staker's account, removing it from the staking contract. The transaction must remove the entire retired balance; partial removals are not allowed. If the total balance drops to zero, the staker's account is deleted. Transactions to activate, inactivate, and update stakes only take effect at the next election block. This is because validator balances, which include staker balances, cannot be changed during an epoch. For update and set active stake transactions, the reporting window time begins when the transaction is sent, but the changes to the funds are only reflected in the validator's balance at the next election block. ![stakers states](https://nimiq.com/developers/assets/images/protocol/stakers-state.png){.object-contain.max-h-[max(80vh,220px)]} ### Invariants There is a set of invariants or rules that ensure the transactions mentioned above do not fail. The following table outlines these key invariants and the transactions they affect: | Invariant | Description | Affected Transactions | | --------------------------------------------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | -------------------------------------------------------- | | Minimum stake for non-retired balances | Active + inactive balances must be equal to or greater than the minimum stake if the non-retired balance is not zero | Create Staker, Add Stake, Set Active Stake, Retire Stake | | Minimum stake for total balances | Total balance (active + inactive + retired) must be equal to or greater than the minimum stake if the total balance is not zero | Create Staker, Add Stake, Retire Stake | | Inactive balance and block height association | An associated block height is required for any inactive balance | Set Active Stake, Update Staker, Retire Stake | | Validator lock periods | Inactive funds are subject to lock periods based on validator status. If the validator is jailed, the longest period between the reporting window and the jail period applies | Set Active Stake, Update Staker, Retire Stake | ### Edge Cases **Resetting the reporting window**: When a staker updates their inactive stake, the reporting window counter resets. For example, if there were 5 blocks left, it would reset at the next election block plus one epoch. This ensures that any potential misconduct by the validator during the initial period is still accounted for, maintaining the integrity of the staking process. **Immediate inactivation and retirement without a validator**: If a staker does not have a validator associated with them and wants to inactivate and retire their stake, they can do so immediately. Without an associated validator, there is no lock on their funds. **Removing stake requirements**: A staker can only remove their stake by completely withdrawing all the funds in the retired balance. The staker must first move all desired stake from active to inactive, then retire it before they can remove it. Partial removal from the retired balance is not allowed. However, a staker can retire a specific amount and leave a balance greater than the minimum stake in the non-retired states. **Waiting period with validator in tombstone**: If a validator is in a tombstone, the staker still needs to wait the reporting window to inactivate their stake. **Updating staker with jailed validator**: If a staker updates their delegation (with inactive funds) to a new validator that is jailed, they can still convert their funds to active. However, the system treats these funds as if they were attached to the validator when the jailing occurred, so the staker must wait for the release (the longer between the reporting window or the jailed period). The staker’s funds will be considered jailed even if they were inactive when the validator misbehaved. **Adding stake with zero balance**: If the staker's active and inactive balances are zero and the staker sends an add stake transaction, they must add more than the minimum stake; otherwise, the invariant is violated. # Staking Contract The staking contract is a special contract serving as a central repository for the data related to validators, stakers, and the staking process. It is initially hardcoded at the genesis block, and thereon, any modification in the balances or state of validators and stakers is updated at every block by validators. Any node on Nimiq's blockchain with a wallet and stake can propose to become a validator or a staker. The **staking contract** includes three fields: ```rust pub struct StakingContract { pub balance: Coin, pub active_validators: BTreeMap, pub punished_slots: PunishedSlots, } ``` ## Balance The `balance` field represents the total amount of coins staked within the `StakingContract`. This includes not only the validators' deposits but also the coins delegated by the stakers. ## Active Validators Validators marked as active. All the validator nodes in the network that *can* be elected as block producers for upcoming epochs, as well as the ones that are actively participating in the block production. This set is stored in a binary tree map that efficiently organizes active validators and their corresponding balances. This structure ensures that only eligible validators, those qualified to receive slots, are included. In cases of misbehavior, validators can either be deactivated or jailed based on the severity of their offense, leading to their removal from this set. Nonetheless, a validator can be excluded from this set and continue to participate in block production until the epoch concludes, as there is no mid-epoch voting process to substitute the validator slots necessary for the consensus. ## Punished Slots The slots marked as punished. Depending on the nature of their misbehavior, validators may have either one slot or all slots marked as punished. The `punished_slots` set keeps track of these punished slots for both the current and previous batch. In the reward distribution phase, the staking contract cross-verifies slots from the previous batch's `punished_slots` to identify and burn rewards linked to those specific slots. Additionally, at every macro block, the staking contract determines the block producers for the next batch. Slots marked as punished are excluded from consideration in the selection of block producers for subsequent batches. ## Staking Contract Account The staking contract is part of the AccountsTrie and serves as a subtrie containing different account types, each responsible for storing specific staking-related data. The distinct path to each account simplifies navigation within the staking contract subtrie, enabling easy access to various pieces of information. The subtrie follows the outlined format: ![Alt Text](https://nimiq.com/developers/assets/images/protocol/staking-contract-path.png) # Validator Keys Validators hold a set of keys in order to participate in the consensus. Besides a validator address, which serves as the validator’s identifier, validators hold three key pairs: a cold, a warm, and a hot key pair. These keys enable validators to sign several transactions. A key pair consists of public and private keys, mathematically linked. The private key is used for authentication by the validator, while the corresponding public key is used to validate the authenticity of the validator. Validators use their private key to sign transactions. Then anyone can verify the validity of such a transaction by using the validator's corresponding public key. For a node to become a validator, it must generate an address and a set of keypairs. Validators also own a fee key from a basic account, which has the sole purpose of paying `automatic_reactivate` transaction fees. To learn how to generate these keys, click [here](https://nimiq.com/developers/nodes/validators/becoming-a-validator#generating-your-validator-address-and-keys). The [Schnorr](https://en.wikipedia.org/wiki/Schnorr_signature){rel=""nofollow""} signature scheme is used for generating the cold and warm key pairs, providing simplicity and short signatures. The [BLS](https://en.wikipedia.org/wiki/BLS_digital_signature){rel=""nofollow""} signature scheme is used for the hot key for signature aggregation and voting efficiency. ## Cold Key - The validator’s address is derived from the cold public key - The cold private key is used for the validator to sign create, update and delete transactions ## Warm Key - The warm public key is stored in the validator as the `signing_key` - The warm private key is used for the validator to sign reactivate, and deactivate transactions - The warm private key is also used for the validator to sign micro blocks, macro block proposals and generate random seeds ## Hot Key - The hot public key is stored in the validator as the `voting_key` - The hot private key is used for the validator to vote for macro block proposals and skip blocks ### Why So Many Keys? Having 3 key pairs for validators adds layers of security and reduces the chance of compromising each key. Validators use their keys to sign blocks, vote for block proposals, and send staking contract transactions. The terminology of hot, warm, and cold keys outlines the frequency of key usage. The hot key is used more often and readily accessible for regular use. While still used regularly, the warm key is less frequently accessed. On the other hand, the cold key is meant to be kept offline and used less often, making it less susceptible to potential attacks. The `update` transaction allows the validator to update its keys in case they are compromised. However, the cold key is immutable, and, by extension, so is the validator’s address. # Validators Validators are the block producers of PoS blockchains. They are responsible for processing and validating transactions, block validation, and maintaining the integrity of the network. Their primary function is to preserve the network's consensus by agreeing on the current state. By maintaining consensus and actively participating in the network, validators earn rewards in the form of transaction fees and block rewards. However, any attempt to undermine the consensus, such as through misbehavior or malicious actions, results in punishments, including burning their rewards and/or jailing, effectively removing them from network participation for a defined period. To become a validator in the Nimiq blockchain, a node must have a Nimiq wallet and create a validator node. A minimum deposit of 100'000 NIM is required to ensure the validator remains active, prevent block production delays, and discourage malicious behavior. This deposit also discourages the creation of validator accounts that could be abandoned and take up unnecessary network resources. Each validator has its own account. Once the node sends a transaction to create an account in the staking contract as a validator, the following data is associated with the validator: | Data | Type | Description | | ---------------- | --------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------- | | `address` | `Address` | The unique address of the validator, used for creating, updating, or deleting the validator | | `signing_key` | `SchnorrPublicKey` | Key used to sign micro blocks | | `voting_key` | `BlsPublicKey` | Key used for voting on skip blocks and macro blocks | | `reward_address` | `Address` | Address where block rewards are sent | | `signal_data` | `Option` | Optional field for chain upgrades or other coordination among validators | | `total_stake` | `Coin` | Total stake assigned, including validator’s deposit and stakers’ delegated funds | | `deposit` | `Coin` | The validator's own deposit; can be decreased by fees from failed transactions (see [transactions](https://nimiq.com/developers/protocol/transactions)) | | `num_stakers` | `u64` | Number of stakers delegating to this validator | | `inactive_from` | `Option` | Block height at which the validator becomes inactive | | `jailed_from` | `Option` | Block height at which the validator was jailed. Takes immediate effect to prevent fund removal | | `retired` | `bool` | Indicates if the validator is retired, in which case it can only delete | ## Transactions Validators interact with the network by sending various transactions, each designed to manage their status, update data, or change their state deliberately. These transactions include creating a new validator, updating its details, and managing states such as deactivation, reactivation, or retirement. Receipts are issued to authenticate each transaction, ensuring transparency and security. Additionally, if one or more blocks are reverted, these transactions can also be reverted. Below, we describe each transaction and its impact on the validator’s lifecycle. ### Create Creates a new validator with an initial deposit that equals the validator's stake. The deposit is locked in the contract and can only be retrieved by deleting the validator. Validators must provide a signing key, voting key, reward address, and optional signal data. ### Update Allows the validator to update details such as the signing key, voting key, reward address, and signal data. The validator must be active to apply these changes. ### Deactivate This transaction moves the validator to an inactive state, where it no longer participates in block validation. Deactivation is scheduled to take effect at the next [election block](https://nimiq.com/developers/protocol/consensus/block-format#macro-blocks), meaning that the validator continues to be active until the next scheduled election. Deactivation is a necessary step before a validator can be retired or deleted. Moreover, if a validator remains offline for an extended period, it is deactivated and loses any rewards for the time it remains inactive. ### Jail A validator is jailed immediately after an equivocation proof is submitted accounting for the misbehavior, such as double-signing blocks or attempting to fork the chain. The jailing process also deactivates the validator if it is not already inactive. The validator remains jailed until the jailing period is served, ensuring it cannot participate or tamper with its funds during this time. ### Reactivate A validator can send this transaction to reactivate from the inactive state. Once the punishment period has ended (whether penalized for delaying block production or jailed), or if the validator is inactive for other reasons, this transaction reactivates the validator. The validator must meet certain conditions to be reactivated: - Must be inactive - Must not be retired - Must not be jailed at the time of reactivation Reactivation restores the validator's ability to participate in block validation and earn rewards. Note that this transaction is unnecessary if the validator has the `automatic_reactivate` setting enabled. ### Retire Retiring a validator is an irreversible action that prevents further participation. It is the first step in the process of deleting a validator. Once a validator is retired, it cannot be reactivated. Retirement involves transitioning the validator to an inactive state, if it is still active, and preparing it for eventual deletion. ### Delete This transaction permanently removes a retired validator from the network and returns the validator's deposit. A validator can only be deleted after completing a cooldown period and if all delegations have been withdrawn. If there are still stakers, a tombstone record is created to track the remaining stake until all stakers withdraw their funds. Tombstones ensure that stakers can retrieve their stake even after the validator is no longer active, safeguarding the network’s economic integrity. ### Additional Considerations 1. **Jailing:** Even when jailed, validators must continue participating in specific votes (skip blocks and macro blocks) to fulfill the 512 votes requirement and maintain network stability 2. **State Transition Delays:** Most state changes, especially those involving deactivation and reactivation, align with election blocks to prevent disruption during the epoch 3. **Finality on Retirement:** Once a validator enters the retired state, it cannot revert to any other state except deletion, ensuring a straightforward exit process from active validation. ### Punishments If a validator delays block production, the **penalty** is the burning of rewards for that specific block, reducing the validator's earnings. For more severe offenses, validators face **jailing**, which locks them out of participation for a defined period. During this lock-up period, validators cannot participate in block validation, though they may still be required to participate in voting until the end of the epoch. Validators can only return to active status once the jailing period is served. For more detailed information on punishments, refer to [Nimiq's punishments documentation](https://nimiq.com/developers/protocol/consensus/punishments). ## States ![validators states](https://nimiq.com/developers/assets/images/protocol/validator-state.png){.object-contain.max-h-[max(80vh,220px)]} **Active:** Actively participating in block validation and earning rewards **Inactive:** Temporarily not participating in validation but can be reactivated **Jailed:** Punished for severe misbehavior, temporarily banned from block production, but may still need to participate in voting (skip blocks and macro blocks) **Retired:** Marked for permanent inactivity and pending deletion **Deleted:** Permanently removed from the network, but if there are stakers still associated with the validator, a tombstone is created to manage the remaining stake and stakers until they are cleared ## Validator Deletion Process Removing a validator is a process that ensures the network has time to detect and report any misbehavior. The following table outlines each transaction involved and the conditions under which they take effect: | **Transaction** | **Description** | **Effective Timing** | **Notes** | | --------------- | ---------------------------------------------------------- | -------------------------------------------------- | ---------------------------------------------------------------------------------------------------------------------------------------- | | **Deactivate** | Marks the validator as inactive. | Takes effect at the start of the next epoch. | Validator cannot be elected in the next epoch. Triggers the reporting window, which lasts until the end of the next epoch (current + 1). | | **Retire** | Marks the validator as retired. Required before deletion. | Can be submitted after the reporting window ends. | **Irreversible.** Once retired, validator cannot return to active state. | | **Delete** | Deletes the validator and returns the 100'000 NIM deposit. | After retirement and once all funds are withdrawn. | Only allowed after the reporting window ends. If stake remains, a tombstone record manages withdrawals. | ::callout{color="info" icon="i-tabler-info-circle"} **Note** If the validator has active stakers at the time of deletion, a tombstone is created to allow those stakers to switch to a different validator or withdraw their stake. :: # Nimiq Blockchain Explorers Explore Nimiq blockchain data, transactions, addresses, and network statistics through community-built explorers. :blockchain-explorers # Nimiq RPC Client ::u-page-section --- description: Start experimenting with the Nimiq RPC API. headline: Quick Start title: Jump right in --- :::u-page-grid ::::u-page-card --- description: Explore all available RPC methods and try them directly in the browser icon: i-tabler:book-2 title: Browse RPC Methods to: https://nimiq.com/developers/rpc/methods variant: outline --- :::: ::::u-page-card --- description: Use public servers for testing and development icon: i-tabler:server title: Open RPC Servers to: https://nimiq.com/developers/rpc/open-servers variant: outline --- :::: ::::u-page-card --- description: Learn how to connect with a CLI, TypeScript, or HTTP icon: i-tabler:code title: Integrations variant: outline --- :::: ::: :: ::u-page-section --- description: The Nimiq RPC API is ideal for servers, exchanges, analytics platforms, and any service needing reliable blockchain connectivity. headline: Why RPC API title: Perfect for backend integration --- :::u-page-grid ::::u-page-card --- description: Direct access to all Nimiq blockchain data and operations icon: i-tabler:database title: Full Node Access variant: outline --- :::: ::::u-page-card --- description: Standard protocols for easy integration with any tech stack icon: i-tabler:api title: RESTful & JSON-RPC variant: outline --- :::: ::::u-page-card --- description: WebSocket subscriptions for live blockchain events icon: i-tabler:broadcast title: Real-Time Updates variant: outline --- :::: ::::u-page-card --- description: 120+ RPC methods covering all blockchain operations icon: i-tabler:layers-linked title: Comprehensive Methods variant: outline --- :::: ::::u-page-card --- description: Fully typed client libraries for TypeScript icon: i-tabler:shield-check title: Type-Safe Clients variant: outline --- :::: ::::u-page-card --- description: High availability and performance icon: i-tabler:server title: Production Ready variant: outline --- :::: ::: :: ::callout{icon="i-tabler:bot" to="https://nimiq.com/developers/ai/mcp"} **Build with AI using the Developer Center** \--- Connect assistants to the built-in MCP server and AI docs in the dedicated AI section. :: ::u-page-section --- description: Discover the full range of RPC methods available for interacting with the Nimiq blockchain. headline: RPC Methods title: Explore the API --- | Category | Methods | Description | | :--------------- | :----------------------------------------------------------------------- | :------------------------------------- | | **Blockchain** | `getBlockByNumber`, `getBlockByHash`, `getLatestBlock` | Access block data and chain state | | **Accounts** | `getAccountByAddress`, `getBalance` | Query account information and balances | | **Transactions** | `getTransactionByHash`, `getTransactionsByAddress`, `sendRawTransaction` | Handle transaction operations | | **Validators** | `getValidators`, `getValidatorByAddress`, `getSlotAt` | Access validator and staking data | | **Network** | `getNetworkInfo`, `getEpochNumber` | Monitor network status and consensus | :::u-button --- class: rounded-full color: primary label: View All RPC Methods to: https://nimiq.com/developers/rpc/methods trailing-icon: i-tabler:arrow-up-right --- ::: :: # Nimiq RPC with ARPL CLI Tool Command-line interface for node management, accounts, staking, and validators. Albatross Remote (ARPL) provides comprehensive Nimiq node management through an intuitive CLI. ## Documentation & Usage For complete documentation, installation instructions, and all available methods, visit the official repository: ::u-button --- class: mt-4 rounded-full color: primary icon: i-simple-icons:github label: View ARPL Repository target: _blank to: https://github.com/sisou/arpl trailing-icon: i-tabler:arrow-up-right --- :: # Nimiq RPC with JavaScript Pure JavaScript using fetch API and WebSocket - runtime agnostic. Use standard JavaScript APIs for RPC calls without additional dependencies. ::callout{color="info" icon="i-tabler-info-circle"} **Using Open RPC Servers** The examples below use `rpc.nimiqwatch.com`, an open RPC server for testing and development. [Learn more about available open servers and their limitations](https://nimiq.com/developers/rpc/open-servers). :: --- ## Basic Request ```javascript const response = await fetch('https://rpc.nimiqwatch.com', { method: 'POST', headers: { 'Content-Type': 'application/json' }, body: JSON.stringify({ jsonrpc: '2.0', method: 'getAccount', params: ['NQ07_0000_0000_0000_0000_0000_0000_0000_0000'], id: 1 }) }) const { result } = await response.json() console.log('Balance:', result.balance) ``` --- ## WebSocket Subscription ```javascript const ws = new WebSocket('wss://rpc.nimiqwatch.com/ws') ws.onopen = () => { ws.send(JSON.stringify({ jsonrpc: '2.0', method: 'subscribeForLogsByAddresses', params: [['NQ07_0000_0000_0000_0000_0000_0000_0000_0000']], id: 1 })) } ws.onmessage = (event) => { const data = JSON.parse(event.data) console.log('New transaction:', data.params) } ``` # Nimiq RPC Raw HTTP/WebSocket Requests Direct calls using curl, wget, or any HTTP client - no dependencies required. Perfect for quick testing, shell scripts, or integrating with any programming language that supports HTTP requests. For better UX, we recommend you to use [ARPL](https://nimiq.com/developers/rpc/integrations/arpl), a tool to interact with Nimiq RPC servers from the command line. ::callout{color="info" icon="i-tabler-info-circle"} **Using Open RPC Servers** The examples below use `rpc.nimiqwatch.com`, an open RPC server for testing and development. [Learn more about available open servers and their limitations](https://nimiq.com/developers/rpc/open-servers). :: ## Request ```bash curl -X POST https://rpc.nimiqwatch.com \ -H "Content-Type: application/json" \ -d '{ "jsonrpc": "2.0", "method": "getTransactionsByAddress", "params": ["NQ07_0000_0000_0000_0000_0000_0000_0000_0000", 500], "id": 1 }' ``` --- ## WebSocket Subscription ```bash # Install websocat: brew install websocat (or download from GitHub) echo '{"jsonrpc":"2.0","method":"subscribeForHeadBlockHash","params":[],"id":1}' | \ websocat wss://rpc.nimiqwatch.com/ws ``` # Nimiq RPC With TypeScript Client Fully typed client with IntelliSense, error handling, and production features. ## Installation {.mt-16} ::code-group ```bash [npm] npm install nimiq-albatross-rpc-client ``` ```bash [yarn] yarn add nimiq-albatross-rpc-client ``` ```bash [pnpm] pnpm add nimiq-albatross-rpc-client ``` ```bash [bun] bun add nimiq-albatross-rpc-client ``` :: ## Documentation & Usage For complete documentation, installation instructions, and all available methods, visit the official repository: ::u-button --- class: mt-4 rounded-full color: primary icon: i-simple-icons:github label: View TypeScript Client Repository target: _blank to: https://github.com/onmax/albatross-rpc-client-ts trailing-icon: i-tabler:arrow-up-right --- :: # RPC Methods Explore all available JSON-RPC methods for interacting with the Nimiq blockchain. Each method provides full documentation, parameters, return types, and interactive examples. :rpc-methods-grid # Open RPC Servers Public Nimiq RPC servers available for testing, development, and prototyping. ## Available Open Servers > For current information about rate limits, uptime, supported methods, and service status, visit each server's status page. :rpc-open-servers ::callout{color="info" icon="i-lucide-users"} **Share Your Node with the Community** Set up your own Nimiq node and consider making it available as an open RPC server to help other developers in the ecosystem. [Setup Guide](https://nimiq.com/developers/nodes/validators/becoming-a-validator) :: ## General considerations for open servers ### Production usage - Not suitable for production applications. - No uptime guarantees or service level agreements. - May experience throttling during peak usage. - Method availability may change without notice. ### Data privacy - All requests *may* be logged for monitoring purposes. - Do not send sensitive information through open servers. - Consider IP addresses and request data as potentially visible to operators. --- *Open servers are community-provided resources. Always verify data independently for critical applications.* # Exposing a Nimiq Node over JSON-RPC This guide walks through enabling the built-in JSON-RPC server that comes with the Nimiq client. Follow the steps in order. ## Prerequisites - Rust toolchain installed (for `cargo run` / `cargo build`). - A synced or syncing Nimiq node (follow the [core-rs-albatross configuration guide](https://github.com/nimiq/core-rs-albatross?tab=readme-ov-file#configuration){rel=""nofollow""} if you still need to set one up). - A second terminal window so you can keep the node running while you send RPC calls. ## Build the client binary ```bash cargo build --release --bin nimiq-client ``` ## Run once to create the config folder Start the client briefly to scaffold `~/.nimiq` and the example config: ```bash cargo run --release --bin nimiq-client ``` On a fresh setup the binary terminates with a `Config file not found` error after writing `~/.nimiq/client.example.toml`; that message is expected. Once you create a configuration for your node, the same command keeps the node running. ## Create a config file that enables RPC Copy the template that was just generated and rename it to `client.toml`: ```bash cp ~/.nimiq/client.example.toml ~/.nimiq/client.toml ``` Edit the file with: ```bash nano ~/.nimiq/client.toml ``` Locate the `[rpc-server]` section, uncomment it, and replace the placeholders in this minimal configuration with your actual values: ```toml [rpc-server] bind = "127.0.0.1" # Use "0.0.0.0" to listen on every interface port = 8648 # Change if the port is taken methods = [] # Empty list = expose every RPC method username = "rpc-user" # Replace with your username password = "super-secret" # Replace with a strong password cors_domains = [] # Needed only when browser apps access the node ``` ::callout{icon="i-tabler-bulb"} Need a quick tour of the RPC surface? Run the helper CLI from the repository root `cargo run --release --bin nimiq-rpc -- -h` . :: ## Start the node with the config Launch the client and keep it running in its own terminal: ```bash cargo run --release --bin nimiq-client -- --config ~/.nimiq/client.toml ``` ## Test the RPC endpoint from another terminal Replace the placeholders with your real host, port, and the credentials you configured. ```bash curl http://: \ -u : \ -H 'Content-Type: application/json' \ -d '{"jsonrpc":"2.0","method":"getPeerCount","params":[],"id":1}' ``` A successful response looks like: ```json { "jsonrpc": "2.0", "result": { "data": 49, "metadata": null }, "id": 1 } ``` ## Quick Reference **Terminal 1** - Build once (optional): `cargo build --release --bin nimiq-client` - Start and keep running: `cargo run --release --bin nimiq-client -- --config ~/.nimiq/client.toml` **Terminal 2** - Send RPC calls while Terminal 1 keeps the node alive: ```bash curl http://127.0.0.1:8648 -u rpc-user:super-secret -H 'Content-Type: application/json' -d '{"jsonrpc":"2.0","method":"getPeerCount","params":[],"id":1}' ``` - Repeat with other methods as desired. Browse the full list at [RPC Methods](https://nimiq.com/developers/rpc/methods). ## Example RPC calls The examples below assume the node is running and syncing Mainnet. Update the placeholders before executing the commands. 1. **Peer count** ```bash curl http://127.0.0.1:8648 \ -u rpc-user:super-secret \ -H 'Content-Type: application/json' \ -d '{"jsonrpc":"2.0","method":"getPeerCount","params":[],"id":1}' ``` :brExample response: ```json { "jsonrpc": "2.0", "result": { "data": 49, "metadata": null }, "id": 1 } ``` 2. **Latest block header** ```bash curl http://127.0.0.1:8648 \ -u rpc-user:super-secret \ -H 'Content-Type: application/json' \ -d '{"jsonrpc":"2.0","method":"getLatestBlock","params":[true],"id":2}' ``` :brExample response: ```json { "jsonrpc": "2.0", "result": { "data": { "hash": "446cd813...d8ee27d", "number": 31232849, "timestamp": 1759491166072, "producer": { "validator": "NQ00 0123 ..." }, "transactions": [] }, "metadata": null }, "id": 2 } ``` 3. **Account information** ```bash curl http://127.0.0.1:8648 \ -u rpc-user:super-secret \ -H 'Content-Type: application/json' \ -d '{"jsonrpc":"2.0","method":"getAccountByAddress","params":["NQ00 0123 ..."],"id":3}' ``` :brExample response: ```json { "jsonrpc": "2.0", "result": { "data": { "address": "NQ00 0123 ...", "balance": 62294498429, "type": "basic" }, "metadata": { "blockNumber": 31232842, "blockHash": "ebcfc8d8...5393cb1" } }, "id": 3 } ``` Replace the placeholder credentials (`rpc-user` / `super-secret`) in the examples with the values you set in `client.toml` before running the commands. ## Troubleshooting - **`Config file not found`** – Ensure `~/.nimiq/client.toml` exists and the path passed to `--config` is correct. - **`Method not allowed`** – Add the method name to the `methods` list or leave it empty to expose every RPC call. - HTTP 401 – Username/password mismatch. Update the credentials in your request or in `client.toml` and restart the node. # Using the Nimiq Web Client Across JavaScript Runtimes Learn how to integrate the Nimiq Albatross light client in any JavaScript environment – from browsers to servers to edge runtimes. ## Overview The Nimiq Albatross light client is distributed as `@nimiq/core` on npm and comes with three optimized WebAssembly builds, each tailored for different JavaScript environments: | Build Target | Import Path | Best For | Key Features | | ------------- | ----------------- | ------------------------------------------ | --------------------------------------------- | | **`bundler`** | `@nimiq/core` | Webpack, Vite, Rollup, esbuild | Automatic WebAssembly loading via bundler | | **`web`** | `@nimiq/core/web` | Vanilla browsers, Cloudflare Workers, Deno | Manual initialization with `init()` | | **`nodejs`** | `@nimiq/core` | Node.js ≥ 16, Bun | Synchronous loading, no initialization needed | > **Why multiple builds?** Each JavaScript runtime handles WebAssembly differently. These builds ensure optimal loading and performance for your specific environment. --- The package includes the WebAssembly binary and TypeScript declarations – no additional build steps required. ## Browser Environments ### Vanilla JavaScript (ES Modules) For direct browser usage without a bundler, use the `/web` export: ```html ``` ::callout{color="info" icon="i-tabler-info-circle"} The `await init()` call is mandatory with the web build. :: ### Hosting the WebAssembly File When serving your application from a CDN, ensure the `nimiq_core_bg.wasm` file is accessible: ```js // Automatic: loads from same directory as the JS file await init() // Manual: specify exact URL await init('/cdn/path/to/nimiq_core_bg.wasm') ``` Modern browsers cache WebAssembly binaries, so this only adds one network request on first load. ## Bundler Integration ### Modern Bundlers (Vite, Rollup, esbuild) These bundlers handle WebAssembly automatically: ```js import * as Nimiq from '@nimiq/core' const config = new Nimiq.ClientConfiguration().build() const client = await Nimiq.Client.create(config) ``` ## Server Environments ### Node.js Node.js uses the synchronous build – no initialization needed: ```js import * as Nimiq from '@nimiq/core' const config = new Nimiq.ClientConfiguration().build() const client = await Nimiq.Client.create(config) ``` ::callout{color="info" icon="i-tabler-info-circle"} **Why no `init()`?** The Node.js build reads the WebAssembly file directly from disk synchronously. :: ::callout --- icon: i-tabler:help-circle to: https://github.com/nimiq/developer-center/issues --- **Need help with a different environment?** — We're here to help you integrate Nimiq with any JavaScript runtime or deployment platform. :: ## Additional Resources - [Nimiq Core Package on npm](https://www.npmjs.com/package/@nimiq/core){rel=""nofollow""} - [WebAssembly Build Targets Documentation](https://rustwasm.github.io/wasm-pack/book/commands/build.html#target){rel=""nofollow""} - [Node.js WebAssembly Documentation](https://nodejs.org/api/wasi.html){rel=""nofollow""} # How the Light Client Works The Nimiq Web Client is a light client — a node that participates in the blockchain network without storing the full chain history. It connects directly to other peers, syncs enough state to verify the current chain tip, and gives your application access to account balances, recent transactions, and real-time block events. It runs as WebAssembly in browsers and as a native module in Node.js. ## Sync modes The client supports two sync modes. You choose one at configuration time via `ClientConfiguration.syncMode()`. | Mode | How it syncs | Trust model | Best for | | :------------------ | :------------------------------------------------------------------------------------------------------------------------------------------------------------ | :------------------------------------------------------------------ | :----------------------------------------------------------------------------------------------------------- | | **Light** (default) | Downloads and verifies the chain of election block headers using the validators' signatures, then follows subsequent micro block headers in real time. | Cryptographically verified — no trust in individual peers required. | Production applications where security matters. | | **Pico** | Downloads only the latest election block and trusts connected peers optimistically. Falls back to light sync automatically if a conflicting peer is detected. | Trust-based with automatic fallback to trustless sync. | Development, testing, and fast prototyping where startup speed matters more than cryptographic verification. | Both modes transition to [block live sync](https://nimiq.com/developers/protocol/node-sync/live-sync/block-live-sync) once the initial sync is complete, following new blocks as they are produced. For a deeper look at the sync protocols, see the [node sync documentation](https://nimiq.com/developers/protocol/node-sync). ## Consensus "Consensus established" means the client is confident it has an accurate view of the current chain state. For a light client, this requires: - At least **3 connected peers** - Initial sync completed (macro sync phase finished) - One of: - **Network activity**: the client has accepted 5 or more block announcements that extend its local chain - **Peer agreement**: the client knows the head block of at least 2/3 of its connected peers, and they agree Once consensus is established, `waitForConsensusEstablished()` resolves and the client is ready to serve queries and broadcast transactions. If the client loses enough peers or detects a chain reorganization, consensus can be lost and re-established. You can monitor consensus state changes with `addConsensusChangedListener()`. ## What the client can access A light client stores micro block **headers only** — no block bodies, no transaction payloads for past blocks. This determines what data your application can and cannot query. **Available:** - Current account state — balances, account types, nonces — via `getAccount()` and `getAccounts()` - Current validator and staker data via `getValidator()` and `getStaker()` - Recent transactions involving a specific address via `getTransactionsByAddress()` - The current head block height and hash - Real-time events: new blocks, consensus changes, peer changes, and transactions for watched addresses - Network state: peer count, connection status **Not available:** - Block bodies (transactions) for past blocks — the client only has headers - Arbitrary historical blocks — `getBlock()` fails if the block is not in local memory - Past account state at a specific block height — only the current state is queryable - Full transaction history from genesis — queries are bounded by `sinceBlockHeight` If your application needs full historical data or block bodies, use the [RPC interface](https://nimiq.com/developers/rpc) with a full node or history node instead. See [Web Client vs RPC](https://nimiq.com/developers/web-client/concepts/web-client-vs-rpc) for a comparison. ## How it connects to the network The client is a peer in the Nimiq network — not a consumer of a server API. It establishes direct WebSocket connections to other nodes and participates in the peer-to-peer protocols: - **Bootstrap**: connects to seed nodes on startup to discover initial peers - **Peer discovery**: learns about additional peers from connected nodes and maintains an address book - **Block gossip**: receives block announcements as they are produced - **Transaction broadcast**: sends signed transactions directly to the network You can configure peer behaviour through `ClientConfiguration`: | Setting | Default | What it controls | | :-------------------------- | :--------------- | :------------------------------------------------- | | `desiredPeerCount()` | 12 | Target number of connected peers | | `peerCountMax()` | 50 | Maximum number of peer connections | | `onlySecureWsConnections()` | `true` | Require WSS (secure WebSocket) connections | | `seedNodes()` | Network defaults | Override the default seed nodes (Multiaddr format) | ## Further reading - [Node sync architecture](https://nimiq.com/developers/protocol/node-sync) — the full sync protocol specification - [Light macro sync](https://nimiq.com/developers/protocol/node-sync/macro-sync/light-macro-sync) — the trustless light macro sync protocol - [Pico macro sync](https://nimiq.com/developers/protocol/node-sync/macro-sync/pico-macro-sync) — the trust-based fast sync protocol - [Browser vs Server](https://nimiq.com/developers/web-client/concepts/browser-vs-server) — runtime-specific differences when using the client # Web Client vs RPC Nimiq offers two ways to interact with the blockchain: the **Web Client** and **RPC**. They differ in architecture, infrastructure requirements, and language support. The Web Client is a light node — it joins the peer-to-peer network directly and syncs with other peers. RPC follows a client-server model: your application sends HTTP requests to a Nimiq node, which interacts with the network on your behalf. ![Web Client vs RPC](https://nimiq.com/developers/assets/images/protocol/network.png) ## Web Client The [Web Client](https://nimiq.com/developers/web-client) is a JavaScript library compiled from Rust to WebAssembly. It runs in browsers and Node.js, connects directly to the blockchain network, and requires no server infrastructure. It supports account queries, transaction creation and broadcasting, wallet management, and real-time event subscriptions. See the [guides](https://nimiq.com/developers/web-client/guides/query-the-blockchain) for what you can build with it. ## RPC [RPC](https://nimiq.com/developers/rpc) exposes a Nimiq node's full functionality over HTTP using the JSON-RPC specification. It works from any programming language that can send HTTP requests. RPC provides everything the Web Client does, plus full node control: managing accounts, configuring node settings, retrieving detailed blockchain state, and managing validator operations. ## Comparison | Aspect | Web Client | RPC | | ------------------ | ------------------------------------------------------ | ----------------------------------------------------------------------------------------------------------- | | **Architecture** | Peer-to-peer, joins the network directly | Client-server, connects to your node | | **Infrastructure** | None — runs in the browser or Node.js | Requires running a Nimiq node | | **Languages** | JavaScript / TypeScript | Any language with HTTP support | | **Functionality** | Light client operations: queries, transactions, events | Full node control: all light client operations plus node management, validator operations, advanced queries | | **Use cases** | Wallets, browser dApps, payment flows, mobile apps | Block explorers, analytics, server applications, validator management | ## When to use each **Choose Web Client when:** - Building browser-based or mobile-friendly applications - You want zero infrastructure — no server to run or maintain - Working in JavaScript / TypeScript - Building decentralized applications where users connect directly **Choose RPC when:** - Building server-side applications or backend services - You need full node control or validator management - Working in languages other than JavaScript - Building block explorers, analytics tools, or data pipelines ## Start building ::u-page-grid :::u-page-card --- title: Web Client icon: i-lucide-globe to: /web-client variant: outline --- ::: :::u-page-card --- icon: i-lucide-terminal title: Nimiq RPC to: https://nimiq.com/developers/rpc variant: outline --- ::: :::u-page-card --- icon: i-lucide-shield-check title: Validators to: https://nimiq.com/developers/nodes/validators/becoming-a-validator variant: outline --- ::: :: ## Further reading - [Nimiq Albatross protocol documentation](https://nimiq.com/developers/protocol) — consensus algorithm, block structure, network protocol - [How the Light Client Works](https://nimiq.com/developers/web-client/concepts/how-the-light-client-works) — what the Web Client can and cannot access # Faucet The Nimiq Faucet provides **testnet NIM only** and is intended for development and testing purposes. Accessible via a web interface or a simple API, it ensures you have the resources to deploy contracts and simulate real-world scenarios cost-free. ## Interactive Playground Paste a **testnet** Nimiq address in the interface below to request funds. :faucet-playground ## Network Details The faucet currently supports the Nimiq Testnet, offering unlimited requests to facilitate continuous integration and development workflows. | Feature | Testnet | | :--------------- | :------------------------------------- | | **URL** | `https://faucet.pos.nimiq-testnet.com` | | **Max Amount** | 10,000 NIM | | **Rate Limit** | Unlimited | | **Intended Use** | Development, CI/CD, Stress Testing | ## API Reference Developers can interact with the faucet programmatically via HTTP requests. This is particularly useful for automated testing pipelines. **Endpoint:** `POST https://faucet.pos.nimiq-testnet.com/tapit` ### Parameters The endpoint accepts a `application/x-www-form-urlencoded` body with the following parameters: | Parameter | Type | Required | Description | | :-------- | :------- | :------- | :--------------------------------------------------------------------- | | `address` | `string` | **Yes** | The recipient's Nimiq address in User-Friendly format (e.g., `NQ...`). | | `amount` | `number` | No | The amount of NIM to request. Defaults to `10000`. :br Max: `10000`. | ### Response The API returns a JSON object indicating the result of the operation. ```json { "success": true, "msg": "Sent 10000 NIM to NQ07 0000..." } ``` ## Integration Examples Implement the faucet in your application or scripts using standard HTTP clients. ::code-group ```ts [TypeScript] interface FaucetResponse { success: boolean msg: string } async function requestFunds(address: string, amount: number = 10000): Promise { const params = new URLSearchParams({ address, amount: amount.toString() }) const response = await fetch('https://faucet.pos.nimiq-testnet.com/tapit', { method: 'POST', headers: { 'Content-Type': 'application/x-www-form-urlencoded' }, body: params }) return await response.json() } // Usage const result = await requestFunds('NQ07 0000 0000 0000 0000 0000 0000 0000 0000') console.log(result) ``` ```js [JavaScript] async function requestFunds(address, amount = 10000) { const params = new URLSearchParams({ address, amount: amount.toString() }) const response = await fetch('https://faucet.pos.nimiq-testnet.com/tapit', { method: 'POST', headers: { 'Content-Type': 'application/x-www-form-urlencoded' }, body: params }) return await response.json() } // Usage const result = await requestFunds('NQ07 0000 0000 0000 0000 0000 0000 0000 0000') console.log(result) ``` ```python [Python] import requests def request_funds(address, amount=10000): url = "https://faucet.pos.nimiq-testnet.com/tapit" data = { "address": address, "amount": amount } response = requests.post(url, data=data) return response.json() # Usage result = request_funds("NQ07 0000 0000 0000 0000 0000 0000 0000 0000") print(result) ``` ```sh [curl] curl -X POST https://faucet.pos.nimiq-testnet.com/tapit \ -d "address=NQ07 0000 0000 0000 0000 0000 0000 0000 0000" \ -d "amount=10000" ``` :: ### Faucet Status You can query the faucet's current status, including its balance and configuration limits. **Endpoint:** `GET https://faucet.pos.nimiq-testnet.com/info` ::code-group ```ts [TypeScript] async function getFaucetInfo() { const response = await fetch('https://faucet.pos.nimiq-testnet.com/info') return await response.json() } // Usage const info = await getFaucetInfo() console.log(info) ``` ```js [JavaScript] async function getFaucetInfo() { const response = await fetch('https://faucet.pos.nimiq-testnet.com/info') return await response.json() } // Usage const info = await getFaucetInfo() console.log(info) ``` ```python [Python] import requests def get_faucet_info(): url = "https://faucet.pos.nimiq-testnet.com/info" response = requests.get(url) return response.json() # Usage info = get_faucet_info() print(info) ``` ```sh [curl] curl -s https://faucet.pos.nimiq-testnet.com/info ``` :: ### Response Data | Field | Type | Description | | :------------------- | :-------- | :---------------------------------------------------------------------- | | `network` | `string` | The network identifier (e.g., `test`). | | `address` | `string` | The Nimiq address of the faucet itself. | | `balance` | `number` | The current NIM balance available in the faucet. | | `dispenseAmount` | `number` | The default dispense amount in NIM. | | `dispensesRemaining` | `number` | Estimated number of dispenses remaining based on current balance. | | `availableInRegion` | `boolean` | Whether the faucet is available in the requester's geographical region. | **Example Response:** ```json { "network": "test", "address": "NQ...", "balance": 123456.78, "dispenseAmount": 110, "dispensesRemaining": 1122, "availableInRegion": true } ``` # Getting Started This guide takes you from zero to a connected Nimiq light client. By the end you'll have a running client synced with the network and test NIM to experiment with. ## Install ::code-group ```bash [pnpm] pnpm add @nimiq/core ``` ```bash [npm] npm install @nimiq/core ``` ```bash [yarn] yarn add @nimiq/core ``` ```bash [bun] bun add @nimiq/core ``` :: If you're using a framework like Vite, Nuxt, or Next.js, see the [integration guides](https://nimiq.com/developers/web-client/integrations/vite) for bundler-specific configuration. ## Pick a network Nimiq runs three networks. Choose the one that fits your current task: | Network | Use for | Network ID | | :---------------- | :----------------------------------------------------- | :-------------- | | **TestAlbatross** | Development and testing. Free test NIM via the faucet. | `TestAlbatross` | | **MainAlbatross** | Production. Real NIM, real transactions. | `MainAlbatross` | | **DevAlbatross** | Local development and protocol work. | `DevAlbatross` | Start with **TestAlbatross** — it behaves like mainnet but costs nothing. ## Connect Create a client and wait for it to sync with the network: ::code-group ```js [browser.js] import init, * as Nimiq from '@nimiq/core/web' await init() const config = new Nimiq.ClientConfiguration() config.network('TestAlbatross') const client = await Nimiq.Client.create(config.build()) await client.waitForConsensusEstablished() console.log('Connected! Head block:', await client.getHeadHeight()) ``` ```js [Node.js] import Nimiq from '@nimiq/core' const config = new Nimiq.ClientConfiguration() config.network('TestAlbatross') const client = await Nimiq.Client.create(config.build()) await client.waitForConsensusEstablished() console.log('Connected! Head block:', await client.getHeadHeight()) ``` :: Once `waitForConsensusEstablished()` resolves, your client is synced and ready to query the blockchain, listen for events, and send transactions. ## Get test funds The [Nimiq Faucet](https://nimiq.com/developers/web-client/faucet) dispenses free NIM on TestAlbatross for development and testing. You can request funds through the interactive playground on the [Faucet page](https://nimiq.com/developers/web-client/faucet), or programmatically: ```sh curl -X POST https://faucet.pos.nimiq-testnet.com/tapit \ -d "address=NQ07 0000 0000 0000 0000 0000 0000 0000 0000" ``` The faucet sends 10,000 NIM per request with no rate limit. See the [Faucet API reference](https://nimiq.com/developers/web-client/faucet#api-reference) for details on parameters and response format. ## You're ready You have a synced client and test funds. Here's where to go next: - [Query the Blockchain](https://nimiq.com/developers/web-client/guides/query-the-blockchain) — fetch balances, blocks, and transaction status - [Listen for Events](https://nimiq.com/developers/web-client/guides/listen-for-events) — subscribe to blocks, transactions, and consensus changes - [Create and Manage Wallets](https://nimiq.com/developers/web-client/guides/wallets) — generate keypairs and derive addresses - [Send Transactions](https://nimiq.com/developers/web-client/guides/send-transactions) — build, sign, and broadcast NIM transfers - [Stake NIM](https://nimiq.com/developers/web-client/guides/stake-nim) — delegate to validators and manage your stake # Listen for Events The web client can notify your application when things happen on the blockchain — new blocks, incoming transactions, peer changes, and consensus state transitions. All listeners are asynchronous and return a numeric handle you can use to unsubscribe later. The examples below assume you have a connected `client` instance. See [Getting Started](https://nimiq.com/developers/web-client/getting-started) if you haven't set one up yet. ## Listen for new blocks `addHeadChangedListener` fires every time the client adopts a new block. The callback receives the block hash, the reason for the change, and arrays of reverted and adopted blocks (relevant during chain reorganizations). ```js const handle = await client.addHeadChangedListener((hash, reason, revertedBlocks, adoptedBlocks) => { console.log('New head:', hash, 'reason:', reason) console.log('Adopted:', adoptedBlocks.length, 'Reverted:', revertedBlocks.length) }) ``` This is useful for updating UI state, refreshing balances, or triggering background work whenever the chain advances. ## Track transactions for an address `addTransactionListener` fires when a transaction involving any of the provided addresses is included in the blockchain. The callback receives the full transaction details. ```js const handle = await client.addTransactionListener( (transaction) => { console.log('Transaction:', transaction.sender, '→', transaction.recipient) console.log('Value:', transaction.value, 'luna') }, ['NQ07 0000 0000 0000 0000 0000 0000 0000 0000'], // addresses to watch ) ``` You can watch multiple addresses at once by passing them all in the array. The listener fires for both incoming and outgoing transactions. ## Monitor consensus state `addConsensusChangedListener` fires when consensus is established or lost. Use this to show connection status in your UI or to pause operations that depend on an up-to-date chain view. ```js const handle = await client.addConsensusChangedListener((state) => { console.log('Consensus state:', state) }) ``` See [How the Light Client Works](https://nimiq.com/developers/web-client/concepts/how-the-light-client-works#consensus) for what "consensus established" means for a light client. ## Track peer changes `addPeerChangedListener` fires when peers connect or disconnect. Useful for monitoring network health. ```js const handle = await client.addPeerChangedListener((peerId, reason, peerCount, peerInfo) => { console.log('Peer', peerId, reason, '— total peers:', peerCount) }) ``` ## Remove a listener Every `add*Listener` method returns a numeric handle. Pass it to `removeListener()` to unsubscribe: ```js const handle = await client.addHeadChangedListener((hash) => { console.log('New head:', hash) }) // Later, when you no longer need the listener: await client.removeListener(handle) ``` ## Next steps - [Create and Manage Wallets](https://nimiq.com/developers/web-client/guides/wallets) — generate keys to start signing transactions - [Send Transactions](https://nimiq.com/developers/web-client/guides/send-transactions) — build and broadcast NIM transfers - [API Reference](https://nimiq.com/developers/web-client/reference) — full callback signatures and return types # Query the Blockchain Once your client has [established consensus](https://nimiq.com/developers/web-client/getting-started), you can query the blockchain for account data, blocks, and transactions. All operations in this guide are read-only — no keys or signing required. The examples below assume you have a connected `client` instance. See [Getting Started](https://nimiq.com/developers/web-client/getting-started) if you haven't set one up yet. ## Fetch an account balance Every Nimiq address has an associated account. Use `getAccount()` to fetch its current state, including the balance in luna (1 NIM = 100,000 luna). ```js const account = await client.getAccount('NQ07 0000 0000 0000 0000 0000 0000 0000 0000') console.log(account.type) // 'basic', 'vesting', or 'htlc' console.log(account.balance) // balance in luna ``` To fetch multiple accounts in a single call: ```js const accounts = await client.getAccounts([ 'NQ07 0000 0000 0000 0000 0000 0000 0000 0000', 'NQ15 0000 0000 0000 0000 0000 0000 0000 0000', ]) for (const account of accounts) { console.log(account.address, account.balance) } ``` ## Get the current head block The head block is the most recent block the client knows about. ```js // Just the height const height = await client.getHeadHeight() // Just the hash const hash = await client.getHeadHash() // The full block (header only — light clients don't have block bodies) const block = await client.getHeadBlock() console.log(block.height, block.hash, block.timestamp) ``` You can also fetch a specific block by hash or height, but only if the client has it in local memory. Light clients do not store historical blocks — see [How the Light Client Works](https://nimiq.com/developers/web-client/concepts/how-the-light-client-works) for details. ```js const block = await client.getBlockAt(12345) // throws if not available locally ``` ## Look up a transaction If you know a transaction hash, you can fetch its details: ```js const tx = await client.getTransaction('abcdef1234567890...') console.log(tx.sender, tx.recipient, tx.value, tx.state) ``` ## Query transactions for an address To get recent transactions involving a specific address: ```js const transactions = await client.getTransactionsByAddress( 'NQ07 0000 0000 0000 0000 0000 0000 0000 0000', ) for (const tx of transactions) { console.log(tx.sender, '→', tx.recipient, tx.value, 'luna') } ``` You can narrow the query with optional parameters: ```js const transactions = await client.getTransactionsByAddress( 'NQ07 0000 0000 0000 0000 0000 0000 0000 0000', 50000, // sinceBlockHeight — only return transactions after this block [], // knownTransactionDetails — exclude already-known transactions undefined, // startAt 10, // limit — maximum number of transactions to return ) ``` For lightweight receipt data (not fully verified), use `getTransactionReceiptsByAddress()` instead. ## Query validators and stakers If you're building around staking, you can look up validator and staker data: ```js // Single validator const validator = await client.getValidator('NQ07 0000 0000 0000 0000 0000 0000 0000 0000') // Multiple validators at once const validators = await client.getValidators([address1, address2]) // Single staker const staker = await client.getStaker('NQ07 0000 0000 0000 0000 0000 0000 0000 0000') // Multiple stakers at once const stakers = await client.getStakers([address1, address2]) ``` ## Next steps - [Listen for Events](https://nimiq.com/developers/web-client/guides/listen-for-events) — react to new blocks and transactions in real time - [Create and Manage Wallets](https://nimiq.com/developers/web-client/guides/wallets) — generate keys to start sending transactions - [API Reference](https://nimiq.com/developers/web-client/reference) — full method signatures and return types # Send Transactions This guide walks through creating, signing, and broadcasting transactions using the web client. You'll need a connected client with consensus and a keypair with funds. If you don't have these yet, see [Getting Started](https://nimiq.com/developers/web-client/getting-started) and [Create and Manage Wallets](https://nimiq.com/developers/web-client/guides/wallets). The examples below assume you have a connected `client`, a funded `keyPair`, and a `sender` address derived from it. See [Getting Started](https://nimiq.com/developers/web-client/getting-started) and [Create and Manage Wallets](https://nimiq.com/developers/web-client/guides/wallets) if you don't have these yet. ## Send a basic transaction A basic transaction transfers NIM from one address to another. Values and fees are in luna (1 NIM = 100,000 luna). ```js const recipient = Nimiq.Address.fromUserFriendlyAddress('NQ15 0000 0000 0000 0000 0000 0000 0000 0000') const tx = Nimiq.TransactionBuilder.newBasic( sender, recipient, 100_000_000_00n, // 1,000 NIM in luna 0n, // fee in luna — 0 is valid for most transactions await client.getHeadHeight(), // validity start height await client.getNetworkId(), ) tx.sign(keyPair) const details = await client.sendTransaction(tx) console.log('Transaction hash:', details.hash) console.log('State:', details.state) ``` The `validityStartHeight` determines when the transaction becomes valid. Setting it to the current head height means it's valid immediately. Transactions expire after a protocol-defined window. ## Send a transaction with data You can attach up to 64 bytes of arbitrary data to a transaction: ```js const data = new TextEncoder().encode('Hello Nimiq!') const tx = Nimiq.TransactionBuilder.newBasicWithData( sender, recipient, data, 500_00n, // 500 NIM in luna 0n, // fee in luna await client.getHeadHeight(), await client.getNetworkId(), ) tx.sign(keyPair) const details = await client.sendTransaction(tx) console.log('Transaction hash:', details.hash) ``` ## Check transaction status After broadcasting, you can check the transaction state: ```js const tx = await client.getTransaction(details.hash) console.log('State:', tx.state) // 'pending', 'included', etc. ``` Or watch for it in real time with a [transaction listener](https://nimiq.com/developers/web-client/guides/listen-for-events#track-transactions-for-an-address): ```js await client.addTransactionListener( (tx) => console.log('Confirmed:', tx.hash, tx.state), [sender], ) ``` ## Fees A fee of `0n` is valid for most transactions. Fees become relevant when the network is congested — higher fees increase the priority of your transaction. Fees are denominated in luna. ## Next steps - [Stake NIM](https://nimiq.com/developers/web-client/guides/stake-nim) — use transactions to create stakers and delegate to validators - [Query the Blockchain](https://nimiq.com/developers/web-client/guides/query-the-blockchain) — check balances and transaction history - [API Reference](https://nimiq.com/developers/web-client/reference) — full TransactionBuilder and Client method signatures # Stake NIM Nimiq uses Proof-of-Stake consensus. You can participate by staking your NIM — delegating it to a validator that produces blocks on your behalf. This guide covers creating a staker, managing stake, and changing delegation, all using the web client. You'll need a connected client with consensus and a funded keypair. See [Getting Started](https://nimiq.com/developers/web-client/getting-started) and [Create and Manage Wallets](https://nimiq.com/developers/web-client/guides/wallets) if you don't have these. The examples below assume you have a connected `client`, a funded `keyPair`, and a `sender` address. All values and fees are in luna (1 NIM = 100,000 luna). Each example also uses `validityStartHeight` and `networkId` from the client. ## Create a staker To start staking, create a staker and delegate to a validator. This transfers NIM from your account into the staking contract. ```js const validator = Nimiq.Address.fromUserFriendlyAddress('NQ15 0000 0000 0000 0000 0000 0000 0000 0000') const tx = Nimiq.TransactionBuilder.newCreateStaker( sender, validator, // the validator to delegate to 100_000_00n, // 100,000 NIM in luna 0n, // fee in luna validityStartHeight, networkId, ) tx.sign(keyPair) await client.sendTransaction(tx) ``` ## Add stake Increase your stake after the staker already exists: ```js const tx = Nimiq.TransactionBuilder.newAddStake( sender, sender, // staker address to add stake to 50_000_00n, // 50,000 NIM in luna 0n, // fee in luna validityStartHeight, networkId, ) tx.sign(keyPair) await client.sendTransaction(tx) ``` You can add stake to any staker address, not just your own. ## Change delegation Switch your delegation to a different validator with `newUpdateStaker`. This is a signaling transaction — it doesn't transfer NIM. ```js const newValidator = Nimiq.Address.fromUserFriendlyAddress('NQ20 0000 0000 0000 0000 0000 0000 0000 0000') const tx = Nimiq.TransactionBuilder.newUpdateStaker( sender, newValidator, // new validator to delegate to true, // reactivate all stake 0n, // fee in luna validityStartHeight, networkId, ) tx.sign(keyPair) await client.sendTransaction(tx) ``` ## Manage active stake You can control how much of your stake is active (earning rewards) versus inactive. ### Set active stake Set the total amount of active stake. Stake beyond this amount becomes inactive. ```js const tx = Nimiq.TransactionBuilder.newSetActiveStake( sender, 80_000_00n, // new active balance in luna 0n, // fee in luna validityStartHeight, networkId, ) tx.sign(keyPair) await client.sendTransaction(tx) ``` ### Retire stake Move a portion of your inactive stake into the retired state, preparing it for removal. ```js const tx = Nimiq.TransactionBuilder.newRetireStake( sender, 20_000_00n, // amount to retire in luna 0n, // fee in luna validityStartHeight, networkId, ) tx.sign(keyPair) await client.sendTransaction(tx) ``` ## Remove stake Withdraw retired NIM from the staking contract back to a regular account. ```js const tx = Nimiq.TransactionBuilder.newRemoveStake( sender, // recipient of the withdrawn NIM 20_000_00n, // amount to remove in luna 0n, // fee in luna validityStartHeight, networkId, ) tx.sign(keyPair) await client.sendTransaction(tx) ``` ## Query staker and validator data Check your staking status or look up validator information: ```js const staker = await client.getStaker(sender) console.log(staker.balance, staker.delegation) const validator = await client.getValidator('NQ15 0000 0000 0000 0000 0000 0000 0000 0000') console.log(validator.balance, validator.rewardAddress) ``` ## Next steps - [Query the Blockchain](https://nimiq.com/developers/web-client/guides/query-the-blockchain) — check balances and staker data - [Listen for Events](https://nimiq.com/developers/web-client/guides/listen-for-events) — monitor transactions related to your staker - [API Reference](https://nimiq.com/developers/web-client/reference) — full TransactionBuilder staking method signatures # Create and Manage Wallets The web client includes a full cryptographic toolkit for key management. You can generate random keypairs, derive keys from mnemonic phrases, and use HD (hierarchical deterministic) derivation — all running locally without any server interaction. These examples assume you have initialized the Nimiq library: ```js import init, * as Nimiq from '@nimiq/core/web' await init() ``` ## Generate a random keypair The simplest way to create a new wallet: ```js const keyPair = Nimiq.KeyPair.generate() const address = keyPair.toAddress() console.log(address.toUserFriendlyAddress()) // 'NQ07 ...' ``` The keypair contains a private key (for signing) and a public key (for verification). The address is derived from the public key. To export and restore a keypair: ```js // Export const hex = keyPair.toHex() // Restore const restored = Nimiq.KeyPair.fromHex(hex) ``` ## Derive from a mnemonic phrase Mnemonic phrases (BIP39) provide a human-readable backup for keys. The web client supports both BIP39 and legacy Nimiq mnemonics. ```js const mnemonic = 'abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon about' // Convert mnemonic to an extended private key const extendedKey = Nimiq.MnemonicUtils.mnemonicToExtendedPrivateKey(mnemonic) // Derive the address const address = extendedKey.toAddress() console.log(address.toUserFriendlyAddress()) ``` You can also provide a password for additional security: ```js const extendedKey = Nimiq.MnemonicUtils.mnemonicToExtendedPrivateKey(mnemonic, 'my-passphrase') ``` To detect whether a mnemonic is BIP39 or legacy: ```js const type = Nimiq.MnemonicUtils.getMnemonicType(mnemonic) // 1 = BIP39, 0 = Legacy, -1 = Unknown ``` ## HD derivation HD (hierarchical deterministic) derivation lets you generate multiple addresses from a single seed. This is useful for wallets that manage many accounts. ```js const mnemonic = 'abandon abandon abandon ...' // Get the seed const seed = Nimiq.MnemonicUtils.mnemonicToSeed(mnemonic) // Derive the master key const masterKey = Nimiq.ExtendedPrivateKey.generateMasterKey(seed) // Derive child keys using a path const account0 = masterKey.derivePath("m/44'/242'/0'/0'") const account1 = masterKey.derivePath("m/44'/242'/1'/0'") console.log(account0.toAddress().toUserFriendlyAddress()) console.log(account1.toAddress().toUserFriendlyAddress()) ``` You can also derive directly from the seed in one step: ```js const key = Nimiq.ExtendedPrivateKey.derivePathFromSeed("m/44'/242'/0'/0'", seed) ``` To validate a derivation path before using it: ```js Nimiq.ExtendedPrivateKey.isValidPath("m/44'/242'/0'/0'") // true ``` ## Work with addresses Addresses can be created from strings, public keys, or byte arrays: ```js // From a user-friendly string const addr = Nimiq.Address.fromUserFriendlyAddress('NQ07 0000 0000 0000 0000 0000 0000 0000 0000') // From any supported format (string, Address, Uint8Array) const addr2 = Nimiq.Address.fromAny('NQ07 0000 0000 0000 0000 0000 0000 0000 0000') // Format for display addr.toUserFriendlyAddress() // 'NQ07 0000 ...' addr.toHex() // hex representation // Compare addresses addr.equals(addr2) // true ``` ## Sign arbitrary data Keypairs can sign any data, not just transactions: ```js const keyPair = Nimiq.KeyPair.generate() const data = new TextEncoder().encode('hello') const signature = keyPair.sign(data) // Verify with the public key const valid = keyPair.publicKey.verify(signature, data) // true ``` ## Next steps - [Send Transactions](https://nimiq.com/developers/web-client/guides/send-transactions) — use your keypair to sign and broadcast NIM transfers - [Stake NIM](https://nimiq.com/developers/web-client/guides/stake-nim) — delegate your NIM to a validator - [API Reference](https://nimiq.com/developers/web-client/reference) — full class documentation for KeyPair, Address, MnemonicUtils, and more # Nimiq Web Client The Nimiq Web Client is a WebAssembly-powered light client packaged as an npm module. It lets your JavaScript application participate in the Nimiq blockchain directly — syncing with the network, reading on-chain state, and broadcasting transactions — without relying on any server or third-party API. ## What you can build ::u-page-grid :::u-page-card --- description: Fetch account balances, look up blocks, and check transaction status — all from the browser. icon: i-nimiq:nodes title: Query the Blockchain to: https://nimiq.com/developers/web-client/guides/query-the-blockchain variant: outline --- ::: :::u-page-card --- description: Subscribe to new blocks, track transactions for an address, and react to consensus changes in real time. icon: i-nimiq:bolt title: Listen for Events to: https://nimiq.com/developers/web-client/guides/listen-for-events variant: outline --- ::: :::u-page-card --- description: Generate keypairs, derive addresses from mnemonics, and manage HD wallets entirely client-side. icon: i-tabler:wallet title: Create and Manage Wallets to: https://nimiq.com/developers/web-client/guides/wallets variant: outline --- ::: :::u-page-card --- description: Build, sign, and broadcast NIM transfers with optional data payloads. icon: i-tabler:send title: Send Transactions to: https://nimiq.com/developers/web-client/guides/send-transactions variant: outline --- ::: :::u-page-card --- description: Create stakers, delegate to validators, and manage your stake directly from your application. icon: i-nimiq:verified title: Stake NIM to: https://nimiq.com/developers/web-client/guides/stake-nim variant: outline --- ::: :: ## Quick start Install the package and connect to the network in a few lines: ::code-group ```bash [pnpm] pnpm add @nimiq/core ``` ```bash [npm] npm install @nimiq/core ``` ```bash [yarn] yarn add @nimiq/core ``` ```bash [bun] bun add @nimiq/core ``` :: ::code-group ```js [browser.js] import init, * as Nimiq from '@nimiq/core/web' await init() const config = new Nimiq.ClientConfiguration() const client = await Nimiq.Client.create(config.build()) await client.waitForConsensusEstablished() ``` ```js [Node.js] import Nimiq from '@nimiq/core' const config = new Nimiq.ClientConfiguration() const client = await Nimiq.Client.create(config.build()) await client.waitForConsensusEstablished() ``` :: ## Where to go next ::callout --- icon: i-tabler:rocket to: https://nimiq.com/developers/web-client/getting-started --- **New to the Web Client?** — Set up your environment, pick a network, and get test funds in the Getting Started guide. :: ::callout --- icon: i-tabler:code to: https://nimiq.com/developers/web-client/integrations/vite --- **Using a framework?** — Follow the integration guide for [Vite](https://nimiq.com/developers/web-client/integrations/vite) , [Nuxt](https://nimiq.com/developers/web-client/integrations/nuxt) , [Next.js](https://nimiq.com/developers/web-client/integrations/nextjs) , or [plain ESM](https://nimiq.com/developers/web-client/integrations/esm) . :: ::callout --- icon: i-tabler:book to: https://nimiq.com/developers/web-client/concepts/browser-vs-server --- **Want to understand the fundamentals?** — Learn how the light client works, or compare the [Web Client vs RPC](https://nimiq.com/developers/web-client/concepts/web-client-vs-rpc) approach. :: ::callout --- icon: i-tabler:file-search to: https://nimiq.com/developers/web-client/reference --- **Looking for a specific method?** — Browse the full API Reference. :: # Nimiq Web Client CommonJS Integration Integrate Nimiq Web Client using CommonJS `require()` for Node.js environments. ## Installation ::code-group ```bash [pnpm] pnpm add @nimiq/core ``` ```bash [npm] npm install @nimiq/core ``` ```bash [yarn] yarn add @nimiq/core ``` ```bash [bun] bun add @nimiq/core ``` :: ## Usage Example ```javascript const Nimiq = require('@nimiq/core') async function main() { const config = new Nimiq.ClientConfiguration() const client = await Nimiq.Client.create(config.build()) await client.waitForConsensusEstablished() } main() ``` ## Next steps Once your client is connected, see the [guides](https://nimiq.com/developers/web-client/guides/query-the-blockchain) to start building. For other integration options, see [Vite](https://nimiq.com/developers/web-client/integrations/vite), [Nuxt](https://nimiq.com/developers/web-client/integrations/nuxt), [Next.js](https://nimiq.com/developers/web-client/integrations/nextjs), or [ESM](https://nimiq.com/developers/web-client/integrations/esm). # Nimiq Web Client ESM Integration Use this approach when you're serving JavaScript directly to the browser without a bundler — for example, from a plain HTML file, a CDN, or a static site. If you're using Vite, Nuxt, or Next.js, use their dedicated integration instead. The ESM build (`@nimiq/core/web`) requires a manual `init()` call to load the WebAssembly module. See [Browser vs Server](https://nimiq.com/developers/web-client/concepts/browser-vs-server) for details on the different build targets. ## Installation ::code-group ```bash [pnpm] pnpm add @nimiq/core ``` ```bash [npm] npm install @nimiq/core ``` ```bash [yarn] yarn add @nimiq/core ``` ```bash [bun] bun add @nimiq/core ``` :: ## Configuration No additional configuration needed! ESM works out of the box in modern browsers and bundlers that support ES modules. ## Usage Example ```js import init, { Client, ClientConfiguration } from '@nimiq/core/web' await init() const config = new ClientConfiguration() const client = await Client.create(config.build()) await client.waitForConsensusEstablished() ``` ## Next steps Once your client is connected, see the [guides](https://nimiq.com/developers/web-client/guides/query-the-blockchain) to start building. For other integration options, see [Vite](https://nimiq.com/developers/web-client/integrations/vite), [Nuxt](https://nimiq.com/developers/web-client/integrations/nuxt), [Next.js](https://nimiq.com/developers/web-client/integrations/nextjs), or [CommonJS](https://nimiq.com/developers/web-client/integrations/commonjs). # Nimiq Web Client Next.js Integration Integrate Nimiq Web Client with Next.js for production-ready React blockchain applications. ## Quick Start with Template Get started instantly with our pre-configured Next.js starter: ```bash npx degit onmax/nimiq-starter/starters/next-js my-nimiq-app cd my-nimiq-app && pnpm install && pnpm dev ``` ::callout --- color: info icon: i-tabler-info-circle title: Community Contribution --- The Next.js starter is based on the original implementation by [DovAzencot](https://github.com/DovAzencot/nimiq-nextjs/){rel=""nofollow""} . :: ## Installation ### Quick Start Install the Nimiq Web Client package: ::code-group ```bash [pnpm] pnpm add @nimiq/core ``` ```bash [npm] npm install @nimiq/core ``` ```bash [yarn] yarn add @nimiq/core ``` ```bash [bun] bun add @nimiq/core ``` :: ## Configuration & Usage ::code-group ```javascript [next.config.js] import path from 'node:path' /** @type {import('next').NextConfig} */ const nextConfig = { webpack: (config, { isServer }) => { config.experiments = { ...config.experiments, asyncWebAssembly: true, topLevelAwait: true, } config.module.rules.push({ test: /\.wasm$/, type: 'webassembly/async', }) config.resolve = { ...config.resolve, alias: { ...config.resolve?.alias, '@nimiq/core': path.resolve('./node_modules/@nimiq/core/bundler/index.js'), }, fallback: { ...config.resolve?.fallback, path: false, fs: false, }, extensions: [...(config.resolve?.extensions || []), '.js', '.mjs'], } if (!isServer) { config.optimization = { ...config.optimization, splitChunks: { ...config.optimization?.splitChunks, cacheGroups: { ...(config.optimization?.splitChunks)?.cacheGroups, nimiq: { test: /@nimiq/, name: 'nimiq', chunks: 'all', priority: 10, }, }, }, } } return config }, } module.exports = nextConfig ``` ```tsx [hooks/useNimiq.ts] import { Client, ClientConfiguration } from '@nimiq/core' import { useEffect, useState } from 'react' export function useNimiq() { const [client, setClient] = useState(null) const [blockHeight, setBlockHeight] = useState(0) const [isConnecting, setIsConnecting] = useState(false) const [error, setError] = useState(null) useEffect(() => { let mounted = true async function init() { setIsConnecting(true) try { const config = new ClientConfiguration() const nimiqClient = await Client.create(config.build()) await nimiqClient.waitForConsensusEstablished() if (mounted) { setClient(nimiqClient) setBlockHeight(await nimiqClient.getHeadHeight()) } } catch (err) { if (mounted) setError(err instanceof Error ? err.message : 'Failed to connect') } finally { if (mounted) setIsConnecting(false) } } init() return () => { mounted = false } }, []) return { client, blockHeight, isConnecting, error } } ``` ```tsx [pages/wallet.tsx] import { useNimiq } from '../hooks/useNimiq' export default function Wallet() { const { client, blockHeight, isConnecting, error } = useNimiq() if (isConnecting) return

Connecting to blockchain...

if (error) { return (

Error: {error}

) } return (

Nimiq Wallet

Block Height: {blockHeight.toLocaleString()}

Network: {client?.getNetworkId()}

) } ``` :: ## Next steps Once your client is connected, see the [guides](https://nimiq.com/developers/web-client/guides/query-the-blockchain) to start building. For other integration options, see [Vite](https://nimiq.com/developers/web-client/integrations/vite), [Nuxt](https://nimiq.com/developers/web-client/integrations/nuxt), [ESM](https://nimiq.com/developers/web-client/integrations/esm), or [CommonJS](https://nimiq.com/developers/web-client/integrations/commonjs). # Nimiq Web Client Nuxt Integration Integrate Nimiq Web Client with Nuxt for full-stack blockchain applications. ## Installation Install the Nimiq Web Client: ::code-group ```bash [pnpm] pnpm add @nimiq/core ``` ```bash [npm] npm install @nimiq/core ``` ```bash [yarn] yarn add @nimiq/core ``` ```bash [bun] bun add @nimiq/core ``` :: ## Configuration The Nimiq Web Client includes a Vite plugin that automatically configures WebAssembly support and all required optimizations. > [!TIP] > View the [plugin source code](https://github.com/nimiq/core-rs-albatross/blob/albatross/web-client/dist/vite.js){rel=""nofollow""} for implementation details. Update your `nuxt.config.ts`: ::code-group ```ts [nuxt.config.ts] import nimiq from '@nimiq/core/vite' // [!code ++] export default defineNuxtConfig({ vite: { // [!code ++] plugins: [nimiq()], // [!code ++] }, // [!code ++] // Only if you are using SSR or @nimiq/core in the server, // otherwise use `ssr: false` or `` nitro: { // [!code ++] experimental: { // [!code ++] wasm: true, // [!code ++] }, // [!code ++] }, // [!code ++] }) ``` :: The plugin automatically configures: - WebAssembly support with `vite-plugin-wasm` - Worker configuration for WASM modules (opt-out via `{ worker: false }`) - Build target optimizations (`esnext`) - Dependency exclusions for `@nimiq/core` Legacy Browser Support Modern browsers (Chrome 89+, Firefox 89+, Safari 15+, Edge 89+) support top-level await natively. If you need to support older browsers, install `vite-plugin-top-level-await`: ::code-group ```bash [pnpm] pnpm add -D vite-plugin-top-level-await ``` ```bash [npm] npm install -D vite-plugin-top-level-await ``` ```bash [yarn] yarn add -D vite-plugin-top-level-await ``` ```bash [bun] bun add -D vite-plugin-top-level-await ``` :: Then add it to your Nuxt config: ::code-group ```ts [nuxt.config.ts] import nimiq from '@nimiq/core/vite' import topLevelAwait from 'vite-plugin-top-level-await' // [!code ++] export default defineNuxtConfig({ vite: { plugins: [ nimiq(), topLevelAwait(), // [!code ++] ], }, }) ``` :: > [!NOTE] > Top-level await is required for ES modules when using dynamic WASM imports. The plugin transforms top-level await to work in older browsers. ## Usage Example ::callout{color="warning" icon="i-tabler-alert-triangle"} **Client-Side Only** The Nimiq Web Client must run in the browser. Use one of these approaches: - Wrap components with `` - Use `.client.ts` filename suffix - Set `ssr: false` in page meta :: ```js import { Client, ClientConfiguration } from '@nimiq/core' const config = new ClientConfiguration() const client = await Client.create(config.build()) await client.waitForConsensusEstablished() ``` ### With Client-Only Wrapper ```vue ``` ## Next steps Once your client is connected, see the [guides](https://nimiq.com/developers/web-client/guides/query-the-blockchain) to start building. For other integration options, see [Vite](https://nimiq.com/developers/web-client/integrations/vite), [Next.js](https://nimiq.com/developers/web-client/integrations/nextjs), [ESM](https://nimiq.com/developers/web-client/integrations/esm), or [CommonJS](https://nimiq.com/developers/web-client/integrations/commonjs). # Nimiq Web Client Vite Integration Integrate Nimiq Web Client with Vite for fast blockchain development with minimal configuration. ## Quick Start with Templates Get started instantly with our pre-configured starter templates: ::code-group ```bash [Vue] npx degit onmax/nimiq-starter/starters/vue-ts my-nimiq-app cd my-nimiq-app && pnpm install && pnpm dev ``` ```bash [React] npx degit onmax/nimiq-starter/starters/react-ts my-nimiq-app cd my-nimiq-app && pnpm install && pnpm dev ``` :: ## Installation Install the Nimiq Web Client: ::code-group ```bash [pnpm] pnpm add @nimiq/core ``` ```bash [npm] npm install @nimiq/core ``` ```bash [yarn] yarn add @nimiq/core ``` ```bash [bun] bun add @nimiq/core ``` :: ## Configuration The Nimiq Web Client includes a Vite plugin that automatically configures WebAssembly support and all required optimizations. > [!TIP] > View the [plugin source code](https://github.com/nimiq/core-rs-albatross/blob/albatross/web-client/dist/vite.js){rel=""nofollow""} for implementation details. Update your `vite.config.ts`: ::code-group ```ts [vite.config.ts] import nimiq from '@nimiq/core/vite' // [!code ++] import { defineConfig } from 'vite' export default defineConfig({ plugins: [nimiq()], // [!code ++] }) ``` :: The plugin automatically configures: - WebAssembly support with `vite-plugin-wasm` - Worker configuration for WASM modules (opt-out via `{ worker: false }`) - Build target optimizations (`esnext`) - Dependency exclusions for `@nimiq/core` Legacy Browser Support Modern browsers (Chrome 89+, Firefox 89+, Safari 15+, Edge 89+) support top-level await natively. If you need to support older browsers, install `vite-plugin-top-level-await`: ::code-group ```bash [pnpm] pnpm add -D vite-plugin-top-level-await ``` ```bash [npm] npm install -D vite-plugin-top-level-await ``` ```bash [yarn] yarn add -D vite-plugin-top-level-await ``` ```bash [bun] bun add -D vite-plugin-top-level-await ``` :: Then add it to your Vite config: ::code-group ```ts [vite.config.ts] import nimiq from '@nimiq/core/vite' import { defineConfig } from 'vite' import topLevelAwait from 'vite-plugin-top-level-await' // [!code ++] export default defineConfig({ plugins: [ nimiq(), topLevelAwait(), // [!code ++] ], }) ``` :: > [!NOTE] > Top-level await is required for ES modules when using dynamic WASM imports. The plugin transforms top-level await to work in older browsers. ## Usage Example ```js import { Client, ClientConfiguration } from '@nimiq/core' const config = new ClientConfiguration() const client = await Client.create(config.build()) await client.waitForConsensusEstablished() ``` ## Next steps Once your client is connected, see the [guides](https://nimiq.com/developers/web-client/guides/query-the-blockchain) to start building. For other integration options, see [Nuxt](https://nimiq.com/developers/web-client/integrations/nuxt), [Next.js](https://nimiq.com/developers/web-client/integrations/nextjs), [ESM](https://nimiq.com/developers/web-client/integrations/esm), or [CommonJS](https://nimiq.com/developers/web-client/integrations/commonjs). # Enumeration: MnemonicType [@nimiq/core](https://nimiq.com/developers/../../../../globals) / [MnemonicUtils](https://nimiq.com/developers/../) / MnemonicType Defined in: @nimiq/core/lib/index.d.ts:308 ## Enumeration Members ### BIP39 > **BIP39**: `1` Defined in: @nimiq/core/lib/index.d.ts:311 --- ### LEGACY > **LEGACY**: `0` Defined in: @nimiq/core/lib/index.d.ts:310 --- ### UNKNOWN > **UNKNOWN**: `-1` Defined in: @nimiq/core/lib/index.d.ts:309 # MnemonicUtils [@nimiq/core](https://nimiq.com/developers/../../../globals) / MnemonicUtils ## Enumerations - [MnemonicType](https://nimiq.com/developers/enumerations/MnemonicType) # Enumeration: Type [@nimiq/core](https://nimiq.com/developers/../../../../globals) / [Secret](https://nimiq.com/developers/../) / Type Defined in: @nimiq/core/lib/index.d.ts:200 ## Enumeration Members ### ENTROPY > **ENTROPY**: `2` Defined in: @nimiq/core/lib/index.d.ts:202 --- ### PRIVATE\_KEY > **PRIVATE\_KEY**: `1` Defined in: @nimiq/core/lib/index.d.ts:201 # Secret [@nimiq/core](https://nimiq.com/developers/../../../globals) / Secret ## Enumerations - [Type](https://nimiq.com/developers/enumerations/Type) # Class: Address [@nimiq/core](https://nimiq.com/developers/../globals) / Address Defined in: @nimiq/core/types/wasm/web.d.ts:667 An object representing a Nimiq address. Offers methods to parse and format addresses from and to strings. ## Constructors ### Constructor > **new Address**(`bytes`): `Address` Defined in: @nimiq/core/types/wasm/web.d.ts:708 #### Parameters ##### bytes `Uint8Array` #### Returns `Address` ## Properties ### NULL > `readonly` `static` **NULL**: `Address` Defined in: @nimiq/core/types/wasm/web.d.ts:728 The all-zeroes burn address. ## Methods ### \_\_getClassname() > **\_\_getClassname**(): `string` Defined in: @nimiq/core/types/wasm/web.d.ts:670 #### Returns `string` --- ### \[dispose]\() > **\[dispose]**(): `void` Defined in: @nimiq/core/types/wasm/web.d.ts:669 #### Returns `void` --- ### compare() > **compare**(`other`): `number` Defined in: @nimiq/core/types/wasm/web.d.ts:677 Compares this address to the other address. Returns -1 if this address is smaller than the other address, 0 if they are equal, and 1 if this address is larger than the other address. #### Parameters ##### other `Address` #### Returns `number` --- ### equals() > **equals**(`other`): `boolean` Defined in: @nimiq/core/types/wasm/web.d.ts:685 Returns if this address is equal to the other address. #### Parameters ##### other `Address` #### Returns `boolean` --- ### free() > **free**(): `void` Defined in: @nimiq/core/types/wasm/web.d.ts:668 #### Returns `void` --- ### serialize() > **serialize**(): `Uint8Array` Defined in: @nimiq/core/types/wasm/web.d.ts:712 Returns the byte representation of the address. #### Returns `Uint8Array` --- ### toHex() > **toHex**(): `string` Defined in: @nimiq/core/types/wasm/web.d.ts:716 Formats the address into hex format. #### Returns `string` --- ### toPlain() > **toPlain**(): `string` Defined in: @nimiq/core/types/wasm/web.d.ts:720 Formats the address into a plain string format. #### Returns `string` --- ### toUserFriendlyAddress() > **toUserFriendlyAddress**(): `string` Defined in: @nimiq/core/types/wasm/web.d.ts:724 Formats the address into user-friendly IBAN format. #### Returns `string` --- ### deserialize() > `static` **deserialize**(`bytes`): `Address` Defined in: @nimiq/core/types/wasm/web.d.ts:681 Deserializes an address from a byte array. #### Parameters ##### bytes `Uint8Array` #### Returns `Address` --- ### fromAny() > `static` **fromAny**(`addr`): `Address` Defined in: @nimiq/core/types/wasm/web.d.ts:691 Parses an address from an Address instance, a hex string representation, or a byte array. Throws when an address cannot be parsed from the argument. #### Parameters ##### addr `string` | `Address` | `Uint8Array`<`ArrayBufferLike`> #### Returns `Address` --- ### fromPublicKeys() > `static` **fromPublicKeys**(`public_keys`, `num_signers`): `Address` Defined in: @nimiq/core/types/wasm/web.d.ts:695 Computes the multisig address of a list of signer public keys. #### Parameters ##### public\_keys (`string` | `Uint8Array`<`ArrayBufferLike`> | [`PublicKey`](https://nimiq.com/developers/PublicKey)) [] ##### num\_signers `number` #### Returns `Address` --- ### fromString() > `static` **fromString**(`str`): `Address` Defined in: @nimiq/core/types/wasm/web.d.ts:701 Parses an address from a string representation, either user-friendly or hex format. Throws when an address cannot be parsed from the string. #### Parameters ##### str `string` #### Returns `Address` --- ### fromUserFriendlyAddress() > `static` **fromUserFriendlyAddress**(`str`): `Address` Defined in: @nimiq/core/types/wasm/web.d.ts:707 Parses an address from its user-friendly string representation. Throws when an address cannot be parsed from the string. #### Parameters ##### str `string` #### Returns `Address` # Class: ArrayUtils [@nimiq/core](https://nimiq.com/developers/../globals) / ArrayUtils Defined in: @nimiq/core/lib/index.d.ts:3 ## Constructors ### Constructor > **new ArrayUtils**(): `ArrayUtils` #### Returns `ArrayUtils` ## Methods ### subarray() > `static` **subarray**(`uintarr`, `begin?`, `end?`): `Uint8Array` Defined in: @nimiq/core/lib/index.d.ts:4 #### Parameters ##### uintarr `Uint8Array` ##### begin? `number` ##### end? `number` #### Returns `Uint8Array` # Class: BLSKeyPair [@nimiq/core](https://nimiq.com/developers/../globals) / BLSKeyPair Defined in: @nimiq/core/types/wasm/web.d.ts:736 A BLS keypair It is used by validators to vote during Tendermint rounds. This is just a wrapper around our internal BLS structs ## Constructors ### Constructor > **new BLSKeyPair**(`secret_key`, `public_key`): `BLSKeyPair` Defined in: @nimiq/core/types/wasm/web.d.ts:751 #### Parameters ##### secret\_key [`BLSSecretKey`](https://nimiq.com/developers/BLSSecretKey) ##### public\_key [`BLSPublicKey`](https://nimiq.com/developers/BLSPublicKey) #### Returns `BLSKeyPair` ## Properties ### publicKey > `readonly` **publicKey**: [`BLSPublicKey`](https://nimiq.com/developers/BLSPublicKey) Defined in: @nimiq/core/types/wasm/web.d.ts:763 Gets the keypair's public key. --- ### secretKey > `readonly` **secretKey**: [`BLSSecretKey`](https://nimiq.com/developers/BLSSecretKey) Defined in: @nimiq/core/types/wasm/web.d.ts:767 Gets the keypair's secret key. ## Methods ### \[dispose]\() > **\[dispose]**(): `void` Defined in: @nimiq/core/types/wasm/web.d.ts:738 #### Returns `void` --- ### free() > **free**(): `void` Defined in: @nimiq/core/types/wasm/web.d.ts:737 #### Returns `void` --- ### serialize() > **serialize**(): `Uint8Array` Defined in: @nimiq/core/types/wasm/web.d.ts:755 Serializes to a byte array. #### Returns `Uint8Array` --- ### toHex() > **toHex**(): `string` Defined in: @nimiq/core/types/wasm/web.d.ts:759 Formats the keypair into a hex string. #### Returns `string` --- ### derive() > `static` **derive**(`private_key`): `BLSKeyPair` Defined in: @nimiq/core/types/wasm/web.d.ts:742 Derives a keypair from an existing private key. #### Parameters ##### private\_key [`BLSSecretKey`](https://nimiq.com/developers/BLSSecretKey) #### Returns `BLSKeyPair` --- ### deserialize() > `static` **deserialize**(`bytes`): `BLSKeyPair` Defined in: @nimiq/core/types/wasm/web.d.ts:746 Deserializes a keypair from a byte array. #### Parameters ##### bytes `Uint8Array` #### Returns `BLSKeyPair` --- ### generate() > `static` **generate**(): `BLSKeyPair` Defined in: @nimiq/core/types/wasm/web.d.ts:750 Generates a new keypair from secure randomness. #### Returns `BLSKeyPair` # Class: BLSPublicKey [@nimiq/core](https://nimiq.com/developers/../globals) / BLSPublicKey Defined in: @nimiq/core/types/wasm/web.d.ts:774 The public part of the BLS keypair. This is specified in the staking contract to verify votes from Validators. ## Constructors ### Constructor > **new BLSPublicKey**(`bytes`): `BLSPublicKey` Defined in: @nimiq/core/types/wasm/web.d.ts:792 Creates a new public key from a byte array. #### Parameters ##### bytes `Uint8Array` #### Returns `BLSPublicKey` ## Methods ### \[dispose]\() > **\[dispose]**(): `void` Defined in: @nimiq/core/types/wasm/web.d.ts:776 #### Returns `void` --- ### free() > **free**(): `void` Defined in: @nimiq/core/types/wasm/web.d.ts:775 #### Returns `void` --- ### serialize() > **serialize**(): `Uint8Array` Defined in: @nimiq/core/types/wasm/web.d.ts:796 Serializes the public key to a byte array. #### Returns `Uint8Array` --- ### toHex() > **toHex**(): `string` Defined in: @nimiq/core/types/wasm/web.d.ts:800 Formats the public key into a hex string. #### Returns `string` --- ### derive() > `static` **derive**(`secret_key`): `BLSPublicKey` Defined in: @nimiq/core/types/wasm/web.d.ts:780 Derives a public key from an existing private key. #### Parameters ##### secret\_key [`BLSSecretKey`](https://nimiq.com/developers/BLSSecretKey) #### Returns `BLSPublicKey` --- ### deserialize() > `static` **deserialize**(`bytes`): `BLSPublicKey` Defined in: @nimiq/core/types/wasm/web.d.ts:784 Deserializes a public key from a byte array. #### Parameters ##### bytes `Uint8Array` #### Returns `BLSPublicKey` --- ### fromHex() > `static` **fromHex**(`hex`): `BLSPublicKey` Defined in: @nimiq/core/types/wasm/web.d.ts:788 Parses a public key from its hex representation. #### Parameters ##### hex `string` #### Returns `BLSPublicKey` # Class: BLSSecretKey [@nimiq/core](https://nimiq.com/developers/../globals) / BLSSecretKey Defined in: @nimiq/core/types/wasm/web.d.ts:807 The secret part of the BLS keypair. This is specified in the config file, and is used by Validators to vote. ## Constructors ### Constructor > **new BLSSecretKey**(`bytes`): `BLSSecretKey` Defined in: @nimiq/core/types/wasm/web.d.ts:825 Creates a new private key from a byte array. #### Parameters ##### bytes `Uint8Array` #### Returns `BLSSecretKey` ## Methods ### \[dispose]\() > **\[dispose]**(): `void` Defined in: @nimiq/core/types/wasm/web.d.ts:809 #### Returns `void` --- ### free() > **free**(): `void` Defined in: @nimiq/core/types/wasm/web.d.ts:808 #### Returns `void` --- ### serialize() > **serialize**(): `Uint8Array` Defined in: @nimiq/core/types/wasm/web.d.ts:829 Serializes the private key to a byte array. #### Returns `Uint8Array` --- ### toHex() > **toHex**(): `string` Defined in: @nimiq/core/types/wasm/web.d.ts:833 Formats the private key into a hex string. #### Returns `string` --- ### deserialize() > `static` **deserialize**(`bytes`): `BLSSecretKey` Defined in: @nimiq/core/types/wasm/web.d.ts:813 Deserializes a private key from a byte array. #### Parameters ##### bytes `Uint8Array` #### Returns `BLSSecretKey` --- ### fromHex() > `static` **fromHex**(`hex`): `BLSSecretKey` Defined in: @nimiq/core/types/wasm/web.d.ts:817 Parses a private key from its hex representation. #### Parameters ##### hex `string` #### Returns `BLSSecretKey` --- ### generate() > `static` **generate**(): `BLSSecretKey` Defined in: @nimiq/core/types/wasm/web.d.ts:821 Generates a new private key from secure randomness. #### Returns `BLSSecretKey` # Class: BufferUtils [@nimiq/core](https://nimiq.com/developers/../globals) / BufferUtils Defined in: @nimiq/core/lib/index.d.ts:48 ## Constructors ### Constructor > **new BufferUtils**(): `BufferUtils` #### Returns `BufferUtils` ## Properties ### \_BASE64\_LOOKUP > `static` **\_BASE64\_LOOKUP**: `string`[] Defined in: @nimiq/core/lib/index.d.ts:56 --- ### BASE32\_ALPHABET > `static` **BASE32\_ALPHABET**: `object` Defined in: @nimiq/core/lib/index.d.ts:50 #### NIMIQ > **NIMIQ**: `string` #### RFC4648 > **RFC4648**: `string` #### RFC4648\_HEX > **RFC4648\_HEX**: `string` --- ### BASE64\_ALPHABET > `static` **BASE64\_ALPHABET**: `string` Defined in: @nimiq/core/lib/index.d.ts:49 --- ### HEX\_ALPHABET > `static` **HEX\_ALPHABET**: `string` Defined in: @nimiq/core/lib/index.d.ts:55 ## Methods ### \_base64encodeChunk() > `static` **\_base64encodeChunk**(`u8`, `start`, `end`): `string` Defined in: @nimiq/core/lib/index.d.ts:62 #### Parameters ##### u8 `Uint8Array` ##### start `number` ##### end `number` #### Returns `string` --- ### \_base64fromByteArray() > `static` **\_base64fromByteArray**(`u8`): `string` Defined in: @nimiq/core/lib/index.d.ts:63 #### Parameters ##### u8 `Uint8Array` #### Returns `string` --- ### \_codePointTextDecoder() > `static` **\_codePointTextDecoder**(`buffer`): `string` Defined in: @nimiq/core/lib/index.d.ts:60 #### Parameters ##### buffer `Uint8Array` #### Returns `string` --- ### \_tripletToBase64() > `static` **\_tripletToBase64**(`num`): `string` Defined in: @nimiq/core/lib/index.d.ts:61 #### Parameters ##### num `number` #### Returns `string` --- ### compare() > `static` **compare**(`a`, `b`): `number` Defined in: @nimiq/core/lib/index.d.ts:82 Returns -1 if a is smaller than b, 1 if a is larger than b, 0 if a equals b. Shorter arrays are always considered smaller than longer ones. #### Parameters ##### a `TypedArray` ##### b `TypedArray` #### Returns `number` --- ### equals() > `static` **equals**(`a`, `b`): `boolean` Defined in: @nimiq/core/lib/index.d.ts:77 #### Parameters ##### a `TypedArray` ##### b `TypedArray` #### Returns `boolean` --- ### fromAny() > `static` **fromAny**(`o`, `length?`): [`SerialBuffer`](https://nimiq.com/developers/SerialBuffer) Defined in: @nimiq/core/lib/index.d.ts:76 #### Parameters ##### o `string` | `Uint8Array`<`ArrayBufferLike`> ##### length? `number` #### Returns [`SerialBuffer`](https://nimiq.com/developers/SerialBuffer) --- ### fromBase32() > `static` **fromBase32**(`base32`, `alphabet?`): `Uint8Array` Defined in: @nimiq/core/lib/index.d.ts:69 #### Parameters ##### base32 `string` ##### alphabet? `string` #### Returns `Uint8Array` --- ### fromBase64() > `static` **fromBase64**(`base64`, `length?`): [`SerialBuffer`](https://nimiq.com/developers/SerialBuffer) Defined in: @nimiq/core/lib/index.d.ts:65 #### Parameters ##### base64 `string` ##### length? `number` #### Returns [`SerialBuffer`](https://nimiq.com/developers/SerialBuffer) --- ### fromBase64Url() > `static` **fromBase64Url**(`base64`, `length?`): [`SerialBuffer`](https://nimiq.com/developers/SerialBuffer) Defined in: @nimiq/core/lib/index.d.ts:67 #### Parameters ##### base64 `string` ##### length? `number` #### Returns [`SerialBuffer`](https://nimiq.com/developers/SerialBuffer) --- ### fromHex() > `static` **fromHex**(`hex`, `length?`): [`SerialBuffer`](https://nimiq.com/developers/SerialBuffer) Defined in: @nimiq/core/lib/index.d.ts:71 #### Parameters ##### hex `string` ##### length? `number` #### Returns [`SerialBuffer`](https://nimiq.com/developers/SerialBuffer) --- ### fromUtf8() > `static` **fromUtf8**(`str`): `Uint8Array` Defined in: @nimiq/core/lib/index.d.ts:73 #### Parameters ##### str `string` #### Returns `Uint8Array` --- ### toBase32() > `static` **toBase32**(`buf`, `alphabet?`): `string` Defined in: @nimiq/core/lib/index.d.ts:68 #### Parameters ##### buf `Uint8Array` ##### alphabet? `string` #### Returns `string` --- ### toBase64() > `static` **toBase64**(`buffer`): `string` Defined in: @nimiq/core/lib/index.d.ts:64 #### Parameters ##### buffer `Uint8Array` #### Returns `string` --- ### toBase64Url() > `static` **toBase64Url**(`buffer`): `string` Defined in: @nimiq/core/lib/index.d.ts:66 #### Parameters ##### buffer `Uint8Array` #### Returns `string` --- ### toHex() > `static` **toHex**(`buffer`): `string` Defined in: @nimiq/core/lib/index.d.ts:70 #### Parameters ##### buffer `Uint8Array` #### Returns `string` --- ### toUtf8() > `static` **toUtf8**(`buf`): `string` Defined in: @nimiq/core/lib/index.d.ts:75 #### Parameters ##### buf `TypedArray` #### Returns `string` --- ### xor() > `static` **xor**(`a`, `b`): `Uint8Array` Defined in: @nimiq/core/lib/index.d.ts:83 #### Parameters ##### a `Uint8Array` ##### b `Uint8Array` #### Returns `Uint8Array` # Class: Client [@nimiq/core](https://nimiq.com/developers/../globals) / Client Defined in: @nimiq/core/types/wasm/web.d.ts:851 Nimiq Albatross client that runs in browsers via WASM and is exposed to Javascript. ### Usage: ```js import init, * as Nimiq from "./pkg/nimiq_web_client.js"; init().then(async () => { const config = new Nimiq.ClientConfiguration(); const client = await config.instantiateClient(); // ... }); ``` ## Methods ### \[dispose]\() > **\[dispose]**(): `void` Defined in: @nimiq/core/types/wasm/web.d.ts:854 #### Returns `void` --- ### addConsensusChangedListener() > **addConsensusChangedListener**(`listener`): `Promise`<`number`> Defined in: @nimiq/core/types/wasm/web.d.ts:858 Adds an event listener for consensus-change events, such as when consensus is established or lost. #### Parameters ##### listener (`state`) => `any` #### Returns `Promise`<`number`> --- ### addHeadChangedListener() > **addHeadChangedListener**(`listener`): `Promise`<`number`> Defined in: @nimiq/core/types/wasm/web.d.ts:862 Adds an event listener for new blocks added to the blockchain. #### Parameters ##### listener (`hash`, `reason`, `reverted_blocks`, `adopted_blocks`) => `any` #### Returns `Promise`<`number`> --- ### addPeerChangedListener() > **addPeerChangedListener**(`listener`): `Promise`<`number`> Defined in: @nimiq/core/types/wasm/web.d.ts:866 Adds an event listener for peer-change events, such as when a new peer joins, or a peer leaves. #### Parameters ##### listener (`peer_id`, `reason`, `peer_count`, `peer_info?`) => `any` #### Returns `Promise`<`number`> --- ### addTransactionListener() > **addTransactionListener**(`listener`, `addresses`): `Promise`<`number`> Defined in: @nimiq/core/types/wasm/web.d.ts:872 Adds an event listener for transactions to and from the provided addresses. The listener is called for transactions when they are *included* in the blockchain. #### Parameters ##### listener (`transaction`) => `any` ##### addresses (`string` | [`Address`](https://nimiq.com/developers/Address) | `Uint8Array`<`ArrayBufferLike`>) [] #### Returns `Promise`<`number`> --- ### connectNetwork() > **connectNetwork**(): `Promise`<`void`> Defined in: @nimiq/core/types/wasm/web.d.ts:878 This function is used to tell the network to (re)start connecting to peers. This is could be used to tell the network to restart connection operations after disconnect network is called. #### Returns `Promise`<`void`> --- ### disconnectNetwork() > **disconnectNetwork**(): `Promise`<`void`> Defined in: @nimiq/core/types/wasm/web.d.ts:891 This function is used to tell the network to disconnect from every connected peer and stop trying to connect to other peers. **Important**: this function returns when the signal to disconnect was sent, before all peers actually disconnect. This means that in order to ensure the network is disconnected, wait for all peers to disappear after calling. #### Returns `Promise`<`void`> --- ### free() > **free**(): `void` Defined in: @nimiq/core/types/wasm/web.d.ts:853 #### Returns `void` --- ### getAccount() > **getAccount**(`address`): `Promise`<[`PlainAccount`](https://nimiq.com/developers/../type-aliases/PlainAccount)> Defined in: @nimiq/core/types/wasm/web.d.ts:897 Fetches the account for the provided address from the network. Throws if the address cannot be parsed and on network errors. #### Parameters ##### address `string` | [`Address`](https://nimiq.com/developers/Address) | `Uint8Array`<`ArrayBufferLike`> #### Returns `Promise`<[`PlainAccount`](https://nimiq.com/developers/../type-aliases/PlainAccount)> --- ### getAccounts() > **getAccounts**(`addresses`): `Promise`<[`PlainAccount`](https://nimiq.com/developers/../type-aliases/PlainAccount)[] > Defined in: @nimiq/core/types/wasm/web.d.ts:903 Fetches the accounts for the provided addresses from the network. Throws if an address cannot be parsed and on network errors. #### Parameters ##### addresses (`string` | [`Address`](https://nimiq.com/developers/Address) | `Uint8Array`<`ArrayBufferLike`>) [] #### Returns `Promise`<[`PlainAccount`](https://nimiq.com/developers/../type-aliases/PlainAccount)[] > --- ### getAddressBook() > **getAddressBook**(): `Promise`<[`PlainPeerInfo`](https://nimiq.com/developers/../interfaces/PlainPeerInfo)[] > Defined in: @nimiq/core/types/wasm/web.d.ts:910 Returns the current address books peers. Each peer will have one address and currently no guarantee for the usefulness of that address can be given. The resulting Array may be empty if there is no peers in the address book. #### Returns `Promise`<[`PlainPeerInfo`](https://nimiq.com/developers/../interfaces/PlainPeerInfo)[] > --- ### getBlock() > **getBlock**(`hash`): `Promise`<[`PlainBlock`](https://nimiq.com/developers/../type-aliases/PlainBlock)> Defined in: @nimiq/core/types/wasm/web.d.ts:918 Fetches a block by its hash. Throws if the client does not have the block. Fetching blocks from the network is not yet available. #### Parameters ##### hash `string` #### Returns `Promise`<[`PlainBlock`](https://nimiq.com/developers/../type-aliases/PlainBlock)> --- ### getBlockAt() > **getBlockAt**(`height`): `Promise`<[`PlainBlock`](https://nimiq.com/developers/../type-aliases/PlainBlock)> Defined in: @nimiq/core/types/wasm/web.d.ts:926 Fetches a block by its height (block number). Throws if the client does not have the block. Fetching blocks from the network is not yet available. #### Parameters ##### height `number` #### Returns `Promise`<[`PlainBlock`](https://nimiq.com/developers/../type-aliases/PlainBlock)> --- ### getElectedValidators() > **getElectedValidators**(): `Promise`<[`PlainElectedValidator`](https://nimiq.com/developers/../interfaces/PlainElectedValidator)[] > Defined in: @nimiq/core/types/wasm/web.d.ts:937 Returns the validators elected for the current epoch, together with the number of validator slots assigned to each of them. The slot distribution is fixed for the duration of an epoch and is the metric used on-chain to evaluate support for protocol upgrades. Combine this with [Client.getValidators](https://nimiq.com/developers/#getvalidators) to relate slot counts to each validator's stake and signal data. Throws if the elected validators are not available (e.g. before consensus is established). #### Returns `Promise`<[`PlainElectedValidator`](https://nimiq.com/developers/../interfaces/PlainElectedValidator)[] > --- ### getHeadBlock() > **getHeadBlock**(): `Promise`<[`PlainBlock`](https://nimiq.com/developers/../type-aliases/PlainBlock)> Defined in: @nimiq/core/types/wasm/web.d.ts:942 Returns the current blockchain head block. Note that the web client is a light client and does not have block bodies, i.e. no transactions. #### Returns `Promise`<[`PlainBlock`](https://nimiq.com/developers/../type-aliases/PlainBlock)> --- ### getHeadHash() > **getHeadHash**(): `Promise`<`string`> Defined in: @nimiq/core/types/wasm/web.d.ts:946 Returns the block hash of the current blockchain head. #### Returns `Promise`<`string`> --- ### getHeadHeight() > **getHeadHeight**(): `Promise`<`number`> Defined in: @nimiq/core/types/wasm/web.d.ts:950 Returns the block number of the current blockchain head. #### Returns `Promise`<`number`> --- ### getNetworkId() > **getNetworkId**(): `Promise`<`number`> Defined in: @nimiq/core/types/wasm/web.d.ts:954 Returns the network ID that the client is connecting to. #### Returns `Promise`<`number`> --- ### getProtocolVersion() > **getProtocolVersion**(): `Promise`<`number`> Defined in: @nimiq/core/types/wasm/web.d.ts:958 Returns the blockchain protocol version the client currently uses to verify transactions. #### Returns `Promise`<`number`> --- ### getStaker() > **getStaker**(`address`): `Promise`<[`PlainStaker`](https://nimiq.com/developers/../interfaces/PlainStaker)> Defined in: @nimiq/core/types/wasm/web.d.ts:964 Fetches the staker for the provided address from the network. Throws if the address cannot be parsed and on network errors. #### Parameters ##### address `string` | [`Address`](https://nimiq.com/developers/Address) | `Uint8Array`<`ArrayBufferLike`> #### Returns `Promise`<[`PlainStaker`](https://nimiq.com/developers/../interfaces/PlainStaker)> --- ### getStakers() > **getStakers**(`addresses`): `Promise`<[`PlainStaker`](https://nimiq.com/developers/../interfaces/PlainStaker)[] > Defined in: @nimiq/core/types/wasm/web.d.ts:970 Fetches the stakers for the provided addresses from the network. Throws if an address cannot be parsed and on network errors. #### Parameters ##### addresses (`string` | [`Address`](https://nimiq.com/developers/Address) | `Uint8Array`<`ArrayBufferLike`>) [] #### Returns `Promise`<[`PlainStaker`](https://nimiq.com/developers/../interfaces/PlainStaker)[] > --- ### getTransaction() > **getTransaction**(`hash`): `Promise`<[`PlainTransactionDetails`](https://nimiq.com/developers/../interfaces/PlainTransactionDetails)> Defined in: @nimiq/core/types/wasm/web.d.ts:974 Fetches the transaction details for the given transaction hash. #### Parameters ##### hash `string` #### Returns `Promise`<[`PlainTransactionDetails`](https://nimiq.com/developers/../interfaces/PlainTransactionDetails)> --- ### getTransactionReceiptsByAddress() > **getTransactionReceiptsByAddress**(`address`, `limit?`, `start_at?`, `min_peers?`): `Promise`<[`PlainTransactionReceipt`](https://nimiq.com/developers/../interfaces/PlainTransactionReceipt)[] > Defined in: @nimiq/core/types/wasm/web.d.ts:986 This function is used to query the network for transaction receipts from and to a specific address, that have been included in the chain. The obtained receipts are *not* verified before being returned. Up to a `limit` number of transaction receipts are returned from newest to oldest. It starts at the `start_at` transaction and goes backwards. If this hash does not exist or does not belong to the address, an empty list is returned. If the network does not have at least `min_peers` to query, then an error is returned. #### Parameters ##### address `string` | [`Address`](https://nimiq.com/developers/Address) | `Uint8Array`<`ArrayBufferLike`> ##### limit? `number` ##### start\_at? `string` ##### min\_peers? `number` #### Returns `Promise`<[`PlainTransactionReceipt`](https://nimiq.com/developers/../interfaces/PlainTransactionReceipt)[] > --- ### getTransactionsByAddress() > **getTransactionsByAddress**(`address`, `since_block_height?`, `known_transaction_details?`, `start_at?`, `limit?`, `min_peers?`): `Promise`<[`PlainTransactionDetails`](https://nimiq.com/developers/../interfaces/PlainTransactionDetails)[] > Defined in: @nimiq/core/types/wasm/web.d.ts:1008 This function is used to query the network for transactions from and to a specific address, that have been included in the chain. The obtained transactions are verified before being returned. If you already have transactions belonging to this address, you can provide some of that information to reduce the amount of network requests made: - Provide the `since_block_height` parameter to exclude any history from before that block height. You should be completely certain about its state. This should not be the last known block height, but an earlier block height that could not have been forked from (e.g. the last known election or checkpoint block). - Provide a list of `known_transaction_details` to have them verified and/or broadcasted again. - Provide a `start_at` parameter to start the query at a specific transaction hash (which will not be included). This hash must exist and the corresponding transaction must involve this address for the query to work correctly. Up to a `limit` number of transactions are returned from newest to oldest. If the network does not have at least `min_peers` to query, an error is returned. #### Parameters ##### address `string` | [`Address`](https://nimiq.com/developers/Address) | `Uint8Array`<`ArrayBufferLike`> ##### since\_block\_height? `number` ##### known\_transaction\_details? [`PlainTransactionDetails`](https://nimiq.com/developers/../interfaces/PlainTransactionDetails)[] ##### start\_at? `string` ##### limit? `number` ##### min\_peers? `number` #### Returns `Promise`<[`PlainTransactionDetails`](https://nimiq.com/developers/../interfaces/PlainTransactionDetails)[] > --- ### getValidator() > **getValidator**(`address`): `Promise`<[`PlainValidator`](https://nimiq.com/developers/../interfaces/PlainValidator)> Defined in: @nimiq/core/types/wasm/web.d.ts:1014 Fetches the validator for the provided address from the network. Throws if the address cannot be parsed and on network errors. #### Parameters ##### address `string` | [`Address`](https://nimiq.com/developers/Address) | `Uint8Array`<`ArrayBufferLike`> #### Returns `Promise`<[`PlainValidator`](https://nimiq.com/developers/../interfaces/PlainValidator)> --- ### getValidators() > **getValidators**(`addresses`): `Promise`<[`PlainValidator`](https://nimiq.com/developers/../interfaces/PlainValidator)[] > Defined in: @nimiq/core/types/wasm/web.d.ts:1020 Fetches the validators for the provided addresses from the network. Throws if an address cannot be parsed and on network errors. #### Parameters ##### addresses (`string` | [`Address`](https://nimiq.com/developers/Address) | `Uint8Array`<`ArrayBufferLike`>) [] #### Returns `Promise`<[`PlainValidator`](https://nimiq.com/developers/../interfaces/PlainValidator)[] > --- ### getVersion() > **getVersion**(): `Promise`<`string`> Defined in: @nimiq/core/types/wasm/web.d.ts:1025 Returns the version of the web client, including a `+dirty` build-metadata suffix when it was built from a Git work tree with uncommitted changes. #### Returns `Promise`<`string`> --- ### isConsensusEstablished() > **isConsensusEstablished**(): `Promise`<`boolean`> Defined in: @nimiq/core/types/wasm/web.d.ts:1029 Returns if the client currently has consensus with the network. #### Returns `Promise`<`boolean`> --- ### removeListener() > **removeListener**(`handle`): `Promise`<`void`> Defined in: @nimiq/core/types/wasm/web.d.ts:1033 Removes an event listener by its handle. #### Parameters ##### handle `number` #### Returns `Promise`<`void`> --- ### sendTransaction() > **sendTransaction**(`transaction`): `Promise`<[`PlainTransactionDetails`](https://nimiq.com/developers/../interfaces/PlainTransactionDetails)> Defined in: @nimiq/core/types/wasm/web.d.ts:1039 Sends a transaction to the network and returns [PlainTransactionDetails](https://nimiq.com/developers/../interfaces/PlainTransactionDetails). Throws in case of network errors. #### Parameters ##### transaction `string` | [`PlainTransaction`](https://nimiq.com/developers/../interfaces/PlainTransaction) | `Uint8Array`<`ArrayBufferLike`> | [`Transaction`](https://nimiq.com/developers/Transaction) #### Returns `Promise`<[`PlainTransactionDetails`](https://nimiq.com/developers/../interfaces/PlainTransactionDetails)> --- ### waitForConsensusEstablished() > **waitForConsensusEstablished**(): `Promise`<`void`> Defined in: @nimiq/core/types/wasm/web.d.ts:1043 Returns a promise that resolves when the client has established consensus with the network. #### Returns `Promise`<`void`> --- ### create() > `static` **create**(`config`): `Promise`<`Client`> Defined in: @nimiq/core/types/wasm/web.d.ts:882 Creates a new Client that automatically starts connecting to the network. #### Parameters ##### config [`PlainClientConfiguration`](https://nimiq.com/developers/../interfaces/PlainClientConfiguration) #### Returns `Promise`<`Client`> # Class: ClientConfiguration [@nimiq/core](https://nimiq.com/developers/../globals) / ClientConfiguration Defined in: @nimiq/core/types/wasm/web.d.ts:1051 Use this to provide initialization-time configuration to the Client. This is a simplified version of the configuration that is used for regular nodes, since not all configuration knobs are available when running inside a browser. ## Constructors ### Constructor > **new ClientConfiguration**(): `ClientConfiguration` Defined in: @nimiq/core/types/wasm/web.d.ts:1087 Creates a default client configuration that can be used to change the client's configuration. Use its `instantiateClient()` method to launch the client and connect to the network. #### Returns `ClientConfiguration` ## Methods ### \[dispose]\() > **\[dispose]**(): `void` Defined in: @nimiq/core/types/wasm/web.d.ts:1053 #### Returns `void` --- ### build() > **build**(): [`PlainClientConfiguration`](https://nimiq.com/developers/../interfaces/PlainClientConfiguration) Defined in: @nimiq/core/types/wasm/web.d.ts:1057 Returns a plain configuration object to be passed to `Client.create`. #### Returns [`PlainClientConfiguration`](https://nimiq.com/developers/../interfaces/PlainClientConfiguration) --- ### desiredPeerCount() > **desiredPeerCount**(`desired_peer_count`): `void` Defined in: @nimiq/core/types/wasm/web.d.ts:1062 Sets the desired number of peers the client should try to connect to. Default is `12`. #### Parameters ##### desired\_peer\_count `number` #### Returns `void` --- ### free() > **free**(): `void` Defined in: @nimiq/core/types/wasm/web.d.ts:1052 #### Returns `void` --- ### logLevel() > **logLevel**(`log_level`): `void` Defined in: @nimiq/core/types/wasm/web.d.ts:1069 Sets the log level that is used when logging to the console. Possible values are `'trace' | 'debug' | 'info' | 'warn' | 'error'`. Default is `'info'`. #### Parameters ##### log\_level `string` #### Returns `void` --- ### network() > **network**(`network`): `void` Defined in: @nimiq/core/types/wasm/web.d.ts:1076 Sets the network ID the client should use. Input is case-insensitive. Possible values are `'MainAlbatross' | 'TestAlbatross' | 'DevAlbatross'`. Default is `'MainAlbatross'`. #### Parameters ##### network `string` #### Returns `void` --- ### networkBufferSize() > **networkBufferSize**(`network_buffer_size`): `void` Defined in: @nimiq/core/types/wasm/web.d.ts:1081 Sets the maximum network buffer size, which should be greater than 0 Default is `1024`. #### Parameters ##### network\_buffer\_size `number` #### Returns `void` --- ### onlySecureWsConnections() > **onlySecureWsConnections**(`only_secure_ws_connections`): `void` Defined in: @nimiq/core/types/wasm/web.d.ts:1092 Sets whether the client should only connect to secure WebSocket connections. Default is `true`. #### Parameters ##### only\_secure\_ws\_connections `boolean` #### Returns `void` --- ### peerCountMax() > **peerCountMax**(`peer_count_max`): `void` Defined in: @nimiq/core/types/wasm/web.d.ts:1097 Sets the maximum number of peers the client should connect to. Default is `50`. #### Parameters ##### peer\_count\_max `number` #### Returns `void` --- ### peerCountPerIpMax() > **peerCountPerIpMax**(`peer_count_per_ip_max`): `void` Defined in: @nimiq/core/types/wasm/web.d.ts:1102 Sets the maximum number of peers the client should connect to per IP address. Default is `10`. #### Parameters ##### peer\_count\_per\_ip\_max `number` #### Returns `void` --- ### peerCountPerSubnetMax() > **peerCountPerSubnetMax**(`peer_count_per_subnet_max`): `void` Defined in: @nimiq/core/types/wasm/web.d.ts:1107 Sets the maximum number of peers the client should connect to per subnet. Default is `10`. #### Parameters ##### peer\_count\_per\_subnet\_max `number` #### Returns `void` --- ### seedNodes() > **seedNodes**(`seeds`): `void` Defined in: @nimiq/core/types/wasm/web.d.ts:1115 Sets the list of seed nodes that are used to connect to the Nimiq Albatross network. Each array entry must be a proper Multiaddr format string. Throws when an entry cannot be deserialized as a string. #### Parameters ##### seeds `any`[] #### Returns `void` --- ### syncMode() > **syncMode**(`sync_mode`): `void` Defined in: @nimiq/core/types/wasm/web.d.ts:1121 Sets the sync mode that should be used. Only "light" and "pico" are supported for web clients Default is "pico" #### Parameters ##### sync\_mode `string` #### Returns `void` # Class: Commitment [@nimiq/core](https://nimiq.com/developers/../globals) / Commitment Defined in: @nimiq/core/types/wasm/web.d.ts:1127 A cryptographic commitment to a [RandomSecret](https://nimiq.com/developers/RandomSecret). The commitment is public, while the secret is, well, secret. ## Constructors ### Constructor > **new Commitment**(`bytes`): `Commitment` Defined in: @nimiq/core/types/wasm/web.d.ts:1162 Creates a new commitment from a byte array. Throws when the byte array is not exactly 32 bytes long. #### Parameters ##### bytes `Uint8Array` #### Returns `Commitment` ## Properties ### serializedSize > `readonly` **serializedSize**: `number` Defined in: @nimiq/core/types/wasm/web.d.ts:1188 --- ### SIZE > `readonly` `static` **SIZE**: `number` Defined in: @nimiq/core/types/wasm/web.d.ts:1189 ## Methods ### \_\_getClassname() > **\_\_getClassname**(): `string` Defined in: @nimiq/core/types/wasm/web.d.ts:1130 #### Returns `string` --- ### \[dispose]\() > **\[dispose]**(): `void` Defined in: @nimiq/core/types/wasm/web.d.ts:1129 #### Returns `void` --- ### equals() > **equals**(`other`): `boolean` Defined in: @nimiq/core/types/wasm/web.d.ts:1144 Returns if this commitment is equal to the other commitment. #### Parameters ##### other `Commitment` #### Returns `boolean` --- ### free() > **free**(): `void` Defined in: @nimiq/core/types/wasm/web.d.ts:1128 #### Returns `void` --- ### serialize() > **serialize**(): `Uint8Array` Defined in: @nimiq/core/types/wasm/web.d.ts:1166 Serializes the commitment to a byte array. #### Returns `Uint8Array` --- ### toHex() > **toHex**(): `string` Defined in: @nimiq/core/types/wasm/web.d.ts:1187 Formats the commitment into a hex string. #### Returns `string` --- ### derive() > `static` **derive**(`random_secret`): `Commitment` Defined in: @nimiq/core/types/wasm/web.d.ts:1134 Derives a commitment from an existing random secret. #### Parameters ##### random\_secret [`RandomSecret`](https://nimiq.com/developers/RandomSecret) #### Returns `Commitment` --- ### deserialize() > `static` **deserialize**(`bytes`): `Commitment` Defined in: @nimiq/core/types/wasm/web.d.ts:1140 Deserializes a commitment from a byte array. Throws when the byte array contains less than 32 bytes. #### Parameters ##### bytes `Uint8Array` #### Returns `Commitment` --- ### fromAny() > `static` **fromAny**(`commitment`): `Commitment` Defined in: @nimiq/core/types/wasm/web.d.ts:1150 Parses a commitment from a Commitment instance, a hex string representation, or a byte array. Throws when a Commitment cannot be parsed from the argument. #### Parameters ##### commitment `string` | `Uint8Array`<`ArrayBufferLike`> | `Commitment` #### Returns `Commitment` --- ### fromHex() > `static` **fromHex**(`hex`): `Commitment` Defined in: @nimiq/core/types/wasm/web.d.ts:1156 Parses a commitment from its hex representation. Throws when the string is not valid hex format or when it represents less than 32 bytes. #### Parameters ##### hex `string` #### Returns `Commitment` --- ### sum() > `static` **sum**(`commitments`): `Commitment` Defined in: @nimiq/core/types/wasm/web.d.ts:1172 Sums up multiple commitments into one aggregated commitment. Attention: This is a simple summation, not a MuSig2 aggregation! For MuSig2 aggregation, use [Commitment.sumMuSig2](https://nimiq.com/developers/#summusig2). #### Parameters ##### commitments (`string` | `Uint8Array`<`ArrayBufferLike`> | `Commitment`) [] #### Returns `Commitment` --- ### sumMuSig2() > `static` **sumMuSig2**(`public_keys`, `commitment_groups`, `data`): `Commitment` Defined in: @nimiq/core/types/wasm/web.d.ts:1183 Aggregates commitments into one aggregated commitment using the MuSig2 scheme. - Each commitment group must correspond to the public key at the same index in the `publicKeys` array. - The number of commitment groups and public keys must be the same. - Each commitment group must contain exactly `MUSIG2_PARAMETER_V = 2` commitments. - The `data` parameter is the same data that will be signed using the aggregated commitment, e.g. the serialized content of a transaction. Returns the aggregated commitment. #### Parameters ##### public\_keys (`string` | `Uint8Array`<`ArrayBufferLike`> | [`PublicKey`](https://nimiq.com/developers/PublicKey)) [] ##### commitment\_groups (`string` | `Uint8Array`<`ArrayBufferLike`> | `Commitment`)\[] [] ##### data `Uint8Array` #### Returns `Commitment` # Class: CommitmentPair [@nimiq/core](https://nimiq.com/developers/../globals) / CommitmentPair Defined in: @nimiq/core/types/wasm/web.d.ts:1196 A structure holding both a random secret and its corresponding public commitment. This is similar to a `KeyPair`. ## Constructors ### Constructor > **new CommitmentPair**(`random_secret`, `commitment`): `CommitmentPair` Defined in: @nimiq/core/types/wasm/web.d.ts:1227 #### Parameters ##### random\_secret [`RandomSecret`](https://nimiq.com/developers/RandomSecret) ##### commitment [`Commitment`](https://nimiq.com/developers/Commitment) #### Returns `CommitmentPair` ## Properties ### commitment > `readonly` **commitment**: [`Commitment`](https://nimiq.com/developers/Commitment) Defined in: @nimiq/core/types/wasm/web.d.ts:1236 --- ### secret > `readonly` **secret**: [`RandomSecret`](https://nimiq.com/developers/RandomSecret) Defined in: @nimiq/core/types/wasm/web.d.ts:1237 --- ### serializedSize > `readonly` **serializedSize**: `number` Defined in: @nimiq/core/types/wasm/web.d.ts:1238 --- ### SIZE > `readonly` `static` **SIZE**: `number` Defined in: @nimiq/core/types/wasm/web.d.ts:1239 ## Methods ### \_\_getClassname() > **\_\_getClassname**(): `string` Defined in: @nimiq/core/types/wasm/web.d.ts:1199 #### Returns `string` --- ### \[dispose]\() > **\[dispose]**(): `void` Defined in: @nimiq/core/types/wasm/web.d.ts:1198 #### Returns `void` --- ### equals() > **equals**(`other`): `boolean` Defined in: @nimiq/core/types/wasm/web.d.ts:1213 Returns if this commitment pair is equal to the other commitment pair. #### Parameters ##### other `CommitmentPair` #### Returns `boolean` --- ### free() > **free**(): `void` Defined in: @nimiq/core/types/wasm/web.d.ts:1197 #### Returns `void` --- ### serialize() > **serialize**(): `Uint8Array` Defined in: @nimiq/core/types/wasm/web.d.ts:1231 Serializes the commitment pair to a byte array. #### Returns `Uint8Array` --- ### toHex() > **toHex**(): `string` Defined in: @nimiq/core/types/wasm/web.d.ts:1235 Formats the commitment pair into a hex string. #### Returns `string` --- ### derive() > `static` **derive**(`random_secret`): `CommitmentPair` Defined in: @nimiq/core/types/wasm/web.d.ts:1203 Derives a commitment pair from an existing random secret. #### Parameters ##### random\_secret [`RandomSecret`](https://nimiq.com/developers/RandomSecret) #### Returns `CommitmentPair` --- ### deserialize() > `static` **deserialize**(`bytes`): `CommitmentPair` Defined in: @nimiq/core/types/wasm/web.d.ts:1209 Deserializes a commitment pair from a byte array. Throws when the byte array contains less than 32 bytes. #### Parameters ##### bytes `Uint8Array` #### Returns `CommitmentPair` --- ### fromAny() > `static` **fromAny**(`pair`): `CommitmentPair` Defined in: @nimiq/core/types/wasm/web.d.ts:1219 Parses a commitment pair from a CommitmentPair instance, a hex string representation, or a byte array. Throws when a CommitmentPair cannot be parsed from the argument. #### Parameters ##### pair `string` | `Uint8Array`<`ArrayBufferLike`> | `CommitmentPair` #### Returns `CommitmentPair` --- ### fromHex() > `static` **fromHex**(`hex`): `CommitmentPair` Defined in: @nimiq/core/types/wasm/web.d.ts:1225 Parses a commitment pair from its hex representation. Throws when the string is not valid hex format or when it represents less than 32 bytes. #### Parameters ##### hex `string` #### Returns `CommitmentPair` --- ### generate() > `static` **generate**(): `CommitmentPair` Defined in: @nimiq/core/types/wasm/web.d.ts:1226 #### Returns `CommitmentPair` # Class: CryptoUtils [@nimiq/core](https://nimiq.com/developers/../globals) / CryptoUtils Defined in: @nimiq/core/types/wasm/web.d.ts:1242 ## Methods ### \[dispose]\() > **\[dispose]**(): `void` Defined in: @nimiq/core/types/wasm/web.d.ts:1245 #### Returns `void` --- ### free() > **free**(): `void` Defined in: @nimiq/core/types/wasm/web.d.ts:1244 #### Returns `void` --- ### computeHmacSha512() > `static` **computeHmacSha512**(`key`, `data`): `Uint8Array` Defined in: @nimiq/core/types/wasm/web.d.ts:1251 Computes a 64-byte [HMAC] -SHA512 hash from the input key and data. #### Parameters ##### key `Uint8Array` ##### data `Uint8Array` #### Returns `Uint8Array` --- ### computePBKDF2sha512() > `static` **computePBKDF2sha512**(`password`, `salt`, `iterations`, `derived_key_length`): `Uint8Array` Defined in: @nimiq/core/types/wasm/web.d.ts:1257 Computes a [PBKDF2] -over-SHA512 key from the password with the given parameters. #### Parameters ##### password `Uint8Array` ##### salt `Uint8Array` ##### iterations `number` ##### derived\_key\_length `number` #### Returns `Uint8Array` --- ### getRandomValues() > `static` **getRandomValues**(`length`): `Uint8Array` Defined in: @nimiq/core/types/wasm/web.d.ts:1261 Generates a secure random byte array of the given length. #### Parameters ##### length `number` #### Returns `Uint8Array` --- ### otpKdf() > `static` **otpKdf**(`message`, `key`, `salt`, `iterations`): `Promise`<`Uint8Array`<`ArrayBufferLike`>> Defined in: @nimiq/core/types/wasm/web.d.ts:1269 Encrypts a message with an [OTP] [KDF] and the given parameters. The KDF uses Argon2d for hashing. #### Parameters ##### message `Uint8Array` ##### key `Uint8Array` ##### salt `Uint8Array` ##### iterations `number` #### Returns `Promise`<`Uint8Array`<`ArrayBufferLike`>> # Class: ES256PublicKey [@nimiq/core](https://nimiq.com/developers/../globals) / ES256PublicKey Defined in: @nimiq/core/types/wasm/web.d.ts:1275 The non-secret (public) part of an ES256 asymmetric key pair that is typically used to digitally verify or encrypt data. ## Constructors ### Constructor > **new ES256PublicKey**(`bytes`): `ES256PublicKey` Defined in: @nimiq/core/types/wasm/web.d.ts:1333 Creates a new public key from a byte array. Compatible with the `-7` COSE algorithm identifier. ## Example ```javascript // Create/register a credential with the Webauthn API: const cred = await navigator.credentials.create({ publicKey: { pubKeyCredParams: [{ type: "public-key", alg: -7, // ES256 = ECDSA over P-256 with SHA-256 }], // ... }, }); // Then create an instance of ES256PublicKey from the credential response: const publicKey = new Nimiq.ES256PublicKey(new Uint8Array(cred.response.getPublicKey())); ``` #### Parameters ##### bytes `Uint8Array` #### Returns `ES256PublicKey` ## Methods ### \_\_getClassname() > **\_\_getClassname**(): `string` Defined in: @nimiq/core/types/wasm/web.d.ts:1278 #### Returns `string` --- ### \[dispose]\() > **\[dispose]**(): `void` Defined in: @nimiq/core/types/wasm/web.d.ts:1277 #### Returns `void` --- ### compare() > **compare**(`other`): `number` Defined in: @nimiq/core/types/wasm/web.d.ts:1285 Compares this public key to the other public key. Returns -1 if this public key is smaller than the other public key, 0 if they are equal, and 1 if this public key is larger than the other public key. #### Parameters ##### other `ES256PublicKey` #### Returns `number` --- ### equals() > **equals**(`other`): `boolean` Defined in: @nimiq/core/types/wasm/web.d.ts:1295 Returns if this public key is equal to the other public key. #### Parameters ##### other `ES256PublicKey` #### Returns `boolean` --- ### free() > **free**(): `void` Defined in: @nimiq/core/types/wasm/web.d.ts:1276 #### Returns `void` --- ### serialize() > **serialize**(): `Uint8Array` Defined in: @nimiq/core/types/wasm/web.d.ts:1337 Serializes the public key to a byte array. #### Returns `Uint8Array` --- ### toAddress() > **toAddress**(): [`Address`](https://nimiq.com/developers/Address) Defined in: @nimiq/core/types/wasm/web.d.ts:1341 Gets the public key's address. #### Returns [`Address`](https://nimiq.com/developers/Address) --- ### toHex() > **toHex**(): `string` Defined in: @nimiq/core/types/wasm/web.d.ts:1345 Formats the public key into a hex string. #### Returns `string` --- ### verify() > **verify**(`signature`, `data`): `boolean` Defined in: @nimiq/core/types/wasm/web.d.ts:1349 Verifies that a signature is valid for this public key and the provided data. #### Parameters ##### signature [`ES256Signature`](https://nimiq.com/developers/ES256Signature) ##### data `Uint8Array` #### Returns `boolean` --- ### deserialize() > `static` **deserialize**(`bytes`): `ES256PublicKey` Defined in: @nimiq/core/types/wasm/web.d.ts:1291 Deserializes a public key from a byte array. Throws when the byte array contains less than 33 bytes. #### Parameters ##### bytes `Uint8Array` #### Returns `ES256PublicKey` --- ### fromHex() > `static` **fromHex**(`hex`): `ES256PublicKey` Defined in: @nimiq/core/types/wasm/web.d.ts:1301 Parses a public key from its hex representation. Throws when the string is not valid hex format or when it represents less than 33 bytes. #### Parameters ##### hex `string` #### Returns `ES256PublicKey` --- ### fromRaw() > `static` **fromRaw**(`raw_bytes`): `ES256PublicKey` Defined in: @nimiq/core/types/wasm/web.d.ts:1305 Deserializes a public key from its raw representation. #### Parameters ##### raw\_bytes `Uint8Array` #### Returns `ES256PublicKey` --- ### fromSpki() > `static` **fromSpki**(`spki_bytes`): `ES256PublicKey` Defined in: @nimiq/core/types/wasm/web.d.ts:1309 Deserializes a public key from its SPKI representation. #### Parameters ##### spki\_bytes `Uint8Array` #### Returns `ES256PublicKey` # Class: ES256Signature [@nimiq/core](https://nimiq.com/developers/../globals) / ES256Signature Defined in: @nimiq/core/types/wasm/web.d.ts:1356 An ES256 Signature represents a cryptographic proof that an ES256 private key signed some data. It can be verified with the private key's public key. ## Methods ### \_\_getClassname() > **\_\_getClassname**(): `string` Defined in: @nimiq/core/types/wasm/web.d.ts:1360 #### Returns `string` --- ### \[dispose]\() > **\[dispose]**(): `void` Defined in: @nimiq/core/types/wasm/web.d.ts:1359 #### Returns `void` --- ### free() > **free**(): `void` Defined in: @nimiq/core/types/wasm/web.d.ts:1358 #### Returns `void` --- ### serialize() > **serialize**(): `Uint8Array` Defined in: @nimiq/core/types/wasm/web.d.ts:1380 Serializes the signature to a byte array. #### Returns `Uint8Array` --- ### toHex() > **toHex**(): `string` Defined in: @nimiq/core/types/wasm/web.d.ts:1384 Formats the signature into a hex string. #### Returns `string` --- ### deserialize() > `static` **deserialize**(`bytes`): `ES256Signature` Defined in: @nimiq/core/types/wasm/web.d.ts:1366 Deserializes an ES256 signature from a byte array. Throws when the byte array contains less than 64 bytes. #### Parameters ##### bytes `Uint8Array` #### Returns `ES256Signature` --- ### fromAsn1() > `static` **fromAsn1**(`bytes`): `ES256Signature` Defined in: @nimiq/core/types/wasm/web.d.ts:1370 Parses an ES256 signature from its ASN.1 representation. #### Parameters ##### bytes `Uint8Array` #### Returns `ES256Signature` --- ### fromHex() > `static` **fromHex**(`hex`): `ES256Signature` Defined in: @nimiq/core/types/wasm/web.d.ts:1376 Parses an ES256 signature from its hex representation. Throws when the string is not valid hex format or when it represents less than 64 bytes. #### Parameters ##### hex `string` #### Returns `ES256Signature` # Class: Entropy [@nimiq/core](https://nimiq.com/developers/../globals) / Entropy Defined in: @nimiq/core/lib/index.d.ts:206 ## Extends - [`Secret`](https://nimiq.com/developers/Secret) ## Constructors ### Constructor > **new Entropy**(`arg`): `Entropy` Defined in: @nimiq/core/lib/index.d.ts:213 Creates a new Entropy from a byte array. #### Parameters ##### arg `Uint8Array` #### Returns `Entropy` #### Overrides [`Secret`](https://nimiq.com/developers/Secret).[`constructor`](https://nimiq.com/developers/Secret#constructor) ## Properties ### ENCRYPTION\_CHECKSUM\_SIZE > `static` **ENCRYPTION\_CHECKSUM\_SIZE**: `number` Defined in: @nimiq/core/lib/index.d.ts:181 #### Inherited from [`Secret`](https://nimiq.com/developers/Secret).[`ENCRYPTION_CHECKSUM_SIZE`](https://nimiq.com/developers/Secret#encryption_checksum_size) --- ### ENCRYPTION\_CHECKSUM\_SIZE\_V3 > `static` **ENCRYPTION\_CHECKSUM\_SIZE\_V3**: `number` Defined in: @nimiq/core/lib/index.d.ts:182 #### Inherited from [`Secret`](https://nimiq.com/developers/Secret).[`ENCRYPTION_CHECKSUM_SIZE_V3`](https://nimiq.com/developers/Secret#encryption_checksum_size_v3) --- ### ENCRYPTION\_KDF\_ROUNDS > `static` **ENCRYPTION\_KDF\_ROUNDS**: `number` Defined in: @nimiq/core/lib/index.d.ts:180 #### Inherited from [`Secret`](https://nimiq.com/developers/Secret).[`ENCRYPTION_KDF_ROUNDS`](https://nimiq.com/developers/Secret#encryption_kdf_rounds) --- ### ENCRYPTION\_SALT\_SIZE > `static` **ENCRYPTION\_SALT\_SIZE**: `number` Defined in: @nimiq/core/lib/index.d.ts:179 #### Inherited from [`Secret`](https://nimiq.com/developers/Secret).[`ENCRYPTION_SALT_SIZE`](https://nimiq.com/developers/Secret#encryption_salt_size) --- ### PURPOSE\_ID > `static` **PURPOSE\_ID**: `number` Defined in: @nimiq/core/lib/index.d.ts:208 --- ### SIZE > `static` **SIZE**: `number` Defined in: @nimiq/core/lib/index.d.ts:207 #### Overrides [`Secret`](https://nimiq.com/developers/Secret).[`SIZE`](https://nimiq.com/developers/Secret#size) ## Accessors ### encryptedSize #### Get Signature > **get** **encryptedSize**(): `number` Defined in: @nimiq/core/lib/index.d.ts:196 Returns the serialized size of this object when encrypted. ##### Returns `number` #### Inherited from [`Secret`](https://nimiq.com/developers/Secret).[`encryptedSize`](https://nimiq.com/developers/Secret#encryptedsize) --- ### serializedSize #### Get Signature > **get** **serializedSize**(): `number` Defined in: @nimiq/core/lib/index.d.ts:241 Returns the serialized size of this Entropy. ##### Returns `number` ## Methods ### compare() > **compare**(`o`): `number` Defined in: @nimiq/core/lib/index.d.ts:97 Compares this object to another object. Returns a negative number if `this` is smaller than o, a positive number if `this` is larger than o, and zero if equal. #### Parameters ##### o `Serializable` #### Returns `number` #### Inherited from [`Secret`](https://nimiq.com/developers/Secret).[`compare`](https://nimiq.com/developers/Secret#compare) --- ### equals() > **equals**(`o`): `boolean` Defined in: @nimiq/core/lib/index.d.ts:249 Checks for equality with another Entropy. #### Parameters ##### o `unknown` #### Returns `boolean` #### Overrides [`Secret`](https://nimiq.com/developers/Secret).[`equals`](https://nimiq.com/developers/Secret#equals) --- ### exportEncrypted() > **exportEncrypted**(`key`): `Promise`<[`SerialBuffer`](https://nimiq.com/developers/SerialBuffer)> Defined in: @nimiq/core/lib/index.d.ts:192 Encrypts the Secret with a password. #### Parameters ##### key `Uint8Array` #### Returns `Promise`<[`SerialBuffer`](https://nimiq.com/developers/SerialBuffer)> #### Inherited from [`Secret`](https://nimiq.com/developers/Secret).[`exportEncrypted`](https://nimiq.com/developers/Secret#exportencrypted) --- ### overwrite() > **overwrite**(`entropy`): `void` Defined in: @nimiq/core/lib/index.d.ts:245 Overwrites this Entropy's bytes with a replacement in-memory #### Parameters ##### entropy `Entropy` #### Returns `void` --- ### serialize() > **serialize**(`buf?`): [`SerialBuffer`](https://nimiq.com/developers/SerialBuffer) Defined in: @nimiq/core/lib/index.d.ts:237 Serializes the Entropy to a byte array. #### Parameters ##### buf? [`SerialBuffer`](https://nimiq.com/developers/SerialBuffer) #### Returns [`SerialBuffer`](https://nimiq.com/developers/SerialBuffer) #### Overrides [`Secret`](https://nimiq.com/developers/Secret).[`serialize`](https://nimiq.com/developers/Secret#serialize) --- ### toBase64() > **toBase64**(): `string` Defined in: @nimiq/core/lib/index.d.ts:106 Formats the object into a base64 string. #### Returns `string` #### Inherited from [`Secret`](https://nimiq.com/developers/Secret).[`toBase64`](https://nimiq.com/developers/Secret#tobase64) --- ### toExtendedPrivateKey() > **toExtendedPrivateKey**(`password?`, `wordlist?`): [`ExtendedPrivateKey`](https://nimiq.com/developers/ExtendedPrivateKey) Defined in: @nimiq/core/lib/index.d.ts:221 Derives an ExtendedPrivateKey from the Entropy. #### Parameters ##### password? `string` ##### wordlist? `string`[] #### Returns [`ExtendedPrivateKey`](https://nimiq.com/developers/ExtendedPrivateKey) --- ### toHex() > **toHex**(): `string` Defined in: @nimiq/core/lib/index.d.ts:110 Formats the object into a hex string. #### Returns `string` #### Inherited from [`Secret`](https://nimiq.com/developers/Secret).[`toHex`](https://nimiq.com/developers/Secret#tohex) --- ### toMnemonic() > **toMnemonic**(`wordlist?`): `string`[] Defined in: @nimiq/core/lib/index.d.ts:225 Converts the Entropy into a mnemonic. #### Parameters ##### wordlist? `string`[] #### Returns `string`[] --- ### toString() > **toString**(): `string` Defined in: @nimiq/core/lib/index.d.ts:102 Formats the object into a hex string. #### Returns `string` #### Inherited from [`Secret`](https://nimiq.com/developers/Secret).[`toString`](https://nimiq.com/developers/Secret#tostring) --- ### deserialize() > `static` **deserialize**(`buf`): `Entropy` Defined in: @nimiq/core/lib/index.d.ts:229 Deserializes an Entropy object from a byte array. #### Parameters ##### buf [`SerialBuffer`](https://nimiq.com/developers/SerialBuffer) #### Returns `Entropy` --- ### exportEncrypted() > `static` **exportEncrypted**(`secret`, `key`): `Promise`<[`SerialBuffer`](https://nimiq.com/developers/SerialBuffer)> Defined in: @nimiq/core/lib/index.d.ts:188 #### Parameters ##### secret [`Secret`](https://nimiq.com/developers/Secret) | `PrivateKey` ##### key `Uint8Array` #### Returns `Promise`<[`SerialBuffer`](https://nimiq.com/developers/SerialBuffer)> #### Inherited from [`Secret`](https://nimiq.com/developers/Secret).[`exportEncrypted`](https://nimiq.com/developers/Secret#exportencrypted-2) --- ### fromEncrypted() > `static` **fromEncrypted**(`buf`, `key`): `Promise`<`Entropy` | `PrivateKey`> Defined in: @nimiq/core/lib/index.d.ts:187 Decrypts a Secret from an encrypted byte array and its password. #### Parameters ##### buf [`SerialBuffer`](https://nimiq.com/developers/SerialBuffer) ##### key `Uint8Array` #### Returns `Promise`<`Entropy` | `PrivateKey`> #### Inherited from [`Secret`](https://nimiq.com/developers/Secret).[`fromEncrypted`](https://nimiq.com/developers/Secret#fromencrypted) --- ### fromHex() > `static` **fromHex**(`hex`): `Entropy` Defined in: @nimiq/core/lib/index.d.ts:233 Deserializes an Entropy object from a hex string. #### Parameters ##### hex `string` #### Returns `Entropy` --- ### generate() > `static` **generate**(): `Entropy` Defined in: @nimiq/core/lib/index.d.ts:217 Generates a new Entropy object from secure randomness. #### Returns `Entropy` # Class: ExtendedPrivateKey [@nimiq/core](https://nimiq.com/developers/../globals) / ExtendedPrivateKey Defined in: @nimiq/core/lib/index.d.ts:113 ## Extends - `Serializable` ## Constructors ### Constructor > **new ExtendedPrivateKey**(`key`, `chainCode`): `ExtendedPrivateKey` Defined in: @nimiq/core/lib/index.d.ts:120 Creates an ExtendedPrivateKey from a private key and chain code. #### Parameters ##### key `PrivateKey` ##### chainCode `Uint8Array` #### Returns `ExtendedPrivateKey` #### Overrides `Serializable.constructor` ## Properties ### CHAIN\_CODE\_SIZE > `static` **CHAIN\_CODE\_SIZE**: `number` Defined in: @nimiq/core/lib/index.d.ts:114 ## Accessors ### chainCode #### Get Signature > **get** **chainCode**(): `Uint8Array` Defined in: @nimiq/core/lib/index.d.ts:168 Returns the chain code of this ExtendedPrivateKey. ##### Returns `Uint8Array` --- ### privateKey #### Get Signature > **get** **privateKey**(): `PrivateKey` Defined in: @nimiq/core/lib/index.d.ts:164 Returns the private key of this ExtendedPrivateKey. ##### Returns `PrivateKey` --- ### serializedSize #### Get Signature > **get** **serializedSize**(): `number` Defined in: @nimiq/core/lib/index.d.ts:156 Returns the serialized size of this ExtendedPrivateKey. ##### Returns `number` ## Methods ### compare() > **compare**(`o`): `number` Defined in: @nimiq/core/lib/index.d.ts:97 Compares this object to another object. Returns a negative number if `this` is smaller than o, a positive number if `this` is larger than o, and zero if equal. #### Parameters ##### o `Serializable` #### Returns `number` #### Inherited from `Serializable.compare` --- ### derive() > **derive**(`index`): `ExtendedPrivateKey` Defined in: @nimiq/core/lib/index.d.ts:128 Derives a child ExtendedPrivateKey from the current key at the provided index. #### Parameters ##### index `number` #### Returns `ExtendedPrivateKey` --- ### derivePath() > **derivePath**(`path`): `ExtendedPrivateKey` Defined in: @nimiq/core/lib/index.d.ts:136 Derives a child ExtendedPrivateKey from the current key at the provided path. #### Parameters ##### path `string` #### Returns `ExtendedPrivateKey` --- ### equals() > **equals**(`o`): `boolean` Defined in: @nimiq/core/lib/index.d.ts:160 Checks for equality with another ExtendedPrivateKey. #### Parameters ##### o `unknown` #### Returns `boolean` #### Overrides `Serializable.equals` --- ### serialize() > **serialize**(`buf?`): [`SerialBuffer`](https://nimiq.com/developers/SerialBuffer) Defined in: @nimiq/core/lib/index.d.ts:152 Serializes the ExtendedPrivateKey to a byte array. #### Parameters ##### buf? [`SerialBuffer`](https://nimiq.com/developers/SerialBuffer) #### Returns [`SerialBuffer`](https://nimiq.com/developers/SerialBuffer) #### Overrides `Serializable.serialize` --- ### toAddress() > **toAddress**(): `Address` Defined in: @nimiq/core/lib/index.d.ts:172 Returns the address related to this ExtendedPrivateKey. #### Returns `Address` --- ### toBase64() > **toBase64**(): `string` Defined in: @nimiq/core/lib/index.d.ts:106 Formats the object into a base64 string. #### Returns `string` #### Inherited from `Serializable.toBase64` --- ### toHex() > **toHex**(): `string` Defined in: @nimiq/core/lib/index.d.ts:110 Formats the object into a hex string. #### Returns `string` #### Inherited from `Serializable.toHex` --- ### toString() > **toString**(): `string` Defined in: @nimiq/core/lib/index.d.ts:102 Formats the object into a hex string. #### Returns `string` #### Inherited from `Serializable.toString` --- ### derivePathFromSeed() > `static` **derivePathFromSeed**(`path`, `seed`): `ExtendedPrivateKey` Defined in: @nimiq/core/lib/index.d.ts:140 Derives an ExtendedPrivateKey from a seed and a derivation path. #### Parameters ##### path `string` ##### seed `Uint8Array` #### Returns `ExtendedPrivateKey` --- ### deserialize() > `static` **deserialize**(`buf`): `ExtendedPrivateKey` Defined in: @nimiq/core/lib/index.d.ts:144 Deserializes an ExtendedPrivateKey from a byte array. #### Parameters ##### buf [`SerialBuffer`](https://nimiq.com/developers/SerialBuffer) #### Returns `ExtendedPrivateKey` --- ### fromHex() > `static` **fromHex**(`hex`): `ExtendedPrivateKey` Defined in: @nimiq/core/lib/index.d.ts:148 Deserializes an ExtendedPrivateKey from a hex string. #### Parameters ##### hex `string` #### Returns `ExtendedPrivateKey` --- ### generateMasterKey() > `static` **generateMasterKey**(`seed`): `ExtendedPrivateKey` Defined in: @nimiq/core/lib/index.d.ts:124 Generates the master ExtendedPrivateKey from a seed. #### Parameters ##### seed `Uint8Array` #### Returns `ExtendedPrivateKey` --- ### isValidPath() > `static` **isValidPath**(`path`): `boolean` Defined in: @nimiq/core/lib/index.d.ts:132 Tests if a HD derivation path is valid. #### Parameters ##### path `string` #### Returns `boolean` # Class: Hash [@nimiq/core](https://nimiq.com/developers/../globals) / Hash Defined in: @nimiq/core/types/wasm/web.d.ts:1387 ## Methods ### \[dispose]\() > **\[dispose]**(): `void` Defined in: @nimiq/core/types/wasm/web.d.ts:1390 #### Returns `void` --- ### free() > **free**(): `void` Defined in: @nimiq/core/types/wasm/web.d.ts:1389 #### Returns `void` --- ### computeBlake2b() > `static` **computeBlake2b**(`data`): `Uint8Array` Defined in: @nimiq/core/types/wasm/web.d.ts:1398 Computes a 32-byte [Blake2b] hash from the input data. Blake2b is used for example to compute a public key's address. #### Parameters ##### data `Uint8Array` #### Returns `Uint8Array` --- ### computeNimiqArgon2d() > `static` **computeNimiqArgon2d**(`password`, `salt`, `iterations`, `derived_key_length`): `Uint8Array` Defined in: @nimiq/core/types/wasm/web.d.ts:1411 Computes an [Argon2d] hash with some Nimiq-specific parameters. `iterations` specifies the number of iterations done in the hash function. It can be used to control the hash computation time. Increasing this will make it harder for an attacker to brute-force the password. `derived_key_length` specifies the number of bytes that are output. #### Parameters ##### password `Uint8Array` ##### salt `Uint8Array` ##### iterations `number` ##### derived\_key\_length `number` #### Returns `Uint8Array` --- ### computeNimiqArgon2id() > `static` **computeNimiqArgon2id**(`password`, `salt`, `iterations`, `derived_key_length`): `Uint8Array` Defined in: @nimiq/core/types/wasm/web.d.ts:1424 Computes an [Argon2id] hash with some Nimiq-specific parameters. `iterations` specifies the number of iterations done in the hash function. It can be used to control the hash computation time. Increasing this will make it harder for an attacker to brute-force the password. `derived_key_length` specifies the number of bytes that are output. #### Parameters ##### password `Uint8Array` ##### salt `Uint8Array` ##### iterations `number` ##### derived\_key\_length `number` #### Returns `Uint8Array` --- ### computeSha256() > `static` **computeSha256**(`data`): `Uint8Array` Defined in: @nimiq/core/types/wasm/web.d.ts:1430 Computes a 32-byte [SHA256] hash from the input data. #### Parameters ##### data `Uint8Array` #### Returns `Uint8Array` --- ### computeSha512() > `static` **computeSha512**(`data`): `Uint8Array` Defined in: @nimiq/core/types/wasm/web.d.ts:1436 Computes a 64-byte [SHA512] hash from the input data. #### Parameters ##### data `Uint8Array` #### Returns `Uint8Array` # Class: HashedTimeLockedContract [@nimiq/core](https://nimiq.com/developers/../globals) / HashedTimeLockedContract Defined in: @nimiq/core/types/wasm/web.d.ts:1442 Utility class providing methods to parse Hashed Time Locked Contract transaction data and proofs. ## Methods ### \[dispose]\() > **\[dispose]**(): `void` Defined in: @nimiq/core/types/wasm/web.d.ts:1445 #### Returns `void` --- ### free() > **free**(): `void` Defined in: @nimiq/core/types/wasm/web.d.ts:1444 #### Returns `void` --- ### dataToPlain() > `static` **dataToPlain**(`data`): [`PlainTransactionRecipientData`](https://nimiq.com/developers/../type-aliases/PlainTransactionRecipientData) Defined in: @nimiq/core/types/wasm/web.d.ts:1449 Parses the data of a Hashed Time Locked Contract creation transaction into a plain object. #### Parameters ##### data `Uint8Array` #### Returns [`PlainTransactionRecipientData`](https://nimiq.com/developers/../type-aliases/PlainTransactionRecipientData) --- ### proofToPlain() > `static` **proofToPlain**(`proof`): [`PlainTransactionProof`](https://nimiq.com/developers/../type-aliases/PlainTransactionProof) Defined in: @nimiq/core/types/wasm/web.d.ts:1453 Parses the proof of a Hashed Time Locked Contract settlement transaction into a plain object. #### Parameters ##### proof `Uint8Array` #### Returns [`PlainTransactionProof`](https://nimiq.com/developers/../type-aliases/PlainTransactionProof) # Class: KeyPair [@nimiq/core](https://nimiq.com/developers/../globals) / KeyPair Defined in: @nimiq/core/types/wasm/web.d.ts:1460 A keypair represents a private key and its respective public key. It is used for signing data, usually transactions. ## Constructors ### Constructor > **new KeyPair**(`private_key`, `public_key`): `KeyPair` Defined in: @nimiq/core/types/wasm/web.d.ts:1485 #### Parameters ##### private\_key [`PrivateKey`](https://nimiq.com/developers/PrivateKey) ##### public\_key [`PublicKey`](https://nimiq.com/developers/PublicKey) #### Returns `KeyPair` ## Properties ### privateKey > `readonly` **privateKey**: [`PrivateKey`](https://nimiq.com/developers/PrivateKey) Defined in: @nimiq/core/types/wasm/web.d.ts:1509 Gets the keypair's private key. --- ### publicKey > `readonly` **publicKey**: [`PublicKey`](https://nimiq.com/developers/PublicKey) Defined in: @nimiq/core/types/wasm/web.d.ts:1513 Gets the keypair's public key. ## Methods ### \_\_getClassname() > **\_\_getClassname**(): `string` Defined in: @nimiq/core/types/wasm/web.d.ts:1463 #### Returns `string` --- ### \[dispose]\() > **\[dispose]**(): `void` Defined in: @nimiq/core/types/wasm/web.d.ts:1462 #### Returns `void` --- ### free() > **free**(): `void` Defined in: @nimiq/core/types/wasm/web.d.ts:1461 #### Returns `void` --- ### serialize() > **serialize**(): `Uint8Array` Defined in: @nimiq/core/types/wasm/web.d.ts:1489 Serializes the keypair to a byte array. #### Returns `Uint8Array` --- ### sign() > **sign**(`data`): [`Signature`](https://nimiq.com/developers/Signature) Defined in: @nimiq/core/types/wasm/web.d.ts:1493 Signs arbitrary data, returns a signature object. #### Parameters ##### data `Uint8Array` #### Returns [`Signature`](https://nimiq.com/developers/Signature) --- ### signTransaction() > **signTransaction**(`transaction`): `void` Defined in: @nimiq/core/types/wasm/web.d.ts:1497 Signs a transaction and sets the signature proof on the transaction object. #### Parameters ##### transaction [`Transaction`](https://nimiq.com/developers/Transaction) #### Returns `void` --- ### toAddress() > **toAddress**(): [`Address`](https://nimiq.com/developers/Address) Defined in: @nimiq/core/types/wasm/web.d.ts:1501 Gets the keypair's address. #### Returns [`Address`](https://nimiq.com/developers/Address) --- ### toHex() > **toHex**(): `string` Defined in: @nimiq/core/types/wasm/web.d.ts:1505 Formats the keypair into a hex string. #### Returns `string` --- ### derive() > `static` **derive**(`private_key`): `KeyPair` Defined in: @nimiq/core/types/wasm/web.d.ts:1467 Derives a keypair from an existing private key. #### Parameters ##### private\_key [`PrivateKey`](https://nimiq.com/developers/PrivateKey) #### Returns `KeyPair` --- ### deserialize() > `static` **deserialize**(`bytes`): `KeyPair` Defined in: @nimiq/core/types/wasm/web.d.ts:1473 Deserializes a keypair from a byte array. Throws when the byte array contains less than 64 bytes. #### Parameters ##### bytes `Uint8Array` #### Returns `KeyPair` --- ### fromHex() > `static` **fromHex**(`hex`): `KeyPair` Defined in: @nimiq/core/types/wasm/web.d.ts:1480 Parses a keypair from its hex representation. Throws when the string is not valid hex or does not represent a 64-byte keypair (optionally followed by a 1-byte lock-state flag, as produced by `toHex`). #### Parameters ##### hex `string` #### Returns `KeyPair` --- ### generate() > `static` **generate**(): `KeyPair` Defined in: @nimiq/core/types/wasm/web.d.ts:1484 Generates a new keypair from secure randomness. #### Returns `KeyPair` # Class: MerklePath [@nimiq/core](https://nimiq.com/developers/../globals) / MerklePath Defined in: @nimiq/core/types/wasm/web.d.ts:1519 A Merkle path consisting of a sequence of hashes that can be used to verify the inclusion of a leaf in a Merkle tree. ## Properties ### hashes > `readonly` **hashes**: `Uint8Array`<`ArrayBufferLike`> [] Defined in: @nimiq/core/types/wasm/web.d.ts:1538 Returns the hashes in the Merkle path. --- ### length > `readonly` **length**: `number` Defined in: @nimiq/core/types/wasm/web.d.ts:1542 Returns the length of the Merkle path. ## Methods ### \[dispose]\() > **\[dispose]**(): `void` Defined in: @nimiq/core/types/wasm/web.d.ts:1522 #### Returns `void` --- ### computeRoot() > **computeRoot**(`leaf`): `Uint8Array` Defined in: @nimiq/core/types/wasm/web.d.ts:1526 Computes the Merkle root of the path given a leaf hash. #### Parameters ##### leaf `Uint8Array` #### Returns `Uint8Array` --- ### free() > **free**(): `void` Defined in: @nimiq/core/types/wasm/web.d.ts:1521 #### Returns `void` --- ### serialize() > **serialize**(): `Uint8Array` Defined in: @nimiq/core/types/wasm/web.d.ts:1534 Serializes the Merkle path into a byte array. #### Returns `Uint8Array` --- ### deserialize() > `static` **deserialize**(`data`): `MerklePath` Defined in: @nimiq/core/types/wasm/web.d.ts:1530 Deserializes a Merkle path from a byte array. #### Parameters ##### data `Uint8Array` #### Returns `MerklePath` # Class: MerkleTree [@nimiq/core](https://nimiq.com/developers/../globals) / MerkleTree Defined in: @nimiq/core/types/wasm/web.d.ts:1548 The Merkle tree is a data structure that allows for efficient verification of the membership of an element in a set. ## Methods ### \[dispose]\() > **\[dispose]**(): `void` Defined in: @nimiq/core/types/wasm/web.d.ts:1551 #### Returns `void` --- ### free() > **free**(): `void` Defined in: @nimiq/core/types/wasm/web.d.ts:1550 #### Returns `void` --- ### computeRoot() > `static` **computeRoot**(`values`): `Uint8Array` Defined in: @nimiq/core/types/wasm/web.d.ts:1555 Computes the root of a Merkle tree from a list of Uint8Arrays. #### Parameters ##### values `Uint8Array`<`ArrayBufferLike`> [] #### Returns `Uint8Array` # Class: MnemonicUtils [@nimiq/core](https://nimiq.com/developers/../globals) / MnemonicUtils Defined in: @nimiq/core/lib/index.d.ts:252 ## Constructors ### Constructor > **new MnemonicUtils**(): `MnemonicUtils` #### Returns `MnemonicUtils` ## Properties ### DEFAULT\_WORDLIST > `static` **DEFAULT\_WORDLIST**: `string`[] Defined in: @nimiq/core/lib/index.d.ts:260 The default English wordlist. --- ### ENGLISH\_WORDLIST > `static` **ENGLISH\_WORDLIST**: `string`[] Defined in: @nimiq/core/lib/index.d.ts:256 The English wordlist. ## Methods ### entropyToMnemonic() > `static` **entropyToMnemonic**(`entropy`, `wordlist?`): `string`[] Defined in: @nimiq/core/lib/index.d.ts:264 Converts an Entropy to a mnemonic. #### Parameters ##### entropy `string` | `ArrayBuffer` | `Uint8Array`<`ArrayBufferLike`> | [`Entropy`](https://nimiq.com/developers/Entropy) ##### wordlist? `string`[] #### Returns `string`[] --- ### getMnemonicType() > `static` **getMnemonicType**(`mnemonic`, `wordlist?`): [`MnemonicType`](https://nimiq.com/developers/../@nimiq/namespaces/MnemonicUtils/enumerations/MnemonicType) Defined in: @nimiq/core/lib/index.d.ts:295 Gets the type of a mnemonic. Return values: - `0 = MnemonicType.LEGACY`: the mnemonic is for a legacy Nimiq wallet. - `1 = MnemonicType.BIP39`: the mnemonic is for a BIP39 wallet. - `-1 = MnemonicType.UNKNOWN`: the mnemonic can be for both. Throws if the menmonic is invalid. #### Parameters ##### mnemonic `string` | `string`[] ##### wordlist? `string`[] #### Returns [`MnemonicType`](https://nimiq.com/developers/../@nimiq/namespaces/MnemonicUtils/enumerations/MnemonicType) --- ### isCollidingChecksum() > `static` **isCollidingChecksum**(`entropy`): `boolean` Defined in: @nimiq/core/lib/index.d.ts:284 Tests if a mnemonic can be both for a legacy Nimiq wallet and a BIP39 wallet. #### Parameters ##### entropy [`Entropy`](https://nimiq.com/developers/Entropy) #### Returns `boolean` --- ### mnemonicToEntropy() > `static` **mnemonicToEntropy**(`mnemonic`, `wordlist?`): [`Entropy`](https://nimiq.com/developers/Entropy) Defined in: @nimiq/core/lib/index.d.ts:268 Converts a mnemonic to an Entropy. #### Parameters ##### mnemonic `string` | `string`[] ##### wordlist? `string`[] #### Returns [`Entropy`](https://nimiq.com/developers/Entropy) --- ### mnemonicToExtendedPrivateKey() > `static` **mnemonicToExtendedPrivateKey**(`mnemonic`, `password?`): [`ExtendedPrivateKey`](https://nimiq.com/developers/ExtendedPrivateKey) Defined in: @nimiq/core/lib/index.d.ts:280 Converts a mnemonic to an extended private key. Optionally takes a password to use for the seed derivation. #### Parameters ##### mnemonic `string` | `string`[] ##### password? `string` #### Returns [`ExtendedPrivateKey`](https://nimiq.com/developers/ExtendedPrivateKey) --- ### mnemonicToSeed() > `static` **mnemonicToSeed**(`mnemonic`, `password?`): [`SerialBuffer`](https://nimiq.com/developers/SerialBuffer) Defined in: @nimiq/core/lib/index.d.ts:274 Converts a mnemonic to a seed. Optionally takes a password to use for the seed derivation. #### Parameters ##### mnemonic `string` | `string`[] ##### password? `string` #### Returns [`SerialBuffer`](https://nimiq.com/developers/SerialBuffer) # Class: NumberUtils [@nimiq/core](https://nimiq.com/developers/../globals) / NumberUtils Defined in: @nimiq/core/lib/index.d.ts:315 ## Constructors ### Constructor > **new NumberUtils**(): `NumberUtils` #### Returns `NumberUtils` ## Properties ### UINT16\_MAX > `static` **UINT16\_MAX**: `number` Defined in: @nimiq/core/lib/index.d.ts:317 --- ### UINT32\_MAX > `static` **UINT32\_MAX**: `number` Defined in: @nimiq/core/lib/index.d.ts:318 --- ### UINT64\_MAX > `static` **UINT64\_MAX**: `number` Defined in: @nimiq/core/lib/index.d.ts:319 --- ### UINT8\_MAX > `static` **UINT8\_MAX**: `number` Defined in: @nimiq/core/lib/index.d.ts:316 ## Methods ### isInteger() > `static` **isInteger**(`val`): `val is number` Defined in: @nimiq/core/lib/index.d.ts:320 #### Parameters ##### val `unknown` #### Returns `val is number` --- ### isUint16() > `static` **isUint16**(`val`): `boolean` Defined in: @nimiq/core/lib/index.d.ts:322 #### Parameters ##### val `unknown` #### Returns `boolean` --- ### isUint32() > `static` **isUint32**(`val`): `boolean` Defined in: @nimiq/core/lib/index.d.ts:323 #### Parameters ##### val `unknown` #### Returns `boolean` --- ### isUint64() > `static` **isUint64**(`val`): `boolean` Defined in: @nimiq/core/lib/index.d.ts:324 #### Parameters ##### val `unknown` #### Returns `boolean` --- ### isUint8() > `static` **isUint8**(`val`): `boolean` Defined in: @nimiq/core/lib/index.d.ts:321 #### Parameters ##### val `unknown` #### Returns `boolean` # Class: PartialSignature [@nimiq/core](https://nimiq.com/developers/../globals) / PartialSignature Defined in: @nimiq/core/types/wasm/web.d.ts:1562 A partial signature is a signature of one of the co-signers in a multisig. Combining all partial signatures yields the full signature (combining is done through summation). ## Constructors ### Constructor > **new PartialSignature**(`bytes`): `PartialSignature` Defined in: @nimiq/core/types/wasm/web.d.ts:1602 Creates a new partial signature from a byte array. Throws when the byte array is not exactly 32 bytes long. #### Parameters ##### bytes `Uint8Array` #### Returns `PartialSignature` ## Properties ### serializedSize > `readonly` **serializedSize**: `number` Defined in: @nimiq/core/types/wasm/web.d.ts:1621 --- ### SIZE > `readonly` `static` **SIZE**: `number` Defined in: @nimiq/core/types/wasm/web.d.ts:1622 ## Methods ### \_\_getClassname() > **\_\_getClassname**(): `string` Defined in: @nimiq/core/types/wasm/web.d.ts:1565 #### Returns `string` --- ### \[dispose]\() > **\[dispose]**(): `void` Defined in: @nimiq/core/types/wasm/web.d.ts:1564 #### Returns `void` --- ### equals() > **equals**(`other`): `boolean` Defined in: @nimiq/core/types/wasm/web.d.ts:1584 Returns if this partial signature is equal to the other partial signature. #### Parameters ##### other `PartialSignature` #### Returns `boolean` --- ### free() > **free**(): `void` Defined in: @nimiq/core/types/wasm/web.d.ts:1563 #### Returns `void` --- ### serialize() > **serialize**(): `Uint8Array` Defined in: @nimiq/core/types/wasm/web.d.ts:1606 Serializes the partial signature to a byte array. #### Returns `Uint8Array` --- ### toHex() > **toHex**(): `string` Defined in: @nimiq/core/types/wasm/web.d.ts:1616 Formats the partial signature into a hex string. #### Returns `string` --- ### toSignature() > **toSignature**(`aggregated_commitment`): [`Signature`](https://nimiq.com/developers/Signature) Defined in: @nimiq/core/types/wasm/web.d.ts:1620 Converts a (aggregated) partial signature into a final signature using the aggregated commitment. #### Parameters ##### aggregated\_commitment [`Commitment`](https://nimiq.com/developers/Commitment) #### Returns [`Signature`](https://nimiq.com/developers/Signature) --- ### create() > `static` **create**(`own_private_key`, `own_public_key`, `own_commitment_pairs`, `other_public_keys`, `other_commitments`, `data`): `PartialSignature` Defined in: @nimiq/core/types/wasm/web.d.ts:1574 Creates a new partial signature for the MuSig2 scheme. - `ownCommitmentPairs` must be 2 pairs of random secret and commitments generated for this signing session. - `otherCommitments` must contain 2 commitments each for all other signers. Returns the created partial signature. #### Parameters ##### own\_private\_key [`PrivateKey`](https://nimiq.com/developers/PrivateKey) ##### own\_public\_key [`PublicKey`](https://nimiq.com/developers/PublicKey) ##### own\_commitment\_pairs (`string` | `Uint8Array`<`ArrayBufferLike`> | [`CommitmentPair`](https://nimiq.com/developers/CommitmentPair)) [] ##### other\_public\_keys (`string` | `Uint8Array`<`ArrayBufferLike`> | [`PublicKey`](https://nimiq.com/developers/PublicKey)) [] ##### other\_commitments (`string` | `Uint8Array`<`ArrayBufferLike`> | [`Commitment`](https://nimiq.com/developers/Commitment))\[] [] ##### data `Uint8Array` #### Returns `PartialSignature` --- ### deserialize() > `static` **deserialize**(`bytes`): `PartialSignature` Defined in: @nimiq/core/types/wasm/web.d.ts:1580 Deserializes a partial signature from a byte array. Throws when the byte array contains less than 32 bytes. #### Parameters ##### bytes `Uint8Array` #### Returns `PartialSignature` --- ### fromAny() > `static` **fromAny**(`sig`): `PartialSignature` Defined in: @nimiq/core/types/wasm/web.d.ts:1590 Parses a partial signature from a PartialSignature instance, a hex string representation, or a byte array. Throws when a PartialSignature cannot be parsed from the argument. #### Parameters ##### sig `string` | `Uint8Array`<`ArrayBufferLike`> | `PartialSignature` #### Returns `PartialSignature` --- ### fromHex() > `static` **fromHex**(`hex`): `PartialSignature` Defined in: @nimiq/core/types/wasm/web.d.ts:1596 Parses a partial signature from its hex representation. Throws when the string is not valid hex format or when it represents less than 32 bytes. #### Parameters ##### hex `string` #### Returns `PartialSignature` --- ### sum() > `static` **sum**(`partial_signatures`): `PartialSignature` Defined in: @nimiq/core/types/wasm/web.d.ts:1612 Sums an array of partial signatures into an aggregated partial signature. Afterwards, use `.toSignature(aggregatedCommitment)` on the result to get the final signature. #### Parameters ##### partial\_signatures (`string` | `Uint8Array`<`ArrayBufferLike`> | `PartialSignature`) [] #### Returns `PartialSignature` # Class: Policy [@nimiq/core](https://nimiq.com/developers/../globals) / Policy Defined in: @nimiq/core/types/wasm/web.d.ts:1628 Policy constants ## Properties ### BATCHES\_PER\_EPOCH > `readonly` `static` **BATCHES\_PER\_EPOCH**: `number` Defined in: @nimiq/core/types/wasm/web.d.ts:1780 How many batches constitute an epoch --- ### BLOCK\_SEPARATION\_TIME > `readonly` `static` **BLOCK\_SEPARATION\_TIME**: `bigint` Defined in: @nimiq/core/types/wasm/web.d.ts:1812 The optimal time in milliseconds between blocks (1s) --- ### BLOCKS\_PER\_BATCH > `readonly` `static` **BLOCKS\_PER\_BATCH**: `number` Defined in: @nimiq/core/types/wasm/web.d.ts:1784 Length of a batch including the macro block --- ### BLOCKS\_PER\_EPOCH > `readonly` `static` **BLOCKS\_PER\_EPOCH**: `number` Defined in: @nimiq/core/types/wasm/web.d.ts:1788 Length of an epoch including the election block --- ### BLS\_CACHE\_MAX\_CAPACITY > `readonly` `static` **BLS\_CACHE\_MAX\_CAPACITY**: `number` Defined in: @nimiq/core/types/wasm/web.d.ts:1816 The maximum size of the BLS public key cache. --- ### COINBASE\_ADDRESS > `readonly` `static` **COINBASE\_ADDRESS**: `string` Defined in: @nimiq/core/types/wasm/web.d.ts:1821 This is the address for the coinbase. Note that this is not a real account, it is just the address we use to denote that some coins originated from a coinbase event. --- ### F\_PLUS\_ONE > `readonly` `static` **F\_PLUS\_ONE**: `number` Defined in: @nimiq/core/types/wasm/web.d.ts:1828 Calculates f+1 slots which is the minimum number of slots necessary to be guaranteed to have at least one honest slots. That's because from a total of 3f+1 slots at most f will be malicious. It is calculated as `ceil(SLOTS/3)` and we use the formula `ceil(x/y) = (x+y-1)/y` for the ceiling division. --- ### GENESIS\_BLOCK\_NUMBER > `readonly` `static` **GENESIS\_BLOCK\_NUMBER**: `number` Defined in: @nimiq/core/types/wasm/web.d.ts:1792 Genesis block number --- ### HISTORY\_CHUNKS\_MAX\_SIZE > `readonly` `static` **HISTORY\_CHUNKS\_MAX\_SIZE**: `bigint` Defined in: @nimiq/core/types/wasm/web.d.ts:1833 Maximum size of history chunks. 25 MB. --- ### JAIL\_EPOCHS > `readonly` `static` **JAIL\_EPOCHS**: `number` Defined in: @nimiq/core/types/wasm/web.d.ts:1837 The number of epochs a validator is put in jail for. The jailing only happens for severe offenses. --- ### MAX\_SIZE\_MICRO\_BODY > `readonly` `static` **MAX\_SIZE\_MICRO\_BODY**: `number` Defined in: @nimiq/core/types/wasm/web.d.ts:1841 The maximum allowed size, in bytes, for a micro block body. --- ### MAX\_SUPPORTED\_VERSION > `readonly` `static` **MAX\_SUPPORTED\_VERSION**: `number` Defined in: @nimiq/core/types/wasm/web.d.ts:1796 Maximum supported protocol version --- ### MIN\_EPOCHS\_STORED > `readonly` `static` **MIN\_EPOCHS\_STORED**: `number` Defined in: @nimiq/core/types/wasm/web.d.ts:1849 Minimum number of epochs that the ChainStore will store fully --- ### MIN\_PRODUCER\_TIMEOUT > `readonly` `static` **MIN\_PRODUCER\_TIMEOUT**: `bigint` Defined in: @nimiq/core/types/wasm/web.d.ts:1845 The minimum timeout in milliseconds for a validator to produce a block (4s) --- ### MINIMUM\_REWARDS\_PERCENTAGE > `readonly` `static` **MINIMUM\_REWARDS\_PERCENTAGE**: `number` Defined in: @nimiq/core/types/wasm/web.d.ts:1853 The minimum rewards percentage that we allow --- ### SLOTS > `readonly` `static` **SLOTS**: `number` Defined in: @nimiq/core/types/wasm/web.d.ts:1857 Number of available validator slots. Note that a single validator may own several validator slots. --- ### STAKING\_CONTRACT\_ADDRESS > `readonly` `static` **STAKING\_CONTRACT\_ADDRESS**: `string` Defined in: @nimiq/core/types/wasm/web.d.ts:1861 This is the address for the staking contract. --- ### STATE\_CHUNKS\_MAX\_SIZE > `readonly` `static` **STATE\_CHUNKS\_MAX\_SIZE**: `number` Defined in: @nimiq/core/types/wasm/web.d.ts:1800 Maximum size of accounts trie chunks. --- ### TIMESTAMP\_MAX\_DRIFT > `readonly` `static` **TIMESTAMP\_MAX\_DRIFT**: `bigint` Defined in: @nimiq/core/types/wasm/web.d.ts:1866 The maximum drift, in milliseconds, that is allowed between any block's timestamp and the node's system time. We only care about drifting to the future. --- ### TOTAL\_SUPPLY > `readonly` `static` **TOTAL\_SUPPLY**: `bigint` Defined in: @nimiq/core/types/wasm/web.d.ts:1870 Total supply in units. --- ### TRANSACTION\_VALIDITY\_WINDOW > `readonly` `static` **TRANSACTION\_VALIDITY\_WINDOW**: `number` Defined in: @nimiq/core/types/wasm/web.d.ts:1804 Number of batches a transaction is valid with Albatross consensus. --- ### TRANSACTION\_VALIDITY\_WINDOW\_BLOCKS > `readonly` `static` **TRANSACTION\_VALIDITY\_WINDOW\_BLOCKS**: `number` Defined in: @nimiq/core/types/wasm/web.d.ts:1808 Number of blocks a transaction is valid with Albatross consensus. --- ### TWO\_F\_PLUS\_ONE > `readonly` `static` **TWO\_F\_PLUS\_ONE**: `number` Defined in: @nimiq/core/types/wasm/web.d.ts:1882 Calculates 2f+1 slots which is the minimum number of slots necessary to produce a macro block, a skip block and other actions. It is also the minimum number of slots necessary to be guaranteed to have a majority of honest slots. That's because from a total of 3f+1 slots at most f will be malicious. If in a group of 2f+1 slots we have f malicious ones (which is the worst case scenario), that still leaves us with f+1 honest slots. Which is more than the f slots that are not in this group (which must all be honest). It is calculated as `ceil(SLOTS*2/3)` and we use the formula `ceil(x/y) = (x+y-1)/y` for the ceiling division. --- ### VALIDATOR\_DEPOSIT > `readonly` `static` **VALIDATOR\_DEPOSIT**: `bigint` Defined in: @nimiq/core/types/wasm/web.d.ts:1888 The deposit necessary to create a validator in Lunas (1 NIM = 100,000 Lunas). A validator is someone who actually participates in block production. They are akin to miners in proof-of-work. ## Methods ### \[dispose]\() > **\[dispose]**(): `void` Defined in: @nimiq/core/types/wasm/web.d.ts:1631 #### Returns `void` --- ### free() > **free**(): `void` Defined in: @nimiq/core/types/wasm/web.d.ts:1630 #### Returns `void` --- ### batchAt() > `static` **batchAt**(`block_number`): `number` Defined in: @nimiq/core/types/wasm/web.d.ts:1635 Returns the batch number at a given `block_number` (height) #### Parameters ##### block\_number `number` #### Returns `number` --- ### batchDelayPenalty() > `static` **batchDelayPenalty**(`delay`): `number` Defined in: @nimiq/core/types/wasm/web.d.ts:1643 Returns the percentage reduction that should be applied to the rewards due to a delayed batch. This function returns a float in the range [0, 1] I.e 1 means that the full rewards should be given, whereas 0.5 means that half of the rewards should be given The input to this function is the batch delay, in milliseconds The function is: [(1 - MINIMUM\_REWARDS\_PERCENTAGE) \* BLOCKS\_DELAY\_DECAY ^ (t^2)] + MINIMUM\_REWARDS\_PERCENTAGE #### Parameters ##### delay `bigint` #### Returns `number` --- ### batchIndexAt() > `static` **batchIndexAt**(`block_number`): `number` Defined in: @nimiq/core/types/wasm/web.d.ts:1648 Returns the batch index at a given block number. The batch index is the number of a block relative to the batch it is in. For example, the first block of any batch always has an batch index of 0. #### Parameters ##### block\_number `number` #### Returns `number` --- ### blockAfterCollateralLockup() > `static` **blockAfterCollateralLockup**(`block_number`): `number` Defined in: @nimiq/core/types/wasm/web.d.ts:1652 Returns the first block after the collateral lock-up window of a given block number has ended. #### Parameters ##### block\_number `number` #### Returns `number` --- ### blockAfterJail() > `static` **blockAfterJail**(`block_number`): `number` Defined in: @nimiq/core/types/wasm/web.d.ts:1656 Returns the first block after the jail period of a given block number has ended. #### Parameters ##### block\_number `number` #### Returns `number` --- ### ~~blockAfterReportingWindow()~~ > `static` **blockAfterReportingWindow**(`block_number`): `number` Defined in: @nimiq/core/types/wasm/web.d.ts:1661 #### Parameters ##### block\_number `number` #### Returns `number` #### Deprecated Renamed to `blockAfterCollateralLockup`. Kept for API backwards compatibility; see `lastBlockOfCollateralLockup`. --- ### electionBlockAfter() > `static` **electionBlockAfter**(`block_number`): `number` Defined in: @nimiq/core/types/wasm/web.d.ts:1665 Returns the number (height) of the next election macro block after a given block number (height). #### Parameters ##### block\_number `number` #### Returns `number` --- ### electionBlockBefore() > `static` **electionBlockBefore**(`block_number`): `number` Defined in: @nimiq/core/types/wasm/web.d.ts:1670 Returns the block number (height) of the preceding election macro block before a given block number (height). If the given block number is an election macro block, it returns the election macro block before it. #### Parameters ##### block\_number `number` #### Returns `number` --- ### electionBlockOf() > `static` **electionBlockOf**(`epoch`): `number` Defined in: @nimiq/core/types/wasm/web.d.ts:1675 Returns the block number of the election macro block of the given epoch (which is always the last block). If the index is out of bounds, None is returned #### Parameters ##### epoch `number` #### Returns `number` --- ### epochAt() > `static` **epochAt**(`block_number`): `number` Defined in: @nimiq/core/types/wasm/web.d.ts:1679 Returns the epoch number at a given block number (height). #### Parameters ##### block\_number `number` #### Returns `number` --- ### epochIndexAt() > `static` **epochIndexAt**(`block_number`): `number` Defined in: @nimiq/core/types/wasm/web.d.ts:1684 Returns the epoch index at a given block number. The epoch index is the number of a block relative to the epoch it is in. For example, the first block of any epoch always has an epoch index of 0. #### Parameters ##### block\_number `number` #### Returns `number` --- ### firstBatchOfEpoch() > `static` **firstBatchOfEpoch**(`block_number`): `boolean` Defined in: @nimiq/core/types/wasm/web.d.ts:1689 Returns a boolean expressing if the batch at a given block number (height) is the first batch of the epoch. #### Parameters ##### block\_number `number` #### Returns `boolean` --- ### firstBlockOf() > `static` **firstBlockOf**(`epoch`): `number` Defined in: @nimiq/core/types/wasm/web.d.ts:1694 Returns the block number of the first block of the given epoch (which is always a micro block). If the index is out of bounds, None is returned #### Parameters ##### epoch `number` #### Returns `number` --- ### firstBlockOfBatch() > `static` **firstBlockOfBatch**(`batch`): `number` Defined in: @nimiq/core/types/wasm/web.d.ts:1699 Returns the block number of the first block of the given batch (which is always a micro block). If the index is out of bounds, None is returned #### Parameters ##### batch `number` #### Returns `number` --- ### isElectionBlockAt() > `static` **isElectionBlockAt**(`block_number`): `boolean` Defined in: @nimiq/core/types/wasm/web.d.ts:1703 Returns a boolean expressing if the block at a given block number (height) is an election macro block. #### Parameters ##### block\_number `number` #### Returns `boolean` --- ### isMacroBlockAt() > `static` **isMacroBlockAt**(`block_number`): `boolean` Defined in: @nimiq/core/types/wasm/web.d.ts:1707 Returns a boolean expressing if the block at a given block number (height) is a macro block. #### Parameters ##### block\_number `number` #### Returns `boolean` --- ### isMicroBlockAt() > `static` **isMicroBlockAt**(`block_number`): `boolean` Defined in: @nimiq/core/types/wasm/web.d.ts:1711 Returns a boolean expressing if the block at a given block number (height) is a micro block. #### Parameters ##### block\_number `number` #### Returns `boolean` --- ### lastBlockOfCollateralLockup() > `static` **lastBlockOfCollateralLockup**(`block_number`): `number` Defined in: @nimiq/core/types/wasm/web.d.ts:1721 Returns the last block height of the collateral lock-up window of a given block number. This governs the collateral lock-up: a deactivated validator's funds (and its stakers') stay locked until this block so they remain slashable while offenses could still be reported. It is kept at one epoch and must always be `>=` the equivocation reporting window (`last_block_of_equivocation_reporting_window`), so collateral is always present while an offense is still reportable. #### Parameters ##### block\_number `number` #### Returns `number` --- ### lastBlockOfEquivocationReportingWindow() > `static` **lastBlockOfEquivocationReportingWindow**(`block_number`): `number` Defined in: @nimiq/core/types/wasm/web.d.ts:1734 Returns the last block height at which an equivocation that happened at `block_number` can still be reported (i.e. included in a block via an equivocation proof). This is intentionally bounded by the transaction validity window so it stays within the validity-store dedup retention (`transaction_validity_window_blocks + blocks_per_batch`). Equivocation proofs are deduplicated against the validity store; if this window were longer, a genuine proof could be re-included after the dedup forgot it, re-jailing the validator and re-burning rewards. The collateral lock-up (`last_block_of_collateral_lockup`) is kept longer (one epoch) and must always be `>=` this window. See the invariant test `reporting_window_stays_within_dedup_retention`. #### Parameters ##### block\_number `number` #### Returns `number` --- ### ~~lastBlockOfReportingWindow()~~ > `static` **lastBlockOfReportingWindow**(`block_number`): `number` Defined in: @nimiq/core/types/wasm/web.d.ts:1740 #### Parameters ##### block\_number `number` #### Returns `number` #### Deprecated Renamed to `lastBlockOfCollateralLockup`. This window never governed equivocation *reporting* (that is `lastBlockOfEquivocationReportingWindow`); it has always been the collateral lock-up window. Kept for API backwards compatibility. --- ### lastElectionBlock() > `static` **lastElectionBlock**(`block_number`): `number` Defined in: @nimiq/core/types/wasm/web.d.ts:1745 Returns the block number (height) of the last election macro block at a given block number (height). If the given block number is an election macro block, then it returns that block number. #### Parameters ##### block\_number `number` #### Returns `number` --- ### lastMacroBlock() > `static` **lastMacroBlock**(`block_number`): `number` Defined in: @nimiq/core/types/wasm/web.d.ts:1750 Returns the block number (height) of the last macro block at a given block number (height). If the given block number is a macro block, then it returns that block number. #### Parameters ##### block\_number `number` #### Returns `number` --- ### macroBlockAfter() > `static` **macroBlockAfter**(`block_number`): `number` Defined in: @nimiq/core/types/wasm/web.d.ts:1755 Returns the block number (height) of the next macro block after a given block number (height). If the given block number is a macro block, it returns the macro block after it. #### Parameters ##### block\_number `number` #### Returns `number` --- ### macroBlockBefore() > `static` **macroBlockBefore**(`block_number`): `number` Defined in: @nimiq/core/types/wasm/web.d.ts:1760 Returns the block number (height) of the preceding macro block before a given block number (height). If the given block number is a macro block, it returns the macro block before it. #### Parameters ##### block\_number `number` #### Returns `number` --- ### macroBlockOf() > `static` **macroBlockOf**(`batch`): `number` Defined in: @nimiq/core/types/wasm/web.d.ts:1766 Returns the block number of the macro block (checkpoint or election) of the given batch (which is always the last block). If the index is out of bounds, None is returned #### Parameters ##### batch `number` #### Returns `number` --- ### supplyAt() > `static` **supplyAt**(`genesis_supply`, `genesis_time`, `current_time`): `bigint` Defined in: @nimiq/core/types/wasm/web.d.ts:1776 Returns the supply at a given time (as Unix time) in Lunas (1 NIM = 100,000 Lunas). It is calculated using the following formula: ```text supply(t) = total_supply - (total_supply - genesis_supply) * supply_decay^t ``` Where t is the time in milliseconds since the PoS genesis block and `genesis_supply` is the supply at the genesis of the Nimiq 2.0 chain. #### Parameters ##### genesis\_supply `bigint` ##### genesis\_time `bigint` ##### current\_time `bigint` #### Returns `bigint` # Class: PrivateKey [@nimiq/core](https://nimiq.com/developers/../globals) / PrivateKey Defined in: @nimiq/core/types/wasm/web.d.ts:1894 The secret (private) part of an asymmetric key pair that is typically used to digitally sign or decrypt data. ## Constructors ### Constructor > **new PrivateKey**(`bytes`): `PrivateKey` Defined in: @nimiq/core/types/wasm/web.d.ts:1922 Creates a new private key from a byte array. Throws when the byte array is not exactly 32 bytes long. #### Parameters ##### bytes `Uint8Array` #### Returns `PrivateKey` ## Properties ### serializedSize > `readonly` **serializedSize**: `number` Defined in: @nimiq/core/types/wasm/web.d.ts:1932 --- ### PURPOSE\_ID > `readonly` `static` **PURPOSE\_ID**: `number` Defined in: @nimiq/core/types/wasm/web.d.ts:1931 --- ### SIZE > `readonly` `static` **SIZE**: `number` Defined in: @nimiq/core/types/wasm/web.d.ts:1933 ## Methods ### \[dispose]\() > **\[dispose]**(): `void` Defined in: @nimiq/core/types/wasm/web.d.ts:1896 #### Returns `void` --- ### equals() > **equals**(`other`): `boolean` Defined in: @nimiq/core/types/wasm/web.d.ts:1906 Returns if this private key is equal to the other private key. #### Parameters ##### other `PrivateKey` #### Returns `boolean` --- ### free() > **free**(): `void` Defined in: @nimiq/core/types/wasm/web.d.ts:1895 #### Returns `void` --- ### serialize() > **serialize**(): `Uint8Array` Defined in: @nimiq/core/types/wasm/web.d.ts:1926 Serializes the private key to a byte array. #### Returns `Uint8Array` --- ### toHex() > **toHex**(): `string` Defined in: @nimiq/core/types/wasm/web.d.ts:1930 Formats the private key into a hex string. #### Returns `string` --- ### deserialize() > `static` **deserialize**(`bytes`): `PrivateKey` Defined in: @nimiq/core/types/wasm/web.d.ts:1902 Deserializes a private key from a byte array. Throws when the byte array contains less than 32 bytes. #### Parameters ##### bytes `Uint8Array` #### Returns `PrivateKey` --- ### fromHex() > `static` **fromHex**(`hex`): `PrivateKey` Defined in: @nimiq/core/types/wasm/web.d.ts:1912 Parses a private key from its hex representation. Throws when the string is not valid hex format or when it represents less than 32 bytes. #### Parameters ##### hex `string` #### Returns `PrivateKey` --- ### generate() > `static` **generate**(): `PrivateKey` Defined in: @nimiq/core/types/wasm/web.d.ts:1916 Generates a new private key from secure randomness. #### Returns `PrivateKey` # Class: PublicKey [@nimiq/core](https://nimiq.com/developers/../globals) / PublicKey Defined in: @nimiq/core/types/wasm/web.d.ts:1939 The non-secret (public) part of an asymmetric key pair that is typically used to digitally verify or encrypt data. ## Constructors ### Constructor > **new PublicKey**(`bytes`): `PublicKey` Defined in: @nimiq/core/types/wasm/web.d.ts:1993 Creates a new public key from a byte array. Throws when the byte array is not exactly 32 bytes long. #### Parameters ##### bytes `Uint8Array` #### Returns `PublicKey` ## Properties ### serializedSize > `readonly` **serializedSize**: `number` Defined in: @nimiq/core/types/wasm/web.d.ts:2014 --- ### SIZE > `readonly` `static` **SIZE**: `number` Defined in: @nimiq/core/types/wasm/web.d.ts:2015 ## Methods ### \_\_getClassname() > **\_\_getClassname**(): `string` Defined in: @nimiq/core/types/wasm/web.d.ts:1942 #### Returns `string` --- ### \[dispose]\() > **\[dispose]**(): `void` Defined in: @nimiq/core/types/wasm/web.d.ts:1941 #### Returns `void` --- ### compare() > **compare**(`other`): `number` Defined in: @nimiq/core/types/wasm/web.d.ts:1953 Compares this public key to the other public key. Returns -1 if this public key is smaller than the other public key, 0 if they are equal, and 1 if this public key is larger than the other public key. #### Parameters ##### other `PublicKey` #### Returns `number` --- ### equals() > **equals**(`other`): `boolean` Defined in: @nimiq/core/types/wasm/web.d.ts:1967 Returns if this public key is equal to the other public key. #### Parameters ##### other `PublicKey` #### Returns `boolean` --- ### free() > **free**(): `void` Defined in: @nimiq/core/types/wasm/web.d.ts:1940 #### Returns `void` --- ### serialize() > **serialize**(): `Uint8Array` Defined in: @nimiq/core/types/wasm/web.d.ts:1997 Serializes the public key to a byte array. #### Returns `Uint8Array` --- ### toAddress() > **toAddress**(): [`Address`](https://nimiq.com/developers/Address) Defined in: @nimiq/core/types/wasm/web.d.ts:2005 Gets the public key's address. #### Returns [`Address`](https://nimiq.com/developers/Address) --- ### toHex() > **toHex**(): `string` Defined in: @nimiq/core/types/wasm/web.d.ts:2009 Formats the public key into a hex string. #### Returns `string` --- ### verify() > **verify**(`signature`, `data`): `boolean` Defined in: @nimiq/core/types/wasm/web.d.ts:2013 Verifies that a signature is valid for this public key and the provided data. #### Parameters ##### signature [`Signature`](https://nimiq.com/developers/Signature) ##### data `Uint8Array` #### Returns `boolean` --- ### combinations() > `static` **combinations**(`keys`, `num_signers`): `PublicKey`[] Defined in: @nimiq/core/types/wasm/web.d.ts:1946 Generates all possible combinations (sums) of delinearized public keys for a given number of signers. #### Parameters ##### keys (`string` | `Uint8Array`<`ArrayBufferLike`> | `PublicKey`) [] ##### num\_signers `number` #### Returns `PublicKey`[] --- ### derive() > `static` **derive**(`private_key`): `PublicKey` Defined in: @nimiq/core/types/wasm/web.d.ts:1957 Derives a public key from an existing private key. #### Parameters ##### private\_key [`PrivateKey`](https://nimiq.com/developers/PrivateKey) #### Returns `PublicKey` --- ### deserialize() > `static` **deserialize**(`bytes`): `PublicKey` Defined in: @nimiq/core/types/wasm/web.d.ts:1963 Deserializes a public key from a byte array. Throws when the byte array contains less than 32 bytes. #### Parameters ##### bytes `Uint8Array` #### Returns `PublicKey` --- ### fromAny() > `static` **fromAny**(`key`): `PublicKey` Defined in: @nimiq/core/types/wasm/web.d.ts:1973 Parses a public key from a PublicKey instance, a hex string representation, or a byte array. Throws when an PublicKey cannot be parsed from the argument. #### Parameters ##### key `string` | `Uint8Array`<`ArrayBufferLike`> | `PublicKey` #### Returns `PublicKey` --- ### fromHex() > `static` **fromHex**(`hex`): `PublicKey` Defined in: @nimiq/core/types/wasm/web.d.ts:1979 Parses a public key from its hex representation. Throws when the string is not valid hex format or when it represents less than 32 bytes. #### Parameters ##### hex `string` #### Returns `PublicKey` --- ### fromRaw() > `static` **fromRaw**(`raw_bytes`): `PublicKey` Defined in: @nimiq/core/types/wasm/web.d.ts:1983 Deserializes a public key from its raw representation. #### Parameters ##### raw\_bytes `Uint8Array` #### Returns `PublicKey` --- ### fromSpki() > `static` **fromSpki**(`spki_bytes`): `PublicKey` Defined in: @nimiq/core/types/wasm/web.d.ts:1987 Deserializes a public key from its SPKI representation. #### Parameters ##### spki\_bytes `Uint8Array` #### Returns `PublicKey` --- ### sum() > `static` **sum**(`keys`): `PublicKey` Defined in: @nimiq/core/types/wasm/web.d.ts:2001 Sums public keys into one combined public key. #### Parameters ##### keys (`string` | `Uint8Array`<`ArrayBufferLike`> | `PublicKey`) [] #### Returns `PublicKey` # Class: RandomSecret [@nimiq/core](https://nimiq.com/developers/../globals) / RandomSecret Defined in: @nimiq/core/types/wasm/web.d.ts:2022 A random secret that proves a [Commitment](https://nimiq.com/developers/Commitment) for signing multisignature transactions. It is supposed to be kept secret (similar to a private key). ## Constructors ### Constructor > **new RandomSecret**(`bytes`): `RandomSecret` Defined in: @nimiq/core/types/wasm/web.d.ts:2053 Creates a new random secret from a byte array. Throws when the byte array is not exactly 32 bytes long. #### Parameters ##### bytes `Uint8Array` #### Returns `RandomSecret` ## Properties ### serializedSize > `readonly` **serializedSize**: `number` Defined in: @nimiq/core/types/wasm/web.d.ts:2062 --- ### SIZE > `readonly` `static` **SIZE**: `number` Defined in: @nimiq/core/types/wasm/web.d.ts:2063 ## Methods ### \_\_getClassname() > **\_\_getClassname**(): `string` Defined in: @nimiq/core/types/wasm/web.d.ts:2025 #### Returns `string` --- ### \[dispose]\() > **\[dispose]**(): `void` Defined in: @nimiq/core/types/wasm/web.d.ts:2024 #### Returns `void` --- ### equals() > **equals**(`other`): `boolean` Defined in: @nimiq/core/types/wasm/web.d.ts:2035 Returns if this random secret is equal to the other random secret. #### Parameters ##### other `RandomSecret` #### Returns `boolean` --- ### free() > **free**(): `void` Defined in: @nimiq/core/types/wasm/web.d.ts:2023 #### Returns `void` --- ### serialize() > **serialize**(): `Uint8Array` Defined in: @nimiq/core/types/wasm/web.d.ts:2057 Serializes the random secret to a byte array. #### Returns `Uint8Array` --- ### toHex() > **toHex**(): `string` Defined in: @nimiq/core/types/wasm/web.d.ts:2061 Formats the random secret into a hex string. #### Returns `string` --- ### deserialize() > `static` **deserialize**(`bytes`): `RandomSecret` Defined in: @nimiq/core/types/wasm/web.d.ts:2031 Deserializes a random secret from a byte array. Throws when the byte array contains less than 32 bytes. #### Parameters ##### bytes `Uint8Array` #### Returns `RandomSecret` --- ### fromAny() > `static` **fromAny**(`secret`): `RandomSecret` Defined in: @nimiq/core/types/wasm/web.d.ts:2041 Parses a random secret from a RandomSecret instance, a hex string representation, or a byte array. Throws when a RandomSecret cannot be parsed from the argument. #### Parameters ##### secret `string` | `Uint8Array`<`ArrayBufferLike`> | `RandomSecret` #### Returns `RandomSecret` --- ### fromHex() > `static` **fromHex**(`hex`): `RandomSecret` Defined in: @nimiq/core/types/wasm/web.d.ts:2047 Parses a random secret from its hex representation. Throws when the string is not valid hex format or when it represents less than 32 bytes. #### Parameters ##### hex `string` #### Returns `RandomSecret` # Abstract Class: Secret [@nimiq/core](https://nimiq.com/developers/../globals) / Secret Defined in: @nimiq/core/lib/index.d.ts:175 ## Extends - `Serializable` ## Extended by - [`Entropy`](https://nimiq.com/developers/Entropy) ## Constructors ### Constructor > **new Secret**(`type`, `purposeId`): `Secret` Defined in: @nimiq/core/lib/index.d.ts:183 #### Parameters ##### type [`Type`](https://nimiq.com/developers/../@nimiq/namespaces/Secret/enumerations/Type) ##### purposeId `number` #### Returns `Secret` #### Overrides `Serializable.constructor` ## Properties ### ENCRYPTION\_CHECKSUM\_SIZE > `static` **ENCRYPTION\_CHECKSUM\_SIZE**: `number` Defined in: @nimiq/core/lib/index.d.ts:181 --- ### ENCRYPTION\_CHECKSUM\_SIZE\_V3 > `static` **ENCRYPTION\_CHECKSUM\_SIZE\_V3**: `number` Defined in: @nimiq/core/lib/index.d.ts:182 --- ### ENCRYPTION\_KDF\_ROUNDS > `static` **ENCRYPTION\_KDF\_ROUNDS**: `number` Defined in: @nimiq/core/lib/index.d.ts:180 --- ### ENCRYPTION\_SALT\_SIZE > `static` **ENCRYPTION\_SALT\_SIZE**: `number` Defined in: @nimiq/core/lib/index.d.ts:179 --- ### SIZE > `static` **SIZE**: `number` Defined in: @nimiq/core/lib/index.d.ts:178 ## Accessors ### encryptedSize #### Get Signature > **get** **encryptedSize**(): `number` Defined in: @nimiq/core/lib/index.d.ts:196 Returns the serialized size of this object when encrypted. ##### Returns `number` ## Methods ### compare() > **compare**(`o`): `number` Defined in: @nimiq/core/lib/index.d.ts:97 Compares this object to another object. Returns a negative number if `this` is smaller than o, a positive number if `this` is larger than o, and zero if equal. #### Parameters ##### o `Serializable` #### Returns `number` #### Inherited from `Serializable.compare` --- ### equals() > **equals**(`o`): `boolean` Defined in: @nimiq/core/lib/index.d.ts:91 Checks for equality with another Serializable. #### Parameters ##### o `unknown` #### Returns `boolean` #### Inherited from `Serializable.equals` --- ### exportEncrypted() > **exportEncrypted**(`key`): `Promise`<[`SerialBuffer`](https://nimiq.com/developers/SerialBuffer)> Defined in: @nimiq/core/lib/index.d.ts:192 Encrypts the Secret with a password. #### Parameters ##### key `Uint8Array` #### Returns `Promise`<[`SerialBuffer`](https://nimiq.com/developers/SerialBuffer)> --- ### serialize() > `abstract` **serialize**(`buf?`): [`SerialBuffer`](https://nimiq.com/developers/SerialBuffer) Defined in: @nimiq/core/lib/index.d.ts:98 #### Parameters ##### buf? [`SerialBuffer`](https://nimiq.com/developers/SerialBuffer) #### Returns [`SerialBuffer`](https://nimiq.com/developers/SerialBuffer) #### Inherited from `Serializable.serialize` --- ### toBase64() > **toBase64**(): `string` Defined in: @nimiq/core/lib/index.d.ts:106 Formats the object into a base64 string. #### Returns `string` #### Inherited from `Serializable.toBase64` --- ### toHex() > **toHex**(): `string` Defined in: @nimiq/core/lib/index.d.ts:110 Formats the object into a hex string. #### Returns `string` #### Inherited from `Serializable.toHex` --- ### toString() > **toString**(): `string` Defined in: @nimiq/core/lib/index.d.ts:102 Formats the object into a hex string. #### Returns `string` #### Inherited from `Serializable.toString` --- ### exportEncrypted() > `static` **exportEncrypted**(`secret`, `key`): `Promise`<[`SerialBuffer`](https://nimiq.com/developers/SerialBuffer)> Defined in: @nimiq/core/lib/index.d.ts:188 #### Parameters ##### secret `Secret` | `PrivateKey` ##### key `Uint8Array` #### Returns `Promise`<[`SerialBuffer`](https://nimiq.com/developers/SerialBuffer)> --- ### fromEncrypted() > `static` **fromEncrypted**(`buf`, `key`): `Promise`<[`Entropy`](https://nimiq.com/developers/Entropy) | `PrivateKey`> Defined in: @nimiq/core/lib/index.d.ts:187 Decrypts a Secret from an encrypted byte array and its password. #### Parameters ##### buf [`SerialBuffer`](https://nimiq.com/developers/SerialBuffer) ##### key `Uint8Array` #### Returns `Promise`<[`Entropy`](https://nimiq.com/developers/Entropy) | `PrivateKey`> # Class: SerialBuffer [@nimiq/core](https://nimiq.com/developers/../globals) / SerialBuffer Defined in: @nimiq/core/lib/index.d.ts:7 ## Extends - `Uint8Array` ## Indexable \[`index`: `number`]: `number` ## Constructors ### Constructor > **new SerialBuffer**(`length`): `SerialBuffer` Defined in: @nimiq/core/lib/index.d.ts:12 #### Parameters ##### length `number` #### Returns `SerialBuffer` #### Overrides `Uint8Array.constructor` ### Constructor > **new SerialBuffer**(`array`): `SerialBuffer` Defined in: @nimiq/core/lib/index.d.ts:13 #### Parameters ##### array `ArrayBufferLike` | `ArrayLike`<`number`> #### Returns `SerialBuffer` #### Overrides `Uint8Array.constructor` ## Properties ### \[toStringTag] > `readonly` **\[toStringTag]**: `"Uint8Array"` Defined in: .pnpm/typescript\@5.9.3/node\_modules/typescript/lib/lib.es2015.symbol.wellknown.d.ts:284 #### Inherited from `Uint8Array.[toStringTag]` --- ### buffer > `readonly` **buffer**: `ArrayBuffer` Defined in: .pnpm/typescript\@5.9.3/node\_modules/typescript/lib/lib.es5.d.ts:2174 The ArrayBuffer instance referenced by the array. #### Inherited from `Uint8Array.buffer` --- ### byteLength > `readonly` **byteLength**: `number` Defined in: .pnpm/typescript\@5.9.3/node\_modules/typescript/lib/lib.es5.d.ts:2179 The length in bytes of the array. #### Inherited from `Uint8Array.byteLength` --- ### byteOffset > `readonly` **byteOffset**: `number` Defined in: .pnpm/typescript\@5.9.3/node\_modules/typescript/lib/lib.es5.d.ts:2184 The offset in bytes of the array. #### Inherited from `Uint8Array.byteOffset` --- ### BYTES\_PER\_ELEMENT > `readonly` **BYTES\_PER\_ELEMENT**: `number` Defined in: .pnpm/typescript\@5.9.3/node\_modules/typescript/lib/lib.es5.d.ts:2169 The size in bytes of each element in the array. #### Inherited from `Uint8Array.BYTES_PER_ELEMENT` --- ### length > `readonly` **length**: `number` Defined in: .pnpm/typescript\@5.9.3/node\_modules/typescript/lib/lib.es5.d.ts:2283 The length of the array. #### Inherited from `Uint8Array.length` --- ### BYTES\_PER\_ELEMENT > `readonly` `static` **BYTES\_PER\_ELEMENT**: `number` Defined in: .pnpm/typescript\@5.9.3/node\_modules/typescript/lib/lib.es5.d.ts:2419 The size in bytes of each element in the array. #### Inherited from `Uint8Array.BYTES_PER_ELEMENT` --- ### EMPTY > `static` **EMPTY**: `SerialBuffer` Defined in: @nimiq/core/lib/index.d.ts:11 ## Accessors ### readPos #### Get Signature > **get** **readPos**(): `number` Defined in: @nimiq/core/lib/index.d.ts:15 ##### Returns `number` #### Set Signature > **set** **readPos**(`value`): `void` Defined in: @nimiq/core/lib/index.d.ts:16 ##### Parameters ###### value `number` ##### Returns `void` --- ### writePos #### Get Signature > **get** **writePos**(): `number` Defined in: @nimiq/core/lib/index.d.ts:17 ##### Returns `number` #### Set Signature > **set** **writePos**(`value`): `void` Defined in: @nimiq/core/lib/index.d.ts:18 ##### Parameters ###### value `number` ##### Returns `void` ## Methods ### \[iterator]\() > **\[iterator]**(): `ArrayIterator`<`number`> Defined in: .pnpm/typescript\@5.9.3/node\_modules/typescript/lib/lib.es2015.iterable.d.ts:313 #### Returns `ArrayIterator`<`number`> #### Inherited from `Uint8Array.[iterator]` --- ### copyWithin() > **copyWithin**(`target`, `start`, `end?`): `this` Defined in: .pnpm/typescript\@5.9.3/node\_modules/typescript/lib/lib.es5.d.ts:2195 Returns the this object after copying a section of the array identified by start and end to the same array starting at position target #### Parameters ##### target `number` If target is negative, it is treated as length+target where length is the length of the array. ##### start `number` If start is negative, it is treated as length+start. If end is negative, it is treated as length+end. ##### end? `number` If not specified, length of the this object is used as its default value. #### Returns `this` #### Inherited from `Uint8Array.copyWithin` --- ### entries() > **entries**(): `ArrayIterator`<\[`number`, `number`]> Defined in: .pnpm/typescript\@5.9.3/node\_modules/typescript/lib/lib.es2015.iterable.d.ts:318 Returns an array of key, value pairs for every entry in the array #### Returns `ArrayIterator`<\[`number`, `number`]> #### Inherited from `Uint8Array.entries` --- ### every() > **every**(`predicate`, `thisArg?`): `boolean` Defined in: .pnpm/typescript\@5.9.3/node\_modules/typescript/lib/lib.es5.d.ts:2205 Determines whether all the members of an array satisfy the specified test. #### Parameters ##### predicate (`value`, `index`, `array`) => `unknown` A function that accepts up to three arguments. The every method calls the predicate function for each element in the array until the predicate returns a value which is coercible to the Boolean value false, or until the end of the array. ##### thisArg? `any` An object to which the this keyword can refer in the predicate function. If thisArg is omitted, undefined is used as the this value. #### Returns `boolean` #### Inherited from `Uint8Array.every` --- ### fill() > **fill**(`value`, `start?`, `end?`): `this` Defined in: .pnpm/typescript\@5.9.3/node\_modules/typescript/lib/lib.es5.d.ts:2215 Changes all array elements from `start` to `end` index to a static `value` and returns the modified array #### Parameters ##### value `number` value to fill array section with ##### start? `number` index to start filling the array at. If start is negative, it is treated as length+start where length is the length of the array. ##### end? `number` index to stop filling the array at. If end is negative, it is treated as length+end. #### Returns `this` #### Inherited from `Uint8Array.fill` --- ### filter() > **filter**(`predicate`, `thisArg?`): `Uint8Array`<`ArrayBuffer`> Defined in: .pnpm/typescript\@5.9.3/node\_modules/typescript/lib/lib.es5.d.ts:2224 Returns the elements of an array that meet the condition specified in a callback function. #### Parameters ##### predicate (`value`, `index`, `array`) => `any` A function that accepts up to three arguments. The filter method calls the predicate function one time for each element in the array. ##### thisArg? `any` An object to which the this keyword can refer in the predicate function. If thisArg is omitted, undefined is used as the this value. #### Returns `Uint8Array`<`ArrayBuffer`> #### Inherited from `Uint8Array.filter` --- ### find() > **find**(`predicate`, `thisArg?`): `number` Defined in: .pnpm/typescript\@5.9.3/node\_modules/typescript/lib/lib.es5.d.ts:2235 Returns the value of the first element in the array where predicate is true, and undefined otherwise. #### Parameters ##### predicate (`value`, `index`, `obj`) => `boolean` find calls predicate once for each element of the array, in ascending order, until it finds one where predicate returns true. If such an element is found, find immediately returns that element value. Otherwise, find returns undefined. ##### thisArg? `any` If provided, it will be used as the this value for each invocation of predicate. If it is not provided, undefined is used instead. #### Returns `number` #### Inherited from `Uint8Array.find` --- ### findIndex() > **findIndex**(`predicate`, `thisArg?`): `number` Defined in: .pnpm/typescript\@5.9.3/node\_modules/typescript/lib/lib.es5.d.ts:2246 Returns the index of the first element in the array where predicate is true, and -1 otherwise. #### Parameters ##### predicate (`value`, `index`, `obj`) => `boolean` find calls predicate once for each element of the array, in ascending order, until it finds one where predicate returns true. If such an element is found, findIndex immediately returns that element index. Otherwise, findIndex returns -1. ##### thisArg? `any` If provided, it will be used as the this value for each invocation of predicate. If it is not provided, undefined is used instead. #### Returns `number` #### Inherited from `Uint8Array.findIndex` --- ### forEach() > **forEach**(`callbackfn`, `thisArg?`): `void` Defined in: .pnpm/typescript\@5.9.3/node\_modules/typescript/lib/lib.es5.d.ts:2255 Performs the specified action for each element in an array. #### Parameters ##### callbackfn (`value`, `index`, `array`) => `void` A function that accepts up to three arguments. forEach calls the callbackfn function one time for each element in the array. ##### thisArg? `any` An object to which the this keyword can refer in the callbackfn function. If thisArg is omitted, undefined is used as the this value. #### Returns `void` #### Inherited from `Uint8Array.forEach` --- ### includes() > **includes**(`searchElement`, `fromIndex?`): `boolean` Defined in: .pnpm/typescript\@5.9.3/node\_modules/typescript/lib/lib.es2016.array.include.d.ts:52 Determines whether an array includes a certain element, returning true or false as appropriate. #### Parameters ##### searchElement `number` The element to search for. ##### fromIndex? `number` The position in this array at which to begin searching for searchElement. #### Returns `boolean` #### Inherited from `Uint8Array.includes` --- ### indexOf() > **indexOf**(`searchElement`, `fromIndex?`): `number` Defined in: .pnpm/typescript\@5.9.3/node\_modules/typescript/lib/lib.es5.d.ts:2263 Returns the index of the first occurrence of a value in an array. #### Parameters ##### searchElement `number` The value to locate in the array. ##### fromIndex? `number` The array index at which to begin the search. If fromIndex is omitted, the search starts at index 0. #### Returns `number` #### Inherited from `Uint8Array.indexOf` --- ### join() > **join**(`separator?`): `string` Defined in: .pnpm/typescript\@5.9.3/node\_modules/typescript/lib/lib.es5.d.ts:2270 Adds all the elements of an array separated by the specified separator string. #### Parameters ##### separator? `string` A string used to separate one element of an array from the next in the resulting String. If omitted, the array elements are separated with a comma. #### Returns `string` #### Inherited from `Uint8Array.join` --- ### keys() > **keys**(): `ArrayIterator`<`number`> Defined in: .pnpm/typescript\@5.9.3/node\_modules/typescript/lib/lib.es2015.iterable.d.ts:323 Returns an list of keys in the array #### Returns `ArrayIterator`<`number`> #### Inherited from `Uint8Array.keys` --- ### lastIndexOf() > **lastIndexOf**(`searchElement`, `fromIndex?`): `number` Defined in: .pnpm/typescript\@5.9.3/node\_modules/typescript/lib/lib.es5.d.ts:2278 Returns the index of the last occurrence of a value in an array. #### Parameters ##### searchElement `number` The value to locate in the array. ##### fromIndex? `number` The array index at which to begin the search. If fromIndex is omitted, the search starts at index 0. #### Returns `number` #### Inherited from `Uint8Array.lastIndexOf` --- ### map() > **map**(`callbackfn`, `thisArg?`): `Uint8Array`<`ArrayBuffer`> Defined in: .pnpm/typescript\@5.9.3/node\_modules/typescript/lib/lib.es5.d.ts:2293 Calls a defined callback function on each element of an array, and returns an array that contains the results. #### Parameters ##### callbackfn (`value`, `index`, `array`) => `number` A function that accepts up to three arguments. The map method calls the callbackfn function one time for each element in the array. ##### thisArg? `any` An object to which the this keyword can refer in the callbackfn function. If thisArg is omitted, undefined is used as the this value. #### Returns `Uint8Array`<`ArrayBuffer`> #### Inherited from `Uint8Array.map` --- ### read() > **read**(`length`): `Uint8Array` Defined in: @nimiq/core/lib/index.d.ts:23 #### Parameters ##### length `number` #### Returns `Uint8Array` --- ### readFloat64() > **readFloat64**(): `number` Defined in: @nimiq/core/lib/index.d.ts:36 #### Returns `number` --- ### readPaddedString() > **readPaddedString**(`length`): `string` Defined in: @nimiq/core/lib/index.d.ts:40 #### Parameters ##### length `number` #### Returns `string` --- ### readString() > **readString**(`length`): `string` Defined in: @nimiq/core/lib/index.d.ts:38 #### Parameters ##### length `number` #### Returns `string` --- ### readUint16() > **readUint16**(): `number` Defined in: @nimiq/core/lib/index.d.ts:27 #### Returns `number` --- ### readUint32() > **readUint32**(): `number` Defined in: @nimiq/core/lib/index.d.ts:29 #### Returns `number` --- ### readUint64() > **readUint64**(): `number` Defined in: @nimiq/core/lib/index.d.ts:31 #### Returns `number` --- ### readUint8() > **readUint8**(): `number` Defined in: @nimiq/core/lib/index.d.ts:25 #### Returns `number` --- ### readVarLengthString() > **readVarLengthString**(): `string` Defined in: @nimiq/core/lib/index.d.ts:42 #### Returns `string` --- ### readVarUint() > **readVarUint**(): `number` Defined in: @nimiq/core/lib/index.d.ts:33 #### Returns `number` --- ### reduce() #### Call Signature > **reduce**(`callbackfn`): `number` Defined in: .pnpm/typescript\@5.9.3/node\_modules/typescript/lib/lib.es5.d.ts:2305 Calls the specified callback function for all the elements in an array. The return value of the callback function is the accumulated result, and is provided as an argument in the next call to the callback function. ##### Parameters ###### callbackfn (`previousValue`, `currentValue`, `currentIndex`, `array`) => `number` A function that accepts up to four arguments. The reduce method calls the callbackfn function one time for each element in the array. ##### Returns `number` ##### Inherited from `Uint8Array.reduce` #### Call Signature > **reduce**(`callbackfn`, `initialValue`): `number` Defined in: .pnpm/typescript\@5.9.3/node\_modules/typescript/lib/lib.es5.d.ts:2306 ##### Parameters ###### callbackfn (`previousValue`, `currentValue`, `currentIndex`, `array`) => `number` ###### initialValue `number` ##### Returns `number` ##### Inherited from `Uint8Array.reduce` #### Call Signature > **reduce**<`U`>(`callbackfn`, `initialValue`): `U` Defined in: .pnpm/typescript\@5.9.3/node\_modules/typescript/lib/lib.es5.d.ts:2318 Calls the specified callback function for all the elements in an array. The return value of the callback function is the accumulated result, and is provided as an argument in the next call to the callback function. ##### Type Parameters ###### U `U` ##### Parameters ###### callbackfn (`previousValue`, `currentValue`, `currentIndex`, `array`) => `U` A function that accepts up to four arguments. The reduce method calls the callbackfn function one time for each element in the array. ###### initialValue `U` If initialValue is specified, it is used as the initial value to start the accumulation. The first call to the callbackfn function provides this value as an argument instead of an array value. ##### Returns `U` ##### Inherited from `Uint8Array.reduce` --- ### reduceRight() #### Call Signature > **reduceRight**(`callbackfn`): `number` Defined in: .pnpm/typescript\@5.9.3/node\_modules/typescript/lib/lib.es5.d.ts:2330 Calls the specified callback function for all the elements in an array, in descending order. The return value of the callback function is the accumulated result, and is provided as an argument in the next call to the callback function. ##### Parameters ###### callbackfn (`previousValue`, `currentValue`, `currentIndex`, `array`) => `number` A function that accepts up to four arguments. The reduceRight method calls the callbackfn function one time for each element in the array. ##### Returns `number` ##### Inherited from `Uint8Array.reduceRight` #### Call Signature > **reduceRight**(`callbackfn`, `initialValue`): `number` Defined in: .pnpm/typescript\@5.9.3/node\_modules/typescript/lib/lib.es5.d.ts:2331 ##### Parameters ###### callbackfn (`previousValue`, `currentValue`, `currentIndex`, `array`) => `number` ###### initialValue `number` ##### Returns `number` ##### Inherited from `Uint8Array.reduceRight` #### Call Signature > **reduceRight**<`U`>(`callbackfn`, `initialValue`): `U` Defined in: .pnpm/typescript\@5.9.3/node\_modules/typescript/lib/lib.es5.d.ts:2343 Calls the specified callback function for all the elements in an array, in descending order. The return value of the callback function is the accumulated result, and is provided as an argument in the next call to the callback function. ##### Type Parameters ###### U `U` ##### Parameters ###### callbackfn (`previousValue`, `currentValue`, `currentIndex`, `array`) => `U` A function that accepts up to four arguments. The reduceRight method calls the callbackfn function one time for each element in the array. ###### initialValue `U` If initialValue is specified, it is used as the initial value to start the accumulation. The first call to the callbackfn function provides this value as an argument instead of an array value. ##### Returns `U` ##### Inherited from `Uint8Array.reduceRight` --- ### reset() > **reset**(): `void` Defined in: @nimiq/core/lib/index.d.ts:22 Resets the read and write position of the buffer to zero. #### Returns `void` --- ### reverse() > **reverse**(): `this` Defined in: .pnpm/typescript\@5.9.3/node\_modules/typescript/lib/lib.es5.d.ts:2348 Reverses the elements in an Array. #### Returns `this` #### Inherited from `Uint8Array.reverse` --- ### set() > **set**(`array`, `offset?`): `void` Defined in: .pnpm/typescript\@5.9.3/node\_modules/typescript/lib/lib.es5.d.ts:2355 Sets a value or an array of values. #### Parameters ##### array `ArrayLike`<`number`> A typed or untyped array of values to set. ##### offset? `number` The index in the current array at which the values are to be written. #### Returns `void` #### Inherited from `Uint8Array.set` --- ### slice() > **slice**(`start?`, `end?`): `Uint8Array`<`ArrayBuffer`> Defined in: .pnpm/typescript\@5.9.3/node\_modules/typescript/lib/lib.es5.d.ts:2362 Returns a section of an array. #### Parameters ##### start? `number` The beginning of the specified portion of the array. ##### end? `number` The end of the specified portion of the array. This is exclusive of the element at the index 'end'. #### Returns `Uint8Array`<`ArrayBuffer`> #### Inherited from `Uint8Array.slice` --- ### some() > **some**(`predicate`, `thisArg?`): `boolean` Defined in: .pnpm/typescript\@5.9.3/node\_modules/typescript/lib/lib.es5.d.ts:2372 Determines whether the specified callback function returns true for any element of an array. #### Parameters ##### predicate (`value`, `index`, `array`) => `unknown` A function that accepts up to three arguments. The some method calls the predicate function for each element in the array until the predicate returns a value which is coercible to the Boolean value true, or until the end of the array. ##### thisArg? `any` An object to which the this keyword can refer in the predicate function. If thisArg is omitted, undefined is used as the this value. #### Returns `boolean` #### Inherited from `Uint8Array.some` --- ### sort() > **sort**(`compareFn?`): `this` Defined in: .pnpm/typescript\@5.9.3/node\_modules/typescript/lib/lib.es5.d.ts:2383 Sorts an array. #### Parameters ##### compareFn? (`a`, `b`) => `number` Function used to determine the order of the elements. It is expected to return a negative value if first argument is less than second argument, zero if they're equal and a positive value otherwise. If omitted, the elements are sorted in ascending order. ```ts [11,2,22,1].sort((a, b) => a - b) ``` #### Returns `this` #### Inherited from `Uint8Array.sort` --- ### subarray() > **subarray**(`start?`, `end?`): `Uint8Array` Defined in: @nimiq/core/lib/index.d.ts:14 Gets a new Uint8Array view of the ArrayBuffer store for this array, referencing the elements at begin, inclusive, up to end, exclusive. #### Parameters ##### start? `number` ##### end? `number` The index of the end of the array. #### Returns `Uint8Array` #### Overrides `Uint8Array.subarray` --- ### toLocaleString() #### Call Signature > **toLocaleString**(): `string` Defined in: .pnpm/typescript\@5.9.3/node\_modules/typescript/lib/lib.es5.d.ts:2396 Converts a number to a string by using the current locale. ##### Returns `string` ##### Inherited from `Uint8Array.toLocaleString` #### Call Signature > **toLocaleString**(`locales`, `options?`): `string` Defined in: .pnpm/typescript\@5.9.3/node\_modules/typescript/lib/lib.es2015.core.d.ts:568 ##### Parameters ###### locales `string` | `string`[] ###### options? `NumberFormatOptions` ##### Returns `string` ##### Inherited from `Uint8Array.toLocaleString` --- ### toString() > **toString**(): `string` Defined in: .pnpm/typescript\@5.9.3/node\_modules/typescript/lib/lib.es5.d.ts:2401 Returns a string representation of an array. #### Returns `string` #### Inherited from `Uint8Array.toString` --- ### valueOf() > **valueOf**(): `this` Defined in: .pnpm/typescript\@5.9.3/node\_modules/typescript/lib/lib.es5.d.ts:2404 Returns the primitive value of the specified object. #### Returns `this` #### Inherited from `Uint8Array.valueOf` --- ### values() > **values**(): `ArrayIterator`<`number`> Defined in: .pnpm/typescript\@5.9.3/node\_modules/typescript/lib/lib.es2015.iterable.d.ts:328 Returns an list of values in the array #### Returns `ArrayIterator`<`number`> #### Inherited from `Uint8Array.values` --- ### write() > **write**(`array`): `void` Defined in: @nimiq/core/lib/index.d.ts:24 #### Parameters ##### array `Uint8Array` #### Returns `void` --- ### writeFloat64() > **writeFloat64**(`value`): `void` Defined in: @nimiq/core/lib/index.d.ts:37 #### Parameters ##### value `number` #### Returns `void` --- ### writePaddedString() > **writePaddedString**(`value`, `length`): `void` Defined in: @nimiq/core/lib/index.d.ts:41 #### Parameters ##### value `string` ##### length `number` #### Returns `void` --- ### writeString() > **writeString**(`value`, `length`): `void` Defined in: @nimiq/core/lib/index.d.ts:39 #### Parameters ##### value `string` ##### length `number` #### Returns `void` --- ### writeUint16() > **writeUint16**(`value`): `void` Defined in: @nimiq/core/lib/index.d.ts:28 #### Parameters ##### value `number` #### Returns `void` --- ### writeUint32() > **writeUint32**(`value`): `void` Defined in: @nimiq/core/lib/index.d.ts:30 #### Parameters ##### value `number` #### Returns `void` --- ### writeUint64() > **writeUint64**(`value`): `void` Defined in: @nimiq/core/lib/index.d.ts:32 #### Parameters ##### value `number` #### Returns `void` --- ### writeUint8() > **writeUint8**(`value`): `void` Defined in: @nimiq/core/lib/index.d.ts:26 #### Parameters ##### value `number` #### Returns `void` --- ### writeVarLengthString() > **writeVarLengthString**(`value`): `void` Defined in: @nimiq/core/lib/index.d.ts:43 #### Parameters ##### value `string` #### Returns `void` --- ### writeVarUint() > **writeVarUint**(`value`): `void` Defined in: @nimiq/core/lib/index.d.ts:34 #### Parameters ##### value `number` #### Returns `void` --- ### from() #### Call Signature > `static` **from**(`arrayLike`): `Uint8Array`<`ArrayBuffer`> Defined in: .pnpm/typescript\@5.9.3/node\_modules/typescript/lib/lib.es5.d.ts:2431 Creates an array from an array-like or iterable object. ##### Parameters ###### arrayLike `ArrayLike`<`number`> An array-like object to convert to an array. ##### Returns `Uint8Array`<`ArrayBuffer`> ##### Inherited from `Uint8Array.from` #### Call Signature > `static` **from**<`T`>(`arrayLike`, `mapfn`, `thisArg?`): `Uint8Array`<`ArrayBuffer`> Defined in: .pnpm/typescript\@5.9.3/node\_modules/typescript/lib/lib.es5.d.ts:2439 Creates an array from an array-like or iterable object. ##### Type Parameters ###### T `T` ##### Parameters ###### arrayLike `ArrayLike`<`T`> An array-like object to convert to an array. ###### mapfn (`v`, `k`) => `number` A mapping function to call on every element of the array. ###### thisArg? `any` Value of 'this' used to invoke the mapfn. ##### Returns `Uint8Array`<`ArrayBuffer`> ##### Inherited from `Uint8Array.from` #### Call Signature > `static` **from**(`elements`): `Uint8Array`<`ArrayBuffer`> Defined in: .pnpm/typescript\@5.9.3/node\_modules/typescript/lib/lib.es2015.iterable.d.ts:338 Creates an array from an array-like or iterable object. ##### Parameters ###### elements `Iterable`<`number`> An iterable object to convert to an array. ##### Returns `Uint8Array`<`ArrayBuffer`> ##### Inherited from `Uint8Array.from` #### Call Signature > `static` **from**<`T`>(`elements`, `mapfn?`, `thisArg?`): `Uint8Array`<`ArrayBuffer`> Defined in: .pnpm/typescript\@5.9.3/node\_modules/typescript/lib/lib.es2015.iterable.d.ts:346 Creates an array from an array-like or iterable object. ##### Type Parameters ###### T `T` ##### Parameters ###### elements `Iterable`<`T`> An iterable object to convert to an array. ###### mapfn? (`v`, `k`) => `number` A mapping function to call on every element of the array. ###### thisArg? `any` Value of 'this' used to invoke the mapfn. ##### Returns `Uint8Array`<`ArrayBuffer`> ##### Inherited from `Uint8Array.from` --- ### of() > `static` **of**(...`items`): `Uint8Array`<`ArrayBuffer`> Defined in: .pnpm/typescript\@5.9.3/node\_modules/typescript/lib/lib.es5.d.ts:2425 Returns a new array from a set of elements. #### Parameters ##### items ...`number`[] A set of elements to include in the new array object. #### Returns `Uint8Array`<`ArrayBuffer`> #### Inherited from `Uint8Array.of` --- ### varLengthStringSize() > `static` **varLengthStringSize**(`value`): `number` Defined in: @nimiq/core/lib/index.d.ts:44 #### Parameters ##### value `string` #### Returns `number` --- ### varUintSize() > `static` **varUintSize**(`value`): `number` Defined in: @nimiq/core/lib/index.d.ts:35 #### Parameters ##### value `number` #### Returns `number` # Class: Signature [@nimiq/core](https://nimiq.com/developers/../globals) / Signature Defined in: @nimiq/core/types/wasm/web.d.ts:2070 An Ed25519 Signature represents a cryptographic proof that a private key signed some data. It can be verified with the private key's public key. ## Methods ### \_\_getClassname() > **\_\_getClassname**(): `string` Defined in: @nimiq/core/types/wasm/web.d.ts:2074 #### Returns `string` --- ### \[dispose]\() > **\[dispose]**(): `void` Defined in: @nimiq/core/types/wasm/web.d.ts:2073 #### Returns `void` --- ### free() > **free**(): `void` Defined in: @nimiq/core/types/wasm/web.d.ts:2072 #### Returns `void` --- ### serialize() > **serialize**(): `Uint8Array` Defined in: @nimiq/core/types/wasm/web.d.ts:2098 Serializes the signature to a byte array. #### Returns `Uint8Array` --- ### toHex() > **toHex**(): `string` Defined in: @nimiq/core/types/wasm/web.d.ts:2102 Formats the signature into a hex string. #### Returns `string` --- ### create() > `static` **create**(`private_key`, `public_key`, `data`): `Signature` Defined in: @nimiq/core/types/wasm/web.d.ts:2078 Create a signature from a private key and its public key over byte data. #### Parameters ##### private\_key [`PrivateKey`](https://nimiq.com/developers/PrivateKey) ##### public\_key [`PublicKey`](https://nimiq.com/developers/PublicKey) ##### data `Uint8Array` #### Returns `Signature` --- ### deserialize() > `static` **deserialize**(`bytes`): `Signature` Defined in: @nimiq/core/types/wasm/web.d.ts:2084 Deserializes an Ed25519 signature from a byte array. Throws when the byte array contains less than 64 bytes. #### Parameters ##### bytes `Uint8Array` #### Returns `Signature` --- ### fromAsn1() > `static` **fromAsn1**(`bytes`): `Signature` Defined in: @nimiq/core/types/wasm/web.d.ts:2088 Parses an Ed25519 signature from its ASN.1 representation. #### Parameters ##### bytes `Uint8Array` #### Returns `Signature` --- ### fromHex() > `static` **fromHex**(`hex`): `Signature` Defined in: @nimiq/core/types/wasm/web.d.ts:2094 Parses an Ed25519 signature from its hex representation. Throws when the string is not valid hex format or when it represents less than 64 bytes. #### Parameters ##### hex `string` #### Returns `Signature` # Class: SignatureProof [@nimiq/core](https://nimiq.com/developers/../globals) / SignatureProof Defined in: @nimiq/core/types/wasm/web.d.ts:2109 A signature proof represents a signature together with its public key and the public key's merkle path. It is used as the proof for transactions. ## Properties ### merklePath > `readonly` **merklePath**: [`MerklePath`](https://nimiq.com/developers/MerklePath) Defined in: @nimiq/core/types/wasm/web.d.ts:2154 The embedded merkle path. --- ### publicKey > `readonly` **publicKey**: [`PublicKey`](https://nimiq.com/developers/PublicKey) | [`ES256PublicKey`](https://nimiq.com/developers/ES256PublicKey) Defined in: @nimiq/core/types/wasm/web.d.ts:2158 The embedded public key. --- ### signature > `readonly` **signature**: [`ES256Signature`](https://nimiq.com/developers/ES256Signature) | [`Signature`](https://nimiq.com/developers/Signature) Defined in: @nimiq/core/types/wasm/web.d.ts:2162 The embedded signature. --- ### ES256\_SINGLE\_SIG\_SIZE > `readonly` `static` **ES256\_SINGLE\_SIG\_SIZE**: `number` Defined in: @nimiq/core/types/wasm/web.d.ts:2150 --- ### SINGLE\_SIG\_SIZE > `readonly` `static` **SINGLE\_SIG\_SIZE**: `number` Defined in: @nimiq/core/types/wasm/web.d.ts:2163 ## Methods ### \[dispose]\() > **\[dispose]**(): `void` Defined in: @nimiq/core/types/wasm/web.d.ts:2112 #### Returns `void` --- ### free() > **free**(): `void` Defined in: @nimiq/core/types/wasm/web.d.ts:2111 #### Returns `void` --- ### isSignedBy() > **isSignedBy**(`sender`): `boolean` Defined in: @nimiq/core/types/wasm/web.d.ts:2120 Checks if the signature proof is signed by the provided address. #### Parameters ##### sender [`Address`](https://nimiq.com/developers/Address) #### Returns `boolean` --- ### serialize() > **serialize**(): `Uint8Array` Defined in: @nimiq/core/types/wasm/web.d.ts:2129 Serializes the proof to a byte array, e.g. for assigning it to a `transaction.proof` field. #### Returns `Uint8Array` --- ### toPlain() > **toPlain**(): [`PlainTransactionProof`](https://nimiq.com/developers/../type-aliases/PlainTransactionProof) Defined in: @nimiq/core/types/wasm/web.d.ts:2137 Creates a JSON-compatible plain object representing the signature proof. #### Returns [`PlainTransactionProof`](https://nimiq.com/developers/../type-aliases/PlainTransactionProof) --- ### verify() > **verify**(`data`): `boolean` Defined in: @nimiq/core/types/wasm/web.d.ts:2141 Verifies the signature proof against the provided data. #### Parameters ##### data `Uint8Array` #### Returns `boolean` --- ### deserialize() > `static` **deserialize**(`bytes`): `SignatureProof` Defined in: @nimiq/core/types/wasm/web.d.ts:2116 Deserializes a signature proof from a byte array. #### Parameters ##### bytes `Uint8Array` #### Returns `SignatureProof` --- ### multiSig() > `static` **multiSig**(`signer_key`, `public_keys`, `signature`): `SignatureProof` Defined in: @nimiq/core/types/wasm/web.d.ts:2125 Creates a Ed25519/Schnorr signature proof for a multi-sig signature. The public keys can also include ES256 keys. #### Parameters ##### signer\_key [`PublicKey`](https://nimiq.com/developers/PublicKey) ##### public\_keys ([`PublicKey`](https://nimiq.com/developers/PublicKey) | [`ES256PublicKey`](https://nimiq.com/developers/ES256PublicKey)) [] ##### signature [`Signature`](https://nimiq.com/developers/Signature) #### Returns `SignatureProof` --- ### singleSig() > `static` **singleSig**(`public_key`, `signature`): `SignatureProof` Defined in: @nimiq/core/types/wasm/web.d.ts:2133 Creates a Ed25519/Schnorr signature proof for a single-sig signature. #### Parameters ##### public\_key [`PublicKey`](https://nimiq.com/developers/PublicKey) ##### signature [`Signature`](https://nimiq.com/developers/Signature) #### Returns `SignatureProof` --- ### webauthnMultiSig() > `static` **webauthnMultiSig**(`signer_key`, `public_keys`, `signature`, `authenticator_data`, `client_data_json`): `SignatureProof` Defined in: @nimiq/core/types/wasm/web.d.ts:2145 Creates a Webauthn signature proof for a multi-sig signature. #### Parameters ##### signer\_key [`PublicKey`](https://nimiq.com/developers/PublicKey) | [`ES256PublicKey`](https://nimiq.com/developers/ES256PublicKey) ##### public\_keys ([`PublicKey`](https://nimiq.com/developers/PublicKey) | [`ES256PublicKey`](https://nimiq.com/developers/ES256PublicKey)) [] ##### signature [`ES256Signature`](https://nimiq.com/developers/ES256Signature) | [`Signature`](https://nimiq.com/developers/Signature) ##### authenticator\_data `Uint8Array` ##### client\_data\_json `Uint8Array` #### Returns `SignatureProof` --- ### webauthnSingleSig() > `static` **webauthnSingleSig**(`public_key`, `signature`, `authenticator_data`, `client_data_json`): `SignatureProof` Defined in: @nimiq/core/types/wasm/web.d.ts:2149 Creates a Webauthn signature proof for a single-sig signature. #### Parameters ##### public\_key [`PublicKey`](https://nimiq.com/developers/PublicKey) | [`ES256PublicKey`](https://nimiq.com/developers/ES256PublicKey) ##### signature [`ES256Signature`](https://nimiq.com/developers/ES256Signature) | [`Signature`](https://nimiq.com/developers/Signature) ##### authenticator\_data `Uint8Array` ##### client\_data\_json `Uint8Array` #### Returns `SignatureProof` # Class: StakingContract [@nimiq/core](https://nimiq.com/developers/../globals) / StakingContract Defined in: @nimiq/core/types/wasm/web.d.ts:2169 Utility class providing methods to parse Staking Contract transaction data and proofs. ## Methods ### \[dispose]\() > **\[dispose]**(): `void` Defined in: @nimiq/core/types/wasm/web.d.ts:2172 #### Returns `void` --- ### free() > **free**(): `void` Defined in: @nimiq/core/types/wasm/web.d.ts:2171 #### Returns `void` --- ### dataToPlain() > `static` **dataToPlain**(`data`): [`PlainTransactionRecipientData`](https://nimiq.com/developers/../type-aliases/PlainTransactionRecipientData) Defined in: @nimiq/core/types/wasm/web.d.ts:2176 Parses the data of a Staking Contract incoming transaction into a plain object. #### Parameters ##### data `Uint8Array` #### Returns [`PlainTransactionRecipientData`](https://nimiq.com/developers/../type-aliases/PlainTransactionRecipientData) --- ### proofToPlain() > `static` **proofToPlain**(`proof`): [`PlainTransactionProof`](https://nimiq.com/developers/../type-aliases/PlainTransactionProof) Defined in: @nimiq/core/types/wasm/web.d.ts:2180 Parses the proof of a Staking Contract outgoing transaction into a plain object. #### Parameters ##### proof `Uint8Array` #### Returns [`PlainTransactionProof`](https://nimiq.com/developers/../type-aliases/PlainTransactionProof) # Class: StakingDataBuilder [@nimiq/core](https://nimiq.com/developers/../globals) / StakingDataBuilder Defined in: @nimiq/core/types/wasm/web.d.ts:2187 The StakingDataBuilder class provides helper methods to easily create staking transaction data. To decode the data into plain objects, use `StakingContract.dataToPlain()`. ## Methods ### \[dispose]\() > **\[dispose]**(): `void` Defined in: @nimiq/core/types/wasm/web.d.ts:2190 #### Returns `void` --- ### free() > **free**(): `void` Defined in: @nimiq/core/types/wasm/web.d.ts:2189 #### Returns `void` --- ### addStake() > `static` **addStake**(`staker_address`): `Uint8Array` Defined in: @nimiq/core/types/wasm/web.d.ts:2196 Creates staking transaction data for adding stake to a staker. Note: This data does not need to be signed seperately and can be used as-is. #### Parameters ##### staker\_address [`Address`](https://nimiq.com/developers/Address) #### Returns `Uint8Array` --- ### createStaker() > `static` **createStaker**(`delegation`): `Uint8Array` Defined in: @nimiq/core/types/wasm/web.d.ts:2206 Creates staking transaction data for creating a staker. Note: The created data contains an empty signature proof. To add a valid proof: 1. Set the data on the transaction as `tx.data` 2. Create a signature proof over the transaction with the staker's keypair 3. Use `StakingDataBuilder.setProof(tx.data, proof)` to set the created proof on the staking data 4. Set the updated staking data back on the transaction as `tx.data` #### Parameters ##### delegation [`Address`](https://nimiq.com/developers/Address) #### Returns `Uint8Array` --- ### removeStake() > `static` **removeStake**(): `Uint8Array` Defined in: @nimiq/core/types/wasm/web.d.ts:2212 Creates staking transaction data for removing stake from the staking contract. Attention: This is used as `senderData` in a transaction with the staking contract as the sender and the staker as signer. #### Returns `Uint8Array` --- ### retireStake() > `static` **retireStake**(`retire_stake`): `Uint8Array` Defined in: @nimiq/core/types/wasm/web.d.ts:2224 Creates staking transaction data for retiring stake. Note: The created data contains an empty signature proof. To add a valid proof: 1. Set the data on the transaction as `tx.data` 2. Create a signature proof over the transaction with the staker's keypair 3. Use `StakingDataBuilder.setProof(tx.data, proof)` to set the created proof on the staking data 4. Set the updated staking data back on the transaction as `tx.data` Throws when the number given for `retire_stake` does not fit within a Coin value. #### Parameters ##### retire\_stake `bigint` #### Returns `Uint8Array` --- ### setActiveStake() > `static` **setActiveStake**(`new_active_balance`): `Uint8Array` Defined in: @nimiq/core/types/wasm/web.d.ts:2236 Creates staking transaction data for setting the active stake of a staker. Note: The created data contains an empty signature proof. To add a valid proof: 1. Set the data on the transaction as `tx.data` 2. Create a signature proof over the transaction with the staker's keypair 3. Use `StakingDataBuilder.setProof(tx.data, proof)` to set the created proof on the staking data 4. Set the updated staking data back on the transaction as `tx.data` Throws when the number given for `new_active_balance` does not fit within a Coin value. #### Parameters ##### new\_active\_balance `bigint` #### Returns `Uint8Array` --- ### setProof() > `static` **setProof**(`data`, `proof`): `Uint8Array` Defined in: @nimiq/core/types/wasm/web.d.ts:2240 Sets the signature proof on the provided staking transaction data. #### Parameters ##### data `Uint8Array` ##### proof [`SignatureProof`](https://nimiq.com/developers/SignatureProof) #### Returns `Uint8Array` --- ### updateStaker() > `static` **updateStaker**(`new_delegation`, `reactivate_all_stake`): `Uint8Array` Defined in: @nimiq/core/types/wasm/web.d.ts:2250 Creates staking transaction data for updating a staker. Note: The created data contains an empty signature proof. To add a valid proof: 1. Set the data on the transaction as `tx.data` 2. Create a signature proof over the transaction with the staker's keypair 3. Use `StakingDataBuilder.setProof(tx.data, proof)` to set the created proof on the staking data 4. Set the updated staking data back on the transaction as `tx.data` #### Parameters ##### new\_delegation [`Address`](https://nimiq.com/developers/Address) ##### reactivate\_all\_stake `boolean` #### Returns `Uint8Array` # Class: StringUtils [@nimiq/core](https://nimiq.com/developers/../globals) / StringUtils Defined in: @nimiq/core/lib/index.d.ts:327 ## Constructors ### Constructor > **new StringUtils**(): `StringUtils` #### Returns `StringUtils` ## Methods ### isHex() > `static` **isHex**(`str`): `boolean` Defined in: @nimiq/core/lib/index.d.ts:329 #### Parameters ##### str `string` #### Returns `boolean` --- ### isHexBytes() > `static` **isHexBytes**(`str`, `length?`): `boolean` Defined in: @nimiq/core/lib/index.d.ts:330 #### Parameters ##### str `string` ##### length? `number` #### Returns `boolean` --- ### isWellFormed() > `static` **isWellFormed**(`str`): `boolean` Defined in: @nimiq/core/lib/index.d.ts:328 #### Parameters ##### str `string` #### Returns `boolean` # Class: Transaction [@nimiq/core](https://nimiq.com/developers/../globals) / Transaction Defined in: @nimiq/core/types/wasm/web.d.ts:2262 Transactions describe a transfer of value, usually from the sender to the recipient. However, transactions can also have no value, when they are used to *signal* a change in the staking contract. Transactions can be used to create contracts, such as vesting contracts and HTLCs. Transactions require a valid signature proof over their serialized content. Furthermore, transactions are only valid for 2 hours after their validity-start block height. ## Constructors ### Constructor > **new Transaction**(`sender`, `sender_type`, `sender_data`, `recipient`, `recipient_type`, `recipient_data`, `value`, `fee`, `flags`, `validity_start_height`, `network_id`): `Transaction` Defined in: @nimiq/core/types/wasm/web.d.ts:2325 Creates a new unsigned transaction that transfers `value` amount of luna (NIM's smallest unit) from the sender to the recipient, where both sender and recipient can be any account type, and custom extra data can be added to the transaction. ### Basic transactions If both the sender and recipient types are omitted or `0` and both data and flags are empty, a smaller basic transaction is created. ### Extended transactions If no flags are given, but sender type is not basic (`0`) or data is set, an extended transaction is created. ### Contract creation transactions To create a new vesting or HTLC contract, set `flags` to `0b1` and specify the contract type as the `recipient_type`: `1` for vesting, `2` for HTLC. The `data` bytes must have the correct format of contract creation data for the respective contract type. ### Signaling transactions To interact with the staking contract, signaling transaction are often used to not transfer any value, but to simply *signal* a state change instead, such as changing one's delegation from one validator to another. To create such a transaction, set `flags` to `0b10` and populate the `data` bytes accordingly. The returned transaction is not yet signed. You can sign it e.g. with `tx.sign(keyPair)`. Throws when an account type is unknown, the numbers given for value and fee do not fit within a u64 or the networkId is unknown. Also throws when no data or recipient type is given for contract creation transactions, or no data is given for signaling transactions. #### Parameters ##### sender [`Address`](https://nimiq.com/developers/Address) ##### sender\_type `number` ##### sender\_data `Uint8Array`<`ArrayBufferLike`> ##### recipient [`Address`](https://nimiq.com/developers/Address) ##### recipient\_type `number` ##### recipient\_data `Uint8Array`<`ArrayBufferLike`> ##### value `bigint` ##### fee `bigint` ##### flags `number` ##### validity\_start\_height `number` ##### network\_id `number` #### Returns `Transaction` ## Properties ### data > **data**: `Uint8Array` Defined in: @nimiq/core/types/wasm/web.d.ts:2373 The transaction's data as a byte array. --- ### fee > `readonly` **fee**: `bigint` Defined in: @nimiq/core/types/wasm/web.d.ts:2377 The transaction's fee in luna (NIM's smallest unit). --- ### feePerByte > `readonly` **feePerByte**: `number` Defined in: @nimiq/core/types/wasm/web.d.ts:2381 The transaction's fee per byte in luna (NIM's smallest unit). --- ### flags > `readonly` **flags**: [`TransactionFlag`](https://nimiq.com/developers/../enumerations/TransactionFlag) Defined in: @nimiq/core/types/wasm/web.d.ts:2387 The transaction's flags: `0b1` = contract creation, `0b10` = signaling. Bit patterns outside the known variants collapse to `None`. Inspect `toPlain().flags` for the raw value. --- ### format > `readonly` **format**: [`TransactionFormat`](https://nimiq.com/developers/../enumerations/TransactionFormat) Defined in: @nimiq/core/types/wasm/web.d.ts:2391 The transaction's [TransactionFormat](https://nimiq.com/developers/../enumerations/TransactionFormat). --- ### networkId > `readonly` **networkId**: `number` Defined in: @nimiq/core/types/wasm/web.d.ts:2395 The transaction's network ID. --- ### proof > **proof**: `Uint8Array` Defined in: @nimiq/core/types/wasm/web.d.ts:2399 The transaction's signature proof as a byte array. --- ### recipient > `readonly` **recipient**: [`Address`](https://nimiq.com/developers/Address) Defined in: @nimiq/core/types/wasm/web.d.ts:2403 The transaction's recipient address. --- ### recipientType > `readonly` **recipientType**: [`AccountType`](https://nimiq.com/developers/../enumerations/AccountType) Defined in: @nimiq/core/types/wasm/web.d.ts:2407 The transaction's recipient [AccountType](https://nimiq.com/developers/../enumerations/AccountType). --- ### sender > `readonly` **sender**: [`Address`](https://nimiq.com/developers/Address) Defined in: @nimiq/core/types/wasm/web.d.ts:2411 The transaction's sender address. --- ### senderData > `readonly` **senderData**: `Uint8Array` Defined in: @nimiq/core/types/wasm/web.d.ts:2415 The transaction's sender data as a byte array. --- ### senderType > `readonly` **senderType**: [`AccountType`](https://nimiq.com/developers/../enumerations/AccountType) Defined in: @nimiq/core/types/wasm/web.d.ts:2419 The transaction's sender [AccountType](https://nimiq.com/developers/../enumerations/AccountType). --- ### serializedSize > `readonly` **serializedSize**: `number` Defined in: @nimiq/core/types/wasm/web.d.ts:2423 The transaction's byte size. --- ### validityStartHeight > `readonly` **validityStartHeight**: `number` Defined in: @nimiq/core/types/wasm/web.d.ts:2427 The transaction's validity-start height. The transaction is valid for 2 hours after this block height. --- ### value > `readonly` **value**: `bigint` Defined in: @nimiq/core/types/wasm/web.d.ts:2431 The transaction's value in luna (NIM's smallest unit). ## Methods ### \_\_getClassname() > **\_\_getClassname**(): `string` Defined in: @nimiq/core/types/wasm/web.d.ts:2265 #### Returns `string` --- ### \[dispose]\() > **\[dispose]**(): `void` Defined in: @nimiq/core/types/wasm/web.d.ts:2264 #### Returns `void` --- ### free() > **free**(): `void` Defined in: @nimiq/core/types/wasm/web.d.ts:2263 #### Returns `void` --- ### getContractCreationAddress() > **getContractCreationAddress**(): [`Address`](https://nimiq.com/developers/Address) Defined in: @nimiq/core/types/wasm/web.d.ts:2286 Returns the address of the contract that is created with this transaction. #### Returns [`Address`](https://nimiq.com/developers/Address) --- ### hash() > **hash**(): `string` Defined in: @nimiq/core/types/wasm/web.d.ts:2290 Computes the transaction's hash, which is used as its unique identifier on the blockchain. #### Returns `string` --- ### isValidAt() > **isValidAt**(`block_height`): `boolean` Defined in: @nimiq/core/types/wasm/web.d.ts:2294 Tests if the transaction is valid at the specified block height. #### Parameters ##### block\_height `number` #### Returns `boolean` --- ### serialize() > **serialize**(): `Uint8Array` Defined in: @nimiq/core/types/wasm/web.d.ts:2329 Serializes the transaction to a byte array. #### Returns `Uint8Array` --- ### serializeContent() > **serializeContent**(): `Uint8Array` Defined in: @nimiq/core/types/wasm/web.d.ts:2333 Serializes the transaction's content to be used for creating its signature. #### Returns `Uint8Array` --- ### sign() > **sign**(`key_pair`, `inner_key_pair`): `void` Defined in: @nimiq/core/types/wasm/web.d.ts:2350 Signs the transaction with the provided key pair. Automatically determines the format of the signature proof required for the transaction. For transactions to the staking contract (in-staking transactions), you can optionally provide an inner key pair that represents the staker or validator. This way the staker/validator and sender of a transaction can be different key pairs (addresses). If no inner key pair is provided, the outer key pair is used for both signatures. Throws when the transaction's recipient data is not valid data for an incoming staking transaction, or when an incoming staking transaction is not sent from a basic account or a vesting contract. ### Limitations - HTLC redemption is not supported and will throw. #### Parameters ##### key\_pair [`KeyPair`](https://nimiq.com/developers/KeyPair) ##### inner\_key\_pair [`KeyPair`](https://nimiq.com/developers/KeyPair) #### Returns `void` --- ### toHex() > **toHex**(): `string` Defined in: @nimiq/core/types/wasm/web.d.ts:2354 Serializes the transaction into a HEX string. #### Returns `string` --- ### toPlain() > **toPlain**(`genesis_block_number?`, `genesis_timestamp?`): [`PlainTransaction`](https://nimiq.com/developers/../interfaces/PlainTransaction) Defined in: @nimiq/core/types/wasm/web.d.ts:2358 Creates a JSON-compatible plain object representing the transaction. #### Parameters ##### genesis\_block\_number? `number` ##### genesis\_timestamp? `bigint` #### Returns [`PlainTransaction`](https://nimiq.com/developers/../interfaces/PlainTransaction) --- ### verify() > **verify**(`protocol_version`, `network_id?`): `void` Defined in: @nimiq/core/types/wasm/web.d.ts:2369 Verifies that a transaction has valid properties and a valid signature proof for the provided `protocol_version`. Optionally checks if the transaction is valid on the provided network. **Throws with any transaction validity error.** Returns without exception if the transaction is valid. A `protocol_version` of `0` is accepted for backwards-compatible pre-upgrade validation. Throws when the given networkId is unknown. #### Parameters ##### protocol\_version `number` ##### network\_id? `number` #### Returns `void` --- ### deserialize() > `static` **deserialize**(`bytes`): `Transaction` Defined in: @nimiq/core/types/wasm/web.d.ts:2269 Deserializes a transaction from a byte array. #### Parameters ##### bytes `Uint8Array` #### Returns `Transaction` --- ### fromAny() > `static` **fromAny**(`tx`): `Transaction` Defined in: @nimiq/core/types/wasm/web.d.ts:2276 Parses a transaction from a Transaction instance, a plain object, a hex string representation, or a byte array. Throws when a transaction cannot be parsed from the argument. #### Parameters ##### tx `string` | [`PlainTransaction`](https://nimiq.com/developers/../interfaces/PlainTransaction) | `Uint8Array`<`ArrayBufferLike`> | `Transaction` #### Returns `Transaction` --- ### fromPlain() > `static` **fromPlain**(`plain`): `Transaction` Defined in: @nimiq/core/types/wasm/web.d.ts:2282 Parses a transaction from a plain object. Throws when a transaction cannot be parsed from the argument. #### Parameters ##### plain [`PlainTransaction`](https://nimiq.com/developers/../interfaces/PlainTransaction) #### Returns `Transaction` # Class: TransactionBuilder [@nimiq/core](https://nimiq.com/developers/../globals) / TransactionBuilder Defined in: @nimiq/core/types/wasm/web.d.ts:2438 The TransactionBuilder class provides helper methods to easily create standard types of transactions. It can only be instantiated from a Client with `client.transactionBuilder()`. ## Methods ### \[dispose]\() > **\[dispose]**(): `void` Defined in: @nimiq/core/types/wasm/web.d.ts:2441 #### Returns `void` --- ### free() > **free**(): `void` Defined in: @nimiq/core/types/wasm/web.d.ts:2440 #### Returns `void` --- ### newAddStake() > `static` **newAddStake**(`sender`, `staker_address`, `value`, `fee`, `validity_start_height`, `network_id`): [`Transaction`](https://nimiq.com/developers/Transaction) Defined in: @nimiq/core/types/wasm/web.d.ts:2450 Adds stake to a staker in the staking contract and transfers `value` amount of luna (NIM's smallest unit) from the sender account to this staker. The returned transaction is not yet signed. You can sign it e.g. with `tx.sign(keyPair)`. Throws when the numbers given for value and fee do not fit within a u64 or the networkId is unknown. #### Parameters ##### sender [`Address`](https://nimiq.com/developers/Address) ##### staker\_address [`Address`](https://nimiq.com/developers/Address) ##### value `bigint` ##### fee `bigint` ##### validity\_start\_height `number` ##### network\_id `number` #### Returns [`Transaction`](https://nimiq.com/developers/Transaction) --- ### newBasic() > `static` **newBasic**(`sender`, `recipient`, `value`, `fee`, `validity_start_height`, `network_id`): [`Transaction`](https://nimiq.com/developers/Transaction) Defined in: @nimiq/core/types/wasm/web.d.ts:2459 Creates a basic transaction that transfers `value` amount of luna (NIM's smallest unit) from the sender to the recipient. The returned transaction is not yet signed. You can sign it e.g. with `tx.sign(keyPair)`. Throws when the numbers given for value and fee do not fit within a u64 or the networkId is unknown. #### Parameters ##### sender [`Address`](https://nimiq.com/developers/Address) ##### recipient [`Address`](https://nimiq.com/developers/Address) ##### value `bigint` ##### fee `bigint` ##### validity\_start\_height `number` ##### network\_id `number` #### Returns [`Transaction`](https://nimiq.com/developers/Transaction) --- ### newBasicWithData() > `static` **newBasicWithData**(`sender`, `recipient`, `data`, `value`, `fee`, `validity_start_height`, `network_id`): [`Transaction`](https://nimiq.com/developers/Transaction) Defined in: @nimiq/core/types/wasm/web.d.ts:2468 Creates a basic transaction that transfers `value` amount of luna (NIM's smallest unit) from the sender to the recipient. It can include arbitrary `data`, up to 64 bytes. The returned transaction is not yet signed. You can sign it e.g. with `tx.sign(keyPair)`. Throws when the numbers given for value and fee do not fit within a u64 or the networkId is unknown. #### Parameters ##### sender [`Address`](https://nimiq.com/developers/Address) ##### recipient [`Address`](https://nimiq.com/developers/Address) ##### data `Uint8Array` ##### value `bigint` ##### fee `bigint` ##### validity\_start\_height `number` ##### network\_id `number` #### Returns [`Transaction`](https://nimiq.com/developers/Transaction) --- ### newCreateStaker() > `static` **newCreateStaker**(`sender`, `delegation`, `value`, `fee`, `validity_start_height`, `network_id`): [`Transaction`](https://nimiq.com/developers/Transaction) Defined in: @nimiq/core/types/wasm/web.d.ts:2477 Creates a new staker in the staking contract and transfers `value` amount of luna (NIM's smallest unit) from the sender account to this new staker. The returned transaction is not yet signed. You can sign it e.g. with `tx.sign(keyPair)`. Throws when the numbers given for value and fee do not fit within a u64 or the networkId is unknown. #### Parameters ##### sender [`Address`](https://nimiq.com/developers/Address) ##### delegation [`Address`](https://nimiq.com/developers/Address) ##### value `bigint` ##### fee `bigint` ##### validity\_start\_height `number` ##### network\_id `number` #### Returns [`Transaction`](https://nimiq.com/developers/Transaction) --- ### newCreateValidator() > `static` **newCreateValidator**(`sender`, `reward_address`, `signing_key`, `voting_key_pair`, `signal_data`, `fee`, `validity_start_height`, `network_id`): [`Transaction`](https://nimiq.com/developers/Transaction) Defined in: @nimiq/core/types/wasm/web.d.ts:2485 Registers a new validator in the staking contract. The returned transaction is not yet signed. You can sign it e.g. with `tx.sign(keyPair)`. Throws when the fee does not fit within a u64 or the `networkId` is unknown. #### Parameters ##### sender [`Address`](https://nimiq.com/developers/Address) ##### reward\_address [`Address`](https://nimiq.com/developers/Address) ##### signing\_key [`PublicKey`](https://nimiq.com/developers/PublicKey) ##### voting\_key\_pair [`BLSKeyPair`](https://nimiq.com/developers/BLSKeyPair) ##### signal\_data `string` ##### fee `bigint` ##### validity\_start\_height `number` ##### network\_id `number` #### Returns [`Transaction`](https://nimiq.com/developers/Transaction) --- ### newDeactivateValidator() > `static` **newDeactivateValidator**(`sender`, `validator`, `fee`, `validity_start_height`, `network_id`): [`Transaction`](https://nimiq.com/developers/Transaction) Defined in: @nimiq/core/types/wasm/web.d.ts:2493 Deactivates a validator in the staking contract. The returned transaction is not yet signed. You can sign it e.g. with `tx.sign(keyPair)`. Throws when the fee does not fit within a u64 or the `networkId` is unknown. #### Parameters ##### sender [`Address`](https://nimiq.com/developers/Address) ##### validator [`Address`](https://nimiq.com/developers/Address) ##### fee `bigint` ##### validity\_start\_height `number` ##### network\_id `number` #### Returns [`Transaction`](https://nimiq.com/developers/Transaction) --- ### newDeleteValidator() > `static` **newDeleteValidator**(`sender`, `fee`, `validity_start_height`, `network_id`): [`Transaction`](https://nimiq.com/developers/Transaction) Defined in: @nimiq/core/types/wasm/web.d.ts:2501 Deleted a validator the staking contract. The deposit is returned to the Sender The returned transaction is not yet signed. You can sign it e.g. with `tx.sign(keyPair)`. Throws when the fee does not fit within a u64 or the `networkId` is unknown. #### Parameters ##### sender [`Address`](https://nimiq.com/developers/Address) ##### fee `bigint` ##### validity\_start\_height `number` ##### network\_id `number` #### Returns [`Transaction`](https://nimiq.com/developers/Transaction) --- ### newRemoveStake() > `static` **newRemoveStake**(`recipient`, `value`, `fee`, `validity_start_height`, `network_id`): [`Transaction`](https://nimiq.com/developers/Transaction) Defined in: @nimiq/core/types/wasm/web.d.ts:2510 Removes stake from the staking contract and transfers `value` amount of luna (NIM's smallest unit) from the staker to the recipient. The returned transaction is not yet signed. You can sign it e.g. with `tx.sign(keyPair)`. Throws when the numbers given for value and fee do not fit within a u64 or the networkId is unknown. #### Parameters ##### recipient [`Address`](https://nimiq.com/developers/Address) ##### value `bigint` ##### fee `bigint` ##### validity\_start\_height `number` ##### network\_id `number` #### Returns [`Transaction`](https://nimiq.com/developers/Transaction) --- ### newRetireStake() > `static` **newRetireStake**(`sender`, `retire_stake`, `fee`, `validity_start_height`, `network_id`): [`Transaction`](https://nimiq.com/developers/Transaction) Defined in: @nimiq/core/types/wasm/web.d.ts:2519 Retires a portion of the inactive stake balance of the staker. This is a signaling transaction and as such does not transfer any value. The returned transaction is not yet signed. You can sign it e.g. with `tx.sign(keyPair)`. Throws when the numbers given for fee and `retire_stake` do not fit within a u64 or the networkId is unknown. #### Parameters ##### sender [`Address`](https://nimiq.com/developers/Address) ##### retire\_stake `bigint` ##### fee `bigint` ##### validity\_start\_height `number` ##### network\_id `number` #### Returns [`Transaction`](https://nimiq.com/developers/Transaction) --- ### newRetireValidator() > `static` **newRetireValidator**(`sender`, `fee`, `validity_start_height`, `network_id`): [`Transaction`](https://nimiq.com/developers/Transaction) Defined in: @nimiq/core/types/wasm/web.d.ts:2527 Retires a validator in the staking contract. The returned transaction is not yet signed. You can sign it e.g. with `tx.sign(keyPair)`. Throws when the fee does not fit within a u64 or the `networkId` is unknown. #### Parameters ##### sender [`Address`](https://nimiq.com/developers/Address) ##### fee `bigint` ##### validity\_start\_height `number` ##### network\_id `number` #### Returns [`Transaction`](https://nimiq.com/developers/Transaction) --- ### newSetActiveStake() > `static` **newSetActiveStake**(`sender`, `new_active_balance`, `fee`, `validity_start_height`, `network_id`): [`Transaction`](https://nimiq.com/developers/Transaction) Defined in: @nimiq/core/types/wasm/web.d.ts:2536 Sets the active stake balance of the staker. This is a signaling transaction and as such does not transfer any value. The returned transaction is not yet signed. You can sign it e.g. with `tx.sign(keyPair)`. Throws when the numbers given for fee and `new_active_balance` do not fit within a u64 or the networkId is unknown. #### Parameters ##### sender [`Address`](https://nimiq.com/developers/Address) ##### new\_active\_balance `bigint` ##### fee `bigint` ##### validity\_start\_height `number` ##### network\_id `number` #### Returns [`Transaction`](https://nimiq.com/developers/Transaction) --- ### newSetSignalData() > `static` **newSetSignalData**(`sender`, `validator`, `signal_data`, `fee`, `validity_start_height`, `network_id`): [`Transaction`](https://nimiq.com/developers/Transaction) Defined in: @nimiq/core/types/wasm/web.d.ts:2547 Sets the signal data of a validator in the staking contract. In contrast to `newUpdateValidator`, this transaction is signed with the validator's *signing (warm) key*, so the cold key is not required to signal protocol upgrades. Pass `undefined` as `signalData` to clear the signal. The returned transaction is not yet signed. You can sign it e.g. with `tx.sign(keyPair)`. Throws when the fee does not fit within a u64 or the `networkId` is unknown. #### Parameters ##### sender [`Address`](https://nimiq.com/developers/Address) ##### validator [`Address`](https://nimiq.com/developers/Address) ##### signal\_data `string` ##### fee `bigint` ##### validity\_start\_height `number` ##### network\_id `number` #### Returns [`Transaction`](https://nimiq.com/developers/Transaction) --- ### newSignalVersion() > `static` **newSignalVersion**(`sender`, `validator`, `version`, `fee`, `validity_start_height`, `network_id`): [`Transaction`](https://nimiq.com/developers/Transaction) Defined in: @nimiq/core/types/wasm/web.d.ts:2558 Signals support for the given protocol `version` with the validator's *signing (warm) key* by updating the validator's signal data in the staking contract. In contrast to `newSetSignalData`, this only updates the protocol-version bytes of the signal data and preserves the rest. To clear the signal data entirely, use `newSetSignalData` with `null`. The returned transaction is not yet signed. You can sign it e.g. with `tx.sign(keyPair)`. Throws when the fee does not fit within a u64 or the `networkId` is unknown. #### Parameters ##### sender [`Address`](https://nimiq.com/developers/Address) ##### validator [`Address`](https://nimiq.com/developers/Address) ##### version `number` ##### fee `bigint` ##### validity\_start\_height `number` ##### network\_id `number` #### Returns [`Transaction`](https://nimiq.com/developers/Transaction) --- ### newUpdateStaker() > `static` **newUpdateStaker**(`sender`, `new_delegation`, `reactivate_all_stake`, `fee`, `validity_start_height`, `network_id`): [`Transaction`](https://nimiq.com/developers/Transaction) Defined in: @nimiq/core/types/wasm/web.d.ts:2567 Updates a staker in the staking contract to stake for a different validator. This is a signaling transaction and as such does not transfer any value. The returned transaction is not yet signed. You can sign it e.g. with `tx.sign(keyPair)`. Throws when the number given for fee does not fit within a u64 or the networkId is unknown. #### Parameters ##### sender [`Address`](https://nimiq.com/developers/Address) ##### new\_delegation [`Address`](https://nimiq.com/developers/Address) ##### reactivate\_all\_stake `boolean` ##### fee `bigint` ##### validity\_start\_height `number` ##### network\_id `number` #### Returns [`Transaction`](https://nimiq.com/developers/Transaction) --- ### newUpdateValidator() > `static` **newUpdateValidator**(`sender`, `reward_address`, `signing_key`, `voting_key_pair`, `signal_data`, `fee`, `validity_start_height`, `network_id`): [`Transaction`](https://nimiq.com/developers/Transaction) Defined in: @nimiq/core/types/wasm/web.d.ts:2575 Updates parameters of a validator in the staking contract. The returned transaction is not yet signed. You can sign it e.g. with `tx.sign(keyPair)`. Throws when the fee does not fit within a u64 or the `networkId` is unknown. #### Parameters ##### sender [`Address`](https://nimiq.com/developers/Address) ##### reward\_address [`Address`](https://nimiq.com/developers/Address) ##### signing\_key [`PublicKey`](https://nimiq.com/developers/PublicKey) ##### voting\_key\_pair [`BLSKeyPair`](https://nimiq.com/developers/BLSKeyPair) ##### signal\_data `string` ##### fee `bigint` ##### validity\_start\_height `number` ##### network\_id `number` #### Returns [`Transaction`](https://nimiq.com/developers/Transaction) # Class: VestingContract [@nimiq/core](https://nimiq.com/developers/../globals) / VestingContract Defined in: @nimiq/core/types/wasm/web.d.ts:2597 Utility class providing methods to parse Vesting Contract transaction data and proofs. ## Methods ### \[dispose]\() > **\[dispose]**(): `void` Defined in: @nimiq/core/types/wasm/web.d.ts:2600 #### Returns `void` --- ### free() > **free**(): `void` Defined in: @nimiq/core/types/wasm/web.d.ts:2599 #### Returns `void` --- ### dataToPlain() > `static` **dataToPlain**(`data`, `tx_value`): [`PlainTransactionRecipientData`](https://nimiq.com/developers/../type-aliases/PlainTransactionRecipientData) Defined in: @nimiq/core/types/wasm/web.d.ts:2604 Parses the data of a Vesting Contract creation transaction into a plain object. #### Parameters ##### data `Uint8Array` ##### tx\_value `bigint` #### Returns [`PlainTransactionRecipientData`](https://nimiq.com/developers/../type-aliases/PlainTransactionRecipientData) --- ### proofToPlain() > `static` **proofToPlain**(`proof`): [`PlainTransactionProof`](https://nimiq.com/developers/../type-aliases/PlainTransactionProof) Defined in: @nimiq/core/types/wasm/web.d.ts:2608 Parses the proof of a Vesting Contract claiming transaction into a plain object. #### Parameters ##### proof `Uint8Array` #### Returns [`PlainTransactionProof`](https://nimiq.com/developers/../type-aliases/PlainTransactionProof) # Enumeration: AccountType [@nimiq/core](https://nimiq.com/developers/../globals) / AccountType Defined in: @nimiq/core/types/wasm/web.d.ts:656 ## Enumeration Members ### Basic > **Basic**: `0` Defined in: @nimiq/core/types/wasm/web.d.ts:657 --- ### HTLC > **HTLC**: `2` Defined in: @nimiq/core/types/wasm/web.d.ts:659 --- ### Staking > **Staking**: `3` Defined in: @nimiq/core/types/wasm/web.d.ts:660 --- ### Vesting > **Vesting**: `1` Defined in: @nimiq/core/types/wasm/web.d.ts:658 # Enumeration: TransactionFlag [@nimiq/core](https://nimiq.com/developers/../globals) / TransactionFlag Defined in: @nimiq/core/types/wasm/web.d.ts:2583 A transaction flag signals a special purpose of the transaction. `ContractCreation` must be set to create new vesting contracts or HTLCs. `Signaling` must be set to interact with the staking contract for non-value transactions. All other transactions' flag is set to `None`. ## Enumeration Members ### ContractCreation > **ContractCreation**: `1` Defined in: @nimiq/core/types/wasm/web.d.ts:2585 --- ### None > **None**: `0` Defined in: @nimiq/core/types/wasm/web.d.ts:2584 --- ### Signaling > **Signaling**: `2` Defined in: @nimiq/core/types/wasm/web.d.ts:2586 # Enumeration: TransactionFormat [@nimiq/core](https://nimiq.com/developers/../globals) / TransactionFormat Defined in: @nimiq/core/types/wasm/web.d.ts:2589 ## Enumeration Members ### Basic > **Basic**: `0` Defined in: @nimiq/core/types/wasm/web.d.ts:2590 --- ### Extended > **Extended**: `1` Defined in: @nimiq/core/types/wasm/web.d.ts:2591 # Function: default() [@nimiq/core](https://nimiq.com/developers/../globals) / default > **default**(`module_or_path?`): `Promise`<[`InitOutput`](https://nimiq.com/developers/../interfaces/InitOutput)> Defined in: @nimiq/core/types/wasm/web.d.ts:3015 If `module_or_path` is {RequestInfo} or {URL}, makes a request and for everything else, calls `WebAssembly.instantiate` directly. ## Parameters ### module\_or\_path? Passing `InitInput` directly is deprecated. { `module_or_path`: InitInput | Promise\; } | [`InitInput`](https://nimiq.com/developers/../type-aliases/InitInput) | `Promise`<[`InitInput`](https://nimiq.com/developers/../type-aliases/InitInput)> ## Returns `Promise`<[`InitOutput`](https://nimiq.com/developers/../interfaces/InitOutput)> # Function: initSync() [@nimiq/core](https://nimiq.com/developers/../globals) / initSync > **initSync**(`module`): [`InitOutput`](https://nimiq.com/developers/../interfaces/InitOutput) Defined in: @nimiq/core/types/wasm/web.d.ts:3005 Instantiates the given `module`, which can either be bytes or a precompiled `WebAssembly.Module`. ## Parameters ### module Passing `SyncInitInput` directly is deprecated. { `module`: [`SyncInitInput`](https://nimiq.com/developers/../type-aliases/SyncInitInput); } | [`SyncInitInput`](https://nimiq.com/developers/../type-aliases/SyncInitInput) ## Returns [`InitOutput`](https://nimiq.com/developers/../interfaces/InitOutput) # @nimiq/core ## Namespaces - [MnemonicUtils](https://nimiq.com/developers/@nimiq/namespaces/MnemonicUtils/) - [Secret](https://nimiq.com/developers/@nimiq/namespaces/Secret/) ## Enumerations - [AccountType](https://nimiq.com/developers/enumerations/AccountType) - [TransactionFlag](https://nimiq.com/developers/enumerations/TransactionFlag) - [TransactionFormat](https://nimiq.com/developers/enumerations/TransactionFormat) ## Classes - [Address](https://nimiq.com/developers/classes/Address) - [ArrayUtils](https://nimiq.com/developers/classes/ArrayUtils) - [BLSKeyPair](https://nimiq.com/developers/classes/BLSKeyPair) - [BLSPublicKey](https://nimiq.com/developers/classes/BLSPublicKey) - [BLSSecretKey](https://nimiq.com/developers/classes/BLSSecretKey) - [BufferUtils](https://nimiq.com/developers/classes/BufferUtils) - [Client](https://nimiq.com/developers/classes/Client) - [ClientConfiguration](https://nimiq.com/developers/classes/ClientConfiguration) - [Commitment](https://nimiq.com/developers/classes/Commitment) - [CommitmentPair](https://nimiq.com/developers/classes/CommitmentPair) - [CryptoUtils](https://nimiq.com/developers/classes/CryptoUtils) - [Entropy](https://nimiq.com/developers/classes/Entropy) - [ES256PublicKey](https://nimiq.com/developers/classes/ES256PublicKey) - [ES256Signature](https://nimiq.com/developers/classes/ES256Signature) - [ExtendedPrivateKey](https://nimiq.com/developers/classes/ExtendedPrivateKey) - [Hash](https://nimiq.com/developers/classes/Hash) - [HashedTimeLockedContract](https://nimiq.com/developers/classes/HashedTimeLockedContract) - [KeyPair](https://nimiq.com/developers/classes/KeyPair) - [MerklePath](https://nimiq.com/developers/classes/MerklePath) - [MerkleTree](https://nimiq.com/developers/classes/MerkleTree) - [MnemonicUtils](https://nimiq.com/developers/classes/MnemonicUtils) - [NumberUtils](https://nimiq.com/developers/classes/NumberUtils) - [PartialSignature](https://nimiq.com/developers/classes/PartialSignature) - [Policy](https://nimiq.com/developers/classes/Policy) - [PrivateKey](https://nimiq.com/developers/classes/PrivateKey) - [PublicKey](https://nimiq.com/developers/classes/PublicKey) - [RandomSecret](https://nimiq.com/developers/classes/RandomSecret) - [Secret](https://nimiq.com/developers/classes/Secret) - [SerialBuffer](https://nimiq.com/developers/classes/SerialBuffer) - [Signature](https://nimiq.com/developers/classes/Signature) - [SignatureProof](https://nimiq.com/developers/classes/SignatureProof) - [StakingContract](https://nimiq.com/developers/classes/StakingContract) - [StakingDataBuilder](https://nimiq.com/developers/classes/StakingDataBuilder) - [StringUtils](https://nimiq.com/developers/classes/StringUtils) - [Transaction](https://nimiq.com/developers/classes/Transaction) - [TransactionBuilder](https://nimiq.com/developers/classes/TransactionBuilder) - [VestingContract](https://nimiq.com/developers/classes/VestingContract) ## Interfaces - [InitOutput](https://nimiq.com/developers/interfaces/InitOutput) - [PlainAddStakeData](https://nimiq.com/developers/interfaces/PlainAddStakeData) - [PlainBasicAccount](https://nimiq.com/developers/interfaces/PlainBasicAccount) - [PlainBlockCommonFields](https://nimiq.com/developers/interfaces/PlainBlockCommonFields) - [PlainClientConfiguration](https://nimiq.com/developers/interfaces/PlainClientConfiguration) - [PlainCreateStakerData](https://nimiq.com/developers/interfaces/PlainCreateStakerData) - [PlainCreateValidatorData](https://nimiq.com/developers/interfaces/PlainCreateValidatorData) - [PlainElectedValidator](https://nimiq.com/developers/interfaces/PlainElectedValidator) - [PlainHtlcContract](https://nimiq.com/developers/interfaces/PlainHtlcContract) - [PlainHtlcData](https://nimiq.com/developers/interfaces/PlainHtlcData) - [PlainHtlcEarlyResolveProof](https://nimiq.com/developers/interfaces/PlainHtlcEarlyResolveProof) - [PlainHtlcRegularTransferProof](https://nimiq.com/developers/interfaces/PlainHtlcRegularTransferProof) - [PlainHtlcTimeoutResolveProof](https://nimiq.com/developers/interfaces/PlainHtlcTimeoutResolveProof) - [PlainMacroBlock](https://nimiq.com/developers/interfaces/PlainMacroBlock) - [PlainMicroBlock](https://nimiq.com/developers/interfaces/PlainMicroBlock) - [PlainPeerInfo](https://nimiq.com/developers/interfaces/PlainPeerInfo) - [PlainRawData](https://nimiq.com/developers/interfaces/PlainRawData) - [PlainRawProof](https://nimiq.com/developers/interfaces/PlainRawProof) - [PlainRetireStakeData](https://nimiq.com/developers/interfaces/PlainRetireStakeData) - [PlainSetActiveStakeData](https://nimiq.com/developers/interfaces/PlainSetActiveStakeData) - [PlainSetSignalDataData](https://nimiq.com/developers/interfaces/PlainSetSignalDataData) - [PlainSlot](https://nimiq.com/developers/interfaces/PlainSlot) - [PlainStaker](https://nimiq.com/developers/interfaces/PlainStaker) - [PlainStakingContract](https://nimiq.com/developers/interfaces/PlainStakingContract) - [PlainStandardProof](https://nimiq.com/developers/interfaces/PlainStandardProof) - [PlainTransaction](https://nimiq.com/developers/interfaces/PlainTransaction) - [PlainTransactionDetails](https://nimiq.com/developers/interfaces/PlainTransactionDetails) - [PlainTransactionReceipt](https://nimiq.com/developers/interfaces/PlainTransactionReceipt) - [PlainUpdateStakerData](https://nimiq.com/developers/interfaces/PlainUpdateStakerData) - [PlainUpdateValidatorData](https://nimiq.com/developers/interfaces/PlainUpdateValidatorData) - [PlainValidator](https://nimiq.com/developers/interfaces/PlainValidator) - [PlainValidatorData](https://nimiq.com/developers/interfaces/PlainValidatorData) - [PlainVestingContract](https://nimiq.com/developers/interfaces/PlainVestingContract) - [PlainVestingData](https://nimiq.com/developers/interfaces/PlainVestingData) ## Type Aliases - [ConsensusState](https://nimiq.com/developers/type-aliases/ConsensusState) - [InitInput](https://nimiq.com/developers/type-aliases/InitInput) - [PlainAccount](https://nimiq.com/developers/type-aliases/PlainAccount) - [PlainBlock](https://nimiq.com/developers/type-aliases/PlainBlock) - [PlainService](https://nimiq.com/developers/type-aliases/PlainService) - [PlainSignalDataUpdateMode](https://nimiq.com/developers/type-aliases/PlainSignalDataUpdateMode) - [PlainTransactionProof](https://nimiq.com/developers/type-aliases/PlainTransactionProof) - [PlainTransactionRecipientData](https://nimiq.com/developers/type-aliases/PlainTransactionRecipientData) - [PlainTransactionSenderData](https://nimiq.com/developers/type-aliases/PlainTransactionSenderData) - [SyncInitInput](https://nimiq.com/developers/type-aliases/SyncInitInput) - [TransactionState](https://nimiq.com/developers/type-aliases/TransactionState) ## Functions - [default](https://nimiq.com/developers/functions/default) - [initSync](https://nimiq.com/developers/functions/initSync) # API Reference Full reference for the `@nimiq/core` package. The entries below are auto-generated from the TypeScript definitions. ## Client and Configuration The main entry points for connecting to the network and configuring the client. | Class | Description | | :------------------------------------------------------------------------------ | :---------------------------------------------------------------------------------------- | | [Client](https://nimiq.com/developers/classes/Client) | Core class — connect to the network, query state, send transactions, subscribe to events. | | [ClientConfiguration](https://nimiq.com/developers/classes/ClientConfiguration) | Builder for configuring network, sync mode, peers, and logging before creating a client. | | [Policy](https://nimiq.com/developers/classes/Policy) | Protocol constants — epoch length, batch size, staking parameters, supply calculations. | ## Accounts and Addresses Working with on-chain accounts and Nimiq addresses. | Class / Type | Description | | :----------------------------------------------------------------------------------- | :------------------------------------------------------ | | [Address](https://nimiq.com/developers/classes/Address) | Create, parse, format, and compare Nimiq addresses. | | [PlainBasicAccount](https://nimiq.com/developers/interfaces/PlainBasicAccount) | Shape of a basic account returned by `getAccount()`. | | [PlainStakingContract](https://nimiq.com/developers/interfaces/PlainStakingContract) | Shape of the staking contract account. | | [PlainVestingContract](https://nimiq.com/developers/interfaces/PlainVestingContract) | Shape of a vesting contract account. | | [PlainHtlcContract](https://nimiq.com/developers/interfaces/PlainHtlcContract) | Shape of an HTLC (hashed time-locked contract) account. | | [AccountType](https://nimiq.com/developers/type-aliases/AccountType) | Enum of account types: basic, vesting, HTLC, staking. | | [PlainAccount](https://nimiq.com/developers/type-aliases/PlainAccount) | Union type of all plain account shapes. | ## Transactions Building, signing, and inspecting transactions. | Class / Type | Description | | :----------------------------------------------------------------------------------------- | :-------------------------------------------------------------------------------------------- | | [TransactionBuilder](https://nimiq.com/developers/classes/TransactionBuilder) | Static methods for creating all transaction types — basic transfers, staking, vesting, HTLCs. | | [Transaction](https://nimiq.com/developers/classes/Transaction) | Transaction object — sign, serialize, verify, and inspect. | | [PlainTransaction](https://nimiq.com/developers/interfaces/PlainTransaction) | Shape of a serialized transaction. | | [PlainTransactionDetails](https://nimiq.com/developers/interfaces/PlainTransactionDetails) | Transaction with inclusion state, block hash, and confirmations. | | [PlainTransactionReceipt](https://nimiq.com/developers/interfaces/PlainTransactionReceipt) | Lightweight receipt (transaction hash + block height). | | [TransactionFlag](https://nimiq.com/developers/type-aliases/TransactionFlag) | Transaction flags (contract creation, signaling). | | [TransactionFormat](https://nimiq.com/developers/type-aliases/TransactionFormat) | Transaction format (basic, extended). | | [TransactionState](https://nimiq.com/developers/type-aliases/TransactionState) | Transaction lifecycle states (pending, included, etc.). | ## Transaction Data and Proofs Typed data and proof structures attached to transactions. | Type | Description | | :------------------------------------------------------------------------------------------------------- | :-------------------------------------------- | | [PlainRawData](https://nimiq.com/developers/interfaces/PlainRawData) | Raw transaction data payload. | | [PlainAddStakeData](https://nimiq.com/developers/interfaces/PlainAddStakeData) | Data for add-stake transactions. | | [PlainCreateStakerData](https://nimiq.com/developers/interfaces/PlainCreateStakerData) | Data for create-staker transactions. | | [PlainCreateValidatorData](https://nimiq.com/developers/interfaces/PlainCreateValidatorData) | Data for create-validator transactions. | | [PlainUpdateStakerData](https://nimiq.com/developers/interfaces/PlainUpdateStakerData) | Data for update-staker transactions. | | [PlainUpdateValidatorData](https://nimiq.com/developers/interfaces/PlainUpdateValidatorData) | Data for update-validator transactions. | | [PlainRetireStakeData](https://nimiq.com/developers/interfaces/PlainRetireStakeData) | Data for retire-stake transactions. | | [PlainSetActiveStakeData](https://nimiq.com/developers/interfaces/PlainSetActiveStakeData) | Data for set-active-stake transactions. | | [PlainVestingData](https://nimiq.com/developers/interfaces/PlainVestingData) | Data for vesting contract creation. | | [PlainHtlcData](https://nimiq.com/developers/interfaces/PlainHtlcData) | Data for HTLC creation. | | [PlainRawProof](https://nimiq.com/developers/interfaces/PlainRawProof) | Raw transaction proof. | | [PlainStandardProof](https://nimiq.com/developers/interfaces/PlainStandardProof) | Standard signature proof. | | [PlainHtlcRegularTransferProof](https://nimiq.com/developers/interfaces/PlainHtlcRegularTransferProof) | HTLC regular transfer proof (with pre-image). | | [PlainHtlcEarlyResolveProof](https://nimiq.com/developers/interfaces/PlainHtlcEarlyResolveProof) | HTLC early resolve proof. | | [PlainHtlcTimeoutResolveProof](https://nimiq.com/developers/interfaces/PlainHtlcTimeoutResolveProof) | HTLC timeout resolve proof. | | [PlainTransactionProof](https://nimiq.com/developers/type-aliases/PlainTransactionProof) | Union type of all proof shapes. | | [PlainTransactionRecipientData](https://nimiq.com/developers/type-aliases/PlainTransactionRecipientData) | Union type of all recipient data shapes. | | [PlainTransactionSenderData](https://nimiq.com/developers/type-aliases/PlainTransactionSenderData) | Union type of all sender data shapes. | ## Blocks Block structures returned by the client. | Type | Description | | :--------------------------------------------------------------------------------------- | :--------------------------------------------------------- | | [PlainMicroBlock](https://nimiq.com/developers/interfaces/PlainMicroBlock) | Shape of a micro block (produced by validators each slot). | | [PlainMacroBlock](https://nimiq.com/developers/interfaces/PlainMacroBlock) | Shape of a macro block (election and checkpoint blocks). | | [PlainBlockCommonFields](https://nimiq.com/developers/interfaces/PlainBlockCommonFields) | Fields shared by both block types. | | [PlainBlock](https://nimiq.com/developers/type-aliases/PlainBlock) | Union type of micro and macro blocks. | ## Keys and Cryptography Key generation, signing, and cryptographic primitives. | Class | Description | | :------------------------------------------------------------------------ | :-------------------------------------------------------- | | [KeyPair](https://nimiq.com/developers/classes/KeyPair) | Generate, derive, sign, and serialize Ed25519 keypairs. | | [PrivateKey](https://nimiq.com/developers/classes/PrivateKey) | Private key generation and serialization. | | [PublicKey](https://nimiq.com/developers/classes/PublicKey) | Public key derivation, verification, and serialization. | | [Signature](https://nimiq.com/developers/classes/Signature) | Ed25519 signature. | | [SignatureProof](https://nimiq.com/developers/classes/SignatureProof) | Signature proof construction for transactions. | | [ES256PublicKey](https://nimiq.com/developers/classes/ES256PublicKey) | ES256 (P-256) public key — used for WebAuthn integration. | | [ES256Signature](https://nimiq.com/developers/classes/ES256Signature) | ES256 (P-256) signature. | | [BLSKeyPair](https://nimiq.com/developers/classes/BLSKeyPair) | BLS keypair — used for validator voting keys. | | [BLSPublicKey](https://nimiq.com/developers/classes/BLSPublicKey) | BLS public key. | | [BLSSecretKey](https://nimiq.com/developers/classes/BLSSecretKey) | BLS secret key. | | [Hash](https://nimiq.com/developers/classes/Hash) | Hashing utilities (Blake2b, SHA-256). | | [CryptoUtils](https://nimiq.com/developers/classes/CryptoUtils) | Shared cryptographic helpers. | | [MerkleTree](https://nimiq.com/developers/classes/MerkleTree) | Merkle tree construction and proof verification. | | [Commitment](https://nimiq.com/developers/classes/Commitment) | Schnorr commitment for multi-signature schemes. | | [CommitmentPair](https://nimiq.com/developers/classes/CommitmentPair) | Commitment pair (secret + commitment). | | [PartialSignature](https://nimiq.com/developers/classes/PartialSignature) | Partial signature for multi-signature aggregation. | | [RandomSecret](https://nimiq.com/developers/classes/RandomSecret) | Random secret for commitment schemes. | | [Secret](https://nimiq.com/developers/classes/Secret) | Base class for cryptographic secrets. | ## Wallets and HD Derivation Mnemonic phrases, entropy, and hierarchical deterministic key derivation. | Class | Description | | :---------------------------------------------------------------------------- | :---------------------------------------------------------------------------------- | | [MnemonicUtils](https://nimiq.com/developers/classes/MnemonicUtils) | Generate mnemonics, convert to keys/seeds, detect mnemonic type (BIP39 vs legacy). | | [ExtendedPrivateKey](https://nimiq.com/developers/classes/ExtendedPrivateKey) | HD key derivation — master key generation, child derivation, path-based derivation. | | [Entropy](https://nimiq.com/developers/classes/Entropy) | Entropy generation and conversion for mnemonic phrases. | ## Staking Validator and staker data structures. | Type | Description | | :------------------------------------------------------------------------------- | :------------------------------------------------- | | [PlainValidator](https://nimiq.com/developers/interfaces/PlainValidator) | Shape of a validator returned by `getValidator()`. | | [PlainValidatorData](https://nimiq.com/developers/interfaces/PlainValidatorData) | Validator configuration fields. | | [PlainStaker](https://nimiq.com/developers/interfaces/PlainStaker) | Shape of a staker returned by `getStaker()`. | | [StakingContract](https://nimiq.com/developers/classes/StakingContract) | Staking contract parsing utilities. | ## Contracts Vesting and HTLC contract helpers. | Class | Description | | :---------------------------------------------------------------------------------------- | :--------------------------------------------- | | [VestingContract](https://nimiq.com/developers/classes/VestingContract) | Parse vesting contract data from transactions. | | [HashedTimeLockedContract](https://nimiq.com/developers/classes/HashedTimeLockedContract) | Parse HTLC data and proofs from transactions. | ## Utilities Serialization, formatting, and buffer helpers. | Class | Description | | :---------------------------------------------------------------- | :-------------------------------------------------------------- | | [SerialBuffer](https://nimiq.com/developers/classes/SerialBuffer) | Binary serialization buffer for reading and writing typed data. | | [BufferUtils](https://nimiq.com/developers/classes/BufferUtils) | Convert between hex, base64, and byte arrays. | | [NumberUtils](https://nimiq.com/developers/classes/NumberUtils) | Number formatting and parsing. | | [StringUtils](https://nimiq.com/developers/classes/StringUtils) | String utilities. | | [ArrayUtils](https://nimiq.com/developers/classes/ArrayUtils) | Array comparison and manipulation. | ## Network and Peers | Type | Description | | :------------------------------------------------------------------------- | :--------------------------------------------------------- | | [PlainPeerInfo](https://nimiq.com/developers/interfaces/PlainPeerInfo) | Shape of peer information from peer-change events. | | [ConsensusState](https://nimiq.com/developers/type-aliases/ConsensusState) | Consensus state values (connecting, syncing, established). | | [PlainService](https://nimiq.com/developers/type-aliases/PlainService) | Network service flags. | ## Initialization | Type | Description | | :------------------------------------------------------------------------------------------- | :------------------------------------------------------------- | | [default](https://nimiq.com/developers/functions/default) | The `init()` function for web target — loads the WASM module. | | [initSync](https://nimiq.com/developers/functions/initSync) | Synchronous WASM initialization (when async is not available). | | [InitInput](https://nimiq.com/developers/type-aliases/InitInput) | Accepted input types for async `init()`. | | [SyncInitInput](https://nimiq.com/developers/type-aliases/SyncInitInput) | Accepted input types for `initSync()`. | | [InitOutput](https://nimiq.com/developers/interfaces/InitOutput) | Output of WASM initialization. | | [PlainClientConfiguration](https://nimiq.com/developers/interfaces/PlainClientConfiguration) | Shape of the built client configuration object. | # Interface: InitOutput [@nimiq/core](https://nimiq.com/developers/../globals) / InitOutput Defined in: @nimiq/core/types/wasm/web.d.ts:2613 ## Properties ### \_\_externref\_drop\_slice() > `readonly` **\_\_externref\_drop\_slice**: (`a`, `b`) => `void` Defined in: @nimiq/core/types/wasm/web.d.ts:2991 #### Parameters ##### a `number` ##### b `number` #### Returns `void` --- ### \_\_externref\_table\_alloc() > `readonly` **\_\_externref\_table\_alloc**: () => `number` Defined in: @nimiq/core/types/wasm/web.d.ts:2986 #### Returns `number` --- ### \_\_externref\_table\_dealloc() > `readonly` **\_\_externref\_table\_dealloc**: (`a`) => `void` Defined in: @nimiq/core/types/wasm/web.d.ts:2990 #### Parameters ##### a `number` #### Returns `void` --- ### \_\_wbg\_address\_free() > `readonly` **\_\_wbg\_address\_free**: (`a`, `b`) => `void` Defined in: @nimiq/core/types/wasm/web.d.ts:2819 #### Parameters ##### a `number` ##### b `number` #### Returns `void` --- ### \_\_wbg\_blskeypair\_free() > `readonly` **\_\_wbg\_blskeypair\_free**: (`a`, `b`) => `void` Defined in: @nimiq/core/types/wasm/web.d.ts:2820 #### Parameters ##### a `number` ##### b `number` #### Returns `void` --- ### \_\_wbg\_blspublickey\_free() > `readonly` **\_\_wbg\_blspublickey\_free**: (`a`, `b`) => `void` Defined in: @nimiq/core/types/wasm/web.d.ts:2821 #### Parameters ##### a `number` ##### b `number` #### Returns `void` --- ### \_\_wbg\_blssecretkey\_free() > `readonly` **\_\_wbg\_blssecretkey\_free**: (`a`, `b`) => `void` Defined in: @nimiq/core/types/wasm/web.d.ts:2822 #### Parameters ##### a `number` ##### b `number` #### Returns `void` --- ### \_\_wbg\_client\_free() > `readonly` **\_\_wbg\_client\_free**: (`a`, `b`) => `void` Defined in: @nimiq/core/types/wasm/web.d.ts:2788 #### Parameters ##### a `number` ##### b `number` #### Returns `void` --- ### \_\_wbg\_clientconfiguration\_free() > `readonly` **\_\_wbg\_clientconfiguration\_free**: (`a`, `b`) => `void` Defined in: @nimiq/core/types/wasm/web.d.ts:2615 #### Parameters ##### a `number` ##### b `number` #### Returns `void` --- ### \_\_wbg\_commitment\_free() > `readonly` **\_\_wbg\_commitment\_free**: (`a`, `b`) => `void` Defined in: @nimiq/core/types/wasm/web.d.ts:2823 #### Parameters ##### a `number` ##### b `number` #### Returns `void` --- ### \_\_wbg\_commitmentpair\_free() > `readonly` **\_\_wbg\_commitmentpair\_free**: (`a`, `b`) => `void` Defined in: @nimiq/core/types/wasm/web.d.ts:2616 #### Parameters ##### a `number` ##### b `number` #### Returns `void` --- ### \_\_wbg\_cryptoutils\_free() > `readonly` **\_\_wbg\_cryptoutils\_free**: (`a`, `b`) => `void` Defined in: @nimiq/core/types/wasm/web.d.ts:2721 #### Parameters ##### a `number` ##### b `number` #### Returns `void` --- ### \_\_wbg\_es256publickey\_free() > `readonly` **\_\_wbg\_es256publickey\_free**: (`a`, `b`) => `void` Defined in: @nimiq/core/types/wasm/web.d.ts:2824 #### Parameters ##### a `number` ##### b `number` #### Returns `void` --- ### \_\_wbg\_es256signature\_free() > `readonly` **\_\_wbg\_es256signature\_free**: (`a`, `b`) => `void` Defined in: @nimiq/core/types/wasm/web.d.ts:2617 #### Parameters ##### a `number` ##### b `number` #### Returns `void` --- ### \_\_wbg\_hash\_free() > `readonly` **\_\_wbg\_hash\_free**: (`a`, `b`) => `void` Defined in: @nimiq/core/types/wasm/web.d.ts:2722 #### Parameters ##### a `number` ##### b `number` #### Returns `void` --- ### \_\_wbg\_hashedtimelockedcontract\_free() > `readonly` **\_\_wbg\_hashedtimelockedcontract\_free**: (`a`, `b`) => `void` Defined in: @nimiq/core/types/wasm/web.d.ts:2723 #### Parameters ##### a `number` ##### b `number` #### Returns `void` --- ### \_\_wbg\_keypair\_free() > `readonly` **\_\_wbg\_keypair\_free**: (`a`, `b`) => `void` Defined in: @nimiq/core/types/wasm/web.d.ts:2618 #### Parameters ##### a `number` ##### b `number` #### Returns `void` --- ### \_\_wbg\_merklepath\_free() > `readonly` **\_\_wbg\_merklepath\_free**: (`a`, `b`) => `void` Defined in: @nimiq/core/types/wasm/web.d.ts:2724 #### Parameters ##### a `number` ##### b `number` #### Returns `void` --- ### \_\_wbg\_merkletree\_free() > `readonly` **\_\_wbg\_merkletree\_free**: (`a`, `b`) => `void` Defined in: @nimiq/core/types/wasm/web.d.ts:2725 #### Parameters ##### a `number` ##### b `number` #### Returns `void` --- ### \_\_wbg\_partialsignature\_free() > `readonly` **\_\_wbg\_partialsignature\_free**: (`a`, `b`) => `void` Defined in: @nimiq/core/types/wasm/web.d.ts:2619 #### Parameters ##### a `number` ##### b `number` #### Returns `void` --- ### \_\_wbg\_policy\_free() > `readonly` **\_\_wbg\_policy\_free**: (`a`, `b`) => `void` Defined in: @nimiq/core/types/wasm/web.d.ts:2922 #### Parameters ##### a `number` ##### b `number` #### Returns `void` --- ### \_\_wbg\_privatekey\_free() > `readonly` **\_\_wbg\_privatekey\_free**: (`a`, `b`) => `void` Defined in: @nimiq/core/types/wasm/web.d.ts:2825 #### Parameters ##### a `number` ##### b `number` #### Returns `void` --- ### \_\_wbg\_publickey\_free() > `readonly` **\_\_wbg\_publickey\_free**: (`a`, `b`) => `void` Defined in: @nimiq/core/types/wasm/web.d.ts:2826 #### Parameters ##### a `number` ##### b `number` #### Returns `void` --- ### \_\_wbg\_randomsecret\_free() > `readonly` **\_\_wbg\_randomsecret\_free**: (`a`, `b`) => `void` Defined in: @nimiq/core/types/wasm/web.d.ts:2620 #### Parameters ##### a `number` ##### b `number` #### Returns `void` --- ### \_\_wbg\_signature\_free() > `readonly` **\_\_wbg\_signature\_free**: (`a`, `b`) => `void` Defined in: @nimiq/core/types/wasm/web.d.ts:2827 #### Parameters ##### a `number` ##### b `number` #### Returns `void` --- ### \_\_wbg\_signatureproof\_free() > `readonly` **\_\_wbg\_signatureproof\_free**: (`a`, `b`) => `void` Defined in: @nimiq/core/types/wasm/web.d.ts:2726 #### Parameters ##### a `number` ##### b `number` #### Returns `void` --- ### \_\_wbg\_stakingcontract\_free() > `readonly` **\_\_wbg\_stakingcontract\_free**: (`a`, `b`) => `void` Defined in: @nimiq/core/types/wasm/web.d.ts:2727 #### Parameters ##### a `number` ##### b `number` #### Returns `void` --- ### \_\_wbg\_stakingdatabuilder\_free() > `readonly` **\_\_wbg\_stakingdatabuilder\_free**: (`a`, `b`) => `void` Defined in: @nimiq/core/types/wasm/web.d.ts:2764 #### Parameters ##### a `number` ##### b `number` #### Returns `void` --- ### \_\_wbg\_transaction\_free() > `readonly` **\_\_wbg\_transaction\_free**: (`a`, `b`) => `void` Defined in: @nimiq/core/types/wasm/web.d.ts:2621 #### Parameters ##### a `number` ##### b `number` #### Returns `void` --- ### \_\_wbg\_transactionbuilder\_free() > `readonly` **\_\_wbg\_transactionbuilder\_free**: (`a`, `b`) => `void` Defined in: @nimiq/core/types/wasm/web.d.ts:2765 #### Parameters ##### a `number` ##### b `number` #### Returns `void` --- ### \_\_wbg\_vestingcontract\_free() > `readonly` **\_\_wbg\_vestingcontract\_free**: (`a`, `b`) => `void` Defined in: @nimiq/core/types/wasm/web.d.ts:2728 #### Parameters ##### a `number` ##### b `number` #### Returns `void` --- ### \_\_wbindgen\_destroy\_closure() > `readonly` **\_\_wbindgen\_destroy\_closure**: (`a`, `b`) => `void` Defined in: @nimiq/core/types/wasm/web.d.ts:2988 #### Parameters ##### a `number` ##### b `number` #### Returns `void` --- ### \_\_wbindgen\_exn\_store() > `readonly` **\_\_wbindgen\_exn\_store**: (`a`) => `void` Defined in: @nimiq/core/types/wasm/web.d.ts:2985 #### Parameters ##### a `number` #### Returns `void` --- ### \_\_wbindgen\_externrefs > `readonly` **\_\_wbindgen\_externrefs**: `Table` Defined in: @nimiq/core/types/wasm/web.d.ts:2987 --- ### \_\_wbindgen\_free() > `readonly` **\_\_wbindgen\_free**: (`a`, `b`, `c`) => `void` Defined in: @nimiq/core/types/wasm/web.d.ts:2989 #### Parameters ##### a `number` ##### b `number` ##### c `number` #### Returns `void` --- ### \_\_wbindgen\_malloc() > `readonly` **\_\_wbindgen\_malloc**: (`a`, `b`) => `number` Defined in: @nimiq/core/types/wasm/web.d.ts:2983 #### Parameters ##### a `number` ##### b `number` #### Returns `number` --- ### \_\_wbindgen\_realloc() > `readonly` **\_\_wbindgen\_realloc**: (`a`, `b`, `c`, `d`) => `number` Defined in: @nimiq/core/types/wasm/web.d.ts:2984 #### Parameters ##### a `number` ##### b `number` ##### c `number` ##### d `number` #### Returns `number` --- ### \_\_wbindgen\_start() > `readonly` **\_\_wbindgen\_start**: () => `void` Defined in: @nimiq/core/types/wasm/web.d.ts:2992 #### Returns `void` --- ### address\_\_\_getClassname() > `readonly` **address\_\_\_getClassname**: (`a`) => \[`number`, `number`] Defined in: @nimiq/core/types/wasm/web.d.ts:2828 #### Parameters ##### a `number` #### Returns \[`number`, `number`] --- ### address\_compare() > `readonly` **address\_compare**: (`a`, `b`) => `number` Defined in: @nimiq/core/types/wasm/web.d.ts:2829 #### Parameters ##### a `number` ##### b `number` #### Returns `number` --- ### address\_deserialize() > `readonly` **address\_deserialize**: (`a`, `b`) => \[`number`, `number`, `number`] Defined in: @nimiq/core/types/wasm/web.d.ts:2830 #### Parameters ##### a `number` ##### b `number` #### Returns \[`number`, `number`, `number`] --- ### address\_equals() > `readonly` **address\_equals**: (`a`, `b`) => `number` Defined in: @nimiq/core/types/wasm/web.d.ts:2831 #### Parameters ##### a `number` ##### b `number` #### Returns `number` --- ### address\_fromAny() > `readonly` **address\_fromAny**: (`a`) => \[`number`, `number`, `number`] Defined in: @nimiq/core/types/wasm/web.d.ts:2832 #### Parameters ##### a `any` #### Returns \[`number`, `number`, `number`] --- ### address\_fromPublicKeys() > `readonly` **address\_fromPublicKeys**: (`a`, `b`) => \[`number`, `number`, `number`] Defined in: @nimiq/core/types/wasm/web.d.ts:2833 #### Parameters ##### a `any` ##### b `number` #### Returns \[`number`, `number`, `number`] --- ### address\_fromString() > `readonly` **address\_fromString**: (`a`, `b`) => \[`number`, `number`, `number`] Defined in: @nimiq/core/types/wasm/web.d.ts:2834 #### Parameters ##### a `number` ##### b `number` #### Returns \[`number`, `number`, `number`] --- ### address\_fromUserFriendlyAddress() > `readonly` **address\_fromUserFriendlyAddress**: (`a`, `b`) => \[`number`, `number`, `number`] Defined in: @nimiq/core/types/wasm/web.d.ts:2835 #### Parameters ##### a `number` ##### b `number` #### Returns \[`number`, `number`, `number`] --- ### address\_new() > `readonly` **address\_new**: (`a`, `b`) => \[`number`, `number`, `number`] Defined in: @nimiq/core/types/wasm/web.d.ts:2836 #### Parameters ##### a `number` ##### b `number` #### Returns \[`number`, `number`, `number`] --- ### address\_null() > `readonly` **address\_null**: () => `number` Defined in: @nimiq/core/types/wasm/web.d.ts:2837 #### Returns `number` --- ### address\_serialize() > `readonly` **address\_serialize**: (`a`) => \[`number`, `number`] Defined in: @nimiq/core/types/wasm/web.d.ts:2838 #### Parameters ##### a `number` #### Returns \[`number`, `number`] --- ### address\_toHex() > `readonly` **address\_toHex**: (`a`) => \[`number`, `number`] Defined in: @nimiq/core/types/wasm/web.d.ts:2839 #### Parameters ##### a `number` #### Returns \[`number`, `number`] --- ### address\_toPlain() > `readonly` **address\_toPlain**: (`a`) => \[`number`, `number`] Defined in: @nimiq/core/types/wasm/web.d.ts:2840 #### Parameters ##### a `number` #### Returns \[`number`, `number`] --- ### address\_toUserFriendlyAddress() > `readonly` **address\_toUserFriendlyAddress**: (`a`) => \[`number`, `number`] Defined in: @nimiq/core/types/wasm/web.d.ts:2919 #### Parameters ##### a `number` #### Returns \[`number`, `number`] --- ### blskeypair\_derive() > `readonly` **blskeypair\_derive**: (`a`) => `number` Defined in: @nimiq/core/types/wasm/web.d.ts:2841 #### Parameters ##### a `number` #### Returns `number` --- ### blskeypair\_deserialize() > `readonly` **blskeypair\_deserialize**: (`a`, `b`) => \[`number`, `number`, `number`] Defined in: @nimiq/core/types/wasm/web.d.ts:2842 #### Parameters ##### a `number` ##### b `number` #### Returns \[`number`, `number`, `number`] --- ### blskeypair\_generate() > `readonly` **blskeypair\_generate**: () => `number` Defined in: @nimiq/core/types/wasm/web.d.ts:2843 #### Returns `number` --- ### blskeypair\_new() > `readonly` **blskeypair\_new**: (`a`, `b`) => `number` Defined in: @nimiq/core/types/wasm/web.d.ts:2844 #### Parameters ##### a `number` ##### b `number` #### Returns `number` --- ### blskeypair\_publicKey() > `readonly` **blskeypair\_publicKey**: (`a`) => `number` Defined in: @nimiq/core/types/wasm/web.d.ts:2845 #### Parameters ##### a `number` #### Returns `number` --- ### blskeypair\_secretKey() > `readonly` **blskeypair\_secretKey**: (`a`) => `number` Defined in: @nimiq/core/types/wasm/web.d.ts:2846 #### Parameters ##### a `number` #### Returns `number` --- ### blskeypair\_serialize() > `readonly` **blskeypair\_serialize**: (`a`) => \[`number`, `number`] Defined in: @nimiq/core/types/wasm/web.d.ts:2847 #### Parameters ##### a `number` #### Returns \[`number`, `number`] --- ### blskeypair\_toHex() > `readonly` **blskeypair\_toHex**: (`a`) => \[`number`, `number`] Defined in: @nimiq/core/types/wasm/web.d.ts:2848 #### Parameters ##### a `number` #### Returns \[`number`, `number`] --- ### blspublickey\_derive() > `readonly` **blspublickey\_derive**: (`a`) => `number` Defined in: @nimiq/core/types/wasm/web.d.ts:2849 #### Parameters ##### a `number` #### Returns `number` --- ### blspublickey\_deserialize() > `readonly` **blspublickey\_deserialize**: (`a`, `b`) => \[`number`, `number`, `number`] Defined in: @nimiq/core/types/wasm/web.d.ts:2850 #### Parameters ##### a `number` ##### b `number` #### Returns \[`number`, `number`, `number`] --- ### blspublickey\_fromHex() > `readonly` **blspublickey\_fromHex**: (`a`, `b`) => \[`number`, `number`, `number`] Defined in: @nimiq/core/types/wasm/web.d.ts:2851 #### Parameters ##### a `number` ##### b `number` #### Returns \[`number`, `number`, `number`] --- ### blspublickey\_new() > `readonly` **blspublickey\_new**: (`a`, `b`) => \[`number`, `number`, `number`] Defined in: @nimiq/core/types/wasm/web.d.ts:2852 #### Parameters ##### a `number` ##### b `number` #### Returns \[`number`, `number`, `number`] --- ### blspublickey\_serialize() > `readonly` **blspublickey\_serialize**: (`a`) => \[`number`, `number`] Defined in: @nimiq/core/types/wasm/web.d.ts:2853 #### Parameters ##### a `number` #### Returns \[`number`, `number`] --- ### blspublickey\_toHex() > `readonly` **blspublickey\_toHex**: (`a`) => \[`number`, `number`] Defined in: @nimiq/core/types/wasm/web.d.ts:2854 #### Parameters ##### a `number` #### Returns \[`number`, `number`] --- ### blssecretkey\_deserialize() > `readonly` **blssecretkey\_deserialize**: (`a`, `b`) => \[`number`, `number`, `number`] Defined in: @nimiq/core/types/wasm/web.d.ts:2855 #### Parameters ##### a `number` ##### b `number` #### Returns \[`number`, `number`, `number`] --- ### blssecretkey\_fromHex() > `readonly` **blssecretkey\_fromHex**: (`a`, `b`) => \[`number`, `number`, `number`] Defined in: @nimiq/core/types/wasm/web.d.ts:2856 #### Parameters ##### a `number` ##### b `number` #### Returns \[`number`, `number`, `number`] --- ### blssecretkey\_generate() > `readonly` **blssecretkey\_generate**: () => `number` Defined in: @nimiq/core/types/wasm/web.d.ts:2857 #### Returns `number` --- ### blssecretkey\_new() > `readonly` **blssecretkey\_new**: (`a`, `b`) => \[`number`, `number`, `number`] Defined in: @nimiq/core/types/wasm/web.d.ts:2858 #### Parameters ##### a `number` ##### b `number` #### Returns \[`number`, `number`, `number`] --- ### blssecretkey\_serialize() > `readonly` **blssecretkey\_serialize**: (`a`) => \[`number`, `number`] Defined in: @nimiq/core/types/wasm/web.d.ts:2859 #### Parameters ##### a `number` #### Returns \[`number`, `number`] --- ### blssecretkey\_toHex() > `readonly` **blssecretkey\_toHex**: (`a`) => \[`number`, `number`] Defined in: @nimiq/core/types/wasm/web.d.ts:2860 #### Parameters ##### a `number` #### Returns \[`number`, `number`] --- ### client\_addConsensusChangedListener() > `readonly` **client\_addConsensusChangedListener**: (`a`, `b`) => `any` Defined in: @nimiq/core/types/wasm/web.d.ts:2789 #### Parameters ##### a `number` ##### b `any` #### Returns `any` --- ### client\_addHeadChangedListener() > `readonly` **client\_addHeadChangedListener**: (`a`, `b`) => `any` Defined in: @nimiq/core/types/wasm/web.d.ts:2790 #### Parameters ##### a `number` ##### b `any` #### Returns `any` --- ### client\_addPeerChangedListener() > `readonly` **client\_addPeerChangedListener**: (`a`, `b`) => `any` Defined in: @nimiq/core/types/wasm/web.d.ts:2791 #### Parameters ##### a `number` ##### b `any` #### Returns `any` --- ### client\_addTransactionListener() > `readonly` **client\_addTransactionListener**: (`a`, `b`, `c`) => `any` Defined in: @nimiq/core/types/wasm/web.d.ts:2792 #### Parameters ##### a `number` ##### b `any` ##### c `any` #### Returns `any` --- ### client\_connectNetwork() > `readonly` **client\_connectNetwork**: (`a`) => `any` Defined in: @nimiq/core/types/wasm/web.d.ts:2793 #### Parameters ##### a `number` #### Returns `any` --- ### client\_create() > `readonly` **client\_create**: (`a`) => `any` Defined in: @nimiq/core/types/wasm/web.d.ts:2794 #### Parameters ##### a `any` #### Returns `any` --- ### client\_disconnectNetwork() > `readonly` **client\_disconnectNetwork**: (`a`) => `any` Defined in: @nimiq/core/types/wasm/web.d.ts:2795 #### Parameters ##### a `number` #### Returns `any` --- ### client\_getAccount() > `readonly` **client\_getAccount**: (`a`, `b`) => `any` Defined in: @nimiq/core/types/wasm/web.d.ts:2796 #### Parameters ##### a `number` ##### b `any` #### Returns `any` --- ### client\_getAccounts() > `readonly` **client\_getAccounts**: (`a`, `b`) => `any` Defined in: @nimiq/core/types/wasm/web.d.ts:2797 #### Parameters ##### a `number` ##### b `any` #### Returns `any` --- ### client\_getAddressBook() > `readonly` **client\_getAddressBook**: (`a`) => `any` Defined in: @nimiq/core/types/wasm/web.d.ts:2798 #### Parameters ##### a `number` #### Returns `any` --- ### client\_getBlock() > `readonly` **client\_getBlock**: (`a`, `b`, `c`) => `any` Defined in: @nimiq/core/types/wasm/web.d.ts:2799 #### Parameters ##### a `number` ##### b `number` ##### c `number` #### Returns `any` --- ### client\_getBlockAt() > `readonly` **client\_getBlockAt**: (`a`, `b`) => `any` Defined in: @nimiq/core/types/wasm/web.d.ts:2800 #### Parameters ##### a `number` ##### b `number` #### Returns `any` --- ### client\_getElectedValidators() > `readonly` **client\_getElectedValidators**: (`a`) => `any` Defined in: @nimiq/core/types/wasm/web.d.ts:2801 #### Parameters ##### a `number` #### Returns `any` --- ### client\_getHeadBlock() > `readonly` **client\_getHeadBlock**: (`a`) => `any` Defined in: @nimiq/core/types/wasm/web.d.ts:2802 #### Parameters ##### a `number` #### Returns `any` --- ### client\_getHeadHash() > `readonly` **client\_getHeadHash**: (`a`) => `any` Defined in: @nimiq/core/types/wasm/web.d.ts:2803 #### Parameters ##### a `number` #### Returns `any` --- ### client\_getHeadHeight() > `readonly` **client\_getHeadHeight**: (`a`) => `any` Defined in: @nimiq/core/types/wasm/web.d.ts:2804 #### Parameters ##### a `number` #### Returns `any` --- ### client\_getNetworkId() > `readonly` **client\_getNetworkId**: (`a`) => `any` Defined in: @nimiq/core/types/wasm/web.d.ts:2805 #### Parameters ##### a `number` #### Returns `any` --- ### client\_getProtocolVersion() > `readonly` **client\_getProtocolVersion**: (`a`) => `any` Defined in: @nimiq/core/types/wasm/web.d.ts:2806 #### Parameters ##### a `number` #### Returns `any` --- ### client\_getStaker() > `readonly` **client\_getStaker**: (`a`, `b`) => `any` Defined in: @nimiq/core/types/wasm/web.d.ts:2807 #### Parameters ##### a `number` ##### b `any` #### Returns `any` --- ### client\_getStakers() > `readonly` **client\_getStakers**: (`a`, `b`) => `any` Defined in: @nimiq/core/types/wasm/web.d.ts:2808 #### Parameters ##### a `number` ##### b `any` #### Returns `any` --- ### client\_getTransaction() > `readonly` **client\_getTransaction**: (`a`, `b`, `c`) => `any` Defined in: @nimiq/core/types/wasm/web.d.ts:2809 #### Parameters ##### a `number` ##### b `number` ##### c `number` #### Returns `any` --- ### client\_getTransactionReceiptsByAddress() > `readonly` **client\_getTransactionReceiptsByAddress**: (`a`, `b`, `c`, `d`, `e`, `f`) => `any` Defined in: @nimiq/core/types/wasm/web.d.ts:2810 #### Parameters ##### a `number` ##### b `any` ##### c `number` ##### d `number` ##### e `number` ##### f `number` #### Returns `any` --- ### client\_getTransactionsByAddress() > `readonly` **client\_getTransactionsByAddress**: (`a`, `b`, `c`, `d`, `e`, `f`, `g`, `h`) => `any` Defined in: @nimiq/core/types/wasm/web.d.ts:2811 #### Parameters ##### a `number` ##### b `any` ##### c `number` ##### d `number` ##### e `number` ##### f `number` ##### g `number` ##### h `number` #### Returns `any` --- ### client\_getValidator() > `readonly` **client\_getValidator**: (`a`, `b`) => `any` Defined in: @nimiq/core/types/wasm/web.d.ts:2812 #### Parameters ##### a `number` ##### b `any` #### Returns `any` --- ### client\_getValidators() > `readonly` **client\_getValidators**: (`a`, `b`) => `any` Defined in: @nimiq/core/types/wasm/web.d.ts:2813 #### Parameters ##### a `number` ##### b `any` #### Returns `any` --- ### client\_getVersion() > `readonly` **client\_getVersion**: (`a`) => `any` Defined in: @nimiq/core/types/wasm/web.d.ts:2814 #### Parameters ##### a `number` #### Returns `any` --- ### client\_isConsensusEstablished() > `readonly` **client\_isConsensusEstablished**: (`a`) => `any` Defined in: @nimiq/core/types/wasm/web.d.ts:2815 #### Parameters ##### a `number` #### Returns `any` --- ### client\_removeListener() > `readonly` **client\_removeListener**: (`a`, `b`) => `any` Defined in: @nimiq/core/types/wasm/web.d.ts:2816 #### Parameters ##### a `number` ##### b `number` #### Returns `any` --- ### client\_sendTransaction() > `readonly` **client\_sendTransaction**: (`a`, `b`) => `any` Defined in: @nimiq/core/types/wasm/web.d.ts:2817 #### Parameters ##### a `number` ##### b `any` #### Returns `any` --- ### client\_waitForConsensusEstablished() > `readonly` **client\_waitForConsensusEstablished**: (`a`) => `any` Defined in: @nimiq/core/types/wasm/web.d.ts:2818 #### Parameters ##### a `number` #### Returns `any` --- ### clientconfiguration\_build() > `readonly` **clientconfiguration\_build**: (`a`) => `any` Defined in: @nimiq/core/types/wasm/web.d.ts:2622 #### Parameters ##### a `number` #### Returns `any` --- ### clientconfiguration\_desiredPeerCount() > `readonly` **clientconfiguration\_desiredPeerCount**: (`a`, `b`) => `void` Defined in: @nimiq/core/types/wasm/web.d.ts:2623 #### Parameters ##### a `number` ##### b `number` #### Returns `void` --- ### clientconfiguration\_logLevel() > `readonly` **clientconfiguration\_logLevel**: (`a`, `b`, `c`) => `void` Defined in: @nimiq/core/types/wasm/web.d.ts:2624 #### Parameters ##### a `number` ##### b `number` ##### c `number` #### Returns `void` --- ### clientconfiguration\_network() > `readonly` **clientconfiguration\_network**: (`a`, `b`, `c`) => \[`number`, `number`] Defined in: @nimiq/core/types/wasm/web.d.ts:2625 #### Parameters ##### a `number` ##### b `number` ##### c `number` #### Returns \[`number`, `number`] --- ### clientconfiguration\_networkBufferSize() > `readonly` **clientconfiguration\_networkBufferSize**: (`a`, `b`) => `void` Defined in: @nimiq/core/types/wasm/web.d.ts:2626 #### Parameters ##### a `number` ##### b `number` #### Returns `void` --- ### clientconfiguration\_new() > `readonly` **clientconfiguration\_new**: () => `number` Defined in: @nimiq/core/types/wasm/web.d.ts:2627 #### Returns `number` --- ### clientconfiguration\_onlySecureWsConnections() > `readonly` **clientconfiguration\_onlySecureWsConnections**: (`a`, `b`) => `void` Defined in: @nimiq/core/types/wasm/web.d.ts:2628 #### Parameters ##### a `number` ##### b `number` #### Returns `void` --- ### clientconfiguration\_peerCountMax() > `readonly` **clientconfiguration\_peerCountMax**: (`a`, `b`) => `void` Defined in: @nimiq/core/types/wasm/web.d.ts:2629 #### Parameters ##### a `number` ##### b `number` #### Returns `void` --- ### clientconfiguration\_peerCountPerIpMax() > `readonly` **clientconfiguration\_peerCountPerIpMax**: (`a`, `b`) => `void` Defined in: @nimiq/core/types/wasm/web.d.ts:2630 #### Parameters ##### a `number` ##### b `number` #### Returns `void` --- ### clientconfiguration\_peerCountPerSubnetMax() > `readonly` **clientconfiguration\_peerCountPerSubnetMax**: (`a`, `b`) => `void` Defined in: @nimiq/core/types/wasm/web.d.ts:2631 #### Parameters ##### a `number` ##### b `number` #### Returns `void` --- ### clientconfiguration\_seedNodes() > `readonly` **clientconfiguration\_seedNodes**: (`a`, `b`, `c`) => \[`number`, `number`] Defined in: @nimiq/core/types/wasm/web.d.ts:2632 #### Parameters ##### a `number` ##### b `number` ##### c `number` #### Returns \[`number`, `number`] --- ### clientconfiguration\_syncMode() > `readonly` **clientconfiguration\_syncMode**: (`a`, `b`, `c`) => `void` Defined in: @nimiq/core/types/wasm/web.d.ts:2633 #### Parameters ##### a `number` ##### b `number` ##### c `number` #### Returns `void` --- ### commitment\_\_\_getClassname() > `readonly` **commitment\_\_\_getClassname**: (`a`) => \[`number`, `number`] Defined in: @nimiq/core/types/wasm/web.d.ts:2861 #### Parameters ##### a `number` #### Returns \[`number`, `number`] --- ### commitment\_derive() > `readonly` **commitment\_derive**: (`a`) => `number` Defined in: @nimiq/core/types/wasm/web.d.ts:2862 #### Parameters ##### a `number` #### Returns `number` --- ### commitment\_deserialize() > `readonly` **commitment\_deserialize**: (`a`, `b`) => \[`number`, `number`, `number`] Defined in: @nimiq/core/types/wasm/web.d.ts:2863 #### Parameters ##### a `number` ##### b `number` #### Returns \[`number`, `number`, `number`] --- ### commitment\_equals() > `readonly` **commitment\_equals**: (`a`, `b`) => `number` Defined in: @nimiq/core/types/wasm/web.d.ts:2864 #### Parameters ##### a `number` ##### b `number` #### Returns `number` --- ### commitment\_fromAny() > `readonly` **commitment\_fromAny**: (`a`) => \[`number`, `number`, `number`] Defined in: @nimiq/core/types/wasm/web.d.ts:2865 #### Parameters ##### a `any` #### Returns \[`number`, `number`, `number`] --- ### commitment\_fromHex() > `readonly` **commitment\_fromHex**: (`a`, `b`) => \[`number`, `number`, `number`] Defined in: @nimiq/core/types/wasm/web.d.ts:2866 #### Parameters ##### a `number` ##### b `number` #### Returns \[`number`, `number`, `number`] --- ### commitment\_new() > `readonly` **commitment\_new**: (`a`, `b`) => \[`number`, `number`, `number`] Defined in: @nimiq/core/types/wasm/web.d.ts:2867 #### Parameters ##### a `number` ##### b `number` #### Returns \[`number`, `number`, `number`] --- ### commitment\_serialize() > `readonly` **commitment\_serialize**: (`a`) => \[`number`, `number`] Defined in: @nimiq/core/types/wasm/web.d.ts:2868 #### Parameters ##### a `number` #### Returns \[`number`, `number`] --- ### commitment\_serialized\_size() > `readonly` **commitment\_serialized\_size**: (`a`) => `number` Defined in: @nimiq/core/types/wasm/web.d.ts:2869 #### Parameters ##### a `number` #### Returns `number` --- ### commitment\_size() > `readonly` **commitment\_size**: () => `number` Defined in: @nimiq/core/types/wasm/web.d.ts:2870 #### Returns `number` --- ### commitment\_sum() > `readonly` **commitment\_sum**: (`a`) => \[`number`, `number`, `number`] Defined in: @nimiq/core/types/wasm/web.d.ts:2871 #### Parameters ##### a `any` #### Returns \[`number`, `number`, `number`] --- ### commitment\_sumMuSig2() > `readonly` **commitment\_sumMuSig2**: (`a`, `b`, `c`, `d`) => \[`number`, `number`, `number`] Defined in: @nimiq/core/types/wasm/web.d.ts:2872 #### Parameters ##### a `any` ##### b `any` ##### c `number` ##### d `number` #### Returns \[`number`, `number`, `number`] --- ### commitment\_toHex() > `readonly` **commitment\_toHex**: (`a`) => \[`number`, `number`] Defined in: @nimiq/core/types/wasm/web.d.ts:2873 #### Parameters ##### a `number` #### Returns \[`number`, `number`] --- ### commitmentpair\_\_\_getClassname() > `readonly` **commitmentpair\_\_\_getClassname**: (`a`) => \[`number`, `number`] Defined in: @nimiq/core/types/wasm/web.d.ts:2634 #### Parameters ##### a `number` #### Returns \[`number`, `number`] --- ### commitmentpair\_commitment() > `readonly` **commitmentpair\_commitment**: (`a`) => `number` Defined in: @nimiq/core/types/wasm/web.d.ts:2635 #### Parameters ##### a `number` #### Returns `number` --- ### commitmentpair\_derive() > `readonly` **commitmentpair\_derive**: (`a`) => `number` Defined in: @nimiq/core/types/wasm/web.d.ts:2636 #### Parameters ##### a `number` #### Returns `number` --- ### commitmentpair\_deserialize() > `readonly` **commitmentpair\_deserialize**: (`a`, `b`) => \[`number`, `number`, `number`] Defined in: @nimiq/core/types/wasm/web.d.ts:2637 #### Parameters ##### a `number` ##### b `number` #### Returns \[`number`, `number`, `number`] --- ### commitmentpair\_equals() > `readonly` **commitmentpair\_equals**: (`a`, `b`) => `number` Defined in: @nimiq/core/types/wasm/web.d.ts:2638 #### Parameters ##### a `number` ##### b `number` #### Returns `number` --- ### commitmentpair\_fromAny() > `readonly` **commitmentpair\_fromAny**: (`a`) => \[`number`, `number`, `number`] Defined in: @nimiq/core/types/wasm/web.d.ts:2639 #### Parameters ##### a `any` #### Returns \[`number`, `number`, `number`] --- ### commitmentpair\_fromHex() > `readonly` **commitmentpair\_fromHex**: (`a`, `b`) => \[`number`, `number`, `number`] Defined in: @nimiq/core/types/wasm/web.d.ts:2640 #### Parameters ##### a `number` ##### b `number` #### Returns \[`number`, `number`, `number`] --- ### commitmentpair\_generate() > `readonly` **commitmentpair\_generate**: () => `number` Defined in: @nimiq/core/types/wasm/web.d.ts:2641 #### Returns `number` --- ### commitmentpair\_new() > `readonly` **commitmentpair\_new**: (`a`, `b`) => `number` Defined in: @nimiq/core/types/wasm/web.d.ts:2642 #### Parameters ##### a `number` ##### b `number` #### Returns `number` --- ### commitmentpair\_secret() > `readonly` **commitmentpair\_secret**: (`a`) => `number` Defined in: @nimiq/core/types/wasm/web.d.ts:2643 #### Parameters ##### a `number` #### Returns `number` --- ### commitmentpair\_serialize() > `readonly` **commitmentpair\_serialize**: (`a`) => \[`number`, `number`] Defined in: @nimiq/core/types/wasm/web.d.ts:2644 #### Parameters ##### a `number` #### Returns \[`number`, `number`] --- ### commitmentpair\_serialized\_size() > `readonly` **commitmentpair\_serialized\_size**: (`a`) => `number` Defined in: @nimiq/core/types/wasm/web.d.ts:2645 #### Parameters ##### a `number` #### Returns `number` --- ### commitmentpair\_size() > `readonly` **commitmentpair\_size**: () => `number` Defined in: @nimiq/core/types/wasm/web.d.ts:2646 #### Returns `number` --- ### commitmentpair\_toHex() > `readonly` **commitmentpair\_toHex**: (`a`) => \[`number`, `number`] Defined in: @nimiq/core/types/wasm/web.d.ts:2647 #### Parameters ##### a `number` #### Returns \[`number`, `number`] --- ### cryptoutils\_computeHmacSha512() > `readonly` **cryptoutils\_computeHmacSha512**: (`a`, `b`, `c`, `d`) => \[`number`, `number`] Defined in: @nimiq/core/types/wasm/web.d.ts:2729 #### Parameters ##### a `number` ##### b `number` ##### c `number` ##### d `number` #### Returns \[`number`, `number`] --- ### cryptoutils\_computePBKDF2sha512() > `readonly` **cryptoutils\_computePBKDF2sha512**: (`a`, `b`, `c`, `d`, `e`, `f`) => \[`number`, `number`, `number`, `number`] Defined in: @nimiq/core/types/wasm/web.d.ts:2730 #### Parameters ##### a `number` ##### b `number` ##### c `number` ##### d `number` ##### e `number` ##### f `number` #### Returns \[`number`, `number`, `number`, `number`] --- ### cryptoutils\_getRandomValues() > `readonly` **cryptoutils\_getRandomValues**: (`a`) => \[`number`, `number`] Defined in: @nimiq/core/types/wasm/web.d.ts:2731 #### Parameters ##### a `number` #### Returns \[`number`, `number`] --- ### cryptoutils\_otpKdf() > `readonly` **cryptoutils\_otpKdf**: (`a`, `b`, `c`, `d`, `e`, `f`, `g`) => `any` Defined in: @nimiq/core/types/wasm/web.d.ts:2732 #### Parameters ##### a `number` ##### b `number` ##### c `number` ##### d `number` ##### e `number` ##### f `number` ##### g `number` #### Returns `any` --- ### es256publickey\_\_\_getClassname() > `readonly` **es256publickey\_\_\_getClassname**: (`a`) => \[`number`, `number`] Defined in: @nimiq/core/types/wasm/web.d.ts:2874 #### Parameters ##### a `number` #### Returns \[`number`, `number`] --- ### es256publickey\_compare() > `readonly` **es256publickey\_compare**: (`a`, `b`) => `number` Defined in: @nimiq/core/types/wasm/web.d.ts:2875 #### Parameters ##### a `number` ##### b `number` #### Returns `number` --- ### es256publickey\_deserialize() > `readonly` **es256publickey\_deserialize**: (`a`, `b`) => \[`number`, `number`, `number`] Defined in: @nimiq/core/types/wasm/web.d.ts:2876 #### Parameters ##### a `number` ##### b `number` #### Returns \[`number`, `number`, `number`] --- ### es256publickey\_equals() > `readonly` **es256publickey\_equals**: (`a`, `b`) => `number` Defined in: @nimiq/core/types/wasm/web.d.ts:2877 #### Parameters ##### a `number` ##### b `number` #### Returns `number` --- ### es256publickey\_fromHex() > `readonly` **es256publickey\_fromHex**: (`a`, `b`) => \[`number`, `number`, `number`] Defined in: @nimiq/core/types/wasm/web.d.ts:2878 #### Parameters ##### a `number` ##### b `number` #### Returns \[`number`, `number`, `number`] --- ### es256publickey\_fromRaw() > `readonly` **es256publickey\_fromRaw**: (`a`, `b`) => \[`number`, `number`, `number`] Defined in: @nimiq/core/types/wasm/web.d.ts:2879 #### Parameters ##### a `number` ##### b `number` #### Returns \[`number`, `number`, `number`] --- ### es256publickey\_fromSpki() > `readonly` **es256publickey\_fromSpki**: (`a`, `b`) => \[`number`, `number`, `number`] Defined in: @nimiq/core/types/wasm/web.d.ts:2880 #### Parameters ##### a `number` ##### b `number` #### Returns \[`number`, `number`, `number`] --- ### es256publickey\_new() > `readonly` **es256publickey\_new**: (`a`, `b`) => \[`number`, `number`, `number`] Defined in: @nimiq/core/types/wasm/web.d.ts:2881 #### Parameters ##### a `number` ##### b `number` #### Returns \[`number`, `number`, `number`] --- ### es256publickey\_serialize() > `readonly` **es256publickey\_serialize**: (`a`) => \[`number`, `number`] Defined in: @nimiq/core/types/wasm/web.d.ts:2882 #### Parameters ##### a `number` #### Returns \[`number`, `number`] --- ### es256publickey\_toAddress() > `readonly` **es256publickey\_toAddress**: (`a`) => `number` Defined in: @nimiq/core/types/wasm/web.d.ts:2883 #### Parameters ##### a `number` #### Returns `number` --- ### es256publickey\_toHex() > `readonly` **es256publickey\_toHex**: (`a`) => \[`number`, `number`] Defined in: @nimiq/core/types/wasm/web.d.ts:2884 #### Parameters ##### a `number` #### Returns \[`number`, `number`] --- ### es256publickey\_verify() > `readonly` **es256publickey\_verify**: (`a`, `b`, `c`, `d`) => `number` Defined in: @nimiq/core/types/wasm/web.d.ts:2885 #### Parameters ##### a `number` ##### b `number` ##### c `number` ##### d `number` #### Returns `number` --- ### es256signature\_\_\_getClassname() > `readonly` **es256signature\_\_\_getClassname**: (`a`) => \[`number`, `number`] Defined in: @nimiq/core/types/wasm/web.d.ts:2648 #### Parameters ##### a `number` #### Returns \[`number`, `number`] --- ### es256signature\_deserialize() > `readonly` **es256signature\_deserialize**: (`a`, `b`) => \[`number`, `number`, `number`] Defined in: @nimiq/core/types/wasm/web.d.ts:2649 #### Parameters ##### a `number` ##### b `number` #### Returns \[`number`, `number`, `number`] --- ### es256signature\_fromAsn1() > `readonly` **es256signature\_fromAsn1**: (`a`, `b`) => \[`number`, `number`, `number`] Defined in: @nimiq/core/types/wasm/web.d.ts:2650 #### Parameters ##### a `number` ##### b `number` #### Returns \[`number`, `number`, `number`] --- ### es256signature\_fromHex() > `readonly` **es256signature\_fromHex**: (`a`, `b`) => \[`number`, `number`, `number`] Defined in: @nimiq/core/types/wasm/web.d.ts:2651 #### Parameters ##### a `number` ##### b `number` #### Returns \[`number`, `number`, `number`] --- ### es256signature\_serialize() > `readonly` **es256signature\_serialize**: (`a`) => \[`number`, `number`] Defined in: @nimiq/core/types/wasm/web.d.ts:2652 #### Parameters ##### a `number` #### Returns \[`number`, `number`] --- ### es256signature\_toHex() > `readonly` **es256signature\_toHex**: (`a`) => \[`number`, `number`] Defined in: @nimiq/core/types/wasm/web.d.ts:2653 #### Parameters ##### a `number` #### Returns \[`number`, `number`] --- ### hash\_computeBlake2b() > `readonly` **hash\_computeBlake2b**: (`a`, `b`) => \[`number`, `number`] Defined in: @nimiq/core/types/wasm/web.d.ts:2733 #### Parameters ##### a `number` ##### b `number` #### Returns \[`number`, `number`] --- ### hash\_computeNimiqArgon2d() > `readonly` **hash\_computeNimiqArgon2d**: (`a`, `b`, `c`, `d`, `e`, `f`) => \[`number`, `number`, `number`, `number`] Defined in: @nimiq/core/types/wasm/web.d.ts:2734 #### Parameters ##### a `number` ##### b `number` ##### c `number` ##### d `number` ##### e `number` ##### f `number` #### Returns \[`number`, `number`, `number`, `number`] --- ### hash\_computeNimiqArgon2id() > `readonly` **hash\_computeNimiqArgon2id**: (`a`, `b`, `c`, `d`, `e`, `f`) => \[`number`, `number`, `number`, `number`] Defined in: @nimiq/core/types/wasm/web.d.ts:2735 #### Parameters ##### a `number` ##### b `number` ##### c `number` ##### d `number` ##### e `number` ##### f `number` #### Returns \[`number`, `number`, `number`, `number`] --- ### hash\_computeSha256() > `readonly` **hash\_computeSha256**: (`a`, `b`) => \[`number`, `number`] Defined in: @nimiq/core/types/wasm/web.d.ts:2736 #### Parameters ##### a `number` ##### b `number` #### Returns \[`number`, `number`] --- ### hash\_computeSha512() > `readonly` **hash\_computeSha512**: (`a`, `b`) => \[`number`, `number`] Defined in: @nimiq/core/types/wasm/web.d.ts:2737 #### Parameters ##### a `number` ##### b `number` #### Returns \[`number`, `number`] --- ### hashedtimelockedcontract\_dataToPlain() > `readonly` **hashedtimelockedcontract\_dataToPlain**: (`a`, `b`) => \[`number`, `number`, `number`] Defined in: @nimiq/core/types/wasm/web.d.ts:2738 #### Parameters ##### a `number` ##### b `number` #### Returns \[`number`, `number`, `number`] --- ### hashedtimelockedcontract\_proofToPlain() > `readonly` **hashedtimelockedcontract\_proofToPlain**: (`a`, `b`) => \[`number`, `number`, `number`] Defined in: @nimiq/core/types/wasm/web.d.ts:2739 #### Parameters ##### a `number` ##### b `number` #### Returns \[`number`, `number`, `number`] --- ### keypair\_\_\_getClassname() > `readonly` **keypair\_\_\_getClassname**: (`a`) => \[`number`, `number`] Defined in: @nimiq/core/types/wasm/web.d.ts:2654 #### Parameters ##### a `number` #### Returns \[`number`, `number`] --- ### keypair\_derive() > `readonly` **keypair\_derive**: (`a`) => `number` Defined in: @nimiq/core/types/wasm/web.d.ts:2655 #### Parameters ##### a `number` #### Returns `number` --- ### keypair\_deserialize() > `readonly` **keypair\_deserialize**: (`a`, `b`) => \[`number`, `number`, `number`] Defined in: @nimiq/core/types/wasm/web.d.ts:2656 #### Parameters ##### a `number` ##### b `number` #### Returns \[`number`, `number`, `number`] --- ### keypair\_fromHex() > `readonly` **keypair\_fromHex**: (`a`, `b`) => \[`number`, `number`, `number`] Defined in: @nimiq/core/types/wasm/web.d.ts:2657 #### Parameters ##### a `number` ##### b `number` #### Returns \[`number`, `number`, `number`] --- ### keypair\_generate() > `readonly` **keypair\_generate**: () => `number` Defined in: @nimiq/core/types/wasm/web.d.ts:2658 #### Returns `number` --- ### keypair\_new() > `readonly` **keypair\_new**: (`a`, `b`) => `number` Defined in: @nimiq/core/types/wasm/web.d.ts:2659 #### Parameters ##### a `number` ##### b `number` #### Returns `number` --- ### keypair\_privateKey() > `readonly` **keypair\_privateKey**: (`a`) => `number` Defined in: @nimiq/core/types/wasm/web.d.ts:2660 #### Parameters ##### a `number` #### Returns `number` --- ### keypair\_publicKey() > `readonly` **keypair\_publicKey**: (`a`) => `number` Defined in: @nimiq/core/types/wasm/web.d.ts:2661 #### Parameters ##### a `number` #### Returns `number` --- ### keypair\_serialize() > `readonly` **keypair\_serialize**: (`a`) => \[`number`, `number`] Defined in: @nimiq/core/types/wasm/web.d.ts:2662 #### Parameters ##### a `number` #### Returns \[`number`, `number`] --- ### keypair\_sign() > `readonly` **keypair\_sign**: (`a`, `b`, `c`) => `number` Defined in: @nimiq/core/types/wasm/web.d.ts:2663 #### Parameters ##### a `number` ##### b `number` ##### c `number` #### Returns `number` --- ### keypair\_signTransaction() > `readonly` **keypair\_signTransaction**: (`a`, `b`) => \[`number`, `number`] Defined in: @nimiq/core/types/wasm/web.d.ts:2664 #### Parameters ##### a `number` ##### b `number` #### Returns \[`number`, `number`] --- ### keypair\_toAddress() > `readonly` **keypair\_toAddress**: (`a`) => `number` Defined in: @nimiq/core/types/wasm/web.d.ts:2665 #### Parameters ##### a `number` #### Returns `number` --- ### keypair\_toHex() > `readonly` **keypair\_toHex**: (`a`) => \[`number`, `number`] Defined in: @nimiq/core/types/wasm/web.d.ts:2666 #### Parameters ##### a `number` #### Returns \[`number`, `number`] --- ### memory > `readonly` **memory**: `Memory` Defined in: @nimiq/core/types/wasm/web.d.ts:2614 --- ### merklepath\_computeRoot() > `readonly` **merklepath\_computeRoot**: (`a`, `b`, `c`) => \[`number`, `number`, `number`, `number`] Defined in: @nimiq/core/types/wasm/web.d.ts:2740 #### Parameters ##### a `number` ##### b `number` ##### c `number` #### Returns \[`number`, `number`, `number`, `number`] --- ### merklepath\_deserialize() > `readonly` **merklepath\_deserialize**: (`a`, `b`) => \[`number`, `number`, `number`] Defined in: @nimiq/core/types/wasm/web.d.ts:2741 #### Parameters ##### a `number` ##### b `number` #### Returns \[`number`, `number`, `number`] --- ### merklepath\_hashes() > `readonly` **merklepath\_hashes**: (`a`) => \[`number`, `number`] Defined in: @nimiq/core/types/wasm/web.d.ts:2742 #### Parameters ##### a `number` #### Returns \[`number`, `number`] --- ### merklepath\_length() > `readonly` **merklepath\_length**: (`a`) => `number` Defined in: @nimiq/core/types/wasm/web.d.ts:2743 #### Parameters ##### a `number` #### Returns `number` --- ### merklepath\_serialize() > `readonly` **merklepath\_serialize**: (`a`) => \[`number`, `number`] Defined in: @nimiq/core/types/wasm/web.d.ts:2744 #### Parameters ##### a `number` #### Returns \[`number`, `number`] --- ### merkletree\_computeRoot() > `readonly` **merkletree\_computeRoot**: (`a`, `b`) => \[`number`, `number`] Defined in: @nimiq/core/types/wasm/web.d.ts:2745 #### Parameters ##### a `number` ##### b `number` #### Returns \[`number`, `number`] --- ### partialsignature\_\_\_getClassname() > `readonly` **partialsignature\_\_\_getClassname**: (`a`) => \[`number`, `number`] Defined in: @nimiq/core/types/wasm/web.d.ts:2667 #### Parameters ##### a `number` #### Returns \[`number`, `number`] --- ### partialsignature\_create() > `readonly` **partialsignature\_create**: (`a`, `b`, `c`, `d`, `e`, `f`, `g`) => \[`number`, `number`, `number`] Defined in: @nimiq/core/types/wasm/web.d.ts:2668 #### Parameters ##### a `number` ##### b `number` ##### c `any` ##### d `any` ##### e `any` ##### f `number` ##### g `number` #### Returns \[`number`, `number`, `number`] --- ### partialsignature\_deserialize() > `readonly` **partialsignature\_deserialize**: (`a`, `b`) => \[`number`, `number`, `number`] Defined in: @nimiq/core/types/wasm/web.d.ts:2669 #### Parameters ##### a `number` ##### b `number` #### Returns \[`number`, `number`, `number`] --- ### partialsignature\_equals() > `readonly` **partialsignature\_equals**: (`a`, `b`) => `number` Defined in: @nimiq/core/types/wasm/web.d.ts:2670 #### Parameters ##### a `number` ##### b `number` #### Returns `number` --- ### partialsignature\_fromAny() > `readonly` **partialsignature\_fromAny**: (`a`) => \[`number`, `number`, `number`] Defined in: @nimiq/core/types/wasm/web.d.ts:2671 #### Parameters ##### a `any` #### Returns \[`number`, `number`, `number`] --- ### partialsignature\_fromHex() > `readonly` **partialsignature\_fromHex**: (`a`, `b`) => \[`number`, `number`, `number`] Defined in: @nimiq/core/types/wasm/web.d.ts:2672 #### Parameters ##### a `number` ##### b `number` #### Returns \[`number`, `number`, `number`] --- ### partialsignature\_new() > `readonly` **partialsignature\_new**: (`a`, `b`) => \[`number`, `number`, `number`] Defined in: @nimiq/core/types/wasm/web.d.ts:2673 #### Parameters ##### a `number` ##### b `number` #### Returns \[`number`, `number`, `number`] --- ### partialsignature\_serialize() > `readonly` **partialsignature\_serialize**: (`a`) => \[`number`, `number`] Defined in: @nimiq/core/types/wasm/web.d.ts:2674 #### Parameters ##### a `number` #### Returns \[`number`, `number`] --- ### partialsignature\_serialized\_size() > `readonly` **partialsignature\_serialized\_size**: (`a`) => `number` Defined in: @nimiq/core/types/wasm/web.d.ts:2675 #### Parameters ##### a `number` #### Returns `number` --- ### partialsignature\_size() > `readonly` **partialsignature\_size**: () => `number` Defined in: @nimiq/core/types/wasm/web.d.ts:2676 #### Returns `number` --- ### partialsignature\_sum() > `readonly` **partialsignature\_sum**: (`a`) => \[`number`, `number`, `number`] Defined in: @nimiq/core/types/wasm/web.d.ts:2677 #### Parameters ##### a `any` #### Returns \[`number`, `number`, `number`] --- ### partialsignature\_toHex() > `readonly` **partialsignature\_toHex**: (`a`) => \[`number`, `number`] Defined in: @nimiq/core/types/wasm/web.d.ts:2678 #### Parameters ##### a `number` #### Returns \[`number`, `number`] --- ### partialsignature\_toSignature() > `readonly` **partialsignature\_toSignature**: (`a`, `b`) => `number` Defined in: @nimiq/core/types/wasm/web.d.ts:2679 #### Parameters ##### a `number` ##### b `number` #### Returns `number` --- ### policy\_batchAt() > `readonly` **policy\_batchAt**: (`a`) => `number` Defined in: @nimiq/core/types/wasm/web.d.ts:2923 #### Parameters ##### a `number` #### Returns `number` --- ### policy\_batchDelayPenalty() > `readonly` **policy\_batchDelayPenalty**: (`a`) => `number` Defined in: @nimiq/core/types/wasm/web.d.ts:2971 #### Parameters ##### a `bigint` #### Returns `number` --- ### policy\_batches\_per\_epoch() > `readonly` **policy\_batches\_per\_epoch**: () => `number` Defined in: @nimiq/core/types/wasm/web.d.ts:2925 #### Returns `number` --- ### policy\_batchIndexAt() > `readonly` **policy\_batchIndexAt**: (`a`) => `number` Defined in: @nimiq/core/types/wasm/web.d.ts:2924 #### Parameters ##### a `number` #### Returns `number` --- ### policy\_blockAfterCollateralLockup() > `readonly` **policy\_blockAfterCollateralLockup**: (`a`) => `number` Defined in: @nimiq/core/types/wasm/web.d.ts:2926 #### Parameters ##### a `number` #### Returns `number` --- ### policy\_blockAfterJail() > `readonly` **policy\_blockAfterJail**: (`a`) => `number` Defined in: @nimiq/core/types/wasm/web.d.ts:2927 #### Parameters ##### a `number` #### Returns `number` --- ### policy\_blockAfterReportingWindow() > `readonly` **policy\_blockAfterReportingWindow**: (`a`) => `number` Defined in: @nimiq/core/types/wasm/web.d.ts:2972 #### Parameters ##### a `number` #### Returns `number` --- ### policy\_blocks\_per\_batch() > `readonly` **policy\_blocks\_per\_batch**: () => `number` Defined in: @nimiq/core/types/wasm/web.d.ts:2928 #### Returns `number` --- ### policy\_blocks\_per\_epoch() > `readonly` **policy\_blocks\_per\_epoch**: () => `number` Defined in: @nimiq/core/types/wasm/web.d.ts:2929 #### Returns `number` --- ### policy\_electionBlockAfter() > `readonly` **policy\_electionBlockAfter**: (`a`) => `number` Defined in: @nimiq/core/types/wasm/web.d.ts:2930 #### Parameters ##### a `number` #### Returns `number` --- ### policy\_electionBlockBefore() > `readonly` **policy\_electionBlockBefore**: (`a`) => `number` Defined in: @nimiq/core/types/wasm/web.d.ts:2931 #### Parameters ##### a `number` #### Returns `number` --- ### policy\_electionBlockOf() > `readonly` **policy\_electionBlockOf**: (`a`) => `number` Defined in: @nimiq/core/types/wasm/web.d.ts:2932 #### Parameters ##### a `number` #### Returns `number` --- ### policy\_epochAt() > `readonly` **policy\_epochAt**: (`a`) => `number` Defined in: @nimiq/core/types/wasm/web.d.ts:2933 #### Parameters ##### a `number` #### Returns `number` --- ### policy\_epochIndexAt() > `readonly` **policy\_epochIndexAt**: (`a`) => `number` Defined in: @nimiq/core/types/wasm/web.d.ts:2934 #### Parameters ##### a `number` #### Returns `number` --- ### policy\_firstBatchOfEpoch() > `readonly` **policy\_firstBatchOfEpoch**: (`a`) => `number` Defined in: @nimiq/core/types/wasm/web.d.ts:2935 #### Parameters ##### a `number` #### Returns `number` --- ### policy\_firstBlockOf() > `readonly` **policy\_firstBlockOf**: (`a`) => `number` Defined in: @nimiq/core/types/wasm/web.d.ts:2936 #### Parameters ##### a `number` #### Returns `number` --- ### policy\_firstBlockOfBatch() > `readonly` **policy\_firstBlockOfBatch**: (`a`) => `number` Defined in: @nimiq/core/types/wasm/web.d.ts:2937 #### Parameters ##### a `number` #### Returns `number` --- ### policy\_genesis\_block\_number() > `readonly` **policy\_genesis\_block\_number**: () => `number` Defined in: @nimiq/core/types/wasm/web.d.ts:2938 #### Returns `number` --- ### policy\_isElectionBlockAt() > `readonly` **policy\_isElectionBlockAt**: (`a`) => `number` Defined in: @nimiq/core/types/wasm/web.d.ts:2939 #### Parameters ##### a `number` #### Returns `number` --- ### policy\_isMacroBlockAt() > `readonly` **policy\_isMacroBlockAt**: (`a`) => `number` Defined in: @nimiq/core/types/wasm/web.d.ts:2940 #### Parameters ##### a `number` #### Returns `number` --- ### policy\_isMicroBlockAt() > `readonly` **policy\_isMicroBlockAt**: (`a`) => `number` Defined in: @nimiq/core/types/wasm/web.d.ts:2941 #### Parameters ##### a `number` #### Returns `number` --- ### policy\_lastBlockOfCollateralLockup() > `readonly` **policy\_lastBlockOfCollateralLockup**: (`a`) => `number` Defined in: @nimiq/core/types/wasm/web.d.ts:2942 #### Parameters ##### a `number` #### Returns `number` --- ### policy\_lastBlockOfEquivocationReportingWindow() > `readonly` **policy\_lastBlockOfEquivocationReportingWindow**: (`a`) => `number` Defined in: @nimiq/core/types/wasm/web.d.ts:2943 #### Parameters ##### a `number` #### Returns `number` --- ### policy\_lastBlockOfReportingWindow() > `readonly` **policy\_lastBlockOfReportingWindow**: (`a`) => `number` Defined in: @nimiq/core/types/wasm/web.d.ts:2970 #### Parameters ##### a `number` #### Returns `number` --- ### policy\_lastElectionBlock() > `readonly` **policy\_lastElectionBlock**: (`a`) => `number` Defined in: @nimiq/core/types/wasm/web.d.ts:2944 #### Parameters ##### a `number` #### Returns `number` --- ### policy\_lastMacroBlock() > `readonly` **policy\_lastMacroBlock**: (`a`) => `number` Defined in: @nimiq/core/types/wasm/web.d.ts:2945 #### Parameters ##### a `number` #### Returns `number` --- ### policy\_macroBlockAfter() > `readonly` **policy\_macroBlockAfter**: (`a`) => `number` Defined in: @nimiq/core/types/wasm/web.d.ts:2946 #### Parameters ##### a `number` #### Returns `number` --- ### policy\_macroBlockBefore() > `readonly` **policy\_macroBlockBefore**: (`a`) => `number` Defined in: @nimiq/core/types/wasm/web.d.ts:2947 #### Parameters ##### a `number` #### Returns `number` --- ### policy\_macroBlockOf() > `readonly` **policy\_macroBlockOf**: (`a`) => `number` Defined in: @nimiq/core/types/wasm/web.d.ts:2948 #### Parameters ##### a `number` #### Returns `number` --- ### policy\_max\_supported\_version() > `readonly` **policy\_max\_supported\_version**: () => `number` Defined in: @nimiq/core/types/wasm/web.d.ts:2949 #### Returns `number` --- ### policy\_state\_chunks\_max\_size() > `readonly` **policy\_state\_chunks\_max\_size**: () => `number` Defined in: @nimiq/core/types/wasm/web.d.ts:2950 #### Returns `number` --- ### policy\_supplyAt() > `readonly` **policy\_supplyAt**: (`a`, `b`, `c`) => `bigint` Defined in: @nimiq/core/types/wasm/web.d.ts:2951 #### Parameters ##### a `bigint` ##### b `bigint` ##### c `bigint` #### Returns `bigint` --- ### policy\_transaction\_validity\_window() > `readonly` **policy\_transaction\_validity\_window**: () => `number` Defined in: @nimiq/core/types/wasm/web.d.ts:2952 #### Returns `number` --- ### policy\_transaction\_validity\_window\_blocks() > `readonly` **policy\_transaction\_validity\_window\_blocks**: () => `number` Defined in: @nimiq/core/types/wasm/web.d.ts:2953 #### Returns `number` --- ### policy\_wasm\_block\_separation\_time() > `readonly` **policy\_wasm\_block\_separation\_time**: () => `bigint` Defined in: @nimiq/core/types/wasm/web.d.ts:2954 #### Returns `bigint` --- ### policy\_wasm\_bls\_cache\_max\_capacity() > `readonly` **policy\_wasm\_bls\_cache\_max\_capacity**: () => `number` Defined in: @nimiq/core/types/wasm/web.d.ts:2955 #### Returns `number` --- ### policy\_wasm\_coinbase\_address() > `readonly` **policy\_wasm\_coinbase\_address**: () => \[`number`, `number`] Defined in: @nimiq/core/types/wasm/web.d.ts:2956 #### Returns \[`number`, `number`] --- ### policy\_wasm\_f\_plus\_one() > `readonly` **policy\_wasm\_f\_plus\_one**: () => `number` Defined in: @nimiq/core/types/wasm/web.d.ts:2957 #### Returns `number` --- ### policy\_wasm\_history\_chunks\_max\_size() > `readonly` **policy\_wasm\_history\_chunks\_max\_size**: () => `bigint` Defined in: @nimiq/core/types/wasm/web.d.ts:2958 #### Returns `bigint` --- ### policy\_wasm\_jail\_epochs() > `readonly` **policy\_wasm\_jail\_epochs**: () => `number` Defined in: @nimiq/core/types/wasm/web.d.ts:2959 #### Returns `number` --- ### policy\_wasm\_max\_size\_micro\_body() > `readonly` **policy\_wasm\_max\_size\_micro\_body**: () => `number` Defined in: @nimiq/core/types/wasm/web.d.ts:2960 #### Returns `number` --- ### policy\_wasm\_min\_block\_producer\_timeout() > `readonly` **policy\_wasm\_min\_block\_producer\_timeout**: () => `bigint` Defined in: @nimiq/core/types/wasm/web.d.ts:2961 #### Returns `bigint` --- ### policy\_wasm\_min\_epochs\_stored() > `readonly` **policy\_wasm\_min\_epochs\_stored**: () => `number` Defined in: @nimiq/core/types/wasm/web.d.ts:2962 #### Returns `number` --- ### policy\_wasm\_minimum\_rewards\_percentage() > `readonly` **policy\_wasm\_minimum\_rewards\_percentage**: () => `number` Defined in: @nimiq/core/types/wasm/web.d.ts:2963 #### Returns `number` --- ### policy\_wasm\_slots() > `readonly` **policy\_wasm\_slots**: () => `number` Defined in: @nimiq/core/types/wasm/web.d.ts:2964 #### Returns `number` --- ### policy\_wasm\_staking\_contract\_address() > `readonly` **policy\_wasm\_staking\_contract\_address**: () => \[`number`, `number`] Defined in: @nimiq/core/types/wasm/web.d.ts:2965 #### Returns \[`number`, `number`] --- ### policy\_wasm\_timestamp\_max\_drift() > `readonly` **policy\_wasm\_timestamp\_max\_drift**: () => `bigint` Defined in: @nimiq/core/types/wasm/web.d.ts:2966 #### Returns `bigint` --- ### policy\_wasm\_total\_supply() > `readonly` **policy\_wasm\_total\_supply**: () => `bigint` Defined in: @nimiq/core/types/wasm/web.d.ts:2967 #### Returns `bigint` --- ### policy\_wasm\_two\_f\_plus\_one() > `readonly` **policy\_wasm\_two\_f\_plus\_one**: () => `number` Defined in: @nimiq/core/types/wasm/web.d.ts:2968 #### Returns `number` --- ### policy\_wasm\_validator\_deposit() > `readonly` **policy\_wasm\_validator\_deposit**: () => `bigint` Defined in: @nimiq/core/types/wasm/web.d.ts:2969 #### Returns `bigint` --- ### privatekey\_deserialize() > `readonly` **privatekey\_deserialize**: (`a`, `b`) => \[`number`, `number`, `number`] Defined in: @nimiq/core/types/wasm/web.d.ts:2886 #### Parameters ##### a `number` ##### b `number` #### Returns \[`number`, `number`, `number`] --- ### privatekey\_equals() > `readonly` **privatekey\_equals**: (`a`, `b`) => `number` Defined in: @nimiq/core/types/wasm/web.d.ts:2887 #### Parameters ##### a `number` ##### b `number` #### Returns `number` --- ### privatekey\_fromHex() > `readonly` **privatekey\_fromHex**: (`a`, `b`) => \[`number`, `number`, `number`] Defined in: @nimiq/core/types/wasm/web.d.ts:2888 #### Parameters ##### a `number` ##### b `number` #### Returns \[`number`, `number`, `number`] --- ### privatekey\_generate() > `readonly` **privatekey\_generate**: () => `number` Defined in: @nimiq/core/types/wasm/web.d.ts:2889 #### Returns `number` --- ### privatekey\_new() > `readonly` **privatekey\_new**: (`a`, `b`) => \[`number`, `number`, `number`] Defined in: @nimiq/core/types/wasm/web.d.ts:2890 #### Parameters ##### a `number` ##### b `number` #### Returns \[`number`, `number`, `number`] --- ### privatekey\_purpose\_id() > `readonly` **privatekey\_purpose\_id**: () => `number` Defined in: @nimiq/core/types/wasm/web.d.ts:2891 #### Returns `number` --- ### privatekey\_serialize() > `readonly` **privatekey\_serialize**: (`a`) => \[`number`, `number`] Defined in: @nimiq/core/types/wasm/web.d.ts:2892 #### Parameters ##### a `number` #### Returns \[`number`, `number`] --- ### privatekey\_serialized\_size() > `readonly` **privatekey\_serialized\_size**: (`a`) => `number` Defined in: @nimiq/core/types/wasm/web.d.ts:2893 #### Parameters ##### a `number` #### Returns `number` --- ### privatekey\_size() > `readonly` **privatekey\_size**: () => `number` Defined in: @nimiq/core/types/wasm/web.d.ts:2920 #### Returns `number` --- ### privatekey\_toHex() > `readonly` **privatekey\_toHex**: (`a`) => \[`number`, `number`] Defined in: @nimiq/core/types/wasm/web.d.ts:2894 #### Parameters ##### a `number` #### Returns \[`number`, `number`] --- ### publickey\_\_\_getClassname() > `readonly` **publickey\_\_\_getClassname**: (`a`) => \[`number`, `number`] Defined in: @nimiq/core/types/wasm/web.d.ts:2895 #### Parameters ##### a `number` #### Returns \[`number`, `number`] --- ### publickey\_combinations() > `readonly` **publickey\_combinations**: (`a`, `b`) => \[`number`, `number`, `number`, `number`] Defined in: @nimiq/core/types/wasm/web.d.ts:2896 #### Parameters ##### a `any` ##### b `number` #### Returns \[`number`, `number`, `number`, `number`] --- ### publickey\_compare() > `readonly` **publickey\_compare**: (`a`, `b`) => `number` Defined in: @nimiq/core/types/wasm/web.d.ts:2897 #### Parameters ##### a `number` ##### b `number` #### Returns `number` --- ### publickey\_derive() > `readonly` **publickey\_derive**: (`a`) => `number` Defined in: @nimiq/core/types/wasm/web.d.ts:2898 #### Parameters ##### a `number` #### Returns `number` --- ### publickey\_deserialize() > `readonly` **publickey\_deserialize**: (`a`, `b`) => \[`number`, `number`, `number`] Defined in: @nimiq/core/types/wasm/web.d.ts:2899 #### Parameters ##### a `number` ##### b `number` #### Returns \[`number`, `number`, `number`] --- ### publickey\_equals() > `readonly` **publickey\_equals**: (`a`, `b`) => `number` Defined in: @nimiq/core/types/wasm/web.d.ts:2900 #### Parameters ##### a `number` ##### b `number` #### Returns `number` --- ### publickey\_fromAny() > `readonly` **publickey\_fromAny**: (`a`) => \[`number`, `number`, `number`] Defined in: @nimiq/core/types/wasm/web.d.ts:2901 #### Parameters ##### a `any` #### Returns \[`number`, `number`, `number`] --- ### publickey\_fromHex() > `readonly` **publickey\_fromHex**: (`a`, `b`) => \[`number`, `number`, `number`] Defined in: @nimiq/core/types/wasm/web.d.ts:2902 #### Parameters ##### a `number` ##### b `number` #### Returns \[`number`, `number`, `number`] --- ### publickey\_fromRaw() > `readonly` **publickey\_fromRaw**: (`a`, `b`) => \[`number`, `number`, `number`] Defined in: @nimiq/core/types/wasm/web.d.ts:2903 #### Parameters ##### a `number` ##### b `number` #### Returns \[`number`, `number`, `number`] --- ### publickey\_fromSpki() > `readonly` **publickey\_fromSpki**: (`a`, `b`) => \[`number`, `number`, `number`] Defined in: @nimiq/core/types/wasm/web.d.ts:2904 #### Parameters ##### a `number` ##### b `number` #### Returns \[`number`, `number`, `number`] --- ### publickey\_new() > `readonly` **publickey\_new**: (`a`, `b`) => \[`number`, `number`, `number`] Defined in: @nimiq/core/types/wasm/web.d.ts:2905 #### Parameters ##### a `number` ##### b `number` #### Returns \[`number`, `number`, `number`] --- ### publickey\_serialize() > `readonly` **publickey\_serialize**: (`a`) => \[`number`, `number`] Defined in: @nimiq/core/types/wasm/web.d.ts:2906 #### Parameters ##### a `number` #### Returns \[`number`, `number`] --- ### publickey\_serialized\_size() > `readonly` **publickey\_serialized\_size**: (`a`) => `number` Defined in: @nimiq/core/types/wasm/web.d.ts:2907 #### Parameters ##### a `number` #### Returns `number` --- ### publickey\_size() > `readonly` **publickey\_size**: () => `number` Defined in: @nimiq/core/types/wasm/web.d.ts:2921 #### Returns `number` --- ### publickey\_sum() > `readonly` **publickey\_sum**: (`a`) => \[`number`, `number`, `number`] Defined in: @nimiq/core/types/wasm/web.d.ts:2908 #### Parameters ##### a `any` #### Returns \[`number`, `number`, `number`] --- ### publickey\_toAddress() > `readonly` **publickey\_toAddress**: (`a`) => `number` Defined in: @nimiq/core/types/wasm/web.d.ts:2909 #### Parameters ##### a `number` #### Returns `number` --- ### publickey\_toHex() > `readonly` **publickey\_toHex**: (`a`) => \[`number`, `number`] Defined in: @nimiq/core/types/wasm/web.d.ts:2910 #### Parameters ##### a `number` #### Returns \[`number`, `number`] --- ### publickey\_verify() > `readonly` **publickey\_verify**: (`a`, `b`, `c`, `d`) => `number` Defined in: @nimiq/core/types/wasm/web.d.ts:2911 #### Parameters ##### a `number` ##### b `number` ##### c `number` ##### d `number` #### Returns `number` --- ### randomsecret\_\_\_getClassname() > `readonly` **randomsecret\_\_\_getClassname**: (`a`) => \[`number`, `number`] Defined in: @nimiq/core/types/wasm/web.d.ts:2680 #### Parameters ##### a `number` #### Returns \[`number`, `number`] --- ### randomsecret\_deserialize() > `readonly` **randomsecret\_deserialize**: (`a`, `b`) => \[`number`, `number`, `number`] Defined in: @nimiq/core/types/wasm/web.d.ts:2681 #### Parameters ##### a `number` ##### b `number` #### Returns \[`number`, `number`, `number`] --- ### randomsecret\_equals() > `readonly` **randomsecret\_equals**: (`a`, `b`) => `number` Defined in: @nimiq/core/types/wasm/web.d.ts:2682 #### Parameters ##### a `number` ##### b `number` #### Returns `number` --- ### randomsecret\_fromAny() > `readonly` **randomsecret\_fromAny**: (`a`) => \[`number`, `number`, `number`] Defined in: @nimiq/core/types/wasm/web.d.ts:2683 #### Parameters ##### a `any` #### Returns \[`number`, `number`, `number`] --- ### randomsecret\_fromHex() > `readonly` **randomsecret\_fromHex**: (`a`, `b`) => \[`number`, `number`, `number`] Defined in: @nimiq/core/types/wasm/web.d.ts:2684 #### Parameters ##### a `number` ##### b `number` #### Returns \[`number`, `number`, `number`] --- ### randomsecret\_new() > `readonly` **randomsecret\_new**: (`a`, `b`) => \[`number`, `number`, `number`] Defined in: @nimiq/core/types/wasm/web.d.ts:2685 #### Parameters ##### a `number` ##### b `number` #### Returns \[`number`, `number`, `number`] --- ### randomsecret\_serialize() > `readonly` **randomsecret\_serialize**: (`a`) => \[`number`, `number`] Defined in: @nimiq/core/types/wasm/web.d.ts:2686 #### Parameters ##### a `number` #### Returns \[`number`, `number`] --- ### randomsecret\_serialized\_size() > `readonly` **randomsecret\_serialized\_size**: (`a`) => `number` Defined in: @nimiq/core/types/wasm/web.d.ts:2687 #### Parameters ##### a `number` #### Returns `number` --- ### randomsecret\_size() > `readonly` **randomsecret\_size**: () => `number` Defined in: @nimiq/core/types/wasm/web.d.ts:2720 #### Returns `number` --- ### randomsecret\_toHex() > `readonly` **randomsecret\_toHex**: (`a`) => \[`number`, `number`] Defined in: @nimiq/core/types/wasm/web.d.ts:2688 #### Parameters ##### a `number` #### Returns \[`number`, `number`] --- ### signature\_\_\_getClassname() > `readonly` **signature\_\_\_getClassname**: (`a`) => \[`number`, `number`] Defined in: @nimiq/core/types/wasm/web.d.ts:2912 #### Parameters ##### a `number` #### Returns \[`number`, `number`] --- ### signature\_create() > `readonly` **signature\_create**: (`a`, `b`, `c`, `d`) => `number` Defined in: @nimiq/core/types/wasm/web.d.ts:2913 #### Parameters ##### a `number` ##### b `number` ##### c `number` ##### d `number` #### Returns `number` --- ### signature\_deserialize() > `readonly` **signature\_deserialize**: (`a`, `b`) => \[`number`, `number`, `number`] Defined in: @nimiq/core/types/wasm/web.d.ts:2914 #### Parameters ##### a `number` ##### b `number` #### Returns \[`number`, `number`, `number`] --- ### signature\_fromAsn1() > `readonly` **signature\_fromAsn1**: (`a`, `b`) => \[`number`, `number`, `number`] Defined in: @nimiq/core/types/wasm/web.d.ts:2915 #### Parameters ##### a `number` ##### b `number` #### Returns \[`number`, `number`, `number`] --- ### signature\_fromHex() > `readonly` **signature\_fromHex**: (`a`, `b`) => \[`number`, `number`, `number`] Defined in: @nimiq/core/types/wasm/web.d.ts:2916 #### Parameters ##### a `number` ##### b `number` #### Returns \[`number`, `number`, `number`] --- ### signature\_serialize() > `readonly` **signature\_serialize**: (`a`) => \[`number`, `number`] Defined in: @nimiq/core/types/wasm/web.d.ts:2917 #### Parameters ##### a `number` #### Returns \[`number`, `number`] --- ### signature\_toHex() > `readonly` **signature\_toHex**: (`a`) => \[`number`, `number`] Defined in: @nimiq/core/types/wasm/web.d.ts:2918 #### Parameters ##### a `number` #### Returns \[`number`, `number`] --- ### signatureproof\_deserialize() > `readonly` **signatureproof\_deserialize**: (`a`, `b`) => \[`number`, `number`, `number`] Defined in: @nimiq/core/types/wasm/web.d.ts:2746 #### Parameters ##### a `number` ##### b `number` #### Returns \[`number`, `number`, `number`] --- ### signatureproof\_es256\_single\_sig\_size() > `readonly` **signatureproof\_es256\_single\_sig\_size**: () => `number` Defined in: @nimiq/core/types/wasm/web.d.ts:2747 #### Returns `number` --- ### signatureproof\_isSignedBy() > `readonly` **signatureproof\_isSignedBy**: (`a`, `b`) => `number` Defined in: @nimiq/core/types/wasm/web.d.ts:2748 #### Parameters ##### a `number` ##### b `number` #### Returns `number` --- ### signatureproof\_merklePath() > `readonly` **signatureproof\_merklePath**: (`a`) => `number` Defined in: @nimiq/core/types/wasm/web.d.ts:2749 #### Parameters ##### a `number` #### Returns `number` --- ### signatureproof\_multiSig() > `readonly` **signatureproof\_multiSig**: (`a`, `b`, `c`) => \[`number`, `number`, `number`] Defined in: @nimiq/core/types/wasm/web.d.ts:2750 #### Parameters ##### a `number` ##### b `any` ##### c `number` #### Returns \[`number`, `number`, `number`] --- ### signatureproof\_publicKey() > `readonly` **signatureproof\_publicKey**: (`a`) => `any` Defined in: @nimiq/core/types/wasm/web.d.ts:2751 #### Parameters ##### a `number` #### Returns `any` --- ### signatureproof\_serialize() > `readonly` **signatureproof\_serialize**: (`a`) => \[`number`, `number`] Defined in: @nimiq/core/types/wasm/web.d.ts:2752 #### Parameters ##### a `number` #### Returns \[`number`, `number`] --- ### signatureproof\_signature() > `readonly` **signatureproof\_signature**: (`a`) => `any` Defined in: @nimiq/core/types/wasm/web.d.ts:2753 #### Parameters ##### a `number` #### Returns `any` --- ### signatureproof\_single\_sig\_size() > `readonly` **signatureproof\_single\_sig\_size**: () => `number` Defined in: @nimiq/core/types/wasm/web.d.ts:2755 #### Returns `number` --- ### signatureproof\_singleSig() > `readonly` **signatureproof\_singleSig**: (`a`, `b`) => `number` Defined in: @nimiq/core/types/wasm/web.d.ts:2754 #### Parameters ##### a `number` ##### b `number` #### Returns `number` --- ### signatureproof\_toPlain() > `readonly` **signatureproof\_toPlain**: (`a`) => \[`number`, `number`, `number`] Defined in: @nimiq/core/types/wasm/web.d.ts:2756 #### Parameters ##### a `number` #### Returns \[`number`, `number`, `number`] --- ### signatureproof\_verify() > `readonly` **signatureproof\_verify**: (`a`, `b`, `c`) => `number` Defined in: @nimiq/core/types/wasm/web.d.ts:2757 #### Parameters ##### a `number` ##### b `number` ##### c `number` #### Returns `number` --- ### signatureproof\_webauthnMultiSig() > `readonly` **signatureproof\_webauthnMultiSig**: (`a`, `b`, `c`, `d`, `e`, `f`, `g`) => \[`number`, `number`, `number`] Defined in: @nimiq/core/types/wasm/web.d.ts:2758 #### Parameters ##### a `any` ##### b `any` ##### c `any` ##### d `number` ##### e `number` ##### f `number` ##### g `number` #### Returns \[`number`, `number`, `number`] --- ### signatureproof\_webauthnSingleSig() > `readonly` **signatureproof\_webauthnSingleSig**: (`a`, `b`, `c`, `d`, `e`, `f`) => \[`number`, `number`, `number`] Defined in: @nimiq/core/types/wasm/web.d.ts:2759 #### Parameters ##### a `any` ##### b `any` ##### c `number` ##### d `number` ##### e `number` ##### f `number` #### Returns \[`number`, `number`, `number`] --- ### stakingcontract\_dataToPlain() > `readonly` **stakingcontract\_dataToPlain**: (`a`, `b`) => \[`number`, `number`, `number`] Defined in: @nimiq/core/types/wasm/web.d.ts:2760 #### Parameters ##### a `number` ##### b `number` #### Returns \[`number`, `number`, `number`] --- ### stakingcontract\_proofToPlain() > `readonly` **stakingcontract\_proofToPlain**: (`a`, `b`) => \[`number`, `number`, `number`] Defined in: @nimiq/core/types/wasm/web.d.ts:2761 #### Parameters ##### a `number` ##### b `number` #### Returns \[`number`, `number`, `number`] --- ### stakingdatabuilder\_addStake() > `readonly` **stakingdatabuilder\_addStake**: (`a`) => \[`number`, `number`] Defined in: @nimiq/core/types/wasm/web.d.ts:2766 #### Parameters ##### a `number` #### Returns \[`number`, `number`] --- ### stakingdatabuilder\_createStaker() > `readonly` **stakingdatabuilder\_createStaker**: (`a`) => \[`number`, `number`, `number`, `number`] Defined in: @nimiq/core/types/wasm/web.d.ts:2767 #### Parameters ##### a `any` #### Returns \[`number`, `number`, `number`, `number`] --- ### stakingdatabuilder\_removeStake() > `readonly` **stakingdatabuilder\_removeStake**: () => \[`number`, `number`] Defined in: @nimiq/core/types/wasm/web.d.ts:2768 #### Returns \[`number`, `number`] --- ### stakingdatabuilder\_retireStake() > `readonly` **stakingdatabuilder\_retireStake**: (`a`) => \[`number`, `number`, `number`, `number`] Defined in: @nimiq/core/types/wasm/web.d.ts:2769 #### Parameters ##### a `bigint` #### Returns \[`number`, `number`, `number`, `number`] --- ### stakingdatabuilder\_setActiveStake() > `readonly` **stakingdatabuilder\_setActiveStake**: (`a`) => \[`number`, `number`, `number`, `number`] Defined in: @nimiq/core/types/wasm/web.d.ts:2770 #### Parameters ##### a `bigint` #### Returns \[`number`, `number`, `number`, `number`] --- ### stakingdatabuilder\_setProof() > `readonly` **stakingdatabuilder\_setProof**: (`a`, `b`, `c`) => \[`number`, `number`, `number`, `number`] Defined in: @nimiq/core/types/wasm/web.d.ts:2771 #### Parameters ##### a `number` ##### b `number` ##### c `number` #### Returns \[`number`, `number`, `number`, `number`] --- ### stakingdatabuilder\_updateStaker() > `readonly` **stakingdatabuilder\_updateStaker**: (`a`, `b`) => \[`number`, `number`, `number`, `number`] Defined in: @nimiq/core/types/wasm/web.d.ts:2772 #### Parameters ##### a `any` ##### b `number` #### Returns \[`number`, `number`, `number`, `number`] --- ### transaction\_\_\_getClassname() > `readonly` **transaction\_\_\_getClassname**: (`a`) => \[`number`, `number`] Defined in: @nimiq/core/types/wasm/web.d.ts:2689 #### Parameters ##### a `number` #### Returns \[`number`, `number`] --- ### transaction\_data() > `readonly` **transaction\_data**: (`a`) => \[`number`, `number`] Defined in: @nimiq/core/types/wasm/web.d.ts:2690 #### Parameters ##### a `number` #### Returns \[`number`, `number`] --- ### transaction\_deserialize() > `readonly` **transaction\_deserialize**: (`a`, `b`) => \[`number`, `number`, `number`] Defined in: @nimiq/core/types/wasm/web.d.ts:2691 #### Parameters ##### a `number` ##### b `number` #### Returns \[`number`, `number`, `number`] --- ### transaction\_fee() > `readonly` **transaction\_fee**: (`a`) => `bigint` Defined in: @nimiq/core/types/wasm/web.d.ts:2692 #### Parameters ##### a `number` #### Returns `bigint` --- ### transaction\_feePerByte() > `readonly` **transaction\_feePerByte**: (`a`) => `number` Defined in: @nimiq/core/types/wasm/web.d.ts:2693 #### Parameters ##### a `number` #### Returns `number` --- ### transaction\_flags() > `readonly` **transaction\_flags**: (`a`) => `number` Defined in: @nimiq/core/types/wasm/web.d.ts:2694 #### Parameters ##### a `number` #### Returns `number` --- ### transaction\_format() > `readonly` **transaction\_format**: (`a`) => `number` Defined in: @nimiq/core/types/wasm/web.d.ts:2695 #### Parameters ##### a `number` #### Returns `number` --- ### transaction\_fromAny() > `readonly` **transaction\_fromAny**: (`a`) => \[`number`, `number`, `number`] Defined in: @nimiq/core/types/wasm/web.d.ts:2696 #### Parameters ##### a `any` #### Returns \[`number`, `number`, `number`] --- ### transaction\_fromPlain() > `readonly` **transaction\_fromPlain**: (`a`) => \[`number`, `number`, `number`] Defined in: @nimiq/core/types/wasm/web.d.ts:2697 #### Parameters ##### a `any` #### Returns \[`number`, `number`, `number`] --- ### transaction\_getContractCreationAddress() > `readonly` **transaction\_getContractCreationAddress**: (`a`) => `number` Defined in: @nimiq/core/types/wasm/web.d.ts:2698 #### Parameters ##### a `number` #### Returns `number` --- ### transaction\_hash() > `readonly` **transaction\_hash**: (`a`) => \[`number`, `number`] Defined in: @nimiq/core/types/wasm/web.d.ts:2699 #### Parameters ##### a `number` #### Returns \[`number`, `number`] --- ### transaction\_isValidAt() > `readonly` **transaction\_isValidAt**: (`a`, `b`) => `number` Defined in: @nimiq/core/types/wasm/web.d.ts:2700 #### Parameters ##### a `number` ##### b `number` #### Returns `number` --- ### transaction\_networkId() > `readonly` **transaction\_networkId**: (`a`) => `number` Defined in: @nimiq/core/types/wasm/web.d.ts:2701 #### Parameters ##### a `number` #### Returns `number` --- ### transaction\_new() > `readonly` **transaction\_new**: (`a`, `b`, `c`, `d`, `e`, `f`, `g`, `h`, `i`, `j`, `k`, `l`, `m`) => \[`number`, `number`, `number`] Defined in: @nimiq/core/types/wasm/web.d.ts:2702 #### Parameters ##### a `number` ##### b `number` ##### c `number` ##### d `number` ##### e `number` ##### f `number` ##### g `number` ##### h `number` ##### i `bigint` ##### j `bigint` ##### k `number` ##### l `number` ##### m `number` #### Returns \[`number`, `number`, `number`] --- ### transaction\_proof() > `readonly` **transaction\_proof**: (`a`) => \[`number`, `number`] Defined in: @nimiq/core/types/wasm/web.d.ts:2703 #### Parameters ##### a `number` #### Returns \[`number`, `number`] --- ### transaction\_recipient() > `readonly` **transaction\_recipient**: (`a`) => `number` Defined in: @nimiq/core/types/wasm/web.d.ts:2704 #### Parameters ##### a `number` #### Returns `number` --- ### transaction\_recipientType() > `readonly` **transaction\_recipientType**: (`a`) => `number` Defined in: @nimiq/core/types/wasm/web.d.ts:2705 #### Parameters ##### a `number` #### Returns `number` --- ### transaction\_sender() > `readonly` **transaction\_sender**: (`a`) => `number` Defined in: @nimiq/core/types/wasm/web.d.ts:2706 #### Parameters ##### a `number` #### Returns `number` --- ### transaction\_senderData() > `readonly` **transaction\_senderData**: (`a`) => \[`number`, `number`] Defined in: @nimiq/core/types/wasm/web.d.ts:2707 #### Parameters ##### a `number` #### Returns \[`number`, `number`] --- ### transaction\_senderType() > `readonly` **transaction\_senderType**: (`a`) => `number` Defined in: @nimiq/core/types/wasm/web.d.ts:2708 #### Parameters ##### a `number` #### Returns `number` --- ### transaction\_serialize() > `readonly` **transaction\_serialize**: (`a`) => \[`number`, `number`] Defined in: @nimiq/core/types/wasm/web.d.ts:2709 #### Parameters ##### a `number` #### Returns \[`number`, `number`] --- ### transaction\_serializeContent() > `readonly` **transaction\_serializeContent**: (`a`) => \[`number`, `number`] Defined in: @nimiq/core/types/wasm/web.d.ts:2710 #### Parameters ##### a `number` #### Returns \[`number`, `number`] --- ### transaction\_serializedSize() > `readonly` **transaction\_serializedSize**: (`a`) => `number` Defined in: @nimiq/core/types/wasm/web.d.ts:2711 #### Parameters ##### a `number` #### Returns `number` --- ### transaction\_set\_data() > `readonly` **transaction\_set\_data**: (`a`, `b`, `c`) => `void` Defined in: @nimiq/core/types/wasm/web.d.ts:2712 #### Parameters ##### a `number` ##### b `number` ##### c `number` #### Returns `void` --- ### transaction\_set\_proof() > `readonly` **transaction\_set\_proof**: (`a`, `b`, `c`) => `void` Defined in: @nimiq/core/types/wasm/web.d.ts:2713 #### Parameters ##### a `number` ##### b `number` ##### c `number` #### Returns `void` --- ### transaction\_sign() > `readonly` **transaction\_sign**: (`a`, `b`, `c`) => \[`number`, `number`] Defined in: @nimiq/core/types/wasm/web.d.ts:2714 #### Parameters ##### a `number` ##### b `number` ##### c `any` #### Returns \[`number`, `number`] --- ### transaction\_toHex() > `readonly` **transaction\_toHex**: (`a`) => \[`number`, `number`] Defined in: @nimiq/core/types/wasm/web.d.ts:2715 #### Parameters ##### a `number` #### Returns \[`number`, `number`] --- ### transaction\_toPlain() > `readonly` **transaction\_toPlain**: (`a`, `b`, `c`, `d`) => \[`number`, `number`, `number`] Defined in: @nimiq/core/types/wasm/web.d.ts:2716 #### Parameters ##### a `number` ##### b `number` ##### c `number` ##### d `bigint` #### Returns \[`number`, `number`, `number`] --- ### transaction\_validityStartHeight() > `readonly` **transaction\_validityStartHeight**: (`a`) => `number` Defined in: @nimiq/core/types/wasm/web.d.ts:2717 #### Parameters ##### a `number` #### Returns `number` --- ### transaction\_value() > `readonly` **transaction\_value**: (`a`) => `bigint` Defined in: @nimiq/core/types/wasm/web.d.ts:2718 #### Parameters ##### a `number` #### Returns `bigint` --- ### transaction\_verify() > `readonly` **transaction\_verify**: (`a`, `b`, `c`) => \[`number`, `number`] Defined in: @nimiq/core/types/wasm/web.d.ts:2719 #### Parameters ##### a `number` ##### b `number` ##### c `number` #### Returns \[`number`, `number`] --- ### transactionbuilder\_newAddStake() > `readonly` **transactionbuilder\_newAddStake**: (`a`, `b`, `c`, `d`, `e`, `f`, `g`) => \[`number`, `number`, `number`] Defined in: @nimiq/core/types/wasm/web.d.ts:2773 #### Parameters ##### a `number` ##### b `number` ##### c `bigint` ##### d `number` ##### e `bigint` ##### f `number` ##### g `number` #### Returns \[`number`, `number`, `number`] --- ### transactionbuilder\_newBasic() > `readonly` **transactionbuilder\_newBasic**: (`a`, `b`, `c`, `d`, `e`, `f`, `g`) => \[`number`, `number`, `number`] Defined in: @nimiq/core/types/wasm/web.d.ts:2774 #### Parameters ##### a `number` ##### b `number` ##### c `bigint` ##### d `number` ##### e `bigint` ##### f `number` ##### g `number` #### Returns \[`number`, `number`, `number`] --- ### transactionbuilder\_newBasicWithData() > `readonly` **transactionbuilder\_newBasicWithData**: (`a`, `b`, `c`, `d`, `e`, `f`, `g`, `h`, `i`) => \[`number`, `number`, `number`] Defined in: @nimiq/core/types/wasm/web.d.ts:2775 #### Parameters ##### a `number` ##### b `number` ##### c `number` ##### d `number` ##### e `bigint` ##### f `number` ##### g `bigint` ##### h `number` ##### i `number` #### Returns \[`number`, `number`, `number`] --- ### transactionbuilder\_newCreateStaker() > `readonly` **transactionbuilder\_newCreateStaker**: (`a`, `b`, `c`, `d`, `e`, `f`, `g`) => \[`number`, `number`, `number`] Defined in: @nimiq/core/types/wasm/web.d.ts:2776 #### Parameters ##### a `number` ##### b `any` ##### c `bigint` ##### d `number` ##### e `bigint` ##### f `number` ##### g `number` #### Returns \[`number`, `number`, `number`] --- ### transactionbuilder\_newCreateValidator() > `readonly` **transactionbuilder\_newCreateValidator**: (`a`, `b`, `c`, `d`, `e`, `f`, `g`, `h`, `i`, `j`) => \[`number`, `number`, `number`] Defined in: @nimiq/core/types/wasm/web.d.ts:2777 #### Parameters ##### a `number` ##### b `number` ##### c `number` ##### d `number` ##### e `number` ##### f `number` ##### g `number` ##### h `bigint` ##### i `number` ##### j `number` #### Returns \[`number`, `number`, `number`] --- ### transactionbuilder\_newDeactivateValidator() > `readonly` **transactionbuilder\_newDeactivateValidator**: (`a`, `b`, `c`, `d`, `e`, `f`) => \[`number`, `number`, `number`] Defined in: @nimiq/core/types/wasm/web.d.ts:2778 #### Parameters ##### a `number` ##### b `number` ##### c `number` ##### d `bigint` ##### e `number` ##### f `number` #### Returns \[`number`, `number`, `number`] --- ### transactionbuilder\_newDeleteValidator() > `readonly` **transactionbuilder\_newDeleteValidator**: (`a`, `b`, `c`, `d`, `e`) => \[`number`, `number`, `number`] Defined in: @nimiq/core/types/wasm/web.d.ts:2779 #### Parameters ##### a `number` ##### b `number` ##### c `bigint` ##### d `number` ##### e `number` #### Returns \[`number`, `number`, `number`] --- ### transactionbuilder\_newRemoveStake() > `readonly` **transactionbuilder\_newRemoveStake**: (`a`, `b`, `c`, `d`, `e`, `f`) => \[`number`, `number`, `number`] Defined in: @nimiq/core/types/wasm/web.d.ts:2780 #### Parameters ##### a `number` ##### b `bigint` ##### c `number` ##### d `bigint` ##### e `number` ##### f `number` #### Returns \[`number`, `number`, `number`] --- ### transactionbuilder\_newRetireStake() > `readonly` **transactionbuilder\_newRetireStake**: (`a`, `b`, `c`, `d`, `e`, `f`) => \[`number`, `number`, `number`] Defined in: @nimiq/core/types/wasm/web.d.ts:2781 #### Parameters ##### a `number` ##### b `bigint` ##### c `number` ##### d `bigint` ##### e `number` ##### f `number` #### Returns \[`number`, `number`, `number`] --- ### transactionbuilder\_newRetireValidator() > `readonly` **transactionbuilder\_newRetireValidator**: (`a`, `b`, `c`, `d`, `e`) => \[`number`, `number`, `number`] Defined in: @nimiq/core/types/wasm/web.d.ts:2782 #### Parameters ##### a `number` ##### b `number` ##### c `bigint` ##### d `number` ##### e `number` #### Returns \[`number`, `number`, `number`] --- ### transactionbuilder\_newSetActiveStake() > `readonly` **transactionbuilder\_newSetActiveStake**: (`a`, `b`, `c`, `d`, `e`, `f`) => \[`number`, `number`, `number`] Defined in: @nimiq/core/types/wasm/web.d.ts:2783 #### Parameters ##### a `number` ##### b `bigint` ##### c `number` ##### d `bigint` ##### e `number` ##### f `number` #### Returns \[`number`, `number`, `number`] --- ### transactionbuilder\_newSetSignalData() > `readonly` **transactionbuilder\_newSetSignalData**: (`a`, `b`, `c`, `d`, `e`, `f`, `g`, `h`) => \[`number`, `number`, `number`] Defined in: @nimiq/core/types/wasm/web.d.ts:2784 #### Parameters ##### a `number` ##### b `number` ##### c `number` ##### d `number` ##### e `number` ##### f `bigint` ##### g `number` ##### h `number` #### Returns \[`number`, `number`, `number`] --- ### transactionbuilder\_newSignalVersion() > `readonly` **transactionbuilder\_newSignalVersion**: (`a`, `b`, `c`, `d`, `e`, `f`, `g`) => \[`number`, `number`, `number`] Defined in: @nimiq/core/types/wasm/web.d.ts:2785 #### Parameters ##### a `number` ##### b `number` ##### c `number` ##### d `number` ##### e `bigint` ##### f `number` ##### g `number` #### Returns \[`number`, `number`, `number`] --- ### transactionbuilder\_newUpdateStaker() > `readonly` **transactionbuilder\_newUpdateStaker**: (`a`, `b`, `c`, `d`, `e`, `f`, `g`) => \[`number`, `number`, `number`] Defined in: @nimiq/core/types/wasm/web.d.ts:2786 #### Parameters ##### a `number` ##### b `any` ##### c `number` ##### d `number` ##### e `bigint` ##### f `number` ##### g `number` #### Returns \[`number`, `number`, `number`] --- ### transactionbuilder\_newUpdateValidator() > `readonly` **transactionbuilder\_newUpdateValidator**: (`a`, `b`, `c`, `d`, `e`, `f`, `g`, `h`, `i`, `j`) => \[`number`, `number`, `number`] Defined in: @nimiq/core/types/wasm/web.d.ts:2787 #### Parameters ##### a `number` ##### b `number` ##### c `number` ##### d `number` ##### e `number` ##### f `number` ##### g `number` ##### h `bigint` ##### i `number` ##### j `number` #### Returns \[`number`, `number`, `number`] --- ### vestingcontract\_dataToPlain() > `readonly` **vestingcontract\_dataToPlain**: (`a`, `b`, `c`) => \[`number`, `number`, `number`] Defined in: @nimiq/core/types/wasm/web.d.ts:2762 #### Parameters ##### a `number` ##### b `number` ##### c `bigint` #### Returns \[`number`, `number`, `number`] --- ### vestingcontract\_proofToPlain() > `readonly` **vestingcontract\_proofToPlain**: (`a`, `b`) => \[`number`, `number`, `number`] Defined in: @nimiq/core/types/wasm/web.d.ts:2763 #### Parameters ##### a `number` ##### b `number` #### Returns \[`number`, `number`, `number`] --- ### wasm\_bindgen\_a0408da6add7f64d\_\_\_convert\_\_closures\_\_\_\_\_invoke\_\_\_\_\_\_\_true\_() > `readonly` **wasm\_bindgen\_a0408da6add7f64d\_\_\_convert\_\_closures\_\_\_\_\_invoke\_\_\_\_\_\_\_true\_**: (`a`, `b`) => `void` Defined in: @nimiq/core/types/wasm/web.d.ts:2981 #### Parameters ##### a `number` ##### b `number` #### Returns `void` --- ### wasm\_bindgen\_a0408da6add7f64d\_\_\_convert\_\_closures\_\_\_\_\_invoke\_\_\_\_\_\_\_true\_\_1\_() > `readonly` **wasm\_bindgen\_a0408da6add7f64d\_\_\_convert\_\_closures\_\_\_\_\_invoke\_\_\_\_\_\_\_true\_\_1\_**: (`a`, `b`) => `void` Defined in: @nimiq/core/types/wasm/web.d.ts:2982 #### Parameters ##### a `number` ##### b `number` #### Returns `void` --- ### wasm\_bindgen\_a0408da6add7f64d\_\_\_convert\_\_closures\_\_\_\_\_invoke\_\_\_js\_sys\_5d668e9e39567d65\_\_\_Function\_fn\_wasm\_bindgen\_a0408da6add7f64d\_\_\_JsValue\_\_\_\_\_wasm\_bindgen\_a0408da6add7f64d\_\_\_sys\_\_Undefined\_\_\_js\_sys\_5d668e9e39567d65\_\_\_Function\_fn\_wasm\_bindgen\_a0408da6add7f64d\_\_\_JsValue\_\_\_\_\_wasm\_bindgen\_a0408da6add7f64d\_\_\_sys\_\_Undefined\_\_\_\_\_\_\_true\_() > `readonly` **wasm\_bindgen\_a0408da6add7f64d\_\_\_convert\_\_closures\_\_\_\_\_invoke\_\_\_js\_sys\_5d668e9e39567d65\_\_\_Function\_fn\_wasm\_bindgen\_a0408da6add7f64d\_\_\_JsValue\_\_\_\_\_wasm\_bindgen\_a0408da6add7f64d\_\_\_sys\_\_Undefined\_\_\_js\_sys\_5d668e9e39567d65\_\_\_Function\_fn\_wasm\_bindgen\_a0408da6add7f64d\_\_\_JsValue\_\_\_\_\_wasm\_bindgen\_a0408da6add7f64d\_\_\_sys\_\_Undefined\_\_\_\_\_\_\_true\_**: (`a`, `b`, `c`, `d`) => `void` Defined in: @nimiq/core/types/wasm/web.d.ts:2974 #### Parameters ##### a `number` ##### b `number` ##### c `any` ##### d `any` #### Returns `void` --- ### wasm\_bindgen\_a0408da6add7f64d\_\_\_convert\_\_closures\_\_\_\_\_invoke\_\_\_wasm\_bindgen\_a0408da6add7f64d\_\_\_JsValue\_\_core\_f0fd674eaa06beef\_\_\_result\_\_Result\_\_\_\_\_wasm\_bindgen\_a0408da6add7f64d\_\_\_JsError\_\_\_true\_() > `readonly` **wasm\_bindgen\_a0408da6add7f64d\_\_\_convert\_\_closures\_\_\_\_\_invoke\_\_\_wasm\_bindgen\_a0408da6add7f64d\_\_\_JsValue\_\_core\_f0fd674eaa06beef\_\_\_result\_\_Result\_\_\_\_\_wasm\_bindgen\_a0408da6add7f64d\_\_\_JsError\_\_\_true\_**: (`a`, `b`, `c`) => \[`number`, `number`] Defined in: @nimiq/core/types/wasm/web.d.ts:2973 #### Parameters ##### a `number` ##### b `number` ##### c `any` #### Returns \[`number`, `number`] --- ### wasm\_bindgen\_a0408da6add7f64d\_\_\_convert\_\_closures\_\_\_\_\_invoke\_\_\_web\_sys\_70e763fc3e04fece\_\_\_features\_\_gen\_CloseEvent\_\_CloseEvent\_\_\_\_\_\_true\_() > `readonly` **wasm\_bindgen\_a0408da6add7f64d\_\_\_convert\_\_closures\_\_\_\_\_invoke\_\_\_web\_sys\_70e763fc3e04fece\_\_\_features\_\_gen\_CloseEvent\_\_CloseEvent\_\_\_\_\_\_true\_**: (`a`, `b`, `c`) => `void` Defined in: @nimiq/core/types/wasm/web.d.ts:2975 #### Parameters ##### a `number` ##### b `number` ##### c `any` #### Returns `void` --- ### wasm\_bindgen\_a0408da6add7f64d\_\_\_convert\_\_closures\_\_\_\_\_invoke\_\_\_web\_sys\_70e763fc3e04fece\_\_\_features\_\_gen\_CloseEvent\_\_CloseEvent\_\_\_\_\_\_true\_\_2() > `readonly` **wasm\_bindgen\_a0408da6add7f64d\_\_\_convert\_\_closures\_\_\_\_\_invoke\_\_\_web\_sys\_70e763fc3e04fece\_\_\_features\_\_gen\_CloseEvent\_\_CloseEvent\_\_\_\_\_\_true\_\_2**: (`a`, `b`, `c`) => `void` Defined in: @nimiq/core/types/wasm/web.d.ts:2976 #### Parameters ##### a `number` ##### b `number` ##### c `any` #### Returns `void` --- ### wasm\_bindgen\_a0408da6add7f64d\_\_\_convert\_\_closures\_\_\_\_\_invoke\_\_\_web\_sys\_70e763fc3e04fece\_\_\_features\_\_gen\_CloseEvent\_\_CloseEvent\_\_\_\_\_\_true\_\_5() > `readonly` **wasm\_bindgen\_a0408da6add7f64d\_\_\_convert\_\_closures\_\_\_\_\_invoke\_\_\_web\_sys\_70e763fc3e04fece\_\_\_features\_\_gen\_CloseEvent\_\_CloseEvent\_\_\_\_\_\_true\_\_5**: (`a`, `b`, `c`) => `void` Defined in: @nimiq/core/types/wasm/web.d.ts:2979 #### Parameters ##### a `number` ##### b `number` ##### c `any` #### Returns `void` --- ### wasm\_bindgen\_a0408da6add7f64d\_\_\_convert\_\_closures\_\_\_\_\_invoke\_\_\_web\_sys\_70e763fc3e04fece\_\_\_features\_\_gen\_Event\_\_Event\_\_\_\_\_\_true\_() > `readonly` **wasm\_bindgen\_a0408da6add7f64d\_\_\_convert\_\_closures\_\_\_\_\_invoke\_\_\_web\_sys\_70e763fc3e04fece\_\_\_features\_\_gen\_Event\_\_Event\_\_\_\_\_\_true\_**: (`a`, `b`, `c`) => `void` Defined in: @nimiq/core/types/wasm/web.d.ts:2977 #### Parameters ##### a `number` ##### b `number` ##### c `any` #### Returns `void` --- ### wasm\_bindgen\_a0408da6add7f64d\_\_\_convert\_\_closures\_\_\_\_\_invoke\_\_\_web\_sys\_70e763fc3e04fece\_\_\_features\_\_gen\_IdbVersionChangeEvent\_\_IdbVersionChangeEvent\_\_\_\_\_\_true\_() > `readonly` **wasm\_bindgen\_a0408da6add7f64d\_\_\_convert\_\_closures\_\_\_\_\_invoke\_\_\_web\_sys\_70e763fc3e04fece\_\_\_features\_\_gen\_IdbVersionChangeEvent\_\_IdbVersionChangeEvent\_\_\_\_\_\_true\_**: (`a`, `b`, `c`) => `void` Defined in: @nimiq/core/types/wasm/web.d.ts:2978 #### Parameters ##### a `number` ##### b `number` ##### c `any` #### Returns `void` --- ### wasm\_bindgen\_a0408da6add7f64d\_\_\_convert\_\_closures\_\_\_\_\_invoke\_\_\_web\_sys\_70e763fc3e04fece\_\_\_features\_\_gen\_MessageEvent\_\_MessageEvent\_\_\_\_\_\_true\_() > `readonly` **wasm\_bindgen\_a0408da6add7f64d\_\_\_convert\_\_closures\_\_\_\_\_invoke\_\_\_web\_sys\_70e763fc3e04fece\_\_\_features\_\_gen\_MessageEvent\_\_MessageEvent\_\_\_\_\_\_true\_**: (`a`, `b`, `c`) => `void` Defined in: @nimiq/core/types/wasm/web.d.ts:2980 #### Parameters ##### a `number` ##### b `number` ##### c `any` #### Returns `void` # Interface: PlainAddStakeData [@nimiq/core](https://nimiq.com/developers/../globals) / PlainAddStakeData Defined in: @nimiq/core/types/wasm/web.d.ts:253 JSON-compatible and human-readable format of add stake data. ## Properties ### raw > **raw**: `string` Defined in: @nimiq/core/types/wasm/web.d.ts:254 --- ### staker > **staker**: `string` Defined in: @nimiq/core/types/wasm/web.d.ts:255 # Interface: PlainBasicAccount [@nimiq/core](https://nimiq.com/developers/../globals) / PlainBasicAccount Defined in: @nimiq/core/types/wasm/web.d.ts:584 ## Properties ### balance > **balance**: `number` Defined in: @nimiq/core/types/wasm/web.d.ts:585 # Interface: PlainBlockCommonFields [@nimiq/core](https://nimiq.com/developers/../globals) / PlainBlockCommonFields Defined in: @nimiq/core/types/wasm/web.d.ts:261 JSON-compatible and human-readable format of blocks. ## Extended by - [`PlainMacroBlock`](https://nimiq.com/developers/PlainMacroBlock) - [`PlainMicroBlock`](https://nimiq.com/developers/PlainMicroBlock) ## Properties ### batch > **batch**: `number` Defined in: @nimiq/core/types/wasm/web.d.ts:277 The batch number that the block is in. --- ### bodyHash > **bodyHash**: `string` Defined in: @nimiq/core/types/wasm/web.d.ts:318 The root of the Merkle tree of the body, in HEX format. It acts as a commitment to the body. --- ### epoch > **epoch**: `number` Defined in: @nimiq/core/types/wasm/web.d.ts:281 The epoch number that the block is in. --- ### extraData > **extraData**: `string` Defined in: @nimiq/core/types/wasm/web.d.ts:310 The extra data of the block, in HEX format. Up to 32 raw bytes. In the genesis block, it encodes the initial supply as a big-endian `u64`. No planned use otherwise. --- ### hash > **hash**: `string` Defined in: @nimiq/core/types/wasm/web.d.ts:265 The block's unique hash, used as its identifier, in HEX format. --- ### height > **height**: `number` Defined in: @nimiq/core/types/wasm/web.d.ts:273 The block's block height, also called block number. --- ### historyHash > **historyHash**: `string` Defined in: @nimiq/core/types/wasm/web.d.ts:322 A Merkle root over all of the transactions that happened in the current epoch, in HEX format. --- ### network > **network**: `string` Defined in: @nimiq/core/types/wasm/web.d.ts:289 The network that this block is valid for. --- ### prevHash > **prevHash**: `string` Defined in: @nimiq/core/types/wasm/web.d.ts:297 The hash of the header of the immediately preceding block (either micro or macro), in HEX format. --- ### seed > **seed**: `string` Defined in: @nimiq/core/types/wasm/web.d.ts:302 The seed of the block. This is the BLS signature of the seed of the immediately preceding block (either micro or macro) using the validator key of the block producer. --- ### size > **size**: `number` Defined in: @nimiq/core/types/wasm/web.d.ts:269 The block's on-chain size, in bytes. --- ### stateHash > **stateHash**: `string` Defined in: @nimiq/core/types/wasm/web.d.ts:314 The root of the Merkle tree of the blockchain state, in HEX format. It acts as a commitment to the state. --- ### timestamp > **timestamp**: `number` Defined in: @nimiq/core/types/wasm/web.d.ts:285 The timestamp of the block. It follows the Unix time and has millisecond precision. --- ### version > **version**: `number` Defined in: @nimiq/core/types/wasm/web.d.ts:293 The protocol version that this block is valid for. # Interface: PlainClientConfiguration [@nimiq/core](https://nimiq.com/developers/../globals) / PlainClientConfiguration Defined in: @nimiq/core/types/wasm/web.d.ts:588 ## Properties ### desiredPeerCount? > `optional` **desiredPeerCount**: `number` Defined in: @nimiq/core/types/wasm/web.d.ts:593 --- ### logLevel? > `optional` **logLevel**: `string` Defined in: @nimiq/core/types/wasm/web.d.ts:591 --- ### networkBufferSize? > `optional` **networkBufferSize**: `number` Defined in: @nimiq/core/types/wasm/web.d.ts:597 --- ### networkId? > `optional` **networkId**: `string` Defined in: @nimiq/core/types/wasm/web.d.ts:589 --- ### numInitialConnections? > `optional` **numInitialConnections**: `number` Defined in: @nimiq/core/types/wasm/web.d.ts:599 --- ### onlySecureWsConnections? > `optional` **onlySecureWsConnections**: `boolean` Defined in: @nimiq/core/types/wasm/web.d.ts:592 --- ### peerCountMax? > `optional` **peerCountMax**: `number` Defined in: @nimiq/core/types/wasm/web.d.ts:594 --- ### peerCountPerIpMax? > `optional` **peerCountPerIpMax**: `number` Defined in: @nimiq/core/types/wasm/web.d.ts:595 --- ### peerCountPerSubnetMax? > `optional` **peerCountPerSubnetMax**: `number` Defined in: @nimiq/core/types/wasm/web.d.ts:596 --- ### seedNodes? > `optional` **seedNodes**: `string`[] Defined in: @nimiq/core/types/wasm/web.d.ts:590 --- ### syncMode? > `optional` **syncMode**: `string` Defined in: @nimiq/core/types/wasm/web.d.ts:598 # Interface: PlainCreateStakerData [@nimiq/core](https://nimiq.com/developers/../globals) / PlainCreateStakerData Defined in: @nimiq/core/types/wasm/web.d.ts:366 JSON-compatible and human-readable format of staker creation data. ## Properties ### delegation > **delegation**: `string` Defined in: @nimiq/core/types/wasm/web.d.ts:368 --- ### raw > **raw**: `string` Defined in: @nimiq/core/types/wasm/web.d.ts:367 # Interface: PlainCreateValidatorData [@nimiq/core](https://nimiq.com/developers/../globals) / PlainCreateValidatorData Defined in: @nimiq/core/types/wasm/web.d.ts:505 JSON-compatible and human-readable format of validator creation data. ## Properties ### proofOfKnowledge > **proofOfKnowledge**: `string` Defined in: @nimiq/core/types/wasm/web.d.ts:511 --- ### raw > **raw**: `string` Defined in: @nimiq/core/types/wasm/web.d.ts:506 --- ### rewardAddress > **rewardAddress**: `string` Defined in: @nimiq/core/types/wasm/web.d.ts:509 --- ### signalData > **signalData**: `string` Defined in: @nimiq/core/types/wasm/web.d.ts:510 --- ### signingKey > **signingKey**: `string` Defined in: @nimiq/core/types/wasm/web.d.ts:507 --- ### votingKey > **votingKey**: `string` Defined in: @nimiq/core/types/wasm/web.d.ts:508 # Interface: PlainElectedValidator [@nimiq/core](https://nimiq.com/developers/../globals) / PlainElectedValidator Defined in: @nimiq/core/types/wasm/web.d.ts:173 JSON-compatible and human-readable format of a validator that is elected for the current epoch, together with the number of validator slots assigned to it. Unlike [PlainValidator](https://nimiq.com/developers/PlainValidator), this reflects the slot distribution that was fixed at the most recent election block. The number of slots is the metric used on-chain to evaluate support for protocol upgrades. ## Properties ### address > **address**: `string` Defined in: @nimiq/core/types/wasm/web.d.ts:177 The validator's address, in user-friendly format. --- ### numSlots > **numSlots**: `number` Defined in: @nimiq/core/types/wasm/web.d.ts:181 The number of validator slots assigned to this validator in the current epoch. # Interface: PlainHtlcContract [@nimiq/core](https://nimiq.com/developers/../globals) / PlainHtlcContract Defined in: @nimiq/core/types/wasm/web.d.ts:602 ## Properties ### balance > **balance**: `number` Defined in: @nimiq/core/types/wasm/web.d.ts:603 --- ### hashAlgorithm > **hashAlgorithm**: `string` Defined in: @nimiq/core/types/wasm/web.d.ts:606 --- ### hashCount > **hashCount**: `number` Defined in: @nimiq/core/types/wasm/web.d.ts:608 --- ### hashRoot > **hashRoot**: `string` Defined in: @nimiq/core/types/wasm/web.d.ts:607 --- ### recipient > **recipient**: `string` Defined in: @nimiq/core/types/wasm/web.d.ts:605 --- ### sender > **sender**: `string` Defined in: @nimiq/core/types/wasm/web.d.ts:604 --- ### timeout > **timeout**: `number` Defined in: @nimiq/core/types/wasm/web.d.ts:609 --- ### totalAmount > **totalAmount**: `number` Defined in: @nimiq/core/types/wasm/web.d.ts:610 # Interface: PlainHtlcData [@nimiq/core](https://nimiq.com/developers/../globals) / PlainHtlcData Defined in: @nimiq/core/types/wasm/web.d.ts:58 JSON-compatible and human-readable format of HTLC creation data. ## Properties ### hashAlgorithm > **hashAlgorithm**: `string` Defined in: @nimiq/core/types/wasm/web.d.ts:62 --- ### hashCount > **hashCount**: `number` Defined in: @nimiq/core/types/wasm/web.d.ts:64 --- ### hashRoot > **hashRoot**: `string` Defined in: @nimiq/core/types/wasm/web.d.ts:63 --- ### raw > **raw**: `string` Defined in: @nimiq/core/types/wasm/web.d.ts:59 --- ### recipient > **recipient**: `string` Defined in: @nimiq/core/types/wasm/web.d.ts:61 --- ### sender > **sender**: `string` Defined in: @nimiq/core/types/wasm/web.d.ts:60 --- ### timeout > **timeout**: `number` Defined in: @nimiq/core/types/wasm/web.d.ts:65 # Interface: PlainHtlcEarlyResolveProof [@nimiq/core](https://nimiq.com/developers/../globals) / PlainHtlcEarlyResolveProof Defined in: @nimiq/core/types/wasm/web.d.ts:71 JSON-compatible and human-readable format of HTLC early resolve proofs. ## Properties ### creator > **creator**: `string` Defined in: @nimiq/core/types/wasm/web.d.ts:83 The creator (also called the "sender") of the HTLC --- ### creatorPathLength > **creatorPathLength**: `number` Defined in: @nimiq/core/types/wasm/web.d.ts:86 --- ### creatorPublicKey > **creatorPublicKey**: `string` Defined in: @nimiq/core/types/wasm/web.d.ts:85 --- ### creatorSignature > **creatorSignature**: `string` Defined in: @nimiq/core/types/wasm/web.d.ts:84 --- ### pathLength > **pathLength**: `number` Defined in: @nimiq/core/types/wasm/web.d.ts:79 --- ### publicKey > **publicKey**: `string` Defined in: @nimiq/core/types/wasm/web.d.ts:78 --- ### raw > **raw**: `string` Defined in: @nimiq/core/types/wasm/web.d.ts:72 --- ### signature > **signature**: `string` Defined in: @nimiq/core/types/wasm/web.d.ts:77 --- ### signer > **signer**: `string` Defined in: @nimiq/core/types/wasm/web.d.ts:76 The signer (also called the "recipient") of the HTLC # Interface: PlainHtlcRegularTransferProof [@nimiq/core](https://nimiq.com/developers/../globals) / PlainHtlcRegularTransferProof Defined in: @nimiq/core/types/wasm/web.d.ts:106 JSON-compatible and human-readable format of HTLC transfer proofs. ## Properties ### hashAlgorithm > **hashAlgorithm**: `string` Defined in: @nimiq/core/types/wasm/web.d.ts:108 --- ### hashDepth > **hashDepth**: `number` Defined in: @nimiq/core/types/wasm/web.d.ts:109 --- ### hashRoot > **hashRoot**: `string` Defined in: @nimiq/core/types/wasm/web.d.ts:110 --- ### pathLength > **pathLength**: `number` Defined in: @nimiq/core/types/wasm/web.d.ts:118 --- ### preImage > **preImage**: `string` Defined in: @nimiq/core/types/wasm/web.d.ts:111 --- ### publicKey > **publicKey**: `string` Defined in: @nimiq/core/types/wasm/web.d.ts:117 --- ### raw > **raw**: `string` Defined in: @nimiq/core/types/wasm/web.d.ts:107 --- ### signature > **signature**: `string` Defined in: @nimiq/core/types/wasm/web.d.ts:116 --- ### signer > **signer**: `string` Defined in: @nimiq/core/types/wasm/web.d.ts:115 The signer (also called the "recipient") of the HTLC # Interface: PlainHtlcTimeoutResolveProof [@nimiq/core](https://nimiq.com/developers/../globals) / PlainHtlcTimeoutResolveProof Defined in: @nimiq/core/types/wasm/web.d.ts:92 JSON-compatible and human-readable format of HTLC timeout proofs. ## Properties ### creator > **creator**: `string` Defined in: @nimiq/core/types/wasm/web.d.ts:97 The creator (also called the "sender") of the HTLC --- ### creatorPathLength > **creatorPathLength**: `number` Defined in: @nimiq/core/types/wasm/web.d.ts:100 --- ### creatorPublicKey > **creatorPublicKey**: `string` Defined in: @nimiq/core/types/wasm/web.d.ts:99 --- ### creatorSignature > **creatorSignature**: `string` Defined in: @nimiq/core/types/wasm/web.d.ts:98 --- ### raw > **raw**: `string` Defined in: @nimiq/core/types/wasm/web.d.ts:93 # Interface: PlainMacroBlock [@nimiq/core](https://nimiq.com/developers/../globals) / PlainMacroBlock Defined in: @nimiq/core/types/wasm/web.d.ts:613 JSON-compatible and human-readable format of blocks. ## Extends - [`PlainBlockCommonFields`](https://nimiq.com/developers/PlainBlockCommonFields) ## Properties ### batch > **batch**: `number` Defined in: @nimiq/core/types/wasm/web.d.ts:277 The batch number that the block is in. #### Inherited from [`PlainBlockCommonFields`](https://nimiq.com/developers/PlainBlockCommonFields).[`batch`](https://nimiq.com/developers/PlainBlockCommonFields#batch) --- ### bodyHash > **bodyHash**: `string` Defined in: @nimiq/core/types/wasm/web.d.ts:318 The root of the Merkle tree of the body, in HEX format. It acts as a commitment to the body. #### Inherited from [`PlainBlockCommonFields`](https://nimiq.com/developers/PlainBlockCommonFields).[`bodyHash`](https://nimiq.com/developers/PlainBlockCommonFields#bodyhash) --- ### epoch > **epoch**: `number` Defined in: @nimiq/core/types/wasm/web.d.ts:281 The epoch number that the block is in. #### Inherited from [`PlainBlockCommonFields`](https://nimiq.com/developers/PlainBlockCommonFields).[`epoch`](https://nimiq.com/developers/PlainBlockCommonFields#epoch) --- ### extraData > **extraData**: `string` Defined in: @nimiq/core/types/wasm/web.d.ts:310 The extra data of the block, in HEX format. Up to 32 raw bytes. In the genesis block, it encodes the initial supply as a big-endian `u64`. No planned use otherwise. #### Inherited from [`PlainBlockCommonFields`](https://nimiq.com/developers/PlainBlockCommonFields).[`extraData`](https://nimiq.com/developers/PlainBlockCommonFields#extradata) --- ### hash > **hash**: `string` Defined in: @nimiq/core/types/wasm/web.d.ts:265 The block's unique hash, used as its identifier, in HEX format. #### Inherited from [`PlainBlockCommonFields`](https://nimiq.com/developers/PlainBlockCommonFields).[`hash`](https://nimiq.com/developers/PlainBlockCommonFields#hash) --- ### height > **height**: `number` Defined in: @nimiq/core/types/wasm/web.d.ts:273 The block's block height, also called block number. #### Inherited from [`PlainBlockCommonFields`](https://nimiq.com/developers/PlainBlockCommonFields).[`height`](https://nimiq.com/developers/PlainBlockCommonFields#height) --- ### historyHash > **historyHash**: `string` Defined in: @nimiq/core/types/wasm/web.d.ts:322 A Merkle root over all of the transactions that happened in the current epoch, in HEX format. #### Inherited from [`PlainBlockCommonFields`](https://nimiq.com/developers/PlainBlockCommonFields).[`historyHash`](https://nimiq.com/developers/PlainBlockCommonFields#historyhash) --- ### isElectionBlock > **isElectionBlock**: `boolean` Defined in: @nimiq/core/types/wasm/web.d.ts:617 If true, this macro block is an election block finalizing an epoch. --- ### network > **network**: `string` Defined in: @nimiq/core/types/wasm/web.d.ts:289 The network that this block is valid for. #### Inherited from [`PlainBlockCommonFields`](https://nimiq.com/developers/PlainBlockCommonFields).[`network`](https://nimiq.com/developers/PlainBlockCommonFields#network) --- ### prevElectionHash > **prevElectionHash**: `string` Defined in: @nimiq/core/types/wasm/web.d.ts:625 The hash of the header of the preceding election macro block, in HEX format. --- ### prevHash > **prevHash**: `string` Defined in: @nimiq/core/types/wasm/web.d.ts:297 The hash of the header of the immediately preceding block (either micro or macro), in HEX format. #### Inherited from [`PlainBlockCommonFields`](https://nimiq.com/developers/PlainBlockCommonFields).[`prevHash`](https://nimiq.com/developers/PlainBlockCommonFields#prevhash) --- ### round > **round**: `number` Defined in: @nimiq/core/types/wasm/web.d.ts:621 The round number this block was proposed in. --- ### seed > **seed**: `string` Defined in: @nimiq/core/types/wasm/web.d.ts:302 The seed of the block. This is the BLS signature of the seed of the immediately preceding block (either micro or macro) using the validator key of the block producer. #### Inherited from [`PlainBlockCommonFields`](https://nimiq.com/developers/PlainBlockCommonFields).[`seed`](https://nimiq.com/developers/PlainBlockCommonFields#seed) --- ### size > **size**: `number` Defined in: @nimiq/core/types/wasm/web.d.ts:269 The block's on-chain size, in bytes. #### Inherited from [`PlainBlockCommonFields`](https://nimiq.com/developers/PlainBlockCommonFields).[`size`](https://nimiq.com/developers/PlainBlockCommonFields#size) --- ### stateHash > **stateHash**: `string` Defined in: @nimiq/core/types/wasm/web.d.ts:314 The root of the Merkle tree of the blockchain state, in HEX format. It acts as a commitment to the state. #### Inherited from [`PlainBlockCommonFields`](https://nimiq.com/developers/PlainBlockCommonFields).[`stateHash`](https://nimiq.com/developers/PlainBlockCommonFields#statehash) --- ### timestamp > **timestamp**: `number` Defined in: @nimiq/core/types/wasm/web.d.ts:285 The timestamp of the block. It follows the Unix time and has millisecond precision. #### Inherited from [`PlainBlockCommonFields`](https://nimiq.com/developers/PlainBlockCommonFields).[`timestamp`](https://nimiq.com/developers/PlainBlockCommonFields#timestamp) --- ### version > **version**: `number` Defined in: @nimiq/core/types/wasm/web.d.ts:293 The protocol version that this block is valid for. #### Inherited from [`PlainBlockCommonFields`](https://nimiq.com/developers/PlainBlockCommonFields).[`version`](https://nimiq.com/developers/PlainBlockCommonFields#version) # Interface: PlainMicroBlock [@nimiq/core](https://nimiq.com/developers/../globals) / PlainMicroBlock Defined in: @nimiq/core/types/wasm/web.d.ts:628 JSON-compatible and human-readable format of blocks. ## Extends - [`PlainBlockCommonFields`](https://nimiq.com/developers/PlainBlockCommonFields) ## Properties ### batch > **batch**: `number` Defined in: @nimiq/core/types/wasm/web.d.ts:277 The batch number that the block is in. #### Inherited from [`PlainBlockCommonFields`](https://nimiq.com/developers/PlainBlockCommonFields).[`batch`](https://nimiq.com/developers/PlainBlockCommonFields#batch) --- ### bodyHash > **bodyHash**: `string` Defined in: @nimiq/core/types/wasm/web.d.ts:318 The root of the Merkle tree of the body, in HEX format. It acts as a commitment to the body. #### Inherited from [`PlainBlockCommonFields`](https://nimiq.com/developers/PlainBlockCommonFields).[`bodyHash`](https://nimiq.com/developers/PlainBlockCommonFields#bodyhash) --- ### epoch > **epoch**: `number` Defined in: @nimiq/core/types/wasm/web.d.ts:281 The epoch number that the block is in. #### Inherited from [`PlainBlockCommonFields`](https://nimiq.com/developers/PlainBlockCommonFields).[`epoch`](https://nimiq.com/developers/PlainBlockCommonFields#epoch) --- ### extraData > **extraData**: `string` Defined in: @nimiq/core/types/wasm/web.d.ts:310 The extra data of the block, in HEX format. Up to 32 raw bytes. In the genesis block, it encodes the initial supply as a big-endian `u64`. No planned use otherwise. #### Inherited from [`PlainBlockCommonFields`](https://nimiq.com/developers/PlainBlockCommonFields).[`extraData`](https://nimiq.com/developers/PlainBlockCommonFields#extradata) --- ### hash > **hash**: `string` Defined in: @nimiq/core/types/wasm/web.d.ts:265 The block's unique hash, used as its identifier, in HEX format. #### Inherited from [`PlainBlockCommonFields`](https://nimiq.com/developers/PlainBlockCommonFields).[`hash`](https://nimiq.com/developers/PlainBlockCommonFields#hash) --- ### height > **height**: `number` Defined in: @nimiq/core/types/wasm/web.d.ts:273 The block's block height, also called block number. #### Inherited from [`PlainBlockCommonFields`](https://nimiq.com/developers/PlainBlockCommonFields).[`height`](https://nimiq.com/developers/PlainBlockCommonFields#height) --- ### historyHash > **historyHash**: `string` Defined in: @nimiq/core/types/wasm/web.d.ts:322 A Merkle root over all of the transactions that happened in the current epoch, in HEX format. #### Inherited from [`PlainBlockCommonFields`](https://nimiq.com/developers/PlainBlockCommonFields).[`historyHash`](https://nimiq.com/developers/PlainBlockCommonFields#historyhash) --- ### network > **network**: `string` Defined in: @nimiq/core/types/wasm/web.d.ts:289 The network that this block is valid for. #### Inherited from [`PlainBlockCommonFields`](https://nimiq.com/developers/PlainBlockCommonFields).[`network`](https://nimiq.com/developers/PlainBlockCommonFields#network) --- ### prevHash > **prevHash**: `string` Defined in: @nimiq/core/types/wasm/web.d.ts:297 The hash of the header of the immediately preceding block (either micro or macro), in HEX format. #### Inherited from [`PlainBlockCommonFields`](https://nimiq.com/developers/PlainBlockCommonFields).[`prevHash`](https://nimiq.com/developers/PlainBlockCommonFields#prevhash) --- ### producer > **producer**: [`PlainSlot`](https://nimiq.com/developers/PlainSlot) Defined in: @nimiq/core/types/wasm/web.d.ts:632 The producer of this micro block. --- ### seed > **seed**: `string` Defined in: @nimiq/core/types/wasm/web.d.ts:302 The seed of the block. This is the BLS signature of the seed of the immediately preceding block (either micro or macro) using the validator key of the block producer. #### Inherited from [`PlainBlockCommonFields`](https://nimiq.com/developers/PlainBlockCommonFields).[`seed`](https://nimiq.com/developers/PlainBlockCommonFields#seed) --- ### size > **size**: `number` Defined in: @nimiq/core/types/wasm/web.d.ts:269 The block's on-chain size, in bytes. #### Inherited from [`PlainBlockCommonFields`](https://nimiq.com/developers/PlainBlockCommonFields).[`size`](https://nimiq.com/developers/PlainBlockCommonFields#size) --- ### stateHash > **stateHash**: `string` Defined in: @nimiq/core/types/wasm/web.d.ts:314 The root of the Merkle tree of the blockchain state, in HEX format. It acts as a commitment to the state. #### Inherited from [`PlainBlockCommonFields`](https://nimiq.com/developers/PlainBlockCommonFields).[`stateHash`](https://nimiq.com/developers/PlainBlockCommonFields#statehash) --- ### timestamp > **timestamp**: `number` Defined in: @nimiq/core/types/wasm/web.d.ts:285 The timestamp of the block. It follows the Unix time and has millisecond precision. #### Inherited from [`PlainBlockCommonFields`](https://nimiq.com/developers/PlainBlockCommonFields).[`timestamp`](https://nimiq.com/developers/PlainBlockCommonFields#timestamp) --- ### version > **version**: `number` Defined in: @nimiq/core/types/wasm/web.d.ts:293 The protocol version that this block is valid for. #### Inherited from [`PlainBlockCommonFields`](https://nimiq.com/developers/PlainBlockCommonFields).[`version`](https://nimiq.com/developers/PlainBlockCommonFields#version) # Interface: PlainPeerInfo [@nimiq/core](https://nimiq.com/developers/../globals) / PlainPeerInfo Defined in: @nimiq/core/types/wasm/web.d.ts:36 Information about a networking peer. ## Properties ### address > **address**: `string` Defined in: @nimiq/core/types/wasm/web.d.ts:44 Address of the peer in `Multiaddr` format --- ### peerId > **peerId**: `string` Defined in: @nimiq/core/types/wasm/web.d.ts:40 A libp2p peer ID --- ### services > **services**: [`PlainService`](https://nimiq.com/developers/../type-aliases/PlainService)[] Defined in: @nimiq/core/types/wasm/web.d.ts:52 List of services the peer is providing --- ### type > **type**: `"full"` | `"history"` | `"light"` Defined in: @nimiq/core/types/wasm/web.d.ts:48 Node type of the peer # Interface: PlainRawData [@nimiq/core](https://nimiq.com/developers/../globals) / PlainRawData Defined in: @nimiq/core/types/wasm/web.d.ts:556 Placeholder struct to serialize data of transactions as hex strings in the style of the Nimiq 1.0 library. ## Properties ### raw > **raw**: `string` Defined in: @nimiq/core/types/wasm/web.d.ts:557 # Interface: PlainRawProof [@nimiq/core](https://nimiq.com/developers/../globals) / PlainRawProof Defined in: @nimiq/core/types/wasm/web.d.ts:549 Placeholder struct to serialize a raw proof of transactions, also works for empty/unset proofs ## Properties ### raw > **raw**: `string` Defined in: @nimiq/core/types/wasm/web.d.ts:550 # Interface: PlainRetireStakeData [@nimiq/core](https://nimiq.com/developers/../globals) / PlainRetireStakeData Defined in: @nimiq/core/types/wasm/web.d.ts:328 JSON-compatible and human-readable format of retire stake data. ## Properties ### raw > **raw**: `string` Defined in: @nimiq/core/types/wasm/web.d.ts:329 --- ### retireStake > **retireStake**: `number` Defined in: @nimiq/core/types/wasm/web.d.ts:330 # Interface: PlainSetActiveStakeData [@nimiq/core](https://nimiq.com/developers/../globals) / PlainSetActiveStakeData Defined in: @nimiq/core/types/wasm/web.d.ts:336 JSON-compatible and human-readable format of set active stake data. ## Properties ### newActiveBalance > **newActiveBalance**: `number` Defined in: @nimiq/core/types/wasm/web.d.ts:338 --- ### raw > **raw**: `string` Defined in: @nimiq/core/types/wasm/web.d.ts:337 # Interface: PlainSetSignalDataData [@nimiq/core](https://nimiq.com/developers/../globals) / PlainSetSignalDataData Defined in: @nimiq/core/types/wasm/web.d.ts:344 JSON-compatible and human-readable format of set signal data (warm-key) data. ## Properties ### mode > **mode**: [`PlainSignalDataUpdateMode`](https://nimiq.com/developers/../type-aliases/PlainSignalDataUpdateMode) Defined in: @nimiq/core/types/wasm/web.d.ts:351 Whether this transaction replaces the entire signal data (`full`) or only updates the protocol-version bytes (`version`). --- ### newSignalData > **newSignalData**: `string` Defined in: @nimiq/core/types/wasm/web.d.ts:356 For `full` mode: the new signal data as a hex string, or `null` to clear it. Always `null` in `version` mode. --- ### raw > **raw**: `string` Defined in: @nimiq/core/types/wasm/web.d.ts:345 --- ### validator > **validator**: `string` Defined in: @nimiq/core/types/wasm/web.d.ts:346 --- ### version > **version**: `number` Defined in: @nimiq/core/types/wasm/web.d.ts:360 For `version` mode: the signaled protocol version; `null` in `full` mode. # Interface: PlainSlot [@nimiq/core](https://nimiq.com/developers/../globals) / PlainSlot Defined in: @nimiq/core/types/wasm/web.d.ts:563 The slot/producer info for a micro block. ## Properties ### publicKey > **publicKey**: `string` Defined in: @nimiq/core/types/wasm/web.d.ts:575 The validator's BLS public key, in HEX format. --- ### slotNumber > **slotNumber**: `number` Defined in: @nimiq/core/types/wasm/web.d.ts:567 The slot number that produced this block. --- ### validator > **validator**: `string` Defined in: @nimiq/core/types/wasm/web.d.ts:571 The validator address that produced this block, in user-friendly format. # Interface: PlainStaker [@nimiq/core](https://nimiq.com/developers/../globals) / PlainStaker Defined in: @nimiq/core/types/wasm/web.d.ts:125 JSON-compatible and human-readable format of a staker. E.g. delegation addresses are presented in their human-readable format. ## Properties ### balance > **balance**: `number` Defined in: @nimiq/core/types/wasm/web.d.ts:129 The staker's active balance. --- ### delegation > **delegation**: `string` Defined in: @nimiq/core/types/wasm/web.d.ts:134 The address of the validator for which the staker is delegating its stake for. If it is not delegating to any validator, this will be set to None. --- ### inactiveBalance > **inactiveBalance**: `number` Defined in: @nimiq/core/types/wasm/web.d.ts:141 The staker's inactive balance. Only released inactive balance can be withdrawn from the staking contract. Stake can only be re-delegated if the whole balance of the staker is inactive and released (or if there was no prior delegation). For inactive balance to be released, the maximum of the inactive and the validator's jailed periods must have passed. --- ### inactiveFrom > **inactiveFrom**: `number` Defined in: @nimiq/core/types/wasm/web.d.ts:149 The block number at which the inactive balance was last inactivated. If the stake is currently delegated to a jailed validator, the maximum of its jail release and the inactive release is taken. Re-delegation requires the whole balance of the staker to be inactive. The stake can only effectively become inactive on the next election block. Thus, this may contain a future block height. --- ### inactiveRelease > **inactiveRelease**: `number` Defined in: @nimiq/core/types/wasm/web.d.ts:155 The block number from which the staker's `inactive_balance` gets released, e.g. for retirement. Re-delegation requires the whole balance of the staker to be inactive and released, as well as its delegated validator to not currently be jailed. --- ### retiredBalance > **retiredBalance**: `number` Defined in: @nimiq/core/types/wasm/web.d.ts:162 The staker's retired balance. Retired balance can only be withdrawn, thus retiring is irreversible. Only released inactive balance can be retired, so the maximum of the inactive and the validator's jailed periods must have passed. Once retired, the funds are immediately available to be withdrawn (removed). # Interface: PlainStakingContract [@nimiq/core](https://nimiq.com/developers/../globals) / PlainStakingContract Defined in: @nimiq/core/types/wasm/web.d.ts:635 ## Properties ### activeValidators > **activeValidators**: \[`string`, `number`] [] Defined in: @nimiq/core/types/wasm/web.d.ts:637 --- ### balance > **balance**: `number` Defined in: @nimiq/core/types/wasm/web.d.ts:636 --- ### currentEpochDisabledSlots > **currentEpochDisabledSlots**: \[`string`, `number`[] ] [] Defined in: @nimiq/core/types/wasm/web.d.ts:638 --- ### previousDisabledSlots > **previousDisabledSlots**: `number`[] Defined in: @nimiq/core/types/wasm/web.d.ts:639 # Interface: PlainStandardProof [@nimiq/core](https://nimiq.com/developers/../globals) / PlainStandardProof Defined in: @nimiq/core/types/wasm/web.d.ts:374 JSON-compatible and human-readable format of standard transaction proofs. ## Properties ### pathLength > **pathLength**: `number` Defined in: @nimiq/core/types/wasm/web.d.ts:379 --- ### publicKey > **publicKey**: `string` Defined in: @nimiq/core/types/wasm/web.d.ts:377 --- ### raw > **raw**: `string` Defined in: @nimiq/core/types/wasm/web.d.ts:375 --- ### signature > **signature**: `string` Defined in: @nimiq/core/types/wasm/web.d.ts:376 --- ### signer > **signer**: `string` Defined in: @nimiq/core/types/wasm/web.d.ts:378 # Interface: PlainTransaction [@nimiq/core](https://nimiq.com/developers/../globals) / PlainTransaction Defined in: @nimiq/core/types/wasm/web.d.ts:414 JSON-compatible and human-readable format of transactions. E.g. addresses are presented in their human-readable format and address types and the network are represented as strings. Data and proof are serialized as an object describing their contents (not yet implemented, only the `{ raw: string }` fallback is available). ## Extended by - [`PlainTransactionDetails`](https://nimiq.com/developers/PlainTransactionDetails) ## Properties ### data > **data**: [`PlainTransactionRecipientData`](https://nimiq.com/developers/../type-aliases/PlainTransactionRecipientData) Defined in: @nimiq/core/types/wasm/web.d.ts:479 The `data` field of a transaction serves different purposes based on the transaction's recipient type. For transactions to "basic" address types, this field can contain up to 64 bytes of unstructured data. For transactions that create contracts or interact with the staking contract, the format of this field must follow a fixed structure and defines the new contracts' properties or how the staking contract is changed. --- ### fee > **fee**: `number` Defined in: @nimiq/core/types/wasm/web.d.ts:449 The transaction's fee in luna (NIM's smallest unit). --- ### feePerByte > **feePerByte**: `number` Defined in: @nimiq/core/types/wasm/web.d.ts:453 The transaction's fee-per-byte in luna (NIM's smallest unit). --- ### flags > **flags**: `number` Defined in: @nimiq/core/types/wasm/web.d.ts:466 Any flags that this transaction carries. `0b1 = 1` means it's a contract-creation transaction, `0b10 = 2` means it's a signalling transaction with 0 value. --- ### format > **format**: `"basic"` | `"extended"` Defined in: @nimiq/core/types/wasm/web.d.ts:426 The transaction's format. Nimiq transactions can have one of two formats: "basic" and "extended". Basic transactions are simple value transfers between two regular address types and cannot contain any extra data. Basic transactions can be serialized to less bytes, so take up less place on the blockchain. Extended transactions on the other hand are all other transactions: contract creations and interactions, staking transactions, transactions with extra data, etc. --- ### network > **network**: `string` Defined in: @nimiq/core/types/wasm/web.d.ts:461 The network name on which this transaction is valid. --- ### proof > **proof**: [`PlainTransactionProof`](https://nimiq.com/developers/../type-aliases/PlainTransactionProof) Defined in: @nimiq/core/types/wasm/web.d.ts:485 The `proof` field contains the signature of the eligible signer. The proof field's structure depends on the transaction's sender type. For transactions from contracts it can also contain additional structured data before the signature. --- ### recipient > **recipient**: `string` Defined in: @nimiq/core/types/wasm/web.d.ts:439 The transaction's recipient address in human-readable IBAN format. --- ### recipientType > **recipientType**: `"vesting"` | `"htlc"` | `"basic"` | `"staking"` Defined in: @nimiq/core/types/wasm/web.d.ts:444 The account type of the transaction's recipient. "basic" are regular private-key controlled accounts, "vesting" and "htlc" are contracts, and "staking" is the staking contract. --- ### sender > **sender**: `string` Defined in: @nimiq/core/types/wasm/web.d.ts:430 The transaction's sender address in human-readable IBAN format. --- ### senderData? > `optional` **senderData**: [`PlainTransactionSenderData`](https://nimiq.com/developers/../type-aliases/PlainTransactionSenderData) Defined in: @nimiq/core/types/wasm/web.d.ts:471 The `sender_data` field serves a purpose based on the transaction's sender type. It is currently only used for extra information in transactions from the staking contract. --- ### senderType > **senderType**: `"vesting"` | `"htlc"` | `"basic"` | `"staking"` Defined in: @nimiq/core/types/wasm/web.d.ts:435 The account type of the transaction's sender. "basic" are regular private-key controlled accounts, "vesting" and "htlc" are contracts, and "staking" is the staking contract. --- ### size > **size**: `number` Defined in: @nimiq/core/types/wasm/web.d.ts:490 The transaction's serialized size in bytes. It is used to determine the fee-per-byte that this transaction pays. --- ### transactionHash > **transactionHash**: `string` Defined in: @nimiq/core/types/wasm/web.d.ts:418 The transaction's unique hash, used as its identifier. Sometimes also called `txId`. --- ### validityStartHeight > **validityStartHeight**: `number` Defined in: @nimiq/core/types/wasm/web.d.ts:457 The block height at which this transaction becomes valid. It is then valid for 7200 blocks (\~2 hours). --- ### value > **value**: `number` Defined in: @nimiq/core/types/wasm/web.d.ts:445 # Interface: PlainTransactionDetails [@nimiq/core](https://nimiq.com/developers/../globals) / PlainTransactionDetails Defined in: @nimiq/core/types/wasm/web.d.ts:401 JSON-compatible and human-readable format of transactions, including details about its state in the blockchain. Contains all fields from [PlainTransaction](https://nimiq.com/developers/PlainTransaction), plus additional fields such as `blockHeight` and `timestamp` if the transaction is included in the blockchain. ## Extends - [`PlainTransaction`](https://nimiq.com/developers/PlainTransaction) ## Properties ### blockHeight? > `optional` **blockHeight**: `number` Defined in: @nimiq/core/types/wasm/web.d.ts:404 --- ### confirmations? > `optional` **confirmations**: `number` Defined in: @nimiq/core/types/wasm/web.d.ts:405 --- ### data > **data**: [`PlainTransactionRecipientData`](https://nimiq.com/developers/../type-aliases/PlainTransactionRecipientData) Defined in: @nimiq/core/types/wasm/web.d.ts:479 The `data` field of a transaction serves different purposes based on the transaction's recipient type. For transactions to "basic" address types, this field can contain up to 64 bytes of unstructured data. For transactions that create contracts or interact with the staking contract, the format of this field must follow a fixed structure and defines the new contracts' properties or how the staking contract is changed. #### Inherited from [`PlainTransaction`](https://nimiq.com/developers/PlainTransaction).[`data`](https://nimiq.com/developers/PlainTransaction#data) --- ### executionResult? > `optional` **executionResult**: `boolean` Defined in: @nimiq/core/types/wasm/web.d.ts:403 --- ### fee > **fee**: `number` Defined in: @nimiq/core/types/wasm/web.d.ts:449 The transaction's fee in luna (NIM's smallest unit). #### Inherited from [`PlainTransaction`](https://nimiq.com/developers/PlainTransaction).[`fee`](https://nimiq.com/developers/PlainTransaction#fee) --- ### feePerByte > **feePerByte**: `number` Defined in: @nimiq/core/types/wasm/web.d.ts:453 The transaction's fee-per-byte in luna (NIM's smallest unit). #### Inherited from [`PlainTransaction`](https://nimiq.com/developers/PlainTransaction).[`feePerByte`](https://nimiq.com/developers/PlainTransaction#feeperbyte) --- ### flags > **flags**: `number` Defined in: @nimiq/core/types/wasm/web.d.ts:466 Any flags that this transaction carries. `0b1 = 1` means it's a contract-creation transaction, `0b10 = 2` means it's a signalling transaction with 0 value. #### Inherited from [`PlainTransaction`](https://nimiq.com/developers/PlainTransaction).[`flags`](https://nimiq.com/developers/PlainTransaction#flags) --- ### format > **format**: `"basic"` | `"extended"` Defined in: @nimiq/core/types/wasm/web.d.ts:426 The transaction's format. Nimiq transactions can have one of two formats: "basic" and "extended". Basic transactions are simple value transfers between two regular address types and cannot contain any extra data. Basic transactions can be serialized to less bytes, so take up less place on the blockchain. Extended transactions on the other hand are all other transactions: contract creations and interactions, staking transactions, transactions with extra data, etc. #### Inherited from [`PlainTransaction`](https://nimiq.com/developers/PlainTransaction).[`format`](https://nimiq.com/developers/PlainTransaction#format) --- ### network > **network**: `string` Defined in: @nimiq/core/types/wasm/web.d.ts:461 The network name on which this transaction is valid. #### Inherited from [`PlainTransaction`](https://nimiq.com/developers/PlainTransaction).[`network`](https://nimiq.com/developers/PlainTransaction#network) --- ### proof > **proof**: [`PlainTransactionProof`](https://nimiq.com/developers/../type-aliases/PlainTransactionProof) Defined in: @nimiq/core/types/wasm/web.d.ts:485 The `proof` field contains the signature of the eligible signer. The proof field's structure depends on the transaction's sender type. For transactions from contracts it can also contain additional structured data before the signature. #### Inherited from [`PlainTransaction`](https://nimiq.com/developers/PlainTransaction).[`proof`](https://nimiq.com/developers/PlainTransaction#proof) --- ### recipient > **recipient**: `string` Defined in: @nimiq/core/types/wasm/web.d.ts:439 The transaction's recipient address in human-readable IBAN format. #### Inherited from [`PlainTransaction`](https://nimiq.com/developers/PlainTransaction).[`recipient`](https://nimiq.com/developers/PlainTransaction#recipient) --- ### recipientType > **recipientType**: `"vesting"` | `"htlc"` | `"basic"` | `"staking"` Defined in: @nimiq/core/types/wasm/web.d.ts:444 The account type of the transaction's recipient. "basic" are regular private-key controlled accounts, "vesting" and "htlc" are contracts, and "staking" is the staking contract. #### Inherited from [`PlainTransaction`](https://nimiq.com/developers/PlainTransaction).[`recipientType`](https://nimiq.com/developers/PlainTransaction#recipienttype) --- ### sender > **sender**: `string` Defined in: @nimiq/core/types/wasm/web.d.ts:430 The transaction's sender address in human-readable IBAN format. #### Inherited from [`PlainTransaction`](https://nimiq.com/developers/PlainTransaction).[`sender`](https://nimiq.com/developers/PlainTransaction#sender) --- ### senderData? > `optional` **senderData**: [`PlainTransactionSenderData`](https://nimiq.com/developers/../type-aliases/PlainTransactionSenderData) Defined in: @nimiq/core/types/wasm/web.d.ts:471 The `sender_data` field serves a purpose based on the transaction's sender type. It is currently only used for extra information in transactions from the staking contract. #### Inherited from [`PlainTransaction`](https://nimiq.com/developers/PlainTransaction).[`senderData`](https://nimiq.com/developers/PlainTransaction#senderdata) --- ### senderType > **senderType**: `"vesting"` | `"htlc"` | `"basic"` | `"staking"` Defined in: @nimiq/core/types/wasm/web.d.ts:435 The account type of the transaction's sender. "basic" are regular private-key controlled accounts, "vesting" and "htlc" are contracts, and "staking" is the staking contract. #### Inherited from [`PlainTransaction`](https://nimiq.com/developers/PlainTransaction).[`senderType`](https://nimiq.com/developers/PlainTransaction#sendertype) --- ### size > **size**: `number` Defined in: @nimiq/core/types/wasm/web.d.ts:490 The transaction's serialized size in bytes. It is used to determine the fee-per-byte that this transaction pays. #### Inherited from [`PlainTransaction`](https://nimiq.com/developers/PlainTransaction).[`size`](https://nimiq.com/developers/PlainTransaction#size) --- ### state > **state**: [`TransactionState`](https://nimiq.com/developers/../type-aliases/TransactionState) Defined in: @nimiq/core/types/wasm/web.d.ts:402 --- ### timestamp? > `optional` **timestamp**: `number` Defined in: @nimiq/core/types/wasm/web.d.ts:406 --- ### transactionHash > **transactionHash**: `string` Defined in: @nimiq/core/types/wasm/web.d.ts:418 The transaction's unique hash, used as its identifier. Sometimes also called `txId`. #### Inherited from [`PlainTransaction`](https://nimiq.com/developers/PlainTransaction).[`transactionHash`](https://nimiq.com/developers/PlainTransaction#transactionhash) --- ### validityStartHeight > **validityStartHeight**: `number` Defined in: @nimiq/core/types/wasm/web.d.ts:457 The block height at which this transaction becomes valid. It is then valid for 7200 blocks (\~2 hours). #### Inherited from [`PlainTransaction`](https://nimiq.com/developers/PlainTransaction).[`validityStartHeight`](https://nimiq.com/developers/PlainTransaction#validitystartheight) --- ### value > **value**: `number` Defined in: @nimiq/core/types/wasm/web.d.ts:445 #### Inherited from [`PlainTransaction`](https://nimiq.com/developers/PlainTransaction).[`value`](https://nimiq.com/developers/PlainTransaction#value) # Interface: PlainTransactionReceipt [@nimiq/core](https://nimiq.com/developers/../globals) / PlainTransactionReceipt Defined in: @nimiq/core/types/wasm/web.d.ts:385 JSON-compatible and human-readable format of transaction receipts. ## Properties ### blockHeight > **blockHeight**: `number` Defined in: @nimiq/core/types/wasm/web.d.ts:393 The transaction's block height where it is included in the blockchain. --- ### transactionHash > **transactionHash**: `string` Defined in: @nimiq/core/types/wasm/web.d.ts:389 The transaction's unique hash, used as its identifier. Sometimes also called `txId`. # Interface: PlainUpdateStakerData [@nimiq/core](https://nimiq.com/developers/../globals) / PlainUpdateStakerData Defined in: @nimiq/core/types/wasm/web.d.ts:496 JSON-compatible and human-readable format of update staker data. ## Properties ### newDelegation > **newDelegation**: `string` Defined in: @nimiq/core/types/wasm/web.d.ts:498 --- ### raw > **raw**: `string` Defined in: @nimiq/core/types/wasm/web.d.ts:497 --- ### reactivateAllStake > **reactivateAllStake**: `boolean` Defined in: @nimiq/core/types/wasm/web.d.ts:499 # Interface: PlainUpdateValidatorData [@nimiq/core](https://nimiq.com/developers/../globals) / PlainUpdateValidatorData Defined in: @nimiq/core/types/wasm/web.d.ts:526 JSON-compatible and human-readable format of validator update data. ## Properties ### newProofOfKnowledge > **newProofOfKnowledge**: `string` Defined in: @nimiq/core/types/wasm/web.d.ts:532 --- ### newRewardAddress > **newRewardAddress**: `string` Defined in: @nimiq/core/types/wasm/web.d.ts:530 --- ### newSignalData > **newSignalData**: `string` Defined in: @nimiq/core/types/wasm/web.d.ts:531 --- ### newSigningKey > **newSigningKey**: `string` Defined in: @nimiq/core/types/wasm/web.d.ts:528 --- ### newVotingKey > **newVotingKey**: `string` Defined in: @nimiq/core/types/wasm/web.d.ts:529 --- ### raw > **raw**: `string` Defined in: @nimiq/core/types/wasm/web.d.ts:527 # Interface: PlainValidator [@nimiq/core](https://nimiq.com/developers/../globals) / PlainValidator Defined in: @nimiq/core/types/wasm/web.d.ts:188 JSON-compatible and human-readable format of a validator. E.g. reward addresses and public keys are presented in their human-readable format. ## Properties ### deposit > **deposit**: `number` Defined in: @nimiq/core/types/wasm/web.d.ts:215 The amount of coins deposited by this validator. The initial deposit is a fixed amount, however this value can be decremented by failing staking transactions due to fees. --- ### inactiveFrom > **inactiveFrom**: `number` Defined in: @nimiq/core/types/wasm/web.d.ts:226 An option indicating if the validator is marked as inactive. If it is, then it contains the block height at which it becomes inactive. A validator can only effectively become inactive on the next election block. Thus, this may contain a block height in the future. --- ### inactiveRelease > **inactiveRelease**: `number` Defined in: @nimiq/core/types/wasm/web.d.ts:231 An option indicating if the validator is marked as inactive. If it is, then it contains the block height at which the inactive stake gets released and the validator can be retired. --- ### jailedFrom > **jailedFrom**: `number` Defined in: @nimiq/core/types/wasm/web.d.ts:242 An option indicating if the validator is jailed. If it is, then it contains the block height at which it became jailed. Opposed to `inactive_from`, jailing can and should take effect immediately to prevent the validator and its stakers from modifying their funds and or delegation. --- ### jailedRelease > **jailedRelease**: `number` Defined in: @nimiq/core/types/wasm/web.d.ts:247 An option indicating if the validator is jailed. If it is, then it contains the block height at which the jail period ends and the validator becomes interactive again. --- ### numStakers > **numStakers**: `number` Defined in: @nimiq/core/types/wasm/web.d.ts:219 The number of stakers that are delegating to this validator. --- ### retired > **retired**: `boolean` Defined in: @nimiq/core/types/wasm/web.d.ts:235 A flag indicating if the validator is retired. --- ### rewardAddress > **rewardAddress**: `string` Defined in: @nimiq/core/types/wasm/web.d.ts:200 The reward address of the validator. All the block rewards are paid to this address. --- ### signalData > **signalData**: `string` Defined in: @nimiq/core/types/wasm/web.d.ts:205 Signaling field. Can be used to do chain upgrades or for any other purpose that requires validators to coordinate among themselves. --- ### signingPublicKey > **signingPublicKey**: `string` Defined in: @nimiq/core/types/wasm/web.d.ts:192 The public key used to sign blocks. It is also used to retire and reactivate the validator. --- ### totalStake > **totalStake**: `number` Defined in: @nimiq/core/types/wasm/web.d.ts:210 The total stake assigned to this validator. It includes the validator deposit as well as the coins delegated to him by stakers. --- ### votingPublicKey > **votingPublicKey**: `string` Defined in: @nimiq/core/types/wasm/web.d.ts:196 The voting public key, it is used to vote for skip and macro blocks. # Interface: PlainValidatorData [@nimiq/core](https://nimiq.com/developers/../globals) / PlainValidatorData Defined in: @nimiq/core/types/wasm/web.d.ts:518 JSON-compatible and human-readable format of validator deactivation/reactivation data. Used for DeactivateValidator & ReactivateValidator, as they have the same fields. ## Properties ### raw > **raw**: `string` Defined in: @nimiq/core/types/wasm/web.d.ts:519 --- ### validator > **validator**: `string` Defined in: @nimiq/core/types/wasm/web.d.ts:520 # Interface: PlainVestingContract [@nimiq/core](https://nimiq.com/developers/../globals) / PlainVestingContract Defined in: @nimiq/core/types/wasm/web.d.ts:642 ## Properties ### balance > **balance**: `number` Defined in: @nimiq/core/types/wasm/web.d.ts:643 --- ### owner > **owner**: `string` Defined in: @nimiq/core/types/wasm/web.d.ts:644 --- ### startTime > **startTime**: `number` Defined in: @nimiq/core/types/wasm/web.d.ts:645 --- ### stepAmount > **stepAmount**: `number` Defined in: @nimiq/core/types/wasm/web.d.ts:647 --- ### timeStep > **timeStep**: `number` Defined in: @nimiq/core/types/wasm/web.d.ts:646 --- ### totalAmount > **totalAmount**: `number` Defined in: @nimiq/core/types/wasm/web.d.ts:648 # Interface: PlainVestingData [@nimiq/core](https://nimiq.com/developers/../globals) / PlainVestingData Defined in: @nimiq/core/types/wasm/web.d.ts:538 JSON-compatible and human-readable format of vesting creation data. ## Properties ### owner > **owner**: `string` Defined in: @nimiq/core/types/wasm/web.d.ts:540 --- ### raw > **raw**: `string` Defined in: @nimiq/core/types/wasm/web.d.ts:539 --- ### startTime > **startTime**: `number` Defined in: @nimiq/core/types/wasm/web.d.ts:541 --- ### stepAmount > **stepAmount**: `number` Defined in: @nimiq/core/types/wasm/web.d.ts:543 --- ### timeStep > **timeStep**: `number` Defined in: @nimiq/core/types/wasm/web.d.ts:542 # Type Alias: ConsensusState [@nimiq/core](https://nimiq.com/developers/../globals) / ConsensusState > **ConsensusState** = `"connecting"` | `"syncing"` | `"established"` Defined in: @nimiq/core/types/wasm/web.d.ts:16 Describes the state of consensus of the client. # Type Alias: InitInput [@nimiq/core](https://nimiq.com/developers/../globals) / InitInput > **InitInput** = `RequestInfo` | `URL` | `Response` | `BufferSource` | `WebAssembly.Module` Defined in: @nimiq/core/types/wasm/web.d.ts:2611 # Type Alias: PlainAccount [@nimiq/core](https://nimiq.com/developers/../globals) / PlainAccount > **PlainAccount** = `object` & [`PlainBasicAccount`](https://nimiq.com/developers/../interfaces/PlainBasicAccount) | `object` & [`PlainVestingContract`](https://nimiq.com/developers/../interfaces/PlainVestingContract) | `object` & [`PlainHtlcContract`](https://nimiq.com/developers/../interfaces/PlainHtlcContract) | `object` & [`PlainStakingContract`](https://nimiq.com/developers/../interfaces/PlainStakingContract) Defined in: @nimiq/core/types/wasm/web.d.ts:651 # Type Alias: PlainBlock [@nimiq/core](https://nimiq.com/developers/../globals) / PlainBlock > **PlainBlock** = `object` & [`PlainMacroBlock`](https://nimiq.com/developers/../interfaces/PlainMacroBlock) | `object` & [`PlainMicroBlock`](https://nimiq.com/developers/../interfaces/PlainMicroBlock) Defined in: @nimiq/core/types/wasm/web.d.ts:653 # Type Alias: PlainService [@nimiq/core](https://nimiq.com/developers/../globals) / PlainService > **PlainService** = `"full-blocks"` | `"history"` | `"accounts-proof"` | `"accounts-chunk"` | `"mempool"` | `"transaction-index"` | `"validator"` | `"pre-genesis-transactions"` | `"unknown"` Defined in: @nimiq/core/types/wasm/web.d.ts:6 Available peer service flags # Type Alias: PlainSignalDataUpdateMode [@nimiq/core](https://nimiq.com/developers/../globals) / PlainSignalDataUpdateMode > **PlainSignalDataUpdateMode** = `"full"` | `"version"` Defined in: @nimiq/core/types/wasm/web.d.ts:582 Whether a set signal data (warm-key) transaction replaces the entire `signalData` field or only updates the protocol-version bytes (preserving the rest). # Type Alias: PlainTransactionProof [@nimiq/core](https://nimiq.com/developers/../globals) / PlainTransactionProof > **PlainTransactionProof** = `object` & [`PlainRawProof`](https://nimiq.com/developers/../interfaces/PlainRawProof) | `object` & [`PlainStandardProof`](https://nimiq.com/developers/../interfaces/PlainStandardProof) | `object` & [`PlainHtlcRegularTransferProof`](https://nimiq.com/developers/../interfaces/PlainHtlcRegularTransferProof) | `object` & [`PlainHtlcTimeoutResolveProof`](https://nimiq.com/developers/../interfaces/PlainHtlcTimeoutResolveProof) | `object` & [`PlainHtlcEarlyResolveProof`](https://nimiq.com/developers/../interfaces/PlainHtlcEarlyResolveProof) Defined in: @nimiq/core/types/wasm/web.d.ts:21 Enum over all possible meanings of a transaction's proof. # Type Alias: PlainTransactionRecipientData [@nimiq/core](https://nimiq.com/developers/../globals) / PlainTransactionRecipientData > **PlainTransactionRecipientData** = `object` & [`PlainRawData`](https://nimiq.com/developers/../interfaces/PlainRawData) | `object` & [`PlainVestingData`](https://nimiq.com/developers/../interfaces/PlainVestingData) | `object` & [`PlainHtlcData`](https://nimiq.com/developers/../interfaces/PlainHtlcData) | `object` & [`PlainCreateValidatorData`](https://nimiq.com/developers/../interfaces/PlainCreateValidatorData) | `object` & [`PlainUpdateValidatorData`](https://nimiq.com/developers/../interfaces/PlainUpdateValidatorData) | `object` & [`PlainValidatorData`](https://nimiq.com/developers/../interfaces/PlainValidatorData) | `object` & [`PlainValidatorData`](https://nimiq.com/developers/../interfaces/PlainValidatorData) | `object` & [`PlainRawData`](https://nimiq.com/developers/../interfaces/PlainRawData) | `object` & [`PlainCreateStakerData`](https://nimiq.com/developers/../interfaces/PlainCreateStakerData) | `object` & [`PlainAddStakeData`](https://nimiq.com/developers/../interfaces/PlainAddStakeData) | `object` & [`PlainUpdateStakerData`](https://nimiq.com/developers/../interfaces/PlainUpdateStakerData) | `object` & [`PlainSetActiveStakeData`](https://nimiq.com/developers/../interfaces/PlainSetActiveStakeData) | `object` & [`PlainRetireStakeData`](https://nimiq.com/developers/../interfaces/PlainRetireStakeData) | `object` & [`PlainSetSignalDataData`](https://nimiq.com/developers/../interfaces/PlainSetSignalDataData) Defined in: @nimiq/core/types/wasm/web.d.ts:26 Enum over all possible meanings of a transaction's recipient data. # Type Alias: PlainTransactionSenderData [@nimiq/core](https://nimiq.com/developers/../globals) / PlainTransactionSenderData > **PlainTransactionSenderData** = `object` & [`PlainRawData`](https://nimiq.com/developers/../interfaces/PlainRawData) | `object` & [`PlainRawData`](https://nimiq.com/developers/../interfaces/PlainRawData) | `object` & [`PlainRawData`](https://nimiq.com/developers/../interfaces/PlainRawData) Defined in: @nimiq/core/types/wasm/web.d.ts:31 Enum over all possible meanings of a transaction's sender data. # Type Alias: SyncInitInput [@nimiq/core](https://nimiq.com/developers/../globals) / SyncInitInput > **SyncInitInput** = `BufferSource` | `WebAssembly.Module` Defined in: @nimiq/core/types/wasm/web.d.ts:2995 # Type Alias: TransactionState [@nimiq/core](https://nimiq.com/developers/../globals) / TransactionState > **TransactionState** = `"new"` | `"pending"` | `"included"` | `"confirmed"` | `"invalidated"` | `"expired"` Defined in: @nimiq/core/types/wasm/web.d.ts:11 Describes the state of a transaction as known by the client. # Nimiq Developer Center ::u-banner --- color: success id: mini-apps-launch title: Mini Apps Framework is live! Build inside Nimiq Pay to: https://nimiq.com/developers/mini-apps --- :: :u-page-hero{description="Fast, feeless & energy-light blockchain rails for web developers." orientation="vertical" title="Build. Connect. Validate."} ::u-page-section{title="Choose your path"} :::u-page-grid ::::u-page-card --- description: Build web and mobile apps that interact with Nimiq directly in the browser. Fully decentralized — no server required icon: i-lucide-globe title: Web Client to: https://nimiq.com/developers/web-client variant: outline --- :::: ::::u-page-card --- description: Integrate wallet features into your app. Sign transactions, manage accounts, and access the Nimiq ecosystem icon: i-lucide-wallet title: Hub API to: https://nimiq.com/developers/hub variant: outline --- :::: ::::u-page-card --- description: Build apps that run inside Nimiq Pay with Nimiq and Ethereum wallet access icon: i-lucide-layout-grid title: Mini Apps to: https://nimiq.com/developers/mini-apps variant: outline --- :::: ::::u-page-card --- description: Build full-stack applications with the JSON-RPC API icon: i-lucide-terminal title: RPC to: https://nimiq.com/developers/rpc variant: outline --- :::: ::::u-page-card --- description: Run a node, stake and contribute proofs icon: i-lucide-server title: Nodes & Validators to: https://nimiq.com/developers/nodes variant: outline --- :::: ::::u-page-card --- description: Learn about the Albatross protocol icon: i-lucide-book-open title: Protocol to: https://nimiq.com/developers/protocol variant: outline --- :::: ::: :: ::u-page-section --- description: Start experimenting with Nimiq right away. headline: Quick Start title: Jump right in — no install --- :::u-page-grid ::::u-page-card --- spotlight: true description: Interactive, in-browser walkthrough icon: i-lucide-play-circle title: Web Client Tutorial to: https://nimiq.guide variant: outline --- :::: ::::u-page-card --- spotlight: true description: Explore docs and run JSON-RPC from your environment icon: i-lucide-rocket title: RPC Quick Start to: https://nimiq.com/developers/rpc variant: outline --- :::: ::::u-page-card --- spotlight: true description: Connect AI tools to the Developer Center documentation server icon: i-lucide-bot title: Nimiq MCP to: https://nimiq.com/developers/ai/mcp variant: outline --- :::: ::: :: ::u-page-section --- description: No middlemen. No servers. No barriers. No fees. Connect directly from any browser. headline: Why Nimiq title: Browser-first blockchain --- :::u-page-grid ::::u-page-card --- description: Build entirely in-browser with no servers icon: i-lucide-monitor-smartphone title: Browser-First variant: outline --- :::: ::::u-page-card --- description: Send & receive value with zero cost icon: i-lucide-badge-check title: Zero Fees variant: outline --- :::: ::::u-page-card --- description: 1-second confirmations icon: i-lucide-zap title: Fast Confirmations variant: outline --- :::: ::::u-page-card --- description: 99.9% less energy than PoW consensus icon: i-lucide-leaf title: Energy-Efficient variant: outline --- :::: ::::u-page-card --- description: 100% open-source and active devs icon: i-lucide-users title: Community-Driven variant: outline --- :::: ::::u-page-card --- description: Simple APIs, rich docs, IDE support icon: i-lucide-code title: Dev-Friendly variant: outline --- :::: ::: :: ::u-page-section --- headline: Popular Resources title: Everything you need to build with Nimiq --- :::u-page-columns ::::u-page-card{icon="i-lucide-globe" title="Web Development" variant="outline"} - [Getting Started](https://nimiq.com/developers/web-client/getting-started) - [Quick Install](https://nimiq.com/developers/web-client#start-with-4-lines-of-code) - [Vite Integration](https://nimiq.com/developers/web-client/integrations/vite) - [Interactive Tutorial](https://nimiq.guide){rel=""nofollow""} - [Web Client vs RPC](https://nimiq.com/developers/web-client/concepts/web-client-vs-rpc) :::: ::::u-page-card --- icon: i-lucide-wrench title: Developer Tools variant: outline --- - [Hub API](https://nimiq.com/developers/hub) - [AI Integrations](https://nimiq.com/developers/ai) - [Nimiq Utils](https://nimiq.com/developers/nimiq-utils) - [Blockchain Explorers](https://nimiq.com/developers/rpc/blockchain-explorers) :::: ::::u-page-card{icon="i-lucide-palette" title="UI & Design" variant="outline"} - [Design Kit](https://nimiq.com/developers/design-kit) - [Nimiq Icons](https://onmax.github.io/nimiq-ui/nimiq-icons/explorer){rel=""nofollow""} - [Nimiq CSS](https://onmax.github.io/nimiq-ui/nimiq-css/getting-started){rel=""nofollow""} - [Identicons Library](https://github.com/onmax/nimiq-identicons){rel=""nofollow""} :::: ::::u-page-card{icon="i-lucide-server" title="Backend & API" variant="outline"} - [RPC Methods](https://nimiq.com/developers/rpc/methods) - [TypeScript Client](https://nimiq.com/developers/rpc/integrations/typescript) - [ARPL CLI Tool](https://github.com/sisou/arpl){rel=""nofollow""} - [Blockchain Explorers](https://nimiq.com/developers/rpc/blockchain-explorers) :::: ::::u-page-card --- icon: i-lucide-shield-check title: Validators & Nodes variant: outline --- - [Becoming a Validator](https://nimiq.com/developers/nodes/validators/becoming-a-validator) - [Staking Handbook](https://nimiq.com/developers/nodes/validators/staking-handbook) - [Trustscore System](https://nimiq.com/developers/nodes/validators/validator-trustscore) - [Staking FAQ](https://nimiq.com/developers/nodes/validators/staking-faq) :::: ::::u-page-card --- icon: i-lucide-book-open title: Core & Protocol variant: outline --- - [Protocol Docs](https://nimiq.com/developers/protocol) - [Core Implementation](https://github.com/nimiq/core-rs-albatross){rel=""nofollow""} :::: ::::u-page-card{icon="i-lucide-users" title="Community" variant="outline"} - [Community Forum](https://forum.nimiq.community/){rel=""nofollow""} - [Telegram](https://t.me/nimiq){rel=""nofollow""} - [Awesome Nimiq](https://github.com/nimiq/awesome){rel=""nofollow""} - [AI Integrations](https://nimiq.com/developers/ai) :::: ::::u-page-card --- icon: i-lucide-arrow-right-left title: Migration variant: outline --- - [Migration Overview](https://nimiq.com/developers/migration) - [For Integrators](https://nimiq.com/developers/migration/migration-integrators) - [JSON-RPC Migration](https://nimiq.com/developers/migration/migration-json-rpc) - [Technical Details](https://nimiq.com/developers/migration/migration-technical-details) :::: ::: ::