Skip to content

Commit

Permalink
Merge pull request #1 from RedChillies-Core/feat/wallet
Browse files Browse the repository at this point in the history
Support for Base 16 and Bech32 Wallet Address
  • Loading branch information
GSaphal committed Dec 24, 2021
2 parents 6e33b01 + 2c39850 commit 3d6263d
Show file tree
Hide file tree
Showing 4 changed files with 80 additions and 25 deletions.
27 changes: 16 additions & 11 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -16,21 +16,26 @@ yarn add merkle-tree-zilliqa-js

## Example

1. The first step is to import the function generateTree from the package.
1. The first step is to import the function generateTreeforBech32,generateTreeforBase16 from the package.

```javascript
import { generateTree } from 'merkle-tree-zilliqa-js';
import { generateTreeforBech32, generateTreeforBase16 } from 'merkle-tree-zilliqa-js';
```

2. The next step is to send a array of data to the generate tree function. Make sure that the data has the following format:

[
{
wallet:"zil..............",
amount:"10000000000",
}
]
Note: Make sure that the wallet passed is in the base32 format i.e zil.............
2. The next step is to send a array of data to the generate tree function. The format of data should be:
[
{
wallet:"",
address:""
},
{
wallet:"",
address:""
},
.....
]

### The address should be in base16 for generateTreeforBase16 and bech32 for generateTreeforBase16.

3. And boom, you are done! It returns you with the merkle root and proof for all the passed wallets, which can be passed on Smart Contracts for claiming the rewards.

Expand Down
4 changes: 2 additions & 2 deletions package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "merkle-tree-zilliqa-js",
"version": "1.0.0",
"version": "1.0.1",
"description": "A JS Library to generate the merkle tree and gets it's root and proof for any given distribution",
"main": "lib/index.js",
"types": "lib/index.d.ts",
Expand Down Expand Up @@ -43,4 +43,4 @@
"js-sha256": "^0.9.0",
"merkletreejs": "^0.2.27"
}
}
}
39 changes: 30 additions & 9 deletions src/__tests__/tests.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import { generateTree } from '../index';
const data = [
import { generateTreeforBase16, generateTreeforBech32 } from '../index';
const dataforBase32 = [
{
wallet: 'zil1m6n92lvaymnsdksy53gawffhqd9fuj5p27cj9p',
amount: '199170000000000000000',
Expand All @@ -17,7 +17,24 @@ const data = [
amount: '2055080000000000000000',
},
];

const dataforBase16 = [
{
wallet: '0xdea6557d9d26e706da04a451d72537034a9e4a81',
amount: '199170000000000000000',
},
{
wallet: '0xbccc7c3707f4e8c671ff300a2298ea5670f50cbe',
amount: '199170000000000000000',
},
{
wallet: '0xdb578850641008b1244a8c8a4507e8e156ec7901',
amount: '3387290000000000000000',
},
{
wallet: '0xc6e886865b306df85aa6fd18d6d1bfa80d6a544d',
amount: '2055080000000000000000',
},
];
const result = {
data: [
{
Expand All @@ -26,36 +43,40 @@ const result = {
'0x0930cc1c35bd425c438e47f974e853c6682d7067dd917c5582a6cc7129b867f9',
'0xdd6b9a5f0846d50278cff64bde1292c39eb7d217c01afeff8055f78a13c21e15',
],
wallet: '0xDEa6557d9D26E706dA04a451D72537034A9E4A81',
wallet: '0xdea6557d9d26e706da04a451d72537034a9e4a81',
},
{
amount: '199170000000000000000',
proof: [
'0xd6cd85604de0c761d32760b3450d6e56a262c6e608d82e70b70e0951a64cf559',
'0x4dfdb08794036c3926a23b15b59fa5a778520560252f0b83b12f9a874a967070',
],
wallet: '0xbCcc7C3707f4E8c671fF300A2298Ea5670F50CBE',
wallet: '0xbccc7c3707f4e8c671ff300a2298ea5670f50cbe',
},
{
amount: '3387290000000000000000',
proof: [
'0x3147fc7569f811ec9b83e181b5a373f5d35694708865a5e282c51974f0ff6368',
'0xdd6b9a5f0846d50278cff64bde1292c39eb7d217c01afeff8055f78a13c21e15',
],
wallet: '0xDb578850641008B1244a8c8A4507E8e156ec7901',
wallet: '0xdb578850641008b1244a8c8a4507e8e156ec7901',
},
{
amount: '2055080000000000000000',
proof: [
'0x7ab75f81f2a4ecf9c2ebce80672ef9ffa5809e4cb86a62c2cf0a20e8682bb281',
'0x4dfdb08794036c3926a23b15b59fa5a778520560252f0b83b12f9a874a967070',
],
wallet: '0xC6E886865b306df85aA6fd18d6d1bFa80D6A544d',
wallet: '0xc6e886865b306df85aa6fd18d6d1bfa80d6a544d',
},
],
root: '0x22385d58a88abea6d001cf0976c3e85393f5f5c8c9928284245b35f519915cd9',
};

test('Merkle Tree Generator', () => {
expect(generateTree(data)).toStrictEqual(result);
test('Merkle Tree Generator for Base 32', () => {
expect(generateTreeforBech32(dataforBase32)).toStrictEqual(result);
});

test('Merkle Tree Generator for Base 16', () => {
expect(generateTreeforBase16(dataforBase16)).toStrictEqual(result);
});
35 changes: 32 additions & 3 deletions src/tree-generator.ts
Original file line number Diff line number Diff line change
Expand Up @@ -10,19 +10,48 @@ interface DataInterface {

const getHashData = (el: any) => {
return sha256([
...bytes.hexToByteArray(fromBech32Address(el.wallet).slice(2, el.wallet.length)),
...bytes.hexToByteArray(fromBech32Address(el.wallet.toLowerCase()).slice(2, el.wallet.length)),
...bytes.hexToByteArray(sha256(new BN(el.amount).toArray('be', 16))),
]);
};
const getHashDataBase16 = (el: any) => {
return sha256([
...bytes.hexToByteArray(el.wallet.toLowerCase().slice(2, el.wallet.length)),
...bytes.hexToByteArray(sha256(new BN(el.amount).toArray('be', 16))),
]);
};

export const generateTree = (props: DataInterface[]) => {
export const generateTreeforBech32 = (props: DataInterface[]) => {
const leavesData: string[] = [];
const accumulator: any[] = [];
props.forEach((element) => {
const hashedData = getHashData(element);
leavesData.push(hashedData);
accumulator.push({
wallet: fromBech32Address(element.wallet),
wallet: fromBech32Address(element.wallet).toLowerCase(),
hex: hashedData,
amount: element.amount,
});
});
const tree = new MerkleTree(leavesData, sha256, {
sortLeaves: true,
});
const merkleRoot = tree.getRoot().toString('hex');
accumulator.forEach((data) => {
const proof = tree.getHexProof(data.hex);
data.proof = proof;
delete data.hex;
});
return { root: `0x${merkleRoot}`, data: accumulator };
};
export const generateTreeforBase16 = (props: DataInterface[]) => {
const leavesData: string[] = [];
const accumulator: any[] = [];
props.forEach((element) => {
const hashedData = getHashDataBase16(element);
leavesData.push(hashedData);
accumulator.push({
wallet: element.wallet.toLowerCase(),
hex: hashedData,
amount: element.amount,
});
Expand Down

0 comments on commit 3d6263d

Please sign in to comment.