diff --git a/examples/bri-3/src/bri/merkleTree/services/merkleTree.service.spec.ts b/examples/bri-3/src/bri/merkleTree/services/merkleTree.service.spec.ts new file mode 100644 index 000000000..c5a729f52 --- /dev/null +++ b/examples/bri-3/src/bri/merkleTree/services/merkleTree.service.spec.ts @@ -0,0 +1,69 @@ +import { MerkleTreeService } from './merkleTree.service'; +import MerkleTree from 'merkletreejs'; + +let merkleTreeService: MerkleTreeService; +let payload: any; +beforeAll(async () => { + payload = { + SupplierInvoiceID: 'INV123', + Amount: 300, + IssueDate: '2023-06-15', + DueDate: '2023-07-15', + Status: 'NEW', + Items: [ + { id: 1, productId: 'product1', price: 100, amount: 1 }, + { id: 2, productId: 'product2', price: 200, amount: 1 }, + ], + }; + merkleTreeService = new MerkleTreeService(); +}); + +describe('MerkleTree Service', () => { + it('Should merkelize raw json with arrays properly', async () => { + // Arrange + const expectedLeaves = [ + 'SupplierInvoiceID', + 'INV123', + 'Amount', + '300', + 'IssueDate', + '2023-06-15', + 'DueDate', + '2023-07-15', + 'Status', + 'NEW', + 'id', + '1', + 'productId', + 'product1', + 'price', + '100', + 'amount', + '1', + 'id', + '2', + 'productId', + 'product2', + 'price', + '200', + 'amount', + '1', + ]; + + // Act + const merkelizedPayload = merkleTreeService.merkelizePayload( + payload, + 'sha256', + ); + + const expectedPayload = merkleTreeService.formMerkleTree( + expectedLeaves, + 'sha256', + ); + + // Assert + expect(MerkleTree.marshalTree(expectedPayload)).toBe( + MerkleTree.marshalTree(merkelizedPayload), + ); + }); +}); diff --git a/examples/bri-3/src/bri/merkleTree/services/merkleTree.service.ts b/examples/bri-3/src/bri/merkleTree/services/merkleTree.service.ts index a0cf6f883..288722c3a 100644 --- a/examples/bri-3/src/bri/merkleTree/services/merkleTree.service.ts +++ b/examples/bri-3/src/bri/merkleTree/services/merkleTree.service.ts @@ -19,4 +19,24 @@ export class MerkleTreeService { return crypto.createHash(hashAlgName).update(data).digest(); }; } + + public merkelizePayload(payload: JSON, hashAlgName: string): MerkleTree { + const leaves: string[] = []; + const recurse = (payload: JSON, _currentKey: string) => { + for (const key in payload) { + const value = payload[key]; + if (value != undefined) { + if (value && typeof value === 'object') { + recurse(value, key); + } else { + leaves.push(key); + leaves.push(value.toString()); + } + } + } + }; + + recurse(payload, null); + return this.formMerkleTree(leaves, hashAlgName); + } }