merkletree.js

const { MerkleTree } = require("merkletreejs");
const keccak256 = require("keccak256");

let whitelistAddresses = [
    "0x5B38Da6a701c568545dCfcB03FcB875f56beddC4",
    "0xAb8483F64d9C6d1EcF9b849Ae677dD3315835cb2",
    "0x4B20993Bc481177ec7E8f571ceCaE8A9e22C02db",
    "0x78731D3Ca6b7E34aC0F824c42a7cC18A495cabaB",
    "0x617F2E2fD72FD9D5503197092aC168c91465E7f2",
    "0x17F6AD8Ef982297579C203069C1DbfFE4348c372",
    "0x5c6B0f7Bf3E7ce046039Bd8FABdfD3f9F5021678"
]


const leafNodes = whitelistAddresses.map(addr => keccak256(addr));
const merkleTree = new MerkleTree(leafNodes, keccak256, { sortPairs: true });

const rootHash = merkleTree.getRoot();

console.log('Whitelist Merkle Tree \n', merkleTree.toString());

console.log("Root Hash: ", rootHash.toString('hex'));

console.log("\nwhitelistAddresses count is ", whitelistAddresses.length);
console.log("\n--------------------- Merkle Proof for Address -----------------------");


// website create proof
const testAddr = "0x5c6B0f7Bf3E7ce046039Bd8FABdfD3f9F5021678";
//const claimingAddress = leafNodes[0];
//const claimingAddress = keccak256(whitelistAddresses[0]);
const claimingAddress = keccak256(testAddr);
console.log("claimingAddress is \n", claimingAddress.toString('hex'));

const hexProof = merkleTree.getHexProof(claimingAddress);

console.log(hexProof);

if( hexProof.length > 0){
    let paramscon = "["

    // to contract params
    for (p in hexProof) {
        if(p != hexProof.length - 1) {
            paramscon += "\"" + hexProof[p] + "\",";
        }else{
            paramscon += "\"" + hexProof[p] + "\"]";
        }   
    }

    console.log(paramscon);
}

MerkleVerify.sol

// SPDX-License-Identifier: MIT
pragma solidity 0.8.4;

import "@openzeppelin/contracts/utils/cryptography/MerkleProof.sol";

contract MerkleVerify {
    bytes32 public merkleRoot = 0x4d871defed228a51607c31f9c8419b314f51fa8fbd81b62f958251d9a4e888cd;

    mapping(address => bool) public whitelistClaimed;

    function whitelistMint(bytes32[] calldata _merkleProof) public {
        require(!whitelistClaimed[msg.sender], "Address has already claimed.");

        bytes32 leaf = keccak256(abi.encodePacked(msg.sender));
        require(MerkleProof.verify(_merkleProof, merkleRoot, leaf), "Invalid proof.");

        whitelistClaimed[msg.sender] = true;
    }
}

https://medium.com/@ItsCuzzo/using-merkle-trees-for-nft-whitelists-523b58ada3f9