This guide is created to help a user of Minterest protocol to optimise their position with regards to Governance rewards - update MINTY balance and stake additional MINTY. The example below allows doing the desired actions directly through Minterest contracts API and not using the UI.
The guide describes how to trigger the stake function and the update balance function. The first one allows to add more MINTY from a wallet into the protocol stake pool, thus increasing the weight of a user in buyback contract and increasing their share of rewards. The second one allows to optimise the user weight by adding all freshly earned rewards into the buyback weight, which again increases the weight of a user and their share of rewards.
Preconditions
In order to do the stake and update balance operations directly on the contract level using Ethers.js, one needs:
A private key of a wallet with enough ETH and MINTY on it
A public key of this wallet
Infura API key (can be easily substituted with Alchemy or any other provider)
Addresses and raw ABI files of the target contracts - Buyback and Rewards Hub
The example below is using node.js as the basis to execute the JavaScript code. One needs to set it up, as well as set up the Ethers.js library itself. The setup of node.js and Ethers.js is out of scope of the guide, as it may differ for different operating systems. Detailed instructions can be found on respective resources.
Considering the node.js and Ethers.js are installed and configured, three files should be created:
A JavaScript file, that will contain the code to execute transactions
Two JSON files to store the ABI of the target contracts
JSON file content
The ABI of the contracts can be retrieved using Etherscan. Open the contract pages of Buyback and Rewards Hub contracts and look for the ABI section. The result of 'RAW/Text Format" export should be copied to the respective JSON file. In the example below the JSON files are called buyback_abi.json and rewardshub_abi.json. They are placed next to the JS file with the code - this is important to simplify the import of the data.
JavaScript file
The next line of code creates a wallet abstraction in the code. This abstraction will be used to sign transaction
The contract abstractions (created in these line of code) will be used to call functions like stake. Note how the instances are already linked to the wallet that will be used to communicate with the chain.
// 4. Create contract instance with signerconstbuyback=newethers.Contract(BUYBACK_ADDRESS,BUYBACK_ABI, wallet);constrewardsHub=newethers.Contract(REWARDS_HUB_ADDRESS,REWARDS_HUB_ABI, wallet);
The following blocks define two functions, which call respective contract API endpoints for staking and updating MINTY balance. The functions are very similar, they send a signed transaction to the chain and wait for a success or error message. In this example the functions use calls to two different contracts.
// 6. Define functions to stake and update MNT balanceconstmakeStake=async (value) => {console.log(`Calling Stake with value ${value} in contract at address: ${BUYBACK_ADDRESS}` );constcreateReceipt=awaitbuyback.stake(value); awaitcreateReceipt.wait();console.log(`Tx successful with hash: ${createReceipt.hash}`);};constupdateMntBalance=async () => {console.log(`Calling Update MNT in contract at address: ${REWARDS_HUB_ADDRESS}` );constcreateReceipt=awaitrewardsHub.distributeAllMnt(PUBLIC_KEY); awaitcreateReceipt.wait();console.log(`Tx successful with hash: ${createReceipt.hash}`);};
Finally, the code below invokes the functions.
// 7. Call the functionsmakeStake(stakeValue);updateMntBalance();
The full code of the example:
// 1. Setup of providerconst { ethers,JsonRpcProvider } =require('ethers');constBUYBACK_ABI=require("./buyback_abi.json");constREWARDS_HUB_ABI=require("./rewardshub_abi.json");constINFURA_API_KEY="2dd49fdb426a42dd9702e218034b0f2c";constprovider=newJsonRpcProvider(`https://mainnet.infura.io/v3/${INFURA_API_KEY}`);// 2. Create variablesconstPRIVATE_KEY="a23d1bf17acc1937db942b6f05a7a87db23bb618be83748f455a7acb420e87ae";constPUBLIC_KEY="0x7Ca0f34b42A22Dd3A0276d95A80837342cC6fc63";constBUYBACK_ADDRESS="0xED78B0879B09392a502Dd5De3f56516Be19F61e8"; constREWARDS_HUB_ADDRESS="0x63e0DBEC2143acae33d2cc53e23D9134359e0399";conststakeValue=10;// 3. Create walletlet wallet =newethers.Wallet(PRIVATE_KEY, provider);// 4. Create contract instance with signerconstbuyback=newethers.Contract(BUYBACK_ADDRESS,BUYBACK_ABI, wallet);constrewardsHub=newethers.Contract(REWARDS_HUB_ADDRESS,REWARDS_HUB_ABI, wallet);// 6. Define functions to stake and update MNT balanceconstmakeStake=async (value) => {console.log(`Calling Stake with value ${value} in contract at address: ${BUYBACK_ADDRESS}` );constcreateReceipt=awaitbuyback.stake(value); awaitcreateReceipt.wait();console.log(`Tx successful with hash: ${createReceipt.hash}`);};constupdateMntBalance=async () => {console.log(`Calling Update MNT in contract at address: ${REWARDS_HUB_ADDRESS}` );constcreateReceipt=awaitrewardsHub.distributeAllMnt(PUBLIC_KEY); awaitcreateReceipt.wait();console.log(`Tx successful with hash: ${createReceipt.hash}`);};// 7. Call the functionsmakeStake(stakeValue);updateMntBalance();