Skip to content

JuanuMusic/ethers-merkletree

Repository files navigation

ethers-merkletree

npm package Build Status Downloads Issues

A library for interacting with Merkle Trees powereed by ethers.js and merkletreejs

Install

npm install ethers-merkletree

Usage

A smart contract that uses a Merkle Tree for validating an account:

  • Says hello to the recipient that pays price to the contract.
  • Both values must be pased, and a proof that they are the right values.
  • If proof is correctly verified, the event Hello(to) is emited.
import "@openzeppelin/contracts/utils/cryptography/MerkleProof.sol";

contract PermissionedSalutation {
    event Hello(string);
    using MerkleProof for bytes32[];
    bytes32 public merkleRoot;

    function setMerkleRoot(bytes32 pMerkleRoot) public {
      merkleRoot = pMerkleRoot
    }

    function sayHello(address to, uint256 price, bytes32[] memory proof) public {
        bytes32 leaf = keccak256(abi.encodePacked(to, price));
        require(proof.verify(merkleRoot, leaf), "invalid proof");
        require(price = msg.value, "invalid price paid");
        emit Hello(to);
    }
}

Typescript Implementation

Import WMerkleTree (and types if needed)

import { WMerkleTree, LeafSignature } from 'ethers-merkletree';`

Mock of a list. You should be generating this on your own.

const myAllowList: LeafSourceObject[] = [
    { to: '0x68AC5eE798Ac6F6B0A42F9b3abc3C9FD26dbdeA6',
      price: ethers.utils.formatEther("1"),
    },
    { to: '0xCf43D97Ed9EC1d458cA69551bcd1Bb157314E0d8',
      price: price: ethers.utils.formatEther("1")
    }
  ];

Describe the items structure mapping it to the solidity types on the contract's parameters of function sayHello. For each of the parameters, define the name and the solicity type.Names MUST be exact to the source items, but there is no constrains for using the same names on the solidity contract, although I highly recomment it for making code easyly readable.

const leafSignature: LeafSignature = [
  { type: 'address', name: 'to' },
  { type: 'uint256', name: 'price' },
];

Create a new instance of WMerkleTree (Wrapped Merkle Tree suggestions accepted) passing the leafSignature and myAllowList

const merkleTree = new WMerkleTree(myAllowList, leafSignature);

You can now get the Merkle root of the Tree.

const merkleRoot = merkleTree.getHexRoot();
await permissionedSalutationContract.setMerkleRoot(merkleRoot);

And request to say hello to Second item on the list, with the evidence that the address can receive a Hello

// Generate the proof of item 1 on the array
const merkleProof = merkleTree.getHexProof(1);
const allowedRecipient = myAllowList[1];
await permissionedSalutationContract.sayHello(item.to item.price, merkleProof, {value: item.price});

API

WMerkleTree(sourceItems, leafSignature)

sourceItems

Type: T extends LeafSourceObject

An array with the items that make the leaves of the tree.

leafSignature

Type: LeafSignature An array of objects that define the signature of the leaf items. nane the name of the property of the item object type of sourceItems. It must match the item property name. It is not needed to match the name on the smart contract function, although I highly recommend it for clarity. type defines the solidity type to which a parameter resolves. (addess,uint256, bytes32,etc...).

About

Merkle tree interaction made easy

Resources

License

Stars

Watchers

Forks

Releases

No releases published

Packages

No packages published