Shardeum Documentation
EcosystemAdvanced Operations

Programmatic Unstaking & Disaster Recovery

There might be situations where you need to unstake a node without using the standard operator-cli unstake command directly on that node, or worse, the validator node's data directory (containing secrets.json) is lost or corrupted. This guide outlines methods to handle such scenarios.

Understanding the Core Unstaking Mechanism

Unstaking is an on-chain transaction. The key components are:

  • Nominator: Your wallet address that originally staked the SHM. The private key of this wallet is needed to authorize the unstake.
  • Nominee: The public key (identity) of the validator node that was staked.
  • System Contract: Unstake transactions are sent to a specific Shardeum system contract address (0x0000000000000000000000000000000000010000).
  • Transaction Data: The data payload of the transaction includes:
`isInternalTx: true`
`internalTXType: 7` (for unstaking)
`nominator`: Your staker wallet address (lowercase).
`timestamp`: Current Unix timestamp in milliseconds.
`nominee`: The public key of the node being unstaked.
`force: false` (for a standard unstake; `true` is for forcing, which is risky).

Scenario 1: Unstaking Using a Different Healthy Validator Node

If the original validator node is offline or inaccessible, but you have its nominator (staker) wallet private key, you can use any other healthy, running Shardeum validator node (even one you just set up temporarily) to perform the unstake.

How it Works:

  1. The operator-cli unstake command on the "helper" node takes the private key of the original staker wallet.
  2. It uses this private key to determine the nominator address.
  3. It then queries the network (via an archiver or an active node) using the nominator address to find the nominee (the public key of the node that was actually staked by that wallet).
    • This is typically done by calling an endpoint like /account/<YOUR_STAKER_WALLET_ADDRESS> on an active node and looking for operatorAccountInfo.nominee.
  4. With both nominator and nominee identified, the CLI constructs and sends the unstake transaction.

Steps:

  1. Ensure you have a running Shardeum validator node (the "helper node"). It doesn't matter if this helper node is staked or not, or who staked it. It just needs to be running and connected to the correct network.
  2. Execute the unstake command on this helper node, providing the private key of the wallet that staked the original (lost/offline) node:
    # Inside the helper node's Docker container, or with operator-cli configured for it
    operator-cli unstake
  3. When prompted, enter the private key of the original staker wallet (the one whose funds you want to recover).

The helper node will then attempt to perform the unstake on behalf of your staker wallet for the originally staked node.

Scenario 2: Unstaking When secrets.json (Validator Identity) is Lost

If the secrets.json file of the validator node is lost (meaning the validator's own private/public key pair is gone), you can still unstake as long as you have the private key of the nominator (staker) wallet.

The process is the same as Scenario 1:

  1. Use any healthy, running Shardeum validator node (a "helper node").
  2. Run operator-cli unstake on the helper node.
  3. Provide the private key of the nominator (staker) wallet that was used to stake the lost node.

The network identifies the stake by the nominator address. The nominee (the lost node's public key) is retrieved from the network based on what that nominator staked.

Scenario 3: Fully Programmatic Unstaking (Advanced)

If you need to automate this or cannot use operator-cli for some reason, you can construct and send the raw transaction yourself using libraries like ethers.js.

Key Steps (Conceptual - refer to unstaking-node-programmatically.md for a script example):

  1. Gather Information:

    • Your nominator (staker) wallet private key and address.
    • The nominee address (public key of the node you want to unstake).
      • If you don't have the nominee address readily available (e.g., secrets.json is lost), you first need to query an active node's /account/<YOUR_NOMINATOR_WALLET_ADDRESS> endpoint to find the operatorAccountInfo.nominee associated with your stake.
    • A healthy Shardeum RPC endpoint for the correct network.
    • An active node's IP and port (or an archiver) to query for canUnstake status.
  2. Check canUnstake Status:

    • Before sending the transaction, query an active node: curl -X GET "http://<ACTIVE_NODE_IP>:<PORT>/canUnstake/<NOMINEE_ADDRESS>/<YOUR_NOMINATOR_WALLET_ADDRESS>"
    • Ensure stakeUnlocked.unlocked is true. If not, respect the remainingTime and reason.
  3. Construct the Transaction:

    • Provider & Wallet: Initialize an ethers.Wallet instance with your nominator's private key and an RPC provider.
    • Nonce & Gas Price: Get the current nonce for your nominator address and the network's gas price.
    • Unstake Data Object:
      const unstakePayload = {
        isInternalTx: true,
        internalTXType: 7,
        nominator: yourNominatorWalletAddress.toLowerCase(),
        timestamp: Date.now(),
        nominee: nomineeAddress, // Public key of the node being unstaked
        force: false,
      };
    • Transaction Object:
      const transaction = {
        from: yourNominatorWalletAddress,
        to: '0x0000000000000000000000000000000000010000', // Shardeum system contract
        gasPrice: gasPrice,
        gasLimit: 30000000, // A sufficiently high gas limit
        data: ethers.utils.hexlify(ethers.utils.toUtf8Bytes(JSON.stringify(unstakePayload))),
        nonce: nonce,
      };
  4. Sign and Send:

    • Use wallet.sendTransaction(transaction) to sign and broadcast.
    • Monitor the transaction hash on the explorer.

Important Notes for Programmatic Unstaking:

  • Error Handling: Implement robust error handling for API calls and transaction submissions.
  • Security: Handle private keys with extreme care. Avoid hardcoding them; use environment variables or secure secret management solutions.
  • secrets.json Backup: The simplest disaster recovery for a lost validator instance (but not the staker wallet) is to have a backup of its secrets.json file. You can then place this file in the data directory of a new validator instance, and it will assume the identity of the old node, allowing operator-cli unstake to work directly. The programmatic method is more for when secrets.json is irretrievably lost or you need a fully automated off-node solution.

On this page