From e38155f384c34fb5014c04f0f214473449a01e12 Mon Sep 17 00:00:00 2001 From: William Wills Date: Fri, 23 Aug 2024 14:45:49 -0400 Subject: [PATCH 01/15] feat: added store get_proof command --- src/actions/getProof.ts | 18 ++++++++++++++++++ src/actions/index.ts | 3 ++- src/types.ts | 10 ++++++++++ src/yargs/commands.ts | 20 ++++++++++++++++---- src/yargs/handlers.ts | 39 ++++++++++++++++++++++++--------------- 5 files changed, 70 insertions(+), 20 deletions(-) create mode 100644 src/actions/getProof.ts diff --git a/src/actions/getProof.ts b/src/actions/getProof.ts new file mode 100644 index 0000000..f04abcc --- /dev/null +++ b/src/actions/getProof.ts @@ -0,0 +1,18 @@ +import {DataIntegrityTree} from "../DataIntegrityTree"; +import {findStoreId} from "../blockchain/datastore"; + +export const getProof = (key, sha256) => { + try { + const storeId = findStoreId()?.toString(); + if (!storeId){ + throw new Error('Failed to find datastore'); + } + const datalayer = new DataIntegrityTree(storeId); + const proof = datalayer.getProof(key, sha256); + + console.log(`Proof for key ${key}\nand sha256 hash ${sha256}:`); + console.log(proof); + } catch (error) { + console.error('Cannot get proof:', error) + } +} \ No newline at end of file diff --git a/src/actions/index.ts b/src/actions/index.ts index 0a954d4..9e1dd6f 100644 --- a/src/actions/index.ts +++ b/src/actions/index.ts @@ -5,4 +5,5 @@ export * from './push'; export * from './remote'; export * from './pull'; export * from './commit'; -export * from './validate'; \ No newline at end of file +export * from './validate'; +export * from './getProof'; \ No newline at end of file diff --git a/src/types.ts b/src/types.ts index f223c0b..a09c405 100644 --- a/src/types.ts +++ b/src/types.ts @@ -41,4 +41,14 @@ export interface DatFile { export interface Credentials { username: string; password: string; +} + +export interface ManageStoreArgs { + action: string, + actionArgs: GetProof +} + +export interface GetProof { + key: string, + sha256: string, } \ No newline at end of file diff --git a/src/yargs/commands.ts b/src/yargs/commands.ts index e37e0ac..b9adebf 100644 --- a/src/yargs/commands.ts +++ b/src/yargs/commands.ts @@ -77,7 +77,7 @@ export function storeCommand(yargs: Argv<{}>) { .positional("action", { describe: "Action to perform on keys", type: "string", - choices: ["validate", "update", "remove"], + choices: ["validate", "update", "remove", "get_proof"], }) .option("writer", { type: "string", @@ -91,10 +91,22 @@ export function storeCommand(yargs: Argv<{}>) { type: "string", describe: "Specify an admin for the store", }) - .strict(); // Ensures that only the defined options are accepted + .check((argv) => { + if (argv.action === "get_proof") { + if (!argv.key || !argv.sha256) { + throw new Error("The --key and --sha256 options are required for the 'get_proof' action."); + } + } else { + if (argv.key || argv.sha256) { + throw new Error("The --key and --sha256 options are only valid for the 'get_proof' action."); + } + } + return true; + }) + .strict(); }, - async (argv: { action: string }) => { - await handlers.manageStore(argv.action); + async (argv) => { + await handlers.manageStore(argv); } ); } diff --git a/src/yargs/handlers.ts b/src/yargs/handlers.ts index b499174..4c706ce 100644 --- a/src/yargs/handlers.ts +++ b/src/yargs/handlers.ts @@ -1,6 +1,6 @@ import { getOrCreateMnemonic, deleteMnemonic, getMnemonic, importMnemonic } from "../blockchain/mnemonic"; -import { commit, push, pull, clone, setRemote, init, validate } from "../actions"; -import { CreateStoreUserInputs } from '../types'; +import {commit, push, pull, clone, setRemote, init, validate, getProof} from "../actions"; +import {CreateStoreUserInputs, ManageStoreArgs} from '../types'; // Command handlers export const handlers = { @@ -40,20 +40,29 @@ export const handlers = { await validate(); console.log("Store validated"); }, - manageStore: async (action: string) => { - switch (action) { - case "validate": - await validate(); - break; - case "update": - // await upsertStore(); - break; - case "remove": - // await removeStore(); - break; - default: - console.error("Unknown store action"); + manageStore: async (argv) => { + try { + switch (argv.action) { + case "validate": + await validate(); + break; + case "update": + // await upsertStore(); + break; + case "remove": + // await removeStore(); + break; + case "get_proof": + const {key, sha256} = argv; + await getProof(key, sha256); + break; + default: + console.error(`Unknown action ${argv.action}`) + } + } catch { + console.error('Invalid command structure') } + }, manageKeys: async (action: string, providedMnemonic?: string) => { switch (action) { From acf4644c97129122ebfdbbbc8128ad1bd3407957 Mon Sep 17 00:00:00 2001 From: William Wills Date: Fri, 23 Aug 2024 19:37:41 -0400 Subject: [PATCH 02/15] fix: ts errors and async --- src/actions/getProof.ts | 2 +- src/yargs/handlers.ts | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/src/actions/getProof.ts b/src/actions/getProof.ts index f04abcc..4aa1ffa 100644 --- a/src/actions/getProof.ts +++ b/src/actions/getProof.ts @@ -1,7 +1,7 @@ import {DataIntegrityTree} from "../DataIntegrityTree"; import {findStoreId} from "../blockchain/datastore"; -export const getProof = (key, sha256) => { +export const getProof = async (key: string, sha256: string) => { try { const storeId = findStoreId()?.toString(); if (!storeId){ diff --git a/src/yargs/handlers.ts b/src/yargs/handlers.ts index 1afa05c..2fc252d 100644 --- a/src/yargs/handlers.ts +++ b/src/yargs/handlers.ts @@ -42,7 +42,7 @@ export const handlers = { validateStore: async () => { await validate(); }, - manageStore: async (argv) => { + manageStore: async (argv: {action: string} & any) => { try { switch (argv.action) { case "validate": From c09a7b11cb96fe759b958c8cc0042b86df2c9d70 Mon Sep 17 00:00:00 2001 From: William Wills Date: Sat, 24 Aug 2024 21:08:59 -0400 Subject: [PATCH 03/15] fix: get_proof command --- src/actions/getProof.ts | 4 ++-- src/yargs/commands.ts | 18 +++++++++++++++--- src/yargs/handlers.ts | 2 +- 3 files changed, 18 insertions(+), 6 deletions(-) diff --git a/src/actions/getProof.ts b/src/actions/getProof.ts index 4aa1ffa..71ce49b 100644 --- a/src/actions/getProof.ts +++ b/src/actions/getProof.ts @@ -12,7 +12,7 @@ export const getProof = async (key: string, sha256: string) => { console.log(`Proof for key ${key}\nand sha256 hash ${sha256}:`); console.log(proof); - } catch (error) { - console.error('Cannot get proof:', error) + } catch (error: any) { + console.error('Cannot get proof:', error.message); } } \ No newline at end of file diff --git a/src/yargs/commands.ts b/src/yargs/commands.ts index 77e331b..eb7d6b0 100644 --- a/src/yargs/commands.ts +++ b/src/yargs/commands.ts @@ -88,6 +88,14 @@ export function storeCommand(yargs: Argv<{}>) { type: "string", choices: ["validate", "update", "remove", "get_proof"], }) + .option ("key", { + type: "string", + describe: "The store key on which to operate" + }) + .option ("sha256", { + type: "string", + describe: "The sha256 hash of the data corresponding to a store key" + }) .option("writer", { type: "string", describe: "Specify an authorized writer for the store", @@ -101,13 +109,17 @@ export function storeCommand(yargs: Argv<{}>) { describe: "Specify an admin for the store", }) .check((argv) => { - if (argv.action === "get_proof") { + if (argv.action === "verify_proof" || argv.action === "get_proof") { if (!argv.key || !argv.sha256) { - throw new Error("The --key and --sha256 options are required for the 'get_proof' action."); + throw new Error(`The --key and --sha256 options are required for the '${argv.action}' action.`); } } else { if (argv.key || argv.sha256) { - throw new Error("The --key and --sha256 options are only valid for the 'get_proof' action."); + throw new Error( + "The --key and --sha256 options are only valid for the following actions:" + + "\n- 'get_proof'" + + "\n- 'verify_proof'" + ); } } return true; diff --git a/src/yargs/handlers.ts b/src/yargs/handlers.ts index 2fc252d..ff3e077 100644 --- a/src/yargs/handlers.ts +++ b/src/yargs/handlers.ts @@ -59,7 +59,7 @@ export const handlers = { await getProof(key, sha256); break; default: - console.error(`Unknown action ${argv.action}`) + console.error(`Unknown action ${argv.action}`); } } catch { console.error('Invalid command structure') From b3f2a55bef35f67c4dba5ac97317ec5d36ff3968 Mon Sep 17 00:00:00 2001 From: William Wills Date: Sat, 24 Aug 2024 21:17:55 -0400 Subject: [PATCH 04/15] fix: merge issues --- src/actions/getProof.ts | 4 ++-- src/yargs/handlers.ts | 1 - 2 files changed, 2 insertions(+), 3 deletions(-) diff --git a/src/actions/getProof.ts b/src/actions/getProof.ts index 71ce49b..2dc021f 100644 --- a/src/actions/getProof.ts +++ b/src/actions/getProof.ts @@ -1,9 +1,9 @@ import {DataIntegrityTree} from "../DataIntegrityTree"; -import {findStoreId} from "../blockchain/datastore"; +import {getActiveStoreId} from "../utils/config"; export const getProof = async (key: string, sha256: string) => { try { - const storeId = findStoreId()?.toString(); + const storeId = getActiveStoreId()?.toString(); if (!storeId){ throw new Error('Failed to find datastore'); } diff --git a/src/yargs/handlers.ts b/src/yargs/handlers.ts index 2aef4d5..6f9f5b1 100644 --- a/src/yargs/handlers.ts +++ b/src/yargs/handlers.ts @@ -1,7 +1,6 @@ import { getOrCreateMnemonic, deleteMnemonic, getMnemonic, importMnemonic } from "../blockchain/mnemonic"; import {commit, push, pull, clone, setRemote, init, validate, login, logout, getProof} from "../actions"; import { CreateStoreUserInputs } from '../types'; -import {logout} from "../actions/logout"; import { startPreviewServer } from '../content_server/server'; import { checkStoreWritePermissions } from "../actions"; import { getActiveStoreId } from "../utils/config"; From c4843dc32c03b1e8ee83561f5d6b3f54c7dd2389 Mon Sep 17 00:00:00 2001 From: William Wills Date: Sun, 25 Aug 2024 14:18:28 -0400 Subject: [PATCH 05/15] feat: added verify_proof command --- src/actions/index.ts | 3 ++- src/actions/verifyProof.ts | 21 +++++++++++++++++++++ src/yargs/commands.ts | 19 ++++++++++--------- src/yargs/handlers.ts | 10 ++++++++-- 4 files changed, 41 insertions(+), 12 deletions(-) create mode 100644 src/actions/verifyProof.ts diff --git a/src/actions/index.ts b/src/actions/index.ts index 55b70e9..9c3782f 100644 --- a/src/actions/index.ts +++ b/src/actions/index.ts @@ -8,4 +8,5 @@ export * from './commit'; export * from './validate'; export * from './getProof'; export * from './login'; -export * from './logout'; \ No newline at end of file +export * from './logout'; +export * from './verifyProof'; \ No newline at end of file diff --git a/src/actions/verifyProof.ts b/src/actions/verifyProof.ts new file mode 100644 index 0000000..cd35520 --- /dev/null +++ b/src/actions/verifyProof.ts @@ -0,0 +1,21 @@ +import {DataIntegrityTree} from "../DataIntegrityTree"; +import {getActiveStoreId} from "../utils/config"; + +export const verfiyProof = async (proof: string, sha256: string) => { + try { + const storeId = getActiveStoreId()?.toString(); + if (!storeId){ + throw new Error('Failed to find datastore'); + } + const datalayer = new DataIntegrityTree(storeId); + const proofVerified = datalayer.verifyProof(proof, sha256); + + if (proofVerified) { + console.log('Proof has been verified'); + } else { + console.error('Proof verification failed with provided hash'); + } + } catch (error: any) { + console.error('Failed to process proof:', error.message); + } +} \ No newline at end of file diff --git a/src/yargs/commands.ts b/src/yargs/commands.ts index 4e52bc8..d388859 100644 --- a/src/yargs/commands.ts +++ b/src/yargs/commands.ts @@ -1,6 +1,7 @@ import yargs, { Argv } from "yargs"; import { handlers } from "./handlers"; import { CreateStoreUserInputs } from "../types"; +import {isArrayBufferView} from "node:util/types"; export function initCommand(yargs: Argv<{}>) { return yargs.command( @@ -94,12 +95,16 @@ export function storeCommand(yargs: Argv<{}>) { .positional("action", { describe: "Action to perform on keys", type: "string", - choices: ["validate", "update", "remove", "get_proof"], + choices: ["validate", "update", "remove", "get_proof", "verify_proof"], }) .option ("key", { type: "string", describe: "The store key on which to operate" }) + .option ("proof", { + type: "string", + describe: "The proof to verify" + }) .option ("sha256", { type: "string", describe: "The sha256 hash of the data corresponding to a store key" @@ -117,17 +122,13 @@ export function storeCommand(yargs: Argv<{}>) { describe: "Specify an admin for the store", }) .check((argv) => { - if (argv.action === "verify_proof" || argv.action === "get_proof") { + if (argv.action === "get_proof") { if (!argv.key || !argv.sha256) { throw new Error(`The --key and --sha256 options are required for the '${argv.action}' action.`); } - } else { - if (argv.key || argv.sha256) { - throw new Error( - "The --key and --sha256 options are only valid for the following actions:" + - "\n- 'get_proof'" + - "\n- 'verify_proof'" - ); + } else if (argv.action === "verify_proof") { + if (!argv.proof || !argv.sha256) { + throw new Error(`The --proof and --sha256 options are required for the '${argv.action}' action.`); } } return true; diff --git a/src/yargs/handlers.ts b/src/yargs/handlers.ts index 6f9f5b1..71b5238 100644 --- a/src/yargs/handlers.ts +++ b/src/yargs/handlers.ts @@ -1,5 +1,5 @@ import { getOrCreateMnemonic, deleteMnemonic, getMnemonic, importMnemonic } from "../blockchain/mnemonic"; -import {commit, push, pull, clone, setRemote, init, validate, login, logout, getProof} from "../actions"; +import {commit, push, pull, clone, setRemote, init, validate, login, logout, getProof, verfiyProof} from "../actions"; import { CreateStoreUserInputs } from '../types'; import { startPreviewServer } from '../content_server/server'; import { checkStoreWritePermissions } from "../actions"; @@ -57,10 +57,16 @@ export const handlers = { case "remove": // await removeStore(); break; - case "get_proof": + case "get_proof": { const {key, sha256} = argv; await getProof(key, sha256); break; + } + case "verify_proof": { + const {proof, sha256} = argv; + await verfiyProof(proof, sha256); + break; + } default: console.error(`Unknown action ${argv.action}`); } From 299824ca895d62e3ae0756b9cc1775270fcce776 Mon Sep 17 00:00:00 2001 From: William Wills Date: Sun, 25 Aug 2024 14:33:53 -0400 Subject: [PATCH 06/15] fix: other commands feat: added store list command --- src/actions/getProof.ts | 3 ++- src/actions/index.ts | 3 ++- src/actions/listKeys.ts | 28 ++++++++++++++++++++++++++++ src/actions/verifyProof.ts | 3 ++- src/yargs/commands.ts | 2 +- src/yargs/handlers.ts | 19 ++++++++++++++++++- 6 files changed, 53 insertions(+), 5 deletions(-) create mode 100644 src/actions/listKeys.ts diff --git a/src/actions/getProof.ts b/src/actions/getProof.ts index 2dc021f..49a05ef 100644 --- a/src/actions/getProof.ts +++ b/src/actions/getProof.ts @@ -3,7 +3,8 @@ import {getActiveStoreId} from "../utils/config"; export const getProof = async (key: string, sha256: string) => { try { - const storeId = getActiveStoreId()?.toString(); + const storeIdResult = getActiveStoreId(); + const storeId = storeIdResult?.toString(); if (!storeId){ throw new Error('Failed to find datastore'); } diff --git a/src/actions/index.ts b/src/actions/index.ts index 9c3782f..c561507 100644 --- a/src/actions/index.ts +++ b/src/actions/index.ts @@ -9,4 +9,5 @@ export * from './validate'; export * from './getProof'; export * from './login'; export * from './logout'; -export * from './verifyProof'; \ No newline at end of file +export * from './verifyProof'; +export * from './listKeys'; \ No newline at end of file diff --git a/src/actions/listKeys.ts b/src/actions/listKeys.ts new file mode 100644 index 0000000..d011de7 --- /dev/null +++ b/src/actions/listKeys.ts @@ -0,0 +1,28 @@ +import {getActiveStoreId} from "../utils/config"; +import {DataIntegrityTree} from "../DataIntegrityTree"; + +export const listKeys = async () => { + try { + const storeIdResult = await getActiveStoreId(); + const storeId = storeIdResult?.toString(); + if (!storeId){ + throw new Error('Failed to find datastore'); + } + const datalayer = new DataIntegrityTree(storeId); + const keysArr = datalayer.listKeys(); + + if (keysArr.length > 0){ + let printableList: string = ''; + keysArr.forEach(key => { + printableList += `${key}\n`; + }); + + console.log(`Keys for store ${storeId}:\n\n${printableList}`); + } else { + console.log(`Store ${storeId} has no keys`); + } + + } catch (error: any) { + console.error('Failed to get store keys:', error.message); + } +} \ No newline at end of file diff --git a/src/actions/verifyProof.ts b/src/actions/verifyProof.ts index cd35520..0aea519 100644 --- a/src/actions/verifyProof.ts +++ b/src/actions/verifyProof.ts @@ -3,7 +3,8 @@ import {getActiveStoreId} from "../utils/config"; export const verfiyProof = async (proof: string, sha256: string) => { try { - const storeId = getActiveStoreId()?.toString(); + const storeIdResult = getActiveStoreId(); + const storeId = storeIdResult?.toString(); if (!storeId){ throw new Error('Failed to find datastore'); } diff --git a/src/yargs/commands.ts b/src/yargs/commands.ts index b35d7e8..b8731f4 100644 --- a/src/yargs/commands.ts +++ b/src/yargs/commands.ts @@ -95,7 +95,7 @@ export function storeCommand(yargs: Argv<{}>) { .positional("action", { describe: "Action to perform on keys", type: "string", - choices: ["validate", "update", "remove", "get_proof", "verify_proof"], + choices: ["validate", "update", "remove", "get_proof", "verify_proof", "list"], }) .option ("key", { type: "string", diff --git a/src/yargs/handlers.ts b/src/yargs/handlers.ts index 3204509..ee71681 100644 --- a/src/yargs/handlers.ts +++ b/src/yargs/handlers.ts @@ -1,5 +1,18 @@ import { getOrCreateMnemonic, deleteMnemonic, getMnemonic, importMnemonic } from "../blockchain/mnemonic"; -import {commit, push, pull, clone, setRemote, init, validate, login, logout, getProof, verfiyProof} from "../actions"; +import { + commit, + push, + pull, + clone, + setRemote, + init, + validate, + login, + logout, + getProof, + verfiyProof, + listKeys +} from "../actions"; import { CreateStoreUserInputs } from '../types'; import { startPreviewServer } from '../content_server/server'; import { checkStoreWritePermissions } from "../actions"; @@ -70,6 +83,10 @@ export const handlers = { await verfiyProof(proof, sha256); break; } + case "list": { + await listKeys(); + break; + } default: console.error(`Unknown action ${argv.action}`); } From 8314a1d05abd21fabea716ed47eace516389cf81 Mon Sep 17 00:00:00 2001 From: William Wills Date: Sun, 25 Aug 2024 14:45:34 -0400 Subject: [PATCH 07/15] feat: added store get_root command --- src/actions/getRoot.ts | 18 ++++++++++++++++++ src/actions/index.ts | 3 ++- src/yargs/commands.ts | 2 +- src/yargs/handlers.ts | 6 +++++- 4 files changed, 26 insertions(+), 3 deletions(-) create mode 100644 src/actions/getRoot.ts diff --git a/src/actions/getRoot.ts b/src/actions/getRoot.ts new file mode 100644 index 0000000..9112179 --- /dev/null +++ b/src/actions/getRoot.ts @@ -0,0 +1,18 @@ +import {getActiveStoreId} from "../utils/config"; +import {DataIntegrityTree} from "../DataIntegrityTree"; + +export const getRoot = async () => { + try { + const storeIdResult = await getActiveStoreId(); + const storeId = storeIdResult?.toString(); + if (!storeId){ + throw new Error('Failed to find datastore'); + } + const datalayer = new DataIntegrityTree(storeId); + const rootHash = datalayer.getRoot(); + console.log(`The root hash is ${rootHash}`); + + } catch (error: any) { + console.error('Failed to get root hash:', error.message); + } +} \ No newline at end of file diff --git a/src/actions/index.ts b/src/actions/index.ts index c561507..d457a86 100644 --- a/src/actions/index.ts +++ b/src/actions/index.ts @@ -10,4 +10,5 @@ export * from './getProof'; export * from './login'; export * from './logout'; export * from './verifyProof'; -export * from './listKeys'; \ No newline at end of file +export * from './listKeys'; +export * from './getRoot'; \ No newline at end of file diff --git a/src/yargs/commands.ts b/src/yargs/commands.ts index b8731f4..0167dc4 100644 --- a/src/yargs/commands.ts +++ b/src/yargs/commands.ts @@ -95,7 +95,7 @@ export function storeCommand(yargs: Argv<{}>) { .positional("action", { describe: "Action to perform on keys", type: "string", - choices: ["validate", "update", "remove", "get_proof", "verify_proof", "list"], + choices: ["validate", "update", "remove", "get_root", "get_proof", "verify_proof", "list"], }) .option ("key", { type: "string", diff --git a/src/yargs/handlers.ts b/src/yargs/handlers.ts index ee71681..f5a4fbc 100644 --- a/src/yargs/handlers.ts +++ b/src/yargs/handlers.ts @@ -11,7 +11,7 @@ import { logout, getProof, verfiyProof, - listKeys + listKeys, getRoot } from "../actions"; import { CreateStoreUserInputs } from '../types'; import { startPreviewServer } from '../content_server/server'; @@ -87,6 +87,10 @@ export const handlers = { await listKeys(); break; } + case "getRoot": { + await getRoot(); + break; + } default: console.error(`Unknown action ${argv.action}`); } From ea0188b90380b7468fbb48e25d569a1264c57db7 Mon Sep 17 00:00:00 2001 From: William Wills Date: Sun, 25 Aug 2024 17:10:49 -0400 Subject: [PATCH 08/15] feat: added store get_key command --- src/actions/getKey.ts | 70 +++++++++++++++++++++++++++++++++++++++++++ src/actions/index.ts | 3 +- src/yargs/commands.ts | 6 +++- src/yargs/handlers.ts | 9 +++++- 4 files changed, 85 insertions(+), 3 deletions(-) create mode 100644 src/actions/getKey.ts diff --git a/src/actions/getKey.ts b/src/actions/getKey.ts new file mode 100644 index 0000000..7154fb1 --- /dev/null +++ b/src/actions/getKey.ts @@ -0,0 +1,70 @@ +import {DataIntegrityTree} from "../DataIntegrityTree"; +import {Buffer} from "buffer"; +import {getActiveStoreId} from "../utils/config"; + +export const getKey = async (key: string) => { + try { + const storeIdResult = await getActiveStoreId(); + const storeId = storeIdResult?.toString(); + if (!storeId){ + throw new Error('Failed to find datastore'); + } + + const datalayer = new DataIntegrityTree(storeId); + const valueStream = datalayer.getValueStream(key); + let valueData: Buffer = Buffer.alloc(0); + const valueDataHexArr: string[] = []; + + valueStream.on('data', (chunk) => { + const hex = chunk.toString('hex'); + valueDataHexArr.push(hex); + valueData = Buffer.concat([valueData, chunk]); + }); + + valueStream.on('end', () => { + const dataUtf8: string = valueData.toString('utf8'); + let dataPrinted = false + console.log(`Data for key ${key}:\n\n`); + + // print as json + try { + JSON.parse(dataUtf8); + console.log(dataUtf8); + dataPrinted = true; + } catch {} + + // print as xml + if (!dataPrinted) { + try { + const parser = new DOMParser(); + parser.parseFromString(dataUtf8, 'text/xml'); + console.log(dataUtf8); + dataPrinted = true; + } catch {} + } + + // print as hex + if (!dataPrinted) { + valueDataHexArr.forEach(chunk => { + let printableHexString = '' + for (let j = 0; j < chunk.length; j++) { + printableHexString += chunk[j]; + if (j % 2 === 0){ + printableHexString += ' '; + } + if (j % 40 === 0){ + printableHexString += '\n' + } + } + }) + } + }); + + valueStream.on('error', (error) => { + throw error; + }); + + } catch (error: any) { + console.error('Cannot get key value:', error.message); + } +} \ No newline at end of file diff --git a/src/actions/index.ts b/src/actions/index.ts index d457a86..c9d7416 100644 --- a/src/actions/index.ts +++ b/src/actions/index.ts @@ -11,4 +11,5 @@ export * from './login'; export * from './logout'; export * from './verifyProof'; export * from './listKeys'; -export * from './getRoot'; \ No newline at end of file +export * from './getRoot'; +export * from './getKey'; \ No newline at end of file diff --git a/src/yargs/commands.ts b/src/yargs/commands.ts index 0167dc4..15d42ca 100644 --- a/src/yargs/commands.ts +++ b/src/yargs/commands.ts @@ -95,7 +95,7 @@ export function storeCommand(yargs: Argv<{}>) { .positional("action", { describe: "Action to perform on keys", type: "string", - choices: ["validate", "update", "remove", "get_root", "get_proof", "verify_proof", "list"], + choices: ["validate", "update", "remove", "get_root", "get_proof", "verify_proof", "list", "get_key"], }) .option ("key", { type: "string", @@ -130,6 +130,10 @@ export function storeCommand(yargs: Argv<{}>) { if (!argv.proof || !argv.sha256) { throw new Error(`The --proof and --sha256 options are required for the '${argv.action}' action.`); } + } else if (argv.action === "get_key") { + if (!argv.key) { + throw new Error(`The --key option is required for the '${argv.action}' action.`); + } } return true; }) diff --git a/src/yargs/handlers.ts b/src/yargs/handlers.ts index f5a4fbc..3d876e2 100644 --- a/src/yargs/handlers.ts +++ b/src/yargs/handlers.ts @@ -11,7 +11,9 @@ import { logout, getProof, verfiyProof, - listKeys, getRoot + listKeys, + getRoot, + getKey } from "../actions"; import { CreateStoreUserInputs } from '../types'; import { startPreviewServer } from '../content_server/server'; @@ -91,6 +93,11 @@ export const handlers = { await getRoot(); break; } + case "get_key": { + const {key} = argv; + await getKey(key); + break; + } default: console.error(`Unknown action ${argv.action}`); } From 44360d0c4d1d6fd4e970c66d4084e5109e68ab2f Mon Sep 17 00:00:00 2001 From: William Wills Date: Sun, 25 Aug 2024 17:27:17 -0400 Subject: [PATCH 09/15] fix: action description --- src/yargs/commands.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/yargs/commands.ts b/src/yargs/commands.ts index 15d42ca..a242b3a 100644 --- a/src/yargs/commands.ts +++ b/src/yargs/commands.ts @@ -93,7 +93,7 @@ export function storeCommand(yargs: Argv<{}>) { (yargs: Argv<{ action: string }>) => { return yargs .positional("action", { - describe: "Action to perform on keys", + describe: "The store action to perform", type: "string", choices: ["validate", "update", "remove", "get_root", "get_proof", "verify_proof", "list", "get_key"], }) From 37f3f80474f692edcb4a3abdd1c615ddafbadf8e Mon Sep 17 00:00:00 2001 From: William Wills Date: Mon, 26 Aug 2024 11:30:27 -0400 Subject: [PATCH 10/15] fix: DataIntegrityTree options fix: action organization --- package-lock.json | 16 +++ package.json | 1 + src/actions/getKey.ts | 70 ------------- src/actions/getProof.ts | 19 ---- src/actions/getRoot.ts | 18 ---- src/actions/index.ts | 8 +- src/actions/listKeys.ts | 28 ----- src/actions/store.ts | 208 ++++++++++++++++++++++++++++++++++--- src/actions/verifyProof.ts | 22 ---- 9 files changed, 210 insertions(+), 180 deletions(-) delete mode 100644 src/actions/getKey.ts delete mode 100644 src/actions/getProof.ts delete mode 100644 src/actions/getRoot.ts delete mode 100644 src/actions/listKeys.ts delete mode 100644 src/actions/verifyProof.ts diff --git a/package-lock.json b/package-lock.json index 360ebc9..5309a39 100644 --- a/package-lock.json +++ b/package-lock.json @@ -18,6 +18,7 @@ "cli-progress": "^3.12.0", "crypto-js": "^4.2.0", "datalayer-driver": "^0.1.17", + "datalayer-driver-linux-x64-gnu": "^0.1.17", "express": "^4.19.2", "ignore": "^5.3.2", "inquirer": "^10.1.8", @@ -1950,6 +1951,21 @@ "datalayer-driver-win32-x64-msvc": "0.1.17" } }, + "node_modules/datalayer-driver-linux-x64-gnu": { + "version": "0.1.17", + "resolved": "https://registry.npmjs.org/datalayer-driver-linux-x64-gnu/-/datalayer-driver-linux-x64-gnu-0.1.17.tgz", + "integrity": "sha512-52ztE1BA+VO13KQN5KP6h+4yclS4bCfQ0/OfrUsr+8vZmRSavnFP0DvKag5XHt2fW1R74sXI28X64uu6AbHHjg==", + "cpu": [ + "x64" + ], + "license": "MIT", + "os": [ + "linux" + ], + "engines": { + "node": ">= 10" + } + }, "node_modules/datalayer-driver-win32-x64-msvc": { "version": "0.1.17", "resolved": "https://registry.npmjs.org/datalayer-driver-win32-x64-msvc/-/datalayer-driver-win32-x64-msvc-0.1.17.tgz", diff --git a/package.json b/package.json index 32841fe..3c035ec 100644 --- a/package.json +++ b/package.json @@ -43,6 +43,7 @@ "cli-progress": "^3.12.0", "crypto-js": "^4.2.0", "datalayer-driver": "^0.1.17", + "datalayer-driver-linux-x64-gnu": "^0.1.17", "express": "^4.19.2", "ignore": "^5.3.2", "inquirer": "^10.1.8", diff --git a/src/actions/getKey.ts b/src/actions/getKey.ts deleted file mode 100644 index 7154fb1..0000000 --- a/src/actions/getKey.ts +++ /dev/null @@ -1,70 +0,0 @@ -import {DataIntegrityTree} from "../DataIntegrityTree"; -import {Buffer} from "buffer"; -import {getActiveStoreId} from "../utils/config"; - -export const getKey = async (key: string) => { - try { - const storeIdResult = await getActiveStoreId(); - const storeId = storeIdResult?.toString(); - if (!storeId){ - throw new Error('Failed to find datastore'); - } - - const datalayer = new DataIntegrityTree(storeId); - const valueStream = datalayer.getValueStream(key); - let valueData: Buffer = Buffer.alloc(0); - const valueDataHexArr: string[] = []; - - valueStream.on('data', (chunk) => { - const hex = chunk.toString('hex'); - valueDataHexArr.push(hex); - valueData = Buffer.concat([valueData, chunk]); - }); - - valueStream.on('end', () => { - const dataUtf8: string = valueData.toString('utf8'); - let dataPrinted = false - console.log(`Data for key ${key}:\n\n`); - - // print as json - try { - JSON.parse(dataUtf8); - console.log(dataUtf8); - dataPrinted = true; - } catch {} - - // print as xml - if (!dataPrinted) { - try { - const parser = new DOMParser(); - parser.parseFromString(dataUtf8, 'text/xml'); - console.log(dataUtf8); - dataPrinted = true; - } catch {} - } - - // print as hex - if (!dataPrinted) { - valueDataHexArr.forEach(chunk => { - let printableHexString = '' - for (let j = 0; j < chunk.length; j++) { - printableHexString += chunk[j]; - if (j % 2 === 0){ - printableHexString += ' '; - } - if (j % 40 === 0){ - printableHexString += '\n' - } - } - }) - } - }); - - valueStream.on('error', (error) => { - throw error; - }); - - } catch (error: any) { - console.error('Cannot get key value:', error.message); - } -} \ No newline at end of file diff --git a/src/actions/getProof.ts b/src/actions/getProof.ts deleted file mode 100644 index 49a05ef..0000000 --- a/src/actions/getProof.ts +++ /dev/null @@ -1,19 +0,0 @@ -import {DataIntegrityTree} from "../DataIntegrityTree"; -import {getActiveStoreId} from "../utils/config"; - -export const getProof = async (key: string, sha256: string) => { - try { - const storeIdResult = getActiveStoreId(); - const storeId = storeIdResult?.toString(); - if (!storeId){ - throw new Error('Failed to find datastore'); - } - const datalayer = new DataIntegrityTree(storeId); - const proof = datalayer.getProof(key, sha256); - - console.log(`Proof for key ${key}\nand sha256 hash ${sha256}:`); - console.log(proof); - } catch (error: any) { - console.error('Cannot get proof:', error.message); - } -} \ No newline at end of file diff --git a/src/actions/getRoot.ts b/src/actions/getRoot.ts deleted file mode 100644 index 9112179..0000000 --- a/src/actions/getRoot.ts +++ /dev/null @@ -1,18 +0,0 @@ -import {getActiveStoreId} from "../utils/config"; -import {DataIntegrityTree} from "../DataIntegrityTree"; - -export const getRoot = async () => { - try { - const storeIdResult = await getActiveStoreId(); - const storeId = storeIdResult?.toString(); - if (!storeId){ - throw new Error('Failed to find datastore'); - } - const datalayer = new DataIntegrityTree(storeId); - const rootHash = datalayer.getRoot(); - console.log(`The root hash is ${rootHash}`); - - } catch (error: any) { - console.error('Failed to get root hash:', error.message); - } -} \ No newline at end of file diff --git a/src/actions/index.ts b/src/actions/index.ts index c9d7416..aa397ec 100644 --- a/src/actions/index.ts +++ b/src/actions/index.ts @@ -6,10 +6,6 @@ export * from './remote'; export * from './pull'; export * from './commit'; export * from './validate'; -export * from './getProof'; +export * from './store'; export * from './login'; -export * from './logout'; -export * from './verifyProof'; -export * from './listKeys'; -export * from './getRoot'; -export * from './getKey'; \ No newline at end of file +export * from './logout'; \ No newline at end of file diff --git a/src/actions/listKeys.ts b/src/actions/listKeys.ts deleted file mode 100644 index d011de7..0000000 --- a/src/actions/listKeys.ts +++ /dev/null @@ -1,28 +0,0 @@ -import {getActiveStoreId} from "../utils/config"; -import {DataIntegrityTree} from "../DataIntegrityTree"; - -export const listKeys = async () => { - try { - const storeIdResult = await getActiveStoreId(); - const storeId = storeIdResult?.toString(); - if (!storeId){ - throw new Error('Failed to find datastore'); - } - const datalayer = new DataIntegrityTree(storeId); - const keysArr = datalayer.listKeys(); - - if (keysArr.length > 0){ - let printableList: string = ''; - keysArr.forEach(key => { - printableList += `${key}\n`; - }); - - console.log(`Keys for store ${storeId}:\n\n${printableList}`); - } else { - console.log(`Store ${storeId} has no keys`); - } - - } catch (error: any) { - console.error('Failed to get store keys:', error.message); - } -} \ No newline at end of file diff --git a/src/actions/store.ts b/src/actions/store.ts index c3acb64..a953027 100644 --- a/src/actions/store.ts +++ b/src/actions/store.ts @@ -1,17 +1,191 @@ - -/* -export const upsert = async ({ writerPublicAddress, adminPublicAddress, oracleFee }): Promise => { - -} - -export const remove = async ({ writerPublicAddress, adminPublicAddress, oracleFee }): Promise => { - -} - -export const transfer = async ({ receivePublicAddress }): Promise => { - -} - -export const melt = async (): Promise => { - -}*/ + +/* +export const upsert = async ({ writerPublicAddress, adminPublicAddress, oracleFee }): Promise => { + +} + +export const remove = async ({ writerPublicAddress, adminPublicAddress, oracleFee }): Promise => { + +} + +export const transfer = async ({ receivePublicAddress }): Promise => { + +} + +export const melt = async (): Promise => { + +}*/ + +import {DIG_FOLDER_PATH, getActiveStoreId} from "../utils/config"; +import {DataIntegrityTree, DataIntegrityTreeOptions} from "../DataIntegrityTree"; +import {Buffer} from "buffer"; + +export const getKey = async (key: string) => { + try { + const storeIdResult = await getActiveStoreId(); + const storeId = storeIdResult?.toString(); + if (!storeId){ + throw new Error('Failed to find datastore'); + } + + const options: DataIntegrityTreeOptions = { + storageMode: "local", + storeDir: DIG_FOLDER_PATH, + }; + const datalayer = new DataIntegrityTree(storeId, options); + const valueStream = datalayer.getValueStream(key); + let valueData: Buffer = Buffer.alloc(0); + const valueDataHexArr: string[] = []; + + valueStream.on('data', (chunk) => { + const hex = chunk.toString('hex'); + valueDataHexArr.push(hex); + valueData = Buffer.concat([valueData, chunk]); + }); + + valueStream.on('end', () => { + const dataUtf8: string = valueData.toString('utf8'); + let dataPrinted = false + console.log(`Data for key ${key}:\n\n`); + + // print as json + try { + JSON.parse(dataUtf8); + console.log(dataUtf8); + dataPrinted = true; + } catch {} + + // print as xml + if (!dataPrinted) { + try { + const parser = new DOMParser(); + parser.parseFromString(dataUtf8, 'text/xml'); + console.log(dataUtf8); + dataPrinted = true; + } catch {} + } + + // print as hex + if (!dataPrinted) { + valueDataHexArr.forEach(chunk => { + let printableHexString = '' + for (let j = 0; j < chunk.length; j++) { + printableHexString += chunk[j]; + if (j % 2 === 0){ + printableHexString += ' '; + } + if (j % 40 === 0){ + printableHexString += '\n' + } + } + }) + } + }); + + valueStream.on('error', (error) => { + throw error; + }); + + } catch (error: any) { + console.error('Cannot get key value:', error.message); + } +} + +export const getProof = async (key: string, sha256: string) => { + try { + const storeIdResult = getActiveStoreId(); + const storeId = storeIdResult?.toString(); + if (!storeId){ + throw new Error('Failed to find datastore'); + } + + const options: DataIntegrityTreeOptions = { + storageMode: "local", + storeDir: DIG_FOLDER_PATH, + }; + const datalayer = new DataIntegrityTree(storeId, options); + const proof = datalayer.getProof(key, sha256); + + console.log(`Proof for key ${key}\nand sha256 hash ${sha256}:`); + console.log(proof); + } catch (error: any) { + console.error('Cannot get proof:', error.message); + } +} + +export const getRoot = async () => { + try { + const storeIdResult = await getActiveStoreId(); + const storeId = storeIdResult?.toString(); + if (!storeId){ + throw new Error('Failed to find datastore'); + } + + const options: DataIntegrityTreeOptions = { + storageMode: "local", + storeDir: DIG_FOLDER_PATH, + }; + const datalayer = new DataIntegrityTree(storeId, options); + const rootHash = datalayer.getRoot(); + console.log(`The root hash is ${rootHash}`); + + } catch (error: any) { + console.error('Failed to get root hash:', error.message); + } +} + +export const listKeys = async () => { + try { + const storeIdResult = await getActiveStoreId(); + const storeId = storeIdResult?.toString(); + if (!storeId){ + throw new Error('Failed to find datastore'); + } + + const options: DataIntegrityTreeOptions = { + storageMode: "local", + storeDir: DIG_FOLDER_PATH, + }; + const datalayer = new DataIntegrityTree(storeId, options); + const keysArr = datalayer.listKeys(); + + if (keysArr.length > 0){ + let printableList: string = ''; + keysArr.forEach(key => { + printableList += `${key}\n`; + }); + + console.log(`Keys for store ${storeId}:\n\n${printableList}`); + } else { + console.log(`Store ${storeId} has no keys`); + } + + } catch (error: any) { + console.error('Failed to get store keys:', error.message); + } +} + +export const verfiyProof = async (proof: string, sha256: string) => { + try { + const storeIdResult = getActiveStoreId(); + const storeId = storeIdResult?.toString(); + if (!storeId){ + throw new Error('Failed to find datastore'); + } + + const options: DataIntegrityTreeOptions = { + storageMode: "local", + storeDir: DIG_FOLDER_PATH, + }; + const datalayer = new DataIntegrityTree(storeId, options); + const proofVerified = datalayer.verifyProof(proof, sha256); + + if (proofVerified) { + console.log('Proof has been verified'); + } else { + console.error('Proof verification failed with provided hash'); + } + } catch (error: any) { + console.error('Failed to process proof:', error.message); + } +} diff --git a/src/actions/verifyProof.ts b/src/actions/verifyProof.ts deleted file mode 100644 index 0aea519..0000000 --- a/src/actions/verifyProof.ts +++ /dev/null @@ -1,22 +0,0 @@ -import {DataIntegrityTree} from "../DataIntegrityTree"; -import {getActiveStoreId} from "../utils/config"; - -export const verfiyProof = async (proof: string, sha256: string) => { - try { - const storeIdResult = getActiveStoreId(); - const storeId = storeIdResult?.toString(); - if (!storeId){ - throw new Error('Failed to find datastore'); - } - const datalayer = new DataIntegrityTree(storeId); - const proofVerified = datalayer.verifyProof(proof, sha256); - - if (proofVerified) { - console.log('Proof has been verified'); - } else { - console.error('Proof verification failed with provided hash'); - } - } catch (error: any) { - console.error('Failed to process proof:', error.message); - } -} \ No newline at end of file From 26ebc968279b4cbe730cf33eeda9167e0b0a3212 Mon Sep 17 00:00:00 2001 From: William Wills Date: Mon, 26 Aug 2024 11:36:32 -0400 Subject: [PATCH 11/15] fix: merge main --- src/yargs/handlers.ts | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/src/yargs/handlers.ts b/src/yargs/handlers.ts index 6a69767..27d6ea5 100644 --- a/src/yargs/handlers.ts +++ b/src/yargs/handlers.ts @@ -18,13 +18,12 @@ import { verfiyProof, listKeys, getRoot, - getKey + getKey, syncRemoteSeed as _syncRemoteSeed, setRemoteSeed as _setRemoteSeed, generateEntropyValue } from "../actions"; import { CreateStoreUserInputs } from "../types"; -import { logout } from "../actions/logout"; import { startPreviewServer } from "../content_server/server"; import { checkStoreWritePermissions } from "../actions"; import { getActiveStoreId } from "../utils/config"; From c2efef624adec72f3622271657c7aae82adeb18f Mon Sep 17 00:00:00 2001 From: William Wills Date: Mon, 26 Aug 2024 11:39:39 -0400 Subject: [PATCH 12/15] feat: store command uses STORE_PATH --- src/actions/store.ts | 17 ++++++++--------- 1 file changed, 8 insertions(+), 9 deletions(-) diff --git a/src/actions/store.ts b/src/actions/store.ts index a953027..a789c04 100644 --- a/src/actions/store.ts +++ b/src/actions/store.ts @@ -1,3 +1,6 @@ +import {getActiveStoreId, STORE_PATH} from "../utils/config"; +import {DataIntegrityTree, DataIntegrityTreeOptions} from "../DataIntegrityTree"; +import {Buffer} from "buffer"; /* export const upsert = async ({ writerPublicAddress, adminPublicAddress, oracleFee }): Promise => { @@ -16,10 +19,6 @@ export const melt = async (): Promise => { }*/ -import {DIG_FOLDER_PATH, getActiveStoreId} from "../utils/config"; -import {DataIntegrityTree, DataIntegrityTreeOptions} from "../DataIntegrityTree"; -import {Buffer} from "buffer"; - export const getKey = async (key: string) => { try { const storeIdResult = await getActiveStoreId(); @@ -30,7 +29,7 @@ export const getKey = async (key: string) => { const options: DataIntegrityTreeOptions = { storageMode: "local", - storeDir: DIG_FOLDER_PATH, + storeDir: STORE_PATH, }; const datalayer = new DataIntegrityTree(storeId, options); const valueStream = datalayer.getValueStream(key); @@ -101,7 +100,7 @@ export const getProof = async (key: string, sha256: string) => { const options: DataIntegrityTreeOptions = { storageMode: "local", - storeDir: DIG_FOLDER_PATH, + storeDir: STORE_PATH, }; const datalayer = new DataIntegrityTree(storeId, options); const proof = datalayer.getProof(key, sha256); @@ -123,7 +122,7 @@ export const getRoot = async () => { const options: DataIntegrityTreeOptions = { storageMode: "local", - storeDir: DIG_FOLDER_PATH, + storeDir: STORE_PATH, }; const datalayer = new DataIntegrityTree(storeId, options); const rootHash = datalayer.getRoot(); @@ -144,7 +143,7 @@ export const listKeys = async () => { const options: DataIntegrityTreeOptions = { storageMode: "local", - storeDir: DIG_FOLDER_PATH, + storeDir: STORE_PATH, }; const datalayer = new DataIntegrityTree(storeId, options); const keysArr = datalayer.listKeys(); @@ -175,7 +174,7 @@ export const verfiyProof = async (proof: string, sha256: string) => { const options: DataIntegrityTreeOptions = { storageMode: "local", - storeDir: DIG_FOLDER_PATH, + storeDir: STORE_PATH, }; const datalayer = new DataIntegrityTree(storeId, options); const proofVerified = datalayer.verifyProof(proof, sha256); From bcab541cd2366b9ca420d559d9b79691d7c02fca Mon Sep 17 00:00:00 2001 From: William Wills Date: Mon, 26 Aug 2024 14:29:47 -0400 Subject: [PATCH 13/15] feat: added store upsert_data and store upsert_file commands --- src/actions/store.ts | 56 +++++++++++++++++++++++++++++++++++++++---- src/yargs/commands.ts | 19 ++++++++++++++- src/yargs/handlers.ts | 14 ++++++++--- 3 files changed, 81 insertions(+), 8 deletions(-) diff --git a/src/actions/store.ts b/src/actions/store.ts index a789c04..e5a3bab 100644 --- a/src/actions/store.ts +++ b/src/actions/store.ts @@ -1,12 +1,10 @@ import {getActiveStoreId, STORE_PATH} from "../utils/config"; import {DataIntegrityTree, DataIntegrityTreeOptions} from "../DataIntegrityTree"; import {Buffer} from "buffer"; +import {Readable} from "stream"; +import fs from "fs"; /* -export const upsert = async ({ writerPublicAddress, adminPublicAddress, oracleFee }): Promise => { - -} - export const remove = async ({ writerPublicAddress, adminPublicAddress, oracleFee }): Promise => { } @@ -19,6 +17,53 @@ export const melt = async (): Promise => { }*/ +export const upsertData = async (key: string, data: string): Promise => { + try { + const storeIdResult = getActiveStoreId(); + const storeId = storeIdResult?.toString(); + if (!storeId){ + throw new Error('Failed to find datastore'); + } + + const dataStream = new Readable(); + dataStream.push(data); + dataStream.push(null); + + const options: DataIntegrityTreeOptions = { + storageMode: "local", + storeDir: STORE_PATH, + }; + const datalayer = new DataIntegrityTree(storeId, options); + await datalayer.upsertKey(dataStream, key); + + console.log(`Upserted data to datastore ${storeId} with key ${key}`); + } catch (error: any) { + console.error('Cannot upsert data:', error.message); + } +} + +export const upsertFile = async (key: string, filePath: string): Promise => { + try { + const storeIdResult = getActiveStoreId(); + const storeId = storeIdResult?.toString(); + if (!storeId){ + throw new Error('Failed to find datastore'); + } + + const fileStream = fs.createReadStream(filePath); + + const options: DataIntegrityTreeOptions = { + storageMode: "local", + storeDir: STORE_PATH, + }; + const datalayer = new DataIntegrityTree(storeId, options); + await datalayer.upsertKey(fileStream, key); + + } catch (error: any) { + console.error('Cannot upsert file:', error.message); + } +} + export const getKey = async (key: string) => { try { const storeIdResult = await getActiveStoreId(); @@ -77,6 +122,7 @@ export const getKey = async (key: string) => { printableHexString += '\n' } } + console.log(printableHexString); }) } }); @@ -188,3 +234,5 @@ export const verfiyProof = async (proof: string, sha256: string) => { console.error('Failed to process proof:', error.message); } } + + diff --git a/src/yargs/commands.ts b/src/yargs/commands.ts index 2accfc5..e9ad475 100644 --- a/src/yargs/commands.ts +++ b/src/yargs/commands.ts @@ -95,12 +95,21 @@ export function storeCommand(yargs: Argv<{}>) { .positional("action", { describe: "The store action to perform", type: "string", - choices: ["validate", "update", "remove", "get_root", "get_proof", "verify_proof", "list", "get_key"], + choices: ["validate", "upsert_file", "upsert_data", "remove", "get_root", "get_proof", "verify_proof", + "list", "get_key",], }) .option ("key", { type: "string", describe: "The store key on which to operate" }) + .option ("data", { + type: "string", + describe: "The data to upsert" + }) + .option ("path", { + type: "string", + describe: "The path to the file to upsert" + }) .option ("proof", { type: "string", describe: "The proof to verify" @@ -134,6 +143,14 @@ export function storeCommand(yargs: Argv<{}>) { if (!argv.key) { throw new Error(`The --key option is required for the '${argv.action}' action.`); } + } else if (argv.action === "upsert_data") { + if (!argv.key || !argv.data) { + throw new Error(`The --key and --data options are required for the '${argv.action}' action.`); + } + } else if (argv.action === "upsert_file") { + if (!argv.key || !argv.path) { + throw new Error(`The --key and --path options are required for the '${argv.action}' action.`); + } } return true; }) diff --git a/src/yargs/handlers.ts b/src/yargs/handlers.ts index 27d6ea5..4ca1715 100644 --- a/src/yargs/handlers.ts +++ b/src/yargs/handlers.ts @@ -19,9 +19,10 @@ import { listKeys, getRoot, getKey, + upsertData, syncRemoteSeed as _syncRemoteSeed, setRemoteSeed as _setRemoteSeed, - generateEntropyValue + generateEntropyValue, upsertFile } from "../actions"; import { CreateStoreUserInputs } from "../types"; import { startPreviewServer } from "../content_server/server"; @@ -84,9 +85,16 @@ export const handlers = { case "validate": await validate(); break; - case "update": - // await upsertStore(); + case "upsert_data": { + const {key, data} = argv; + await upsertData(key, data); break; + } + case "upsert_file": { + const {key, path} = argv; + await upsertFile(key, path); + break; + } case "remove": // await removeStore(); break; From 25245fe729b8d1aad8dbaa46b562f2a6661c1a87 Mon Sep 17 00:00:00 2001 From: William Wills Date: Mon, 26 Aug 2024 14:41:02 -0400 Subject: [PATCH 14/15] feat: added store delete_key command --- src/actions/store.ts | 27 +++++++++++++++++++++++---- src/yargs/commands.ts | 7 ++++++- src/yargs/handlers.ts | 11 ++++++++--- 3 files changed, 37 insertions(+), 8 deletions(-) diff --git a/src/actions/store.ts b/src/actions/store.ts index e5a3bab..8c04d45 100644 --- a/src/actions/store.ts +++ b/src/actions/store.ts @@ -17,7 +17,26 @@ export const melt = async (): Promise => { }*/ -export const upsertData = async (key: string, data: string): Promise => { +export const deleteKey = async (key: string) => { + try { + const storeIdResult = getActiveStoreId(); + const storeId = storeIdResult?.toString(); + if (!storeId){ + throw new Error('Failed to find datastore'); + } + + const options: DataIntegrityTreeOptions = { + storageMode: "local", + storeDir: STORE_PATH, + }; + const datalayer = new DataIntegrityTree(storeId, options); + datalayer.deleteKey(key); + } catch (error: any) { + console.error('Cannot delete key:', error.message); + } +} + +export const upsertData = async (key: string, data: string) => { try { const storeIdResult = getActiveStoreId(); const storeId = storeIdResult?.toString(); @@ -42,7 +61,7 @@ export const upsertData = async (key: string, data: string): Promise => { } } -export const upsertFile = async (key: string, filePath: string): Promise => { +export const upsertFile = async (key: string, filePath: string) => { try { const storeIdResult = getActiveStoreId(); const storeId = storeIdResult?.toString(); @@ -210,7 +229,7 @@ export const listKeys = async () => { } } -export const verfiyProof = async (proof: string, sha256: string) => { +export const verifyProof = async (proof: string, sha256: string) => { try { const storeIdResult = getActiveStoreId(); const storeId = storeIdResult?.toString(); @@ -231,7 +250,7 @@ export const verfiyProof = async (proof: string, sha256: string) => { console.error('Proof verification failed with provided hash'); } } catch (error: any) { - console.error('Failed to process proof:', error.message); + console.error('Cannot process proof:', error.message); } } diff --git a/src/yargs/commands.ts b/src/yargs/commands.ts index e9ad475..29ec32c 100644 --- a/src/yargs/commands.ts +++ b/src/yargs/commands.ts @@ -96,7 +96,7 @@ export function storeCommand(yargs: Argv<{}>) { describe: "The store action to perform", type: "string", choices: ["validate", "upsert_file", "upsert_data", "remove", "get_root", "get_proof", "verify_proof", - "list", "get_key",], + "list", "get_key", "delete_key"], }) .option ("key", { type: "string", @@ -152,6 +152,11 @@ export function storeCommand(yargs: Argv<{}>) { throw new Error(`The --key and --path options are required for the '${argv.action}' action.`); } } + else if (argv.action === "delete_key") { + if (!argv.key) { + throw new Error(`The --key option is required for the '${argv.action}' action.`); + } + } return true; }) .strict(); diff --git a/src/yargs/handlers.ts b/src/yargs/handlers.ts index 4ca1715..176528f 100644 --- a/src/yargs/handlers.ts +++ b/src/yargs/handlers.ts @@ -15,14 +15,14 @@ import { login, logout, getProof, - verfiyProof, + verifyProof, listKeys, getRoot, getKey, upsertData, syncRemoteSeed as _syncRemoteSeed, setRemoteSeed as _setRemoteSeed, - generateEntropyValue, upsertFile + generateEntropyValue, upsertFile, deleteKey } from "../actions"; import { CreateStoreUserInputs } from "../types"; import { startPreviewServer } from "../content_server/server"; @@ -105,7 +105,7 @@ export const handlers = { } case "verify_proof": { const {proof, sha256} = argv; - await verfiyProof(proof, sha256); + await verifyProof(proof, sha256); break; } case "list": { @@ -121,6 +121,11 @@ export const handlers = { await getKey(key); break; } + case "delete_key": { + const {key} = argv; + await deleteKey(key); + break; + } default: console.error(`Unknown action ${argv.action}`); } From fe3e244362fbe901278dbf4259d22123c2843438 Mon Sep 17 00:00:00 2001 From: William Wills Date: Mon, 26 Aug 2024 14:49:27 -0400 Subject: [PATCH 15/15] fix: merge errors --- src/yargs/handlers.ts | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/src/yargs/handlers.ts b/src/yargs/handlers.ts index 77c560c..25df953 100644 --- a/src/yargs/handlers.ts +++ b/src/yargs/handlers.ts @@ -20,13 +20,14 @@ import { getRoot, getKey, upsertData, - upsertFile, deleteKey + upsertFile, + deleteKey, syncRemoteSeed as _syncRemoteSeed, setRemoteSeed as _setRemoteSeed, generateEntropyValue } from "../actions"; import { CreateStoreUserInputs } from "../types"; -import { startPreviewServer } from "../content_server/server"; +import { startContentServer } from "../content_server/server"; import { checkStoreWritePermissions } from "../actions"; import { getActiveStoreId } from "../utils/config";