Skip to content

Commit

Permalink
cli cmd for return depositors (#652)
Browse files Browse the repository at this point in the history
* return user cli

* rename data pkg

* move utils into data package and import in screener cli

* changeset
  • Loading branch information
luketchang authored Nov 24, 2023
1 parent 0a08a9e commit 74c4be8
Show file tree
Hide file tree
Showing 24 changed files with 105 additions and 46 deletions.
6 changes: 6 additions & 0 deletions .changeset/angry-roses-care.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
---
"@nocturne-xyz/deposit-screener": patch
"@nocturne-xyz/data": patch
---

move csv and address parsing util functions into data package and import in screener
5 changes: 5 additions & 0 deletions .changeset/seven-months-fold.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
"@nocturne-xyz/data": minor
---

add return-depositors command to track return users
1 change: 1 addition & 0 deletions actors/deposit-screener/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,7 @@
"@nocturne-xyz/config": "workspace:^",
"@nocturne-xyz/contracts": "^3.0.0",
"@nocturne-xyz/core": "workspace:^",
"@nocturne-xyz/data": "workspace:^",
"@nocturne-xyz/offchain-utils": "workspace:^",
"@nocturne-xyz/subgraph-sync-adapters": "workspace:^",
"@opentelemetry/api": "^1.4.1",
Expand Down
2 changes: 1 addition & 1 deletion actors/deposit-screener/src/cli/commands/inspect/check.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,14 +6,14 @@ import { isRejection } from "../../../screening/checks/RuleSet";
import { Logger } from "winston";
import {
AddressDataSnapshot,
dedupAddressesInOrder,
ensureExists,
formDepositInfo,
getLocalRedis,
populateRedisCache,
} from "./helpers/utils";
import * as JSON from "bigint-json-serialization";
import path from "path";
import { dedupAddressesInOrder } from "@nocturne-xyz/data";

/**
* Example
Expand Down
14 changes: 0 additions & 14 deletions actors/deposit-screener/src/cli/commands/inspect/helpers/utils.ts
Original file line number Diff line number Diff line change
Expand Up @@ -111,20 +111,6 @@ export function toMisttrackResponse(data: MisttrackData): Response {
return res;
}

export function dedupAddressesInOrder(addresses: string[]): string[] {
// deduplicate and sort
const uniqueAddresses = new Set();
const dedupedAddresses = [];
for (const address of addresses) {
if (!uniqueAddresses.has(address)) {
uniqueAddresses.add(address);
dedupedAddresses.push(address);
}
}

return dedupedAddresses;
}

export function ensureExists(
inputPath: string,
{ path: outputPath, type }: OutputItem
Expand Down
24 changes: 5 additions & 19 deletions actors/deposit-screener/src/cli/commands/inspect/snapshot.ts
Original file line number Diff line number Diff line change
@@ -1,18 +1,17 @@
import { makeLogger } from "@nocturne-xyz/offchain-utils";
import { Command } from "commander";
import fs from "fs";
import { requireApiKeys } from "../../../utils";
import { createWriteStream } from "fs";
import { API_CALL_MAP, ApiCallNames } from "../../../screening/checks/apiCalls";
import { Address, sleep } from "@nocturne-xyz/core";
import { sleep } from "@nocturne-xyz/core";
import * as JSON from "bigint-json-serialization";
import {
CachedAddressData,
dedupAddressesInOrder,
ensureExists,
formDepositInfo,
getLocalRedis,
} from "./helpers/utils";
import { parseAndFilterCsvOfAddresses } from "@nocturne-xyz/data";

/**
* Example
Expand Down Expand Up @@ -43,21 +42,6 @@ const runSnapshot = new Command("snapshot")
.option("--log-level <string>", "min log importance to log to stdout.")
.action(main);

async function parseAndFilterCsvOfAddresses(path: string): Promise<Address[]> {
const inputFileText = await fs.promises.readFile(path, "utf-8");
// split the input file into lines
const inputFileLines = inputFileText.split("\n");
// take the first column
const addresses = inputFileLines.map((line) => line.trim().split(",")[0]);
// filter out anything that doesn't look like an address
const filteredAddresses = addresses.filter((address) => {
return address.match(/^0x[0-9a-fA-F]{40}$/i);
});

// deduplicate and sort
return dedupAddressesInOrder(filteredAddresses);
}

async function main(options: any): Promise<void> {
requireApiKeys();

Expand All @@ -73,7 +57,9 @@ async function main(options: any): Promise<void> {
);

logger.info(`Starting snapshot for addresses from ${inputCsv}`);
const dedupedAddresses = await parseAndFilterCsvOfAddresses(inputCsv);
const dedupedAddresses = await parseAndFilterCsvOfAddresses(inputCsv, {
dedupAddresses: true,
});
const numAddresses = dedupedAddresses.length;

const writeStream = createWriteStream(outputData, { encoding: "utf-8" });
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@ import { ethers } from "ethers";
* Example
* yarn deposit-screener-cli inspect trmTxMonitor --token-address 0x6b175474e89094c44da98b954eedeac495271d0f --eth-transfer-style indirect --from-address 0xd90e2f925DA726b50C4Ed8D0Fb90Ad053324F31b --start-block 0 --end-block 27025780 --log-level=info
*/
const runTrmTxMonitor = new Command("trmTxMonitor")
const runTrmTxMonitor = new Command("trm-tx-monitor")
.summary(
"query token/ETH outflows and submit to TRM transaction monitoring API"
)
Expand Down
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
6 changes: 4 additions & 2 deletions packages/data-cli/package.json → packages/data/package.json
Original file line number Diff line number Diff line change
@@ -1,9 +1,11 @@
{
"name": "@nocturne-xyz/data-cli",
"name": "@nocturne-xyz/data",
"version": "0.1.2",
"license": "MIT",
"main": "dist/index.js",
"bin": "dist/src/index.js",
"bin": {
"data-cli": "dist/src/cli/index.js"
},
"types": "dist/index.d.ts",
"files": [
"dist/**/*",
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,6 @@ interface FetchDepositorsOpts {
type: DepositEventType;
fromBlock: number;
toBlock: number;
limit?: number;
}

async function writeDepositorsToCsv(
Expand Down Expand Up @@ -64,11 +63,10 @@ const depositors = new Command("depositors")
)
.requiredOption("--from-block <number>", "Block number to start from")
.requiredOption("--to-block <number>", "Block number to end at")
.option("--limit <number>", "Max number of depositors to fetch", "1000")
.action(main);

async function main(options: any): Promise<void> {
const { fromBlock, toBlock, limit } = options;
const { fromBlock, toBlock } = options;

const subgraphUrl = process.env.SUBGRAPH_URL;
if (!subgraphUrl) {
Expand All @@ -79,7 +77,6 @@ async function main(options: any): Promise<void> {
type: DepositEventType.Instantiated,
fromBlock,
toBlock,
limit,
});

console.log(`Found ${depositors.length} depositors`);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ import { program } from "commander";
import * as dotenv from "dotenv";
import { setupDefaultInstrumentation } from "@nocturne-xyz/offchain-utils";
import depositors from "./depositors";
import { returnDepositors } from "./returnDepositors";

export default async function main(): Promise<void> {
dotenv.config();
Expand All @@ -12,7 +13,8 @@ export default async function main(): Promise<void> {
program
.name("data-cli")
.description("CLI for onchain data inspection")
.addCommand(depositors);
.addCommand(depositors)
.addCommand(returnDepositors);
await program.parseAsync(process.argv);
}

Expand Down
32 changes: 32 additions & 0 deletions packages/data/src/cli/returnDepositors.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
import { parseAndFilterCsvOfAddresses } from "../utils";
import { Command } from "commander";

export const returnDepositors = new Command("return-depositors")
.summary("Print list of return depositors (at least 2 deposits)")
.description(
"Print list of return depositors to number of deposits. Minimum 2 deposits to show in list."
)
.requiredOption("--input-csv <string>", "Path to input CSV")
.action(main);

async function main(options: any): Promise<void> {
const { inputCsv } = options;

const addresses = await parseAndFilterCsvOfAddresses(inputCsv, {
dedupAddresses: false,
});

const depositorsMap = new Map<string, number>();
for (const address of addresses) {
const count = depositorsMap.get(address) || 0;
depositorsMap.set(address, count + 1);
}

const filtered = new Map(
Array.from(depositorsMap.entries())
.filter(([, count]) => count > 1)
.sort((a, b) => b[1] - a[1])
);

console.log(filtered);
}
1 change: 1 addition & 0 deletions packages/data/src/index.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
export * from "./utils";
40 changes: 40 additions & 0 deletions packages/data/src/utils.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
import { Address } from "@nocturne-xyz/core";
import fs from "fs";

interface ParseAndFilterCsvOfAddressesOpts {
dedupAddresses?: boolean;
}

export async function parseAndFilterCsvOfAddresses(
path: string,
opts: ParseAndFilterCsvOfAddressesOpts = {}
): Promise<Address[]> {
const inputFileText = await fs.promises.readFile(path, "utf-8");
// split the input file into lines
const inputFileLines = inputFileText.split("\n");
// take the first column
const addresses = inputFileLines.map((line) => line.trim().split(",")[0]);
// filter out anything that doesn't look like an address
const filteredAddresses = addresses.filter((address) => {
return address.match(/^0x[0-9a-fA-F]{40}$/i);
});

// deduplicate and sort
return opts.dedupAddresses
? dedupAddressesInOrder(filteredAddresses)
: filteredAddresses;
}

export function dedupAddressesInOrder(addresses: string[]): string[] {
// deduplicate and sort
const uniqueAddresses = new Set();
const dedupedAddresses = [];
for (const address of addresses) {
if (!uniqueAddresses.has(address)) {
uniqueAddresses.add(address);
dedupedAddresses.push(address);
}
}

return dedupedAddresses;
}
File renamed without changes.
File renamed without changes.
2 changes: 1 addition & 1 deletion tsconfig.json
Original file line number Diff line number Diff line change
Expand Up @@ -53,7 +53,7 @@
"path": "./packages/core"
},
{
"path": "./packages/data-cli"
"path": "./packages/data"
},
{
"path": "./packages/op-request-plugins"
Expand Down
7 changes: 4 additions & 3 deletions yarn.lock
Original file line number Diff line number Diff line change
Expand Up @@ -2688,9 +2688,9 @@ __metadata:
languageName: unknown
linkType: soft

"@nocturne-xyz/data-cli@workspace:packages/data-cli":
"@nocturne-xyz/data@workspace:^, @nocturne-xyz/data@workspace:packages/data":
version: 0.0.0-use.local
resolution: "@nocturne-xyz/data-cli@workspace:packages/data-cli"
resolution: "@nocturne-xyz/data@workspace:packages/data"
dependencies:
"@nocturne-xyz/contracts": ^3.0.0
"@nocturne-xyz/core": "workspace:^"
Expand Down Expand Up @@ -2730,7 +2730,7 @@ __metadata:
typescript: ^4.8.4
winston: ^3.9.0
bin:
data-cli: dist/src/index.js
data-cli: dist/src/cli/index.js
languageName: unknown
linkType: soft

Expand Down Expand Up @@ -2765,6 +2765,7 @@ __metadata:
"@nocturne-xyz/config": "workspace:^"
"@nocturne-xyz/contracts": ^3.0.0
"@nocturne-xyz/core": "workspace:^"
"@nocturne-xyz/data": "workspace:^"
"@nocturne-xyz/offchain-utils": "workspace:^"
"@nocturne-xyz/subgraph-sync-adapters": "workspace:^"
"@opentelemetry/api": ^1.4.1
Expand Down

0 comments on commit 74c4be8

Please sign in to comment.