Activating delegated harvesting

Share your account’s importance securely with a node.

Background

Delegated harvesting enables accounts to receive rewards from creating new blocks without running a node.

Follow this guide to delegate your account importance without compromising the account’s funds.

Prerequisites

Getting into some code

Before you can activate delegated harvesting, make sure your main account has at least 500 cat.harvest units. Then, you will have to delegate your main account importance to a proxy public key (remote account) before requesting a node to add you as a delegated harvester.

sequenceDiagram participant Account participant Network participant Node Account ->> Network: AccountLinkTransaction(remotePublicKey) activate Network Network -->> Account: Confirms transaction deactivate Network Account ->> Network: TransferTransaction(nodePublicKey, encryptedRemotePrivateKey) activate Network Network -->> Account: Confirms the transaction deactivate Network Network -->> Node: Sends notification opt eligible remote account Node ->> Node: Adds delegated harvester Node ->> Node: Saves remote private key on disk end

Delegated harvesting activation diagram

  1. Define your main account and the remote account using their private keys. The proxy private key (remote account) must belong to a brand new account that did not send or received any transaction previously.
const accountPrivateKey = process.env.PRIVATE_KEY as string;
const account = Account.createFromPrivateKey(accountPrivateKey, NetworkType.MIJIN_TEST);

const remoteAccount = Account.generateNewAccount(NetworkType.MIJIN_TEST);
  1. Create an AccountLinkTransaction to delegate the main account’s importance to the remote account using its public key.
const accountLinkTransaction = AccountLinkTransaction.create(
    Deadline.create(),
    remoteAccount.publicKey,
    LinkAction.Link,
    NetworkType.MIJIN_TEST);

The next step is to share the remote account private key with the node you wish to connect for delegated harvesting.

  1. Create a PersistentDelegationRequestTransaction. Add the node’s public key as the transaction recipient and share the remote account private key by creating a special encrypted message as follows:
const nodePublicKey = process.env.NODE_PUBLIC_KEY as string;
const nodePublicAccount = PublicAccount.createFromPublicKey(nodePublicKey, NetworkType.MIJIN_TEST);

const persistentDelegationRequestTransaction = PersistentDelegationRequestTransaction
    .createPersistentDelegationRequestTransaction(
        Deadline.create(),
        remoteAccount.privateKey,
        nodePublicAccount.publicKey,
        account.privateKey,
        NetworkType.MIJIN_TEST);

Note

Get the node’s public key by querying http://<node-url>:3000/node/info.

The special encrypted message ensures that the proxy private key is securely shared, only readable by the node owner. Moreover, the remote account does not possess any mosaics. The valuable assets remain safely in the main account where the node owner cannot disrupt security.

  1. Announce both transactions together with an AggregateCompleteTransaction, signing it with your main account.
const aggregateTransaction = AggregateTransaction.createComplete(
    Deadline.create(),
    [
        accountLinkTransaction.toAggregate(account.publicAccount),
        persistentDelegationRequestTransaction.toAggregate(account.publicAccount),
    ],
    NetworkType.MIJIN_TEST,
    []);

const networkGenerationHash = process.env.NETWORK_GENERATION_HASH as string;
const signedTransaction = account.sign(aggregateTransaction, networkGenerationHash);

const nodeUrl = 'http://localhost:3000';
const transactionHttp = new TransactionHttp(nodeUrl);
transactionHttp
    .announce(signedTransaction)
    .subscribe(x=> console.log(x),err => console.error(err));

The node receives an encrypted message using WebSockets. Once the node decrypts the private key of the potential delegated harvester, the node owner may add the remote account as a delegated harvester if the following requirements are met:

  • The node permits delegated harvesting.
  • The node has harvesting slots available.
  • The remote account has not sent or received transactions.

Note

Announcing a valid PersistentDelegationRequestTransaction does not guarantee being added as a delegated harvester. Currently, the only way to verify that an account has successfully activated delegated harvesting is to become the signer of a new block.