diff --git a/README.md b/README.md index 2a87f53..1dd9dec 100644 --- a/README.md +++ b/README.md @@ -65,7 +65,7 @@ You can apply those values with two options ### How to start -1. `yarn start --help` +1. `yarn start --help` or `yarn run help` 2. If you want to use a secure, anonymous tor connection add `--tor-port ` behind the command or add `TOR_PORT` at the `.env` file. 3. Add `PRIVATE_KEY` to `.env` file (optional, only if you want to use it for many operations) - open `.env.example` file, add private key after `PRIVATE_KEY=` and rename file to `.env`. diff --git a/package.json b/package.json index da5df04..476332b 100644 --- a/package.json +++ b/package.json @@ -15,8 +15,8 @@ "build:node": "ts-node scripts/fflate.ts && webpack", "build": "yarn types && yarn build:node", "start": "ts-node src/cli.ts", - "startHelp": "ts-node src/cli.ts help", - "createDeposit": "ts-node src/cli.ts create", + "help": "ts-node src/cli.ts help", + "create": "ts-node src/cli.ts create", "deposit": "ts-node src/cli.ts deposit", "depositInvoice": "ts-node src/cli.ts depositInvoice", "withdraw": "ts-node src/cli.ts withdraw", diff --git a/src/services/data.ts b/src/services/data.ts index 6a1c3a2..862b18f 100644 --- a/src/services/data.ts +++ b/src/services/data.ts @@ -1,4 +1,5 @@ import path from 'path'; +import { deflate, constants } from 'zlib'; import { stat, mkdir, readFile, writeFile } from 'fs/promises'; import { zip, unzip, AsyncZippable, Unzipped } from 'fflate'; import { BaseEvents, MinimalEvents } from '@tornado/core'; @@ -13,6 +14,28 @@ export async function existsAsync(fileOrDir: string): Promise { } } +/** + * Supports legacy gz format for legacy UI + */ +export function deflateAsync(data: Uint8Array): Promise { + return new Promise((resolve, reject) => { + deflate( + data, + { + level: constants.Z_BEST_COMPRESSION, + strategy: constants.Z_FILTERED, + }, + (err, buffer) => { + if (!err) { + resolve(buffer); + } else { + reject(err); + } + }, + ); + }); +} + export function zipAsync(file: AsyncZippable): Promise { return new Promise((res, rej) => { zip(file, { mtime: new Date('1/1/1980') }, (err, data) => { @@ -37,6 +60,28 @@ export function unzipAsync(data: Uint8Array): Promise { }); } +export async function saveLegacyFile({ + fileName, + userDirectory, + dataString, +}: { + fileName: string; + userDirectory: string; + dataString: string; +}) { + fileName = fileName.toLowerCase(); + + const filePath = path.join(userDirectory, fileName); + + const payload = await deflateAsync(new TextEncoder().encode(dataString)); + + if (!(await existsAsync(userDirectory))) { + await mkdir(userDirectory, { recursive: true }); + } + + await writeFile(filePath + '.gz', payload); +} + export async function saveUserFile({ fileName, userDirectory, diff --git a/src/services/nodeEvents.ts b/src/services/nodeEvents.ts index 371a0e8..4f21077 100644 --- a/src/services/nodeEvents.ts +++ b/src/services/nodeEvents.ts @@ -13,6 +13,7 @@ import { BaseRegistryServiceConstructor, BaseEchoServiceConstructor, BaseEchoService, + DEPOSIT, } from '@tornado/core'; import type { BaseEvents, @@ -23,7 +24,7 @@ import type { AllGovernanceEvents, EchoEvents, } from '@tornado/core'; -import { saveUserFile, loadSavedEvents, loadCachedEvents } from './data'; +import { saveUserFile, loadSavedEvents, loadCachedEvents, saveLegacyFile } from './data'; export type NodeTornadoServiceConstructor = BaseTornadoServiceConstructor & { cacheDirectory?: string; @@ -190,6 +191,32 @@ export class NodeTornadoService extends BaseTornadoService { userDirectory: this.userDirectory, dataString: JSON.stringify(events, null, 2) + '\n', }); + + if (this.getType().toLowerCase() === DEPOSIT) { + const legacyEvents = (events as DepositsEvents[]).map( + ({ blockNumber, transactionHash, commitment, leafIndex, timestamp }) => ({ + blockNumber, + transactionHash, + commitment, + leafIndex, + timestamp: String(timestamp), + }), + ); + + await saveLegacyFile({ + fileName: instanceName + '.json', + userDirectory: this.userDirectory, + dataString: JSON.stringify(legacyEvents, null, 2) + '\n', + }); + } else { + const legacyEvents = events as WithdrawalsEvents[]; + + await saveLegacyFile({ + fileName: instanceName + '.json', + userDirectory: this.userDirectory, + dataString: JSON.stringify(legacyEvents, null, 2) + '\n', + }); + } } } } @@ -480,6 +507,18 @@ export class NodeEncryptedNotesService extends BaseEncryptedNotesService { userDirectory: this.userDirectory, dataString: JSON.stringify(events, null, 2) + '\n', }); + + const legacyEvents = events.map(({ transactionHash, blockNumber, encryptedNote }) => ({ + txHash: transactionHash, + blockNumber, + encryptedNote, + })); + + await saveLegacyFile({ + fileName: instanceName + '.json', + userDirectory: this.userDirectory, + dataString: JSON.stringify(legacyEvents, null, 2) + '\n', + }); } } }