From 3fd3a85a0ba43b7d0e9ade397cca182225ae4d2a Mon Sep 17 00:00:00 2001
From: Franco NG <franco.ng@lightcurve.io>
Date: Tue, 6 Feb 2024 14:36:40 +0100
Subject: [PATCH 1/3] Uses native 64-bit number operations support

---
 packages/tree-builder/package.json                        | 1 +
 .../src/applications/example/create_accounts.ts           | 8 +++-----
 packages/tree-builder/src/utils.ts                        | 5 +++++
 .../tree-builder/test/applications/build_tree.test.ts     | 6 +++---
 yarn.lock                                                 | 5 +++++
 5 files changed, 17 insertions(+), 8 deletions(-)

diff --git a/packages/tree-builder/package.json b/packages/tree-builder/package.json
index 3307728..d674eee 100644
--- a/packages/tree-builder/package.json
+++ b/packages/tree-builder/package.json
@@ -48,6 +48,7 @@
 		"@oclif/core": "^3",
 		"@oclif/plugin-help": "^6",
 		"@openzeppelin/merkle-tree": "^1.0.6",
+		"bignumber.js": "^9.1.2",
 		"ethereumjs-util": "^7.1.5",
 		"ethers": "^6.8.1",
 		"tweetnacl": "^1.0.3"
diff --git a/packages/tree-builder/src/applications/example/create_accounts.ts b/packages/tree-builder/src/applications/example/create_accounts.ts
index cfdad85..d593e51 100644
--- a/packages/tree-builder/src/applications/example/create_accounts.ts
+++ b/packages/tree-builder/src/applications/example/create_accounts.ts
@@ -1,9 +1,7 @@
 import * as fs from 'fs';
 import { address } from '@liskhq/lisk-cryptography';
 import { Account, ExampleKey } from '../../interface';
-
-// 1 LSK = 10^8 Beddows
-const LSK_MULTIPLIER = 10 ** 8;
+import { multiplyBeddows } from '../../utils';
 
 // Balances are random between 0 - <RANDOM_RANGE>
 const RANDOM_RANGE = 10000;
@@ -61,7 +59,7 @@ export function createAccounts(numberOfAccounts = 54) {
 	for (let index = 0; index < numberOfAccounts - multiSigs.length; index++) {
 		const account = sortedKeyPairs[index];
 		const balance = randomBalance(RANDOM_RANGE);
-		const balanceBeddows = Math.round(balance * LSK_MULTIPLIER);
+		const balanceBeddows = multiplyBeddows(balance);
 
 		results.push({
 			lskAddress: account.address,
@@ -72,7 +70,7 @@ export function createAccounts(numberOfAccounts = 54) {
 	for (const multiSig of multiSigs) {
 		const account = sortedKeyPairs[results.length];
 		const balance = randomBalance(RANDOM_RANGE);
-		const balanceBeddows = Math.round(balance * LSK_MULTIPLIER).toString();
+		const balanceBeddows = multiplyBeddows(balance);
 
 		results.push({
 			lskAddress: account.address,
diff --git a/packages/tree-builder/src/utils.ts b/packages/tree-builder/src/utils.ts
index ba9f6b8..e1fe3b0 100644
--- a/packages/tree-builder/src/utils.ts
+++ b/packages/tree-builder/src/utils.ts
@@ -1,5 +1,7 @@
 import { utils } from '@liskhq/lisk-cryptography';
+import BigNumber from 'bignumber.js';
 import { UserBalance } from './interface';
+import { LSK_MULTIPLIER } from './constants';
 
 export function append0x(input: string | Buffer): string {
 	if (input instanceof Buffer) {
@@ -29,3 +31,6 @@ export function getTotalBalance(balance: UserBalance): bigint {
 		balance.lockedBalances.reduce((acc, cur) => acc + cur.amount, BigInt(0))
 	);
 }
+export function multiplyBeddows(input: number): string {
+	return new BigNumber(input).multipliedBy(LSK_MULTIPLIER).toString();
+}
diff --git a/packages/tree-builder/test/applications/build_tree.test.ts b/packages/tree-builder/test/applications/build_tree.test.ts
index f6dd47f..e7f6563 100644
--- a/packages/tree-builder/test/applications/build_tree.test.ts
+++ b/packages/tree-builder/test/applications/build_tree.test.ts
@@ -6,9 +6,9 @@ import { StandardMerkleTree } from '@openzeppelin/merkle-tree';
 import { defaultAbiCoder } from '@ethersproject/abi';
 import { Account, ExampleKey } from '../../src/interface';
 import { createPayload, buildTree } from '../../src/applications/generate-merkle-tree/build_tree';
-import { LEAF_ENCODING, LSK_MULTIPLIER } from '../../src/constants';
+import { LEAF_ENCODING } from '../../src/constants';
 import { createKeyPairs } from '../../src/applications/example/create_key_pairs';
-import { append0x } from '../../src/utils';
+import { append0x, multiplyBeddows } from '../../src/utils';
 
 describe('buildTree', () => {
 	let accounts: Account[];
@@ -29,7 +29,7 @@ describe('buildTree', () => {
 			const numberOfOptionalKeys = Math.floor(5 * Math.random());
 			return {
 				lskAddress: key.address,
-				balanceBeddows: Math.floor(balance * LSK_MULTIPLIER).toString(),
+				balanceBeddows: multiplyBeddows(balance),
 				numberOfSignatures: numberOfMandatoryKeys + numberOfOptionalKeys,
 				mandatoryKeys: keyPairsSorted.slice(0, numberOfMandatoryKeys).map(key => key.publicKey),
 				optionalKeys: keyPairsSorted
diff --git a/yarn.lock b/yarn.lock
index e7af807..ee0a14c 100644
--- a/yarn.lock
+++ b/yarn.lock
@@ -1585,6 +1585,11 @@ before-after-hook@^2.2.0:
   resolved "https://registry.yarnpkg.com/before-after-hook/-/before-after-hook-2.2.3.tgz#c51e809c81a4e354084422b9b26bad88249c517c"
   integrity sha512-NzUnlZexiaH/46WDhANlyR2bXRopNg4F/zuSA3OpZnllCUgRaOF2znDioDWrmbNVsuZk6l9pMquQB38cfBZwkQ==
 
+bignumber.js@^9.1.2:
+  version "9.1.2"
+  resolved "https://registry.yarnpkg.com/bignumber.js/-/bignumber.js-9.1.2.tgz#b7c4242259c008903b13707983b5f4bbd31eda0c"
+  integrity sha512-2/mKyZH9K85bzOEfhXDBFZTGd1CTs+5IHpeFQo9luiBG7hghdC851Pj2WAhb6E3R6b9tZj/XKhbg4fum+Kepug==
+
 bin-links@^3.0.0:
   version "3.0.3"
   resolved "https://registry.yarnpkg.com/bin-links/-/bin-links-3.0.3.tgz#3842711ef3db2cd9f16a5f404a996a12db355a6e"

From 3f35ac94c7e576d4cb4a56a285c0005daff86e5b Mon Sep 17 00:00:00 2001
From: Franco NG <franco.ng@lightcurve.io>
Date: Tue, 6 Feb 2024 16:24:04 +0100
Subject: [PATCH 2/3] Remove bignumber.js, use new method for random int

---
 packages/tree-builder/package.json                 |  1 -
 .../src/applications/example/create_accounts.ts    | 14 +++++---------
 packages/tree-builder/src/constants.ts             |  3 ---
 packages/tree-builder/src/utils.ts                 |  8 ++++----
 .../test/applications/build_tree.test.ts           |  5 ++---
 yarn.lock                                          |  5 -----
 6 files changed, 11 insertions(+), 25 deletions(-)

diff --git a/packages/tree-builder/package.json b/packages/tree-builder/package.json
index d674eee..3307728 100644
--- a/packages/tree-builder/package.json
+++ b/packages/tree-builder/package.json
@@ -48,7 +48,6 @@
 		"@oclif/core": "^3",
 		"@oclif/plugin-help": "^6",
 		"@openzeppelin/merkle-tree": "^1.0.6",
-		"bignumber.js": "^9.1.2",
 		"ethereumjs-util": "^7.1.5",
 		"ethers": "^6.8.1",
 		"tweetnacl": "^1.0.3"
diff --git a/packages/tree-builder/src/applications/example/create_accounts.ts b/packages/tree-builder/src/applications/example/create_accounts.ts
index d593e51..49b39a4 100644
--- a/packages/tree-builder/src/applications/example/create_accounts.ts
+++ b/packages/tree-builder/src/applications/example/create_accounts.ts
@@ -1,10 +1,10 @@
 import * as fs from 'fs';
 import { address } from '@liskhq/lisk-cryptography';
 import { Account, ExampleKey } from '../../interface';
-import { multiplyBeddows } from '../../utils';
+import { randomBalanceBeddows } from '../../utils';
 
-// Balances are random between 0 - <RANDOM_RANGE>
-const RANDOM_RANGE = 10000;
+// Random Balance in Beddows between 0 - 2 ** 8 * (RANDOM_BYTES_RANGE)
+const RANDOM_BYTES_RANGE = 5;
 
 // Multisig Accounts
 // For each account it will use the address of the index as account holder,
@@ -39,8 +39,6 @@ const multiSigs = [
 	},
 ];
 
-const randomBalance = (range: number): number => Number((range * Math.random()).toFixed(8));
-
 export function createAccounts(numberOfAccounts = 54) {
 	const keyPairs = JSON.parse(
 		fs.readFileSync('../../data/example/key-pairs.json', 'utf-8'),
@@ -58,8 +56,7 @@ export function createAccounts(numberOfAccounts = 54) {
 	// Regular Accounts
 	for (let index = 0; index < numberOfAccounts - multiSigs.length; index++) {
 		const account = sortedKeyPairs[index];
-		const balance = randomBalance(RANDOM_RANGE);
-		const balanceBeddows = multiplyBeddows(balance);
+		const balanceBeddows = randomBalanceBeddows(RANDOM_BYTES_RANGE);
 
 		results.push({
 			lskAddress: account.address,
@@ -69,8 +66,7 @@ export function createAccounts(numberOfAccounts = 54) {
 
 	for (const multiSig of multiSigs) {
 		const account = sortedKeyPairs[results.length];
-		const balance = randomBalance(RANDOM_RANGE);
-		const balanceBeddows = multiplyBeddows(balance);
+		const balanceBeddows = randomBalanceBeddows(RANDOM_BYTES_RANGE);
 
 		results.push({
 			lskAddress: account.address,
diff --git a/packages/tree-builder/src/constants.ts b/packages/tree-builder/src/constants.ts
index da9c525..35b5e38 100644
--- a/packages/tree-builder/src/constants.ts
+++ b/packages/tree-builder/src/constants.ts
@@ -1,8 +1,5 @@
 import { computeStorePrefix } from './utils';
 
-// 1 LSK = 10^8 Beddows
-export const LSK_MULTIPLIER = 10 ** 8;
-
 // Each leaf will be encoded in the following order:
 // LSK_ADDRESS_IN_HEX: bytes20
 // BALANCE_IN_BEDDOWS: uint64
diff --git a/packages/tree-builder/src/utils.ts b/packages/tree-builder/src/utils.ts
index e1fe3b0..4662b33 100644
--- a/packages/tree-builder/src/utils.ts
+++ b/packages/tree-builder/src/utils.ts
@@ -1,7 +1,5 @@
 import { utils } from '@liskhq/lisk-cryptography';
-import BigNumber from 'bignumber.js';
 import { UserBalance } from './interface';
-import { LSK_MULTIPLIER } from './constants';
 
 export function append0x(input: string | Buffer): string {
 	if (input instanceof Buffer) {
@@ -31,6 +29,8 @@ export function getTotalBalance(balance: UserBalance): bigint {
 		balance.lockedBalances.reduce((acc, cur) => acc + cur.amount, BigInt(0))
 	);
 }
-export function multiplyBeddows(input: number): string {
-	return new BigNumber(input).multipliedBy(LSK_MULTIPLIER).toString();
+
+// When bytes = 8, max value = 2 ** (8 * 8) - 1
+export function randomBalanceBeddows(maxBytes = 8): string {
+	return BigInt(append0x(utils.getRandomBytes(maxBytes))).toString();
 }
diff --git a/packages/tree-builder/test/applications/build_tree.test.ts b/packages/tree-builder/test/applications/build_tree.test.ts
index e7f6563..8d3a938 100644
--- a/packages/tree-builder/test/applications/build_tree.test.ts
+++ b/packages/tree-builder/test/applications/build_tree.test.ts
@@ -8,7 +8,7 @@ import { Account, ExampleKey } from '../../src/interface';
 import { createPayload, buildTree } from '../../src/applications/generate-merkle-tree/build_tree';
 import { LEAF_ENCODING } from '../../src/constants';
 import { createKeyPairs } from '../../src/applications/example/create_key_pairs';
-import { append0x, multiplyBeddows } from '../../src/utils';
+import { append0x, randomBalanceBeddows } from '../../src/utils';
 
 describe('buildTree', () => {
 	let accounts: Account[];
@@ -24,12 +24,11 @@ describe('buildTree', () => {
 
 		// Create 5 accounts on the fly, they are all Multisig such that all fields are filled
 		accounts = keyPairsSorted.slice(0, 5).map(key => {
-			const balance = Number((10000 * Math.random()).toFixed(8));
 			const numberOfMandatoryKeys = Math.floor(5 * Math.random()) + 1;
 			const numberOfOptionalKeys = Math.floor(5 * Math.random());
 			return {
 				lskAddress: key.address,
-				balanceBeddows: multiplyBeddows(balance),
+				balanceBeddows: randomBalanceBeddows(),
 				numberOfSignatures: numberOfMandatoryKeys + numberOfOptionalKeys,
 				mandatoryKeys: keyPairsSorted.slice(0, numberOfMandatoryKeys).map(key => key.publicKey),
 				optionalKeys: keyPairsSorted
diff --git a/yarn.lock b/yarn.lock
index ee0a14c..e7af807 100644
--- a/yarn.lock
+++ b/yarn.lock
@@ -1585,11 +1585,6 @@ before-after-hook@^2.2.0:
   resolved "https://registry.yarnpkg.com/before-after-hook/-/before-after-hook-2.2.3.tgz#c51e809c81a4e354084422b9b26bad88249c517c"
   integrity sha512-NzUnlZexiaH/46WDhANlyR2bXRopNg4F/zuSA3OpZnllCUgRaOF2znDioDWrmbNVsuZk6l9pMquQB38cfBZwkQ==
 
-bignumber.js@^9.1.2:
-  version "9.1.2"
-  resolved "https://registry.yarnpkg.com/bignumber.js/-/bignumber.js-9.1.2.tgz#b7c4242259c008903b13707983b5f4bbd31eda0c"
-  integrity sha512-2/mKyZH9K85bzOEfhXDBFZTGd1CTs+5IHpeFQo9luiBG7hghdC851Pj2WAhb6E3R6b9tZj/XKhbg4fum+Kepug==
-
 bin-links@^3.0.0:
   version "3.0.3"
   resolved "https://registry.yarnpkg.com/bin-links/-/bin-links-3.0.3.tgz#3842711ef3db2cd9f16a5f404a996a12db355a6e"

From 6be97adab7d2c3f4690554cffd950f42fd6e4625 Mon Sep 17 00:00:00 2001
From: Franco NG <franco.ng@lightcurve.io>
Date: Tue, 6 Feb 2024 17:24:15 +0100
Subject: [PATCH 3/3] Update example mnemonic to 12-word for Lisk Desktop
 testing purpose

---
 .../tree-builder/src/applications/example/create_key_pairs.ts | 4 +++-
 1 file changed, 3 insertions(+), 1 deletion(-)

diff --git a/packages/tree-builder/src/applications/example/create_key_pairs.ts b/packages/tree-builder/src/applications/example/create_key_pairs.ts
index 8fefcbf..5361187 100644
--- a/packages/tree-builder/src/applications/example/create_key_pairs.ts
+++ b/packages/tree-builder/src/applications/example/create_key_pairs.ts
@@ -5,10 +5,12 @@ import { ExampleKey } from '../../interface';
 const initialPath = "m/44'/134'";
 
 export async function createKeyPairs(amount = 100) {
+	const mnemonic =
+		'abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon about';
 	const keys: ExampleKey[] = [];
 	for (let i = 0; i < amount; i++) {
 		const keyPath = `${initialPath}/${i}'`;
-		const privateKey = await ed.getPrivateKeyFromPhraseAndPath('lisk', keyPath);
+		const privateKey = await ed.getPrivateKeyFromPhraseAndPath(mnemonic, keyPath);
 		keys.push({
 			address: address.getLisk32AddressFromAddress(address.getAddressFromPrivateKey(privateKey)),
 			keyPath,