7

I am attempting to verify a Merkle Tree using the metaplex SDK for the Candy Guard from Cm v3. Specifically I wanna get this working in JS, same as this in Rust What I have is this:

import {
  getMerkleProof,
  getMerkleRoot,
  getMerkleTree,
} from "@metaplex-foundation/js";
import { keccak_256 } from "@noble/hashes/sha3";

const allowList = [
  "AT8nPwujHAD14cLojTcB1qdBzA1VXnT6LVGuUd6Y73Cy",
  "AT8nPwujHAD14cLojsTcB1zzqdBzA1VXnTtLVGuUd6Y73Cy",
  "Ur1CbWSGsXCdedknRbJsEk7urwAvu1uddmQv51nAnXB",
  "GjwcWFQYzemBtpUoN5fMAP2FZviTtMRWCmrppGuTthJS",
];

// what is stored on chain
const merkleRoot = getMerkleRoot(allowList);
console.log({ merkleRoot: merkleRoot });

// what is passed via router guard along with payer
const validMerkleProof = getMerkleProof(
  allowList,
  "Ur1CbWSGsXCdedknRbJsEk7urwAvu1uddmQv51nAnXB"
);

const isTreeValid = getMerkleTree(allowList).verify(
  validMerkleProof.map((e) => Buffer.from(keccak_256(e))),
  Buffer.from(keccak_256("Ur1CbWSGsXCdedknRbJsEk7urwAvu1uddmQv51nAnXB")),
  Buffer.from(keccak_256(merkleRoot.toString()))
);

console.log({ tree1: isTreeValid });

I'd like to get isTreeValid to be true, I cant figure out how to bufferize, hash the data I pass into the verify function.

I am just doing this to inspect stuff, no real purpose beyond exploring.

2
  • 1. if allowList array is available at the same environment/project where you perform the check and 2. you trust these allowList array and 3. it is relatively small (I assume so if it is in on a web page) then it is just a simple check against your allowList array. Or I missing something? Oct 8, 2023 at 15:01
  • @DmitryShvetsov hey, i asked this 1 year ago. I got an answer from Austin Bot below. It has been already solved. Thanks anyway. Oct 9, 2023 at 16:05

1 Answer 1

2

the issue is that you were doing this

validMerkleProof.map((e) => Buffer.from(keccak_256(e))),

This was re hashing the already hashed proofs from the merkleProof function.

With the following code I was able to get your example working.

 console.log(validMerkleProof)
  const isTreeValid = getMerkleTree(allowList).verify(
    validMerkleProof.map((e) => Buffer.from(e)),
    Buffer.from(keccak_256("Ur1CbWSGsXCdedknRbJsEk7urwAvu1uddmQv51nAnXB")),
    Buffer.from(merkleRoot)
  );

Notice instead of mapping keccak_256 again over e i'm just making a buffer from the u8 array.

Also node that you are calling verify on he merkle tree class returned from the metaplex js library which is returning an object from the merklejs library. There should be a verify function in the metaplex js too that may have handled this.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.