testnet
GitHub

Minting OKRW from a Smart Contract

intermediate integration 45 min

A step-by-step tutorial on how to create, deploy, and interact with a smart contract that mints OKRW tokens using the precompile.

What You Will Learn

  • How to interface with a Maroo precompile in Solidity.
  • How to write a contract that can mint OKRW.
  • How to configure your local testnet to authorize your contract as a minter.
  • How to use Hardhat scripts to deploy and call your contract.
  • How to verify the minting event and balance changes.

Prerequisites

  • A running Maroo local testnet (`marood testnet`).
  • Basic understanding of Solidity and Hardhat.

Tools Needed

Node.js 18+Hardhatmarood CLI
In this tutorial, you will build a simple 'Faucet' contract. This contract will be authorized to mint a fixed amount of OKRW to any address that requests it, demonstrating the full lifecycle of programmatic minting on Maroo.
1

1. Project Setup

First, let's set up a new Hardhat project. Open your terminal and run the following commands:
terminal bash
mkdir maroo-faucet && cd maroo-faucet
npm init -y
npm install --save-dev hardhat @nomicfoundation/hardhat-toolbox @openzeppelin/contracts
npx hardhat init # Choose 'Create a TypeScript project'
2

2. Create the Smart Contracts

We need the IOkrw.sol interface to interact with the precompile. Create this file in your contracts directory. Then, we'll write the OkrwFaucet.sol contract that uses this interface.
contracts/IOkrw.sol solidity
// SPDX-License-Identifier: Apache-2.0
pragma solidity ^0.8.18;

interface IOkrw {
    error UnauthorizedMinter(address caller, address authorizedMinter);
    error InvalidAddress(address addr);
    error InvalidAmount(uint256 amount);

    function mint(address recipient, uint256 amount) external returns (bool);

    event Mint(address indexed minter, address indexed recipient, uint256 amount);
}
contracts/OkrwFaucet.sol solidity
// SPDX-License-Identifier: Apache-2.0
pragma solidity ^0.8.18;

import "./IOkrw.sol";

contract OkrwFaucet {
    IOkrw constant okrw = IOkrw(0x1000000000000000000000000000000000000001);
    uint256 public immutable dripAmount = 100 * 10**18; // 100 OKRW

    event Dispensed(address indexed recipient, uint256 amount);

    function requestTokens() external {
        // This call will only succeed if this contract's address
        // is the authorized minter on the Maroo network.
        bool success = okrw.mint(msg.sender, dripAmount);
        require(success, "Faucet: OKRW minting failed");
        emit Dispensed(msg.sender, dripAmount);
    }
}
3

3. Deploy the Faucet

Now, let's write a Hardhat script to deploy our faucet. This will give us the contract address we need for the next step.
scripts/deploy.ts typescript
import { ethers } from "hardhat";

async function main() {
  const Faucet = await ethers.getContractFactory("OkrwFaucet");
  const faucet = await Faucet.deploy();
  await faucet.waitForDeployment();
  const faucetAddress = await faucet.getAddress();
  console.log(`OkrwFaucet deployed to: ${faucetAddress}`);
}

main().catch((error) => {
  console.error(error);
  process.exitCode = 1;
});
Tip: You'll need to configure your `hardhat.config.ts` to connect to your local Maroo node. The default RPC URL is `http://127.0.0.1:8545` and the chain ID is `9000`.
4

4. Authorize the Faucet as Minter

The OKRW precompile only allows a specific address to mint. We must now authorize our newly deployed OkrwFaucet contract. Run the deploy script, copy the contract address, and then use the marood CLI to update the x/okrw module parameters.
terminal bash
npx hardhat run scripts/deploy.ts --network localhost
# Copy the output address, e.g., 0x5FbDB2315678afecb367f032d93F642f64180aa3
terminal bash
# Replace with your validator key name from the local testnet setup
VALIDATOR_KEY_NAME="validator"

# Paste the deployed contract address here
CONTRACT_ADDR_HEX="0x5FbDB2315678afecb367f032d93F642f64180aa3"

# Convert hex address to bech32 format for the transaction
CONTRACT_ADDR_BECH32=$(marood debug addr $CONTRACT_ADDR_HEX | grep "Bech32 Acc" | awk '{print $3}')

# Send the transaction to update the minter address
marood tx okrw update-params --minter-address $CONTRACT_ADDR_BECH32 --from $VALIDATOR_KEY_NAME --chain-id maroo_9000-1 --keyring-backend test -y --broadcast-mode=block
5

5. Interact and Verify

With the faucet deployed and authorized, anyone can now call requestTokens() to receive 100 OKRW. Let's create a script to do this and then verify the balance change.
scripts/request.ts typescript
import { ethers } from "hardhat";

async function main() {
  const faucetAddress = "0x5FbDB2315678afecb367f032d93F642f64180aa3"; // Paste your deployed address
  const faucet = await ethers.getContractAt("OkrwFaucet", faucetAddress);
  const [signer] = await ethers.getSigners();

  console.log(`Requesting 100 OKRW for ${signer.address}...`);
  const tx = await faucet.requestTokens();
  const receipt = await tx.wait();
  console.log("Tokens requested! Tx hash:", receipt.hash);
}

main().catch(console.error);
terminal bash
# Run the request script
npx hardhat run scripts/request.ts --network localhost

# Verify the balance of the Hardhat default account (0xf39...2266)
marood query bank balances 0xf39fd6e51aad88f6f4ce6ab8827279cfffb92266

# You should see a balance of 100000000000000000000aokrw

Conclusion

Congratulations! You have successfully created a smart contract that can mint OKRW, configured the Maroo chain to authorize it, and used it to receive tokens. This pattern is fundamental for building applications that manage OKRW liquidity on Maroo.
Source: maroo
ESC
Type to search