Setup Stake Pool

Stake Pool setup with cardanocli-js

Find out more about cardanocli-js here.

Dependencies

Install Node.js

Install Node.js on Ubuntu

sudo snap install node --classic

Install cardano-node

x86: https://docs.cardano.org/projects/cardano-node/en/latest/getting-started/install.html ARM: https://github.com/alessandrokonrad/Pi-Pool

Setup Environment

Install cardanocli-js:

mkdir ~/node
cd ~/node
npm install cardanocli-js

Download required config files for the cardano node. Make sure you are in the ~/node directory:

mkdir files
cd files
wget https://hydra.iohk.io/job/Cardano/cardano-node/cardano-deployment/latest-finished/download/1/mainnet-config.json
wget https://hydra.iohk.io/job/Cardano/cardano-node/cardano-deployment/latest-finished/download/1/mainnet-byron-genesis.json
wget https://hydra.iohk.io/job/Cardano/cardano-node/cardano-deployment/latest-finished/download/1/mainnet-shelley-genesis.json
wget https://hydra.iohk.io/job/Cardano/cardano-node/cardano-deployment/latest-finished/download/1/mainnet-topology.json

Now run the node in order to sync the Cardano blockchain. Execute from ~/node:

cardano-node run \
   --topology files/mainnet-topology.json \
   --database-path db \
   --socket-path db/socket \
   --host-addr 0.0.0.0 \
   --port 3000 \
   --config files/mainnet-config.json

After the node is in sync we can start with the instantiation of cardanocli-js. Save the following code in a file called cardanocli.js under ~/node

const os = require("os");
const path = require("path");
const fetch = require("sync-fetch");

const dir = path.join(os.homedir(), "node");

const cardanocliJs = new CardanocliJs({
  era: "mary", //current era
  dir: dir, // working directory
  socketPath: path.join(dir,"db","socket"),
  shelleyGenesisPath: path.join(dir,"files","mainnet-shelley-genesis.json")
});

const createWallet = (account) => {
  cardanocliJs.addressKeyGen(account);
  cardanocliJs.stakeAddressKeyGen(account);
  cardanocliJs.stakeAddressBuild(account);
  cardanocliJs.addressBuild(account);
  return cardanocliJs.wallet(account);
};

const registerWallet = (wallet) => {
  const account = wallet.name;
  const keyDeposit = cardanocliJs.queryProtocolParameters().keyDeposit;
  const stakeCert = cardanocliJs.stakeAddressRegistrationCertificate(account);
  const balance = wallet.balance().amount.lovelace;
  
  const tx = {
    txIn: wallet.balance().utxo,
    txOut: [
      { address: wallet.paymentAddr, amount: { lovelace: balance - keyDeposit } },
    ],
    certs: [stakeCert],
    witnessCount: 2,
  };
  const txBodyRaw = cardanocliJs.transactionBuildRaw(tx); //create raw body
  const fee = cardanocliJs.transactionCalculateMinFee({
    ...tx,
    txBody: txBodyRaw,
  }); //calculate fees for the raw body
  tx.txOut[0].amount.lovelace -= fee; //subtract the required Tx fees
  const txBody = cardanocliJs.transactionBuildRaw({ ...tx, fee }); //final body with fees included
  const txSigned = cardanocliJs.transactionSign({
    txBody,
    signingKeys: [
      wallet.payment.skey,
      wallet.stake.skey,
    ],
  });

  return txSigned;
};

const createPool = (name) => {
  cardanocliJs.nodeKeyGenKES(name);
  cardanocliJs.nodeKeyGen(name);
  cardanocliJs.nodeIssueOpCert(name);
  cardanocliJs.nodeKeyGenVRF(name);
  return cardanocliJs.pool(name);
};

const registerPool = (pool, wallet, data) => {
  const name = pool.name;
  const poolId = cardanocliJs.stakePoolId(name);
  const poolCert = cardanocliJs.stakePoolRegistrationCertificate(name, data);
  const delegCert = cardanocliJs.stakeAddressDelegationCertificate(
    wallet.name,
    poolId
  );
  const poolDeposit = cardanocliJs.queryProtocolParameters().poolDeposit;
  const tx = {
    txIn: wallet.balance().utxo,
    txOut: [
      {
        address: wallet.paymentAddr,
        amount: { lovelace: wallet.balance().amount.lovelace - poolDeposit },
      },
    ],
    witnessCount: 3,
    certs: [poolCert, delegCert],
  };
  const txBodyRaw = cardanocliJs.transactionBuildRaw(tx);
  const fee = cardanocliJs.transactionCalculateMinFee({
    ...tx,
    txBody: txBodyRaw,
  });
  tx.txOut[0].amount.lovelace -= fee;
  const txBody = cardanocliJs.transactionBuildRaw({ ...tx, fee });
  const txSigned = cardanocliJs.transactionSign({
    txBody,
    signingKeys: [wallet.payment.skey, wallet.stake.skey, pool.node.skey],
  });
  return txSigned;
};

module.export = {
  cardanocliJs,
  fetch,
  createWallet,
  registerWallet,
  createPool,
  registerPool    
}

Stake Pool Registration

With the command nodewe open the Node.js interpreter. This is where we are going to register the pool. We are going to register a single owner pool in this example:

$ node
Welcome to Node.js v14.15.0.
Type ".help" for more information.
>

Register Wallet

> const c = require("./cardanocli.js")
> const cardanocliJs = c.cardanocliJs
>
> const wallet = c.createWallet("Main")
> wallet.paymentAddr
addrdfhuj239hfj832f32jf2i3jf3hf923
> wallet.balance().amount
{ lovelace: 5000000 }
> const tx_wallet = c.registerWallet(wallet)
> const txHash_wallet = cardanocliJs.transactionSubmit(tx_wallet)
> txHash_wallet
hfs98dh823hf9823h93f2h9

Register Pool

> const pool = c.createPool("MyPool")
> const metaUrl = "https://pool.com/poolmeta.json"
> const poolData = {
    pledge: cardanocliJs.toLovelace(100),
    margin: 0.015
    cost: cardanocliJs.toLovelace(340),
    owners: [wallet.stake.vkey],
    rewardAccount: wallet.stake.vkey,
    relays: [
    {host: "relay.one.example", port: 3001},
    {ip: "123.456.78.9", port: 3001}
    ],
    url: metaUrl,
    metaHash: cardanocliJs.stakePoolMetadataHash(c.fetch(metaUrl).text())
}
> const tx_pool = registerPool(pool,wallet,poolData)
> const txHash_pool = cardanocliJs.transactionSubmit(tx_pool)
> txHash_pool
hf9h9832hfu9jhuf9hewfhe

Last updated