@0xcert/merkle
Advanced tools
Comparing version 1.0.0-rc3 to 1.0.0-rc4
@@ -5,4 +5,4 @@ { | ||
{ | ||
"version": "1.0.0-rc3", | ||
"tag": "@0xcert/merkle_v1.0.0-rc3", | ||
"version": "1.0.0-rc4", | ||
"tag": "@0xcert/merkle_v1.0.0-rc4", | ||
"date": "Thu, 22 Nov 2018 00:51:03 GMT", | ||
@@ -9,0 +9,0 @@ "comments": {} |
@@ -6,3 +6,3 @@ export declare type MerkleHasher = ((v: any) => string) | ((v: any) => Promise<string>); | ||
} | ||
export interface MerkleHash { | ||
export interface MerkleNode { | ||
index: number; | ||
@@ -13,3 +13,3 @@ hash: string; | ||
values: MerkleValue[]; | ||
nodes: MerkleHash[]; | ||
nodes: MerkleNode[]; | ||
} | ||
@@ -22,17 +22,8 @@ export interface MerkleOptions { | ||
constructor(options?: MerkleOptions); | ||
notarize(data: (string | number | boolean)[]): Promise<{ | ||
values: { | ||
index: number; | ||
value: string | number | boolean; | ||
}[]; | ||
nodes: { | ||
index: number; | ||
hash: string; | ||
}[]; | ||
}>; | ||
notarize(data: (string | number | boolean)[]): Promise<MerkleRecipe>; | ||
disclose(recipe: MerkleRecipe, expose: number[]): Promise<{ | ||
values: any[]; | ||
nodes: MerkleHash[]; | ||
nodes: MerkleNode[]; | ||
}>; | ||
imprint(evidence: MerkleRecipe): Promise<string>; | ||
imprint(recipe: MerkleRecipe): Promise<string>; | ||
} |
@@ -50,6 +50,6 @@ "use strict"; | ||
} | ||
imprint(evidence) { | ||
imprint(recipe) { | ||
return __awaiter(this, void 0, void 0, function* () { | ||
const nodes = [ | ||
...yield Promise.all(evidence.values.map((v) => __awaiter(this, void 0, void 0, function* () { | ||
...yield Promise.all(recipe.values.map((v) => __awaiter(this, void 0, void 0, function* () { | ||
return ({ | ||
@@ -61,3 +61,3 @@ index: v.index * 2 + 1, | ||
}))), | ||
...evidence.nodes, | ||
...recipe.nodes, | ||
]; | ||
@@ -64,0 +64,0 @@ const size = Math.max(...nodes.map((n) => n.index + 1), 0); |
import { Spec } from '@hayspec/spec'; | ||
import { Merkle } from '../../..'; | ||
interface Data { | ||
declare const spec: Spec<{ | ||
merkle: Merkle; | ||
} | ||
declare const spec: Spec<Data>; | ||
}>; | ||
export default spec; |
@@ -21,5 +21,5 @@ "use strict"; | ||
const expose = []; | ||
const recipe = yield ctx.get('merkle').notarize(values); | ||
const evidence = yield ctx.get('merkle').disclose(recipe, expose); | ||
ctx.deepEqual(evidence, { | ||
const fullRecipe = yield ctx.get('merkle').notarize(values); | ||
const minRecipe = yield ctx.get('merkle').disclose(fullRecipe, expose); | ||
ctx.deepEqual(minRecipe, { | ||
values: [], | ||
@@ -34,5 +34,5 @@ nodes: [ | ||
const expose = []; | ||
const recipe = yield ctx.get('merkle').notarize(values); | ||
const evidence = yield ctx.get('merkle').disclose(recipe, expose); | ||
ctx.deepEqual(evidence, { | ||
const fullRecipe = yield ctx.get('merkle').notarize(values); | ||
const minRecipe = yield ctx.get('merkle').disclose(fullRecipe, expose); | ||
ctx.deepEqual(minRecipe, { | ||
values: [], | ||
@@ -47,5 +47,5 @@ nodes: [ | ||
const expose = [0, 2]; | ||
const recipe = yield ctx.get('merkle').notarize(values); | ||
const evidence = yield ctx.get('merkle').disclose(recipe, expose); | ||
ctx.deepEqual(evidence, { | ||
const fullRecipe = yield ctx.get('merkle').notarize(values); | ||
const minRecipe = yield ctx.get('merkle').disclose(fullRecipe, expose); | ||
ctx.deepEqual(minRecipe, { | ||
values: [ | ||
@@ -52,0 +52,0 @@ { index: 0, value: 'A' }, |
import { Spec } from '@hayspec/spec'; | ||
import { Merkle } from '../../..'; | ||
interface Data { | ||
declare const spec: Spec<{ | ||
merkle: Merkle; | ||
} | ||
declare const spec: Spec<Data>; | ||
}>; | ||
export default spec; |
@@ -18,17 +18,17 @@ "use strict"; | ||
})); | ||
spec.test('recreate from from empty array', (ctx) => __awaiter(this, void 0, void 0, function* () { | ||
spec.test('recreate from empty array', (ctx) => __awaiter(this, void 0, void 0, function* () { | ||
const values = []; | ||
const expose = []; | ||
const recipe = yield ctx.get('merkle').notarize(values); | ||
const evidence = yield ctx.get('merkle').disclose(recipe, expose); | ||
const imprint = yield ctx.get('merkle').imprint(evidence); | ||
ctx.is(imprint, recipe.nodes[0].hash); | ||
const fullRecipe = yield ctx.get('merkle').notarize(values); | ||
const minRecipe = yield ctx.get('merkle').disclose(fullRecipe, expose); | ||
const imprint = yield ctx.get('merkle').imprint(minRecipe); | ||
ctx.is(imprint, fullRecipe.nodes[0].hash); | ||
})); | ||
spec.test('recreate from from A, B, C, D with exposed indexes 1, 2', (ctx) => __awaiter(this, void 0, void 0, function* () { | ||
spec.test('recreate from A, B, C, D with exposed indexes 1, 2', (ctx) => __awaiter(this, void 0, void 0, function* () { | ||
const values = ['A', 'B', 'C', 'D']; | ||
const expose = [0, 2]; | ||
const recipe = yield ctx.get('merkle').notarize(values); | ||
const evidence = yield ctx.get('merkle').disclose(recipe, expose); | ||
const imprint = yield ctx.get('merkle').imprint(evidence); | ||
ctx.is(imprint, recipe.nodes[0].hash); | ||
const fullRecipe = yield ctx.get('merkle').notarize(values); | ||
const minRecipe = yield ctx.get('merkle').disclose(fullRecipe, expose); | ||
const imprint = yield ctx.get('merkle').imprint(minRecipe); | ||
ctx.is(imprint, fullRecipe.nodes[0].hash); | ||
})); | ||
@@ -38,6 +38,6 @@ spec.test('recreate from from A, B, C, D, E, F, G, H with exposed indexes 7', (ctx) => __awaiter(this, void 0, void 0, function* () { | ||
const expose = [7]; | ||
const recipe = yield ctx.get('merkle').notarize(values); | ||
const evidence = yield ctx.get('merkle').disclose(recipe, expose); | ||
const imprint = yield ctx.get('merkle').imprint(evidence); | ||
ctx.is(imprint, recipe.nodes[0].hash); | ||
const fullRecipe = yield ctx.get('merkle').notarize(values); | ||
const minRecipe = yield ctx.get('merkle').disclose(fullRecipe, expose); | ||
const imprint = yield ctx.get('merkle').imprint(minRecipe); | ||
ctx.is(imprint, fullRecipe.nodes[0].hash); | ||
})); | ||
@@ -47,8 +47,8 @@ spec.test('recreate from from A, B, C, D, E, F, G, H with exposed indexes 3, 5, 6', (ctx) => __awaiter(this, void 0, void 0, function* () { | ||
const expose = [3, 5, 6]; | ||
const recipe = yield ctx.get('merkle').notarize(values); | ||
const evidence = yield ctx.get('merkle').disclose(recipe, expose); | ||
const imprint = yield ctx.get('merkle').imprint(evidence); | ||
ctx.is(imprint, recipe.nodes[0].hash); | ||
const fullRecipe = yield ctx.get('merkle').notarize(values); | ||
const minRecipe = yield ctx.get('merkle').disclose(fullRecipe, expose); | ||
const imprint = yield ctx.get('merkle').imprint(minRecipe); | ||
ctx.is(imprint, fullRecipe.nodes[0].hash); | ||
})); | ||
exports.default = spec; | ||
//# sourceMappingURL=imprint-instance-method.test.js.map |
import { Spec } from '@hayspec/spec'; | ||
import { Merkle } from '../../..'; | ||
interface Data { | ||
declare const spec: Spec<{ | ||
merkle: Merkle; | ||
} | ||
declare const spec: Spec<Data>; | ||
}>; | ||
export default spec; |
@@ -20,4 +20,4 @@ "use strict"; | ||
const values = []; | ||
const evidence = yield ctx.get('merkle').notarize(values); | ||
ctx.deepEqual(evidence, { | ||
const recipe = yield ctx.get('merkle').notarize(values); | ||
ctx.deepEqual(recipe, { | ||
values: [], | ||
@@ -31,4 +31,4 @@ nodes: [ | ||
const values = ['A']; | ||
const evidence = yield ctx.get('merkle').notarize(values); | ||
ctx.deepEqual(evidence, { | ||
const recipe = yield ctx.get('merkle').notarize(values); | ||
ctx.deepEqual(recipe, { | ||
values: [ | ||
@@ -44,6 +44,6 @@ { index: 0, value: 'A' }, | ||
})); | ||
spec.test('builds evidence for values A,B,C,D', (ctx) => __awaiter(this, void 0, void 0, function* () { | ||
spec.test('builds recipe for values A,B,C,D', (ctx) => __awaiter(this, void 0, void 0, function* () { | ||
const values = ['A', 'B', 'C', 'D']; | ||
const evidence = yield ctx.get('merkle').notarize(values); | ||
ctx.deepEqual(evidence, { | ||
const recipe = yield ctx.get('merkle').notarize(values); | ||
ctx.deepEqual(recipe, { | ||
values: [ | ||
@@ -50,0 +50,0 @@ { index: 0, value: 'A' }, |
{ | ||
"name": "@0xcert/merkle", | ||
"version": "1.0.0-rc3", | ||
"version": "1.0.0-rc4", | ||
"description": "Implementation of basic functions of binary Merkle tree.", | ||
@@ -67,3 +67,3 @@ "main": "./dist/index.js", | ||
"devDependencies": { | ||
"@0xcert/utils": "1.0.0-rc3", | ||
"@0xcert/utils": "1.0.0-rc4", | ||
"@hayspec/cli": "^0.8.3", | ||
@@ -70,0 +70,0 @@ "@hayspec/spec": "^0.8.3", |
@@ -28,3 +28,3 @@ <img src="https://github.com/0xcert/framework/raw/master/assets/cover-sub.png" /> | ||
A user defines an array of values `['A', 'B', 'C', 'D']`. These values can be hached into an `imprint`, which is a root tree hash. A user can expose selected values to a third-party by providing the evidence file which consists of `values` and `nodes`. This file holds enough information for a third-party to recreate an imprint. | ||
A user defines an array of values `['A', 'B', 'C', 'D']`. These values can be hashed into an `imprint`, which is a merkle root tree hash. A user can expose selected values to a third-party by providing the evidence file which includes a recipe of `values` and `nodes`. This file holds enough information for a third-party to recreate the imprint. | ||
@@ -40,5 +40,5 @@ ```js | ||
const expose = [2, 3]; | ||
const recipe = await merkle.notarize(values); | ||
const evidence = await merkle.disclose(recipe, expose); | ||
const imprint = await merkle.imprint(evidence); | ||
const fullRecipe = await merkle.notarize(values); | ||
const minRecipe = await merkle.disclose(fullRecipe, expose); | ||
const imprint = await merkle.imprint(minRecipe); | ||
``` | ||
@@ -45,0 +45,0 @@ |
/** | ||
* Merkle tree node definition. | ||
* Merkle tree hash function interface. | ||
*/ | ||
@@ -7,3 +7,3 @@ export type MerkleHasher = ((v: any) => string) | ((v: any) => Promise<string>); | ||
/** | ||
* | ||
* Merkle value interface. | ||
*/ | ||
@@ -16,5 +16,5 @@ export interface MerkleValue { | ||
/** | ||
* | ||
* Merkle node interface. | ||
*/ | ||
export interface MerkleHash { | ||
export interface MerkleNode { | ||
index: number; | ||
@@ -25,11 +25,11 @@ hash: string; | ||
/** | ||
* | ||
* Merkle recipe interface with information for rebuilding merkle root. | ||
*/ | ||
export interface MerkleRecipe { | ||
values: MerkleValue[]; | ||
nodes: MerkleHash[]; | ||
nodes: MerkleNode[]; | ||
} | ||
/** | ||
* Merkle tree configuration. | ||
* Merkle tree options interface. | ||
*/ | ||
@@ -47,3 +47,4 @@ export interface MerkleOptions { | ||
/** | ||
* | ||
* Class constructor. | ||
* @param options Configuration options. | ||
*/ | ||
@@ -58,6 +59,6 @@ public constructor(options?: MerkleOptions) { | ||
/** | ||
* Returns a complete evidence data object. | ||
* Returns a complete merkle recipe object with all merkle values and nodes. | ||
* @param data List of arbitrary values. | ||
*/ | ||
public async notarize(data: (string | number | boolean)[]) { | ||
public async notarize(data: (string | number | boolean)[]): Promise<MerkleRecipe> { | ||
const values = [...data]; | ||
@@ -85,5 +86,7 @@ const nodes = [await this.$options.hasher('')]; | ||
/** | ||
* Returns evidence data object that includes only data for exposed values | ||
* from which we can recreate the imprint. | ||
* @param recipe Object returned by notarize() | ||
* Returns partial recipe object that includes only data for exposed values | ||
* from which we can still recreate the imprint. This method expects a | ||
* complete recipe (returned by the notarize function) then deletes nodes and | ||
* values that are not needed to recalculate the merkle root (imprint). | ||
* @param recipe A complete data recipe. | ||
* @param expose Value indexes to expose. | ||
@@ -114,9 +117,9 @@ */ | ||
/** | ||
* Returns the root merkle tree hash built from the evidence object. | ||
* @param evidence Object returned by disclose() | ||
* Returns the root merkle tree hash built from the provided recipe object. | ||
* @param recipe Recipe object with nodes and values. | ||
*/ | ||
public async imprint(evidence: MerkleRecipe) { | ||
public async imprint(recipe: MerkleRecipe) { | ||
const nodes = [ | ||
...await Promise.all( | ||
evidence.values.map(async (v) => ({ | ||
recipe.values.map(async (v) => ({ | ||
index: v.index * 2 + 1, | ||
@@ -127,3 +130,3 @@ hash: await this.$options.hasher(v.value), | ||
), | ||
...evidence.nodes, | ||
...recipe.nodes, | ||
]; | ||
@@ -130,0 +133,0 @@ const size = Math.max(...nodes.map((n) => n.index + 1), 0); |
@@ -5,8 +5,6 @@ import { sha } from '@0xcert/utils'; | ||
interface Data { | ||
const spec = new Spec<{ | ||
merkle: Merkle; | ||
} | ||
}>(); | ||
const spec = new Spec<Data>(); | ||
spec.before(async (ctx) => { | ||
@@ -19,5 +17,5 @@ ctx.set('merkle', new Merkle({ hasher: (v) => sha(256, v) })); | ||
const expose = []; | ||
const recipe = await ctx.get('merkle').notarize(values); | ||
const evidence = await ctx.get('merkle').disclose(recipe, expose); | ||
ctx.deepEqual(evidence, { | ||
const fullRecipe = await ctx.get('merkle').notarize(values); | ||
const minRecipe = await ctx.get('merkle').disclose(fullRecipe, expose); | ||
ctx.deepEqual(minRecipe, { | ||
values: [], | ||
@@ -33,5 +31,5 @@ nodes: [ | ||
const expose = []; | ||
const recipe = await ctx.get('merkle').notarize(values); | ||
const evidence = await ctx.get('merkle').disclose(recipe, expose); | ||
ctx.deepEqual(evidence, { | ||
const fullRecipe = await ctx.get('merkle').notarize(values); | ||
const minRecipe = await ctx.get('merkle').disclose(fullRecipe, expose); | ||
ctx.deepEqual(minRecipe, { | ||
values: [], | ||
@@ -47,5 +45,5 @@ nodes: [ | ||
const expose = [0, 2]; | ||
const recipe = await ctx.get('merkle').notarize(values); | ||
const evidence = await ctx.get('merkle').disclose(recipe, expose); | ||
ctx.deepEqual(evidence, { | ||
const fullRecipe = await ctx.get('merkle').notarize(values); | ||
const minRecipe = await ctx.get('merkle').disclose(fullRecipe, expose); | ||
ctx.deepEqual(minRecipe, { | ||
values: [ | ||
@@ -52,0 +50,0 @@ { index: 0, value: 'A' }, |
@@ -5,8 +5,6 @@ import { sha } from '@0xcert/utils'; | ||
interface Data { | ||
const spec = new Spec<{ | ||
merkle: Merkle; | ||
} | ||
}>(); | ||
const spec = new Spec<Data>(); | ||
spec.before(async (ctx) => { | ||
@@ -16,18 +14,18 @@ ctx.set('merkle', new Merkle({ hasher: (v) => sha(256, v) })); | ||
spec.test('recreate from from empty array', async (ctx) => { | ||
spec.test('recreate from empty array', async (ctx) => { | ||
const values = []; | ||
const expose = []; | ||
const recipe = await ctx.get('merkle').notarize(values); | ||
const evidence = await ctx.get('merkle').disclose(recipe, expose); | ||
const imprint = await ctx.get('merkle').imprint(evidence); | ||
ctx.is(imprint, recipe.nodes[0].hash); | ||
const fullRecipe = await ctx.get('merkle').notarize(values); | ||
const minRecipe = await ctx.get('merkle').disclose(fullRecipe, expose); | ||
const imprint = await ctx.get('merkle').imprint(minRecipe); | ||
ctx.is(imprint, fullRecipe.nodes[0].hash); | ||
}); | ||
spec.test('recreate from from A, B, C, D with exposed indexes 1, 2', async (ctx) => { | ||
spec.test('recreate from A, B, C, D with exposed indexes 1, 2', async (ctx) => { | ||
const values = ['A', 'B', 'C', 'D']; | ||
const expose = [0, 2]; | ||
const recipe = await ctx.get('merkle').notarize(values); | ||
const evidence = await ctx.get('merkle').disclose(recipe, expose); | ||
const imprint = await ctx.get('merkle').imprint(evidence); | ||
ctx.is(imprint, recipe.nodes[0].hash); | ||
const fullRecipe = await ctx.get('merkle').notarize(values); | ||
const minRecipe = await ctx.get('merkle').disclose(fullRecipe, expose); | ||
const imprint = await ctx.get('merkle').imprint(minRecipe); | ||
ctx.is(imprint, fullRecipe.nodes[0].hash); | ||
}); | ||
@@ -38,6 +36,6 @@ | ||
const expose = [7]; | ||
const recipe = await ctx.get('merkle').notarize(values); | ||
const evidence = await ctx.get('merkle').disclose(recipe, expose); | ||
const imprint = await ctx.get('merkle').imprint(evidence); | ||
ctx.is(imprint, recipe.nodes[0].hash); | ||
const fullRecipe = await ctx.get('merkle').notarize(values); | ||
const minRecipe = await ctx.get('merkle').disclose(fullRecipe, expose); | ||
const imprint = await ctx.get('merkle').imprint(minRecipe); | ||
ctx.is(imprint, fullRecipe.nodes[0].hash); | ||
}); | ||
@@ -48,8 +46,8 @@ | ||
const expose = [3, 5, 6]; | ||
const recipe = await ctx.get('merkle').notarize(values); | ||
const evidence = await ctx.get('merkle').disclose(recipe, expose); | ||
const imprint = await ctx.get('merkle').imprint(evidence); | ||
ctx.is(imprint, recipe.nodes[0].hash); | ||
const fullRecipe = await ctx.get('merkle').notarize(values); | ||
const minRecipe = await ctx.get('merkle').disclose(fullRecipe, expose); | ||
const imprint = await ctx.get('merkle').imprint(minRecipe); | ||
ctx.is(imprint, fullRecipe.nodes[0].hash); | ||
}); | ||
export default spec; |
@@ -5,8 +5,6 @@ import { sha } from '@0xcert/utils'; | ||
interface Data { | ||
const spec = new Spec<{ | ||
merkle: Merkle; | ||
} | ||
}>(); | ||
const spec = new Spec<Data>(); | ||
spec.before(async (ctx) => { | ||
@@ -18,4 +16,4 @@ ctx.set('merkle', new Merkle({ hasher: (v) => sha(256, v) })); | ||
const values = []; | ||
const evidence = await ctx.get('merkle').notarize(values); | ||
ctx.deepEqual(evidence, { | ||
const recipe = await ctx.get('merkle').notarize(values); | ||
ctx.deepEqual(recipe, { | ||
values: [], | ||
@@ -30,4 +28,4 @@ nodes: [ | ||
const values = ['A']; | ||
const evidence = await ctx.get('merkle').notarize(values); | ||
ctx.deepEqual(evidence, { | ||
const recipe = await ctx.get('merkle').notarize(values); | ||
ctx.deepEqual(recipe, { | ||
values: [ | ||
@@ -44,6 +42,6 @@ { index: 0, value: 'A' }, | ||
spec.test('builds evidence for values A,B,C,D', async (ctx) => { | ||
spec.test('builds recipe for values A,B,C,D', async (ctx) => { | ||
const values = ['A', 'B', 'C', 'D']; | ||
const evidence = await ctx.get('merkle').notarize(values); | ||
ctx.deepEqual(evidence, { | ||
const recipe = await ctx.get('merkle').notarize(values); | ||
ctx.deepEqual(recipe, { | ||
values: [ | ||
@@ -50,0 +48,0 @@ { index: 0, value: 'A' }, |
@@ -239,11 +239,2 @@ { | ||
"ban-ts-ignore": true, | ||
"no-console": [ | ||
true, | ||
"log", | ||
"debug", | ||
"info", | ||
"time", | ||
"timeEnd", | ||
"trace" | ||
], | ||
"no-debugger": true, | ||
@@ -250,0 +241,0 @@ "no-eval": true, |
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
60375
880