§ Wiki · Wiki entry

Setting Up a Neuron for NNS Proposals

Stake a neuron and attach a software hotkey so you can submit node-provider NNS proposals with ic-admin — no HSM required — and which maintenance tasks can skip proposals entirely with a direct registry call.

Node providers change the registry in one of two ways. Some maintenance tasks are direct registry calls, signed with the node operator key and applied immediately. Everything else is an NNS proposal, submitted on behalf of a neuron and applied only once the community adopts it. This entry covers the one-time setup the second path needs: a staked neuron, plus a software hotkey that lets ic-admin submit proposals for it. None of it uses an HSM.

Direct call or proposal?

Check this first — if your task has a direct call, you do not need a neuron for it.

Direct registry calls (node operator key, no neuron, no vote):

NNS proposals (neuron required):

Keys involved

Four keys play distinct roles. Keep them apart.

  • Neuron controller — owns the staked ICP and can do everything with the neuron, including dissolving it. This is your Ledger hardware wallet.
  • Node-provider hotkey — a software identity on your workstation. It can submit proposals and vote for the neuron, but cannot move, disburse, or dissolve the stake. This is the key ic-admin signs with.
  • Node-provider principal — the long-lived identity of your provider entity, recorded in the registry. It is the principal of the same Ledger that controls the neuron.
  • Node operator key — the per-data-center key (node_operator_private_key.pem) used during node deployment and for the direct registry calls above. It is not involved in proposals.

Requirements

  • Stake of at least 51 ICP. A rejected proposal costs its neuron 50 ICP (the NNS reject_cost_e8s), and a neuron must hold at least that much to submit. The extra ICP covers ledger fees. Some older documentation quotes 10 ICP; that figure is out of date.
  • Dissolve delay of at least 6 months. This is the minimum to submit proposals. The minimum to vote is lower (currently two weeks), so a neuron that can vote cannot necessarily propose.
  • ic-admin, icp, and openssl installed — see step 1 of Node Provider Onboarding.

The rejection fee is a governance parameter and can change. Check the current value before staking:

icp canister call -n ic --identity anonymous --query \
  rrkah-fqaaa-aaaaa-aaaaq-cai get_network_economics_parameters '()' \
  | grep reject_cost_e8s

The value is in e8s: 5_000_000_000 is 50 ICP. If a proposal is rejected, the fee is deducted from the stake — top the neuron back up before submitting again.

Step 1 — Create the hotkey

icp identity new --storage plaintext node-provider-hotkey
icp identity export node-provider-hotkey | openssl ec -out ~/node-provider-hotkey.pem
chmod 600 ~/node-provider-hotkey.pem
icp identity principal --identity node-provider-hotkey

Save the printed principal, and store the seed phrase that icp identity new prints offline. The openssl ec step is required: ic-admin only reads SEC1 keys (BEGIN EC PRIVATE KEY), and icp identity export writes PKCS#8 (BEGIN PRIVATE KEY). It changes the format, not the key.

Step 2 — Stake the neuron

The neuron is controlled by a Ledger hardware wallet; the same device provides your node-provider principal. In the NNS dapp, connected to the Ledger:

  1. Send at least 51 ICP to the Ledger account.
  2. Under Neurons, stake at least 51 ICP from the Ledger account and confirm on the device.
  3. Add the NNS dapp as a hotkey on the neuron, so you can manage it in the browser without the device.
  4. Set the dissolve delay to at least 6 months.
  5. Copy the neuron ID.

Step 3 — Add the hotkey to the neuron

In the NNS dapp, open the neuron, go to Hotkeys, and add the principal from step 1.

Step 4 — Submit proposals

Every node-provider proposal follows the same pattern: sign with the hotkey and pass the neuron ID as --proposer.

./ic-admin \
  --nns-url https://icp-api.io \
  -s ~/node-provider-hotkey.pem \
  <propose-to-...> \
  --proposer $NEURON_ID \
  --proposal-title "..." \
  --summary-file summary.md \
  <command-specific flags>

Add --dry-run to print the payload without submitting it. Do this first: once a proposal is submitted it is public, and if it is voted down it costs the neuron 50 ICP.

Before submitting, post the context on the node-provider thread of the developer forum and link it in the summary. Proposals without that context are routinely voted down. Track the result on the governance dashboard.

Keeping the setup safe

  • The hotkey file is plaintext. If it leaks, an attacker can submit proposals and vote as your neuron, but cannot take the stake. Remove the hotkey from the neuron in the NNS dapp and create a new one.
  • Do not dissolve the neuron while you still expect to submit proposals. Once the dissolve delay falls below 6 months, it can no longer propose.
  • Use the same neuron for all of your proposals. Reviewers recognise the neuron ID, which makes your proposals easier to verify.