Fetch participants pubkey and onboarding tx height

This commit is contained in:
Prathamesh Musale 2024-08-14 16:21:44 +05:30
parent 1e0c58769b
commit 40ec3e1fc1
5 changed files with 61 additions and 18 deletions

8
.env.example Normal file
View File

@ -0,0 +1,8 @@
# Default: https://laconicd.laconic.com/api
LACONICD_GQL_ENDPOINT=
# Default: https://laconicd.laconic.com
LACONICD_RPC_ENDPOINT=
# Default: laconic_9000-1
LACONICD_CHAIN_ID=

View File

@ -1,4 +1,4 @@
# map-subscribers # cli
* Install dependencies: * Install dependencies:
@ -6,11 +6,18 @@
yarn yarn
``` ```
* Map subscribers with onboarded participants: * Create required env configuration:
```bash ```bash
yarn ts-node cli/map-subscribers.ts --onboardedJson <onboarded-participants-json-file> --subscribersCsv <subscribers-csv-file> --output <output-csv-file> # Update the values as required
cp .env.example .env
```
* Map subscribers to onboarded participants:
```bash
yarn ts-node cli/map-subscribers-to-participants.ts --subscribersCsv <subscribers-csv-file> --output <output-csv-file>
# Example: # Example:
# yarn ts-node cli/map-subscribers.ts --onboardedJson onboarded-participants.json --subscribersCsv subscribers.csv --output result.csv # yarn ts-node cli/map-subscribers-to-participants.ts --subscribersCsv subscribers.csv --output result.csv
``` ```

View File

@ -7,23 +7,23 @@ import { parse as csvParse } from 'csv-parse';
import * as csvWriter from 'csv-writer'; import * as csvWriter from 'csv-writer';
import dotenv from 'dotenv'; import dotenv from 'dotenv';
import { StargateClient } from '@cosmjs/stargate';
import { Registry } from '@cerc-io/registry-sdk'; import { Registry } from '@cerc-io/registry-sdk';
dotenv.config(); dotenv.config();
const LACONICD_GQL_ENDPOINT = process.env.LACONICD_GQL_ENDPOINT || 'https://laconicd.laconic.com/api';
const LACONICD_RPC_ENDPOINT = process.env.LACONICD_RPC_ENDPOINT || 'https://laconicd.laconic.com';
const LACONICD_CHAIN_ID = process.env.LACONICD_CHAIN_ID || 'laconic_9000-1'; const LACONICD_CHAIN_ID = process.env.LACONICD_CHAIN_ID || 'laconic_9000-1';
async function main(): Promise<void> { async function main(): Promise<void> {
const argv = _getArgv(); const argv = _getArgv();
const registry = new Registry(LACONICD_GQL_ENDPOINT, LACONICD_RPC_ENDPOINT, LACONICD_CHAIN_ID); const registry = new Registry(LACONICD_GQL_ENDPOINT, LACONICD_RPC_ENDPOINT, LACONICD_CHAIN_ID);
const client = await StargateClient.connect(LACONICD_RPC_ENDPOINT);
const participants = await registry.getParticipants(); const participants = await registry.getParticipants();
const subscribers = await readSubscribers(argv.subscribersCsv); const subscribers = await readSubscribers(argv.subscribersCsv);
processSubscribers(participants, subscribers, argv.output); processSubscribers(client, participants, subscribers, argv.output);
} }
async function readSubscribers(subscribersCsvPath: string): Promise<any> { async function readSubscribers(subscribersCsvPath: string): Promise<any> {
@ -37,7 +37,7 @@ function hashSubscriberId(subscriberId: string): string {
return '0x' + crypto.createHash('sha256').update(subscriberId).digest('hex'); return '0x' + crypto.createHash('sha256').update(subscriberId).digest('hex');
} }
async function processSubscribers(participants: any[], subscribers: any[], outputPath: string) { async function processSubscribers(client: StargateClient, participants: any[], subscribers: any[], outputPath: string) {
// Map kyc_id to participant data // Map kyc_id to participant data
const kycMap: Record<string, any> = {}; const kycMap: Record<string, any> = {};
participants.forEach((participant: any) => { participants.forEach((participant: any) => {
@ -45,23 +45,47 @@ async function processSubscribers(participants: any[], subscribers: any[], outpu
}); });
const onboardedSubscribers: any[] = []; const onboardedSubscribers: any[] = [];
subscribers.forEach((subscriber) => { subscribers.forEach(async (subscriber) => {
const hashedSubscriberId = hashSubscriberId(subscriber['subscriber_id']); const hashedSubscriberId = hashSubscriberId(subscriber['subscriber_id']);
const participant = kycMap[hashedSubscriberId]; const participant = kycMap[hashedSubscriberId];
if (!participant) { if (!participant) {
return; return;
} }
const participantAddresss = participant['cosmos_address'];
// Fetch participant's Laconic pubkey
const participantAccount = await client.getAccount(participantAddresss);
const participantPubkey = participantAccount?.pubkey;
// Skip participant if pubkey not found
// (account may have funds but hasn't done any tx till now)
if (!participantPubkey) {
return;
}
// Skip participant if an onboarding tx not found
const onboardingTxs = await client.searchTx(`message.sender='${participantAddresss}' AND message.action='/cerc.onboarding.v1.MsgOnboardParticipant'`);
if (onboardingTxs.length === 0) {
return;
}
const latestOnboardingTx = onboardingTxs.reduce((prev, current) => {
return current.height > prev.height ? current : prev;
});
const onboardedSubscriber = { const onboardedSubscriber = {
subscriber_id: subscriber['subscriber_id'], subscriber_id: subscriber['subscriber_id'],
email: subscriber['email'], email: subscriber['email'],
cosmos_address: participant['cosmos_address'], status: subscriber['status'],
'premium?': subscriber['premium?'],
created_at: subscriber['created_at'],
cosmos_address: participantAddresss,
nitro_address: participant['nitro_address'], nitro_address: participant['nitro_address'],
role: participant['role'], role: participant['role'],
hashed_subscriber_id: participant['kyc_id'], hashed_subscriber_id: participant['kyc_id'],
status: subscriber['status'], laconic_pubkey: participantPubkey,
premium: subscriber['premium?'], onboarding_height: latestOnboardingTx.height
created_at: subscriber['created_at']
}; };
onboardedSubscribers.push(onboardedSubscriber); onboardedSubscribers.push(onboardedSubscriber);
@ -72,14 +96,17 @@ async function processSubscribers(participants: any[], subscribers: any[], outpu
header: [ header: [
{ id: 'subscriber_id', title: 'subscriber_id' }, { id: 'subscriber_id', title: 'subscriber_id' },
{ id: 'email', title: 'email' }, { id: 'email', title: 'email' },
{ id: 'status', title: 'status' },
{ id: 'premium?', title: 'premium?' },
{ id: 'created_at', title: 'created_at' },
{ id: 'cosmos_address', title: 'cosmos_address' }, { id: 'cosmos_address', title: 'cosmos_address' },
{ id: 'nitro_address', title: 'nitro_address' }, { id: 'nitro_address', title: 'nitro_address' },
{ id: 'role', title: 'role' }, { id: 'role', title: 'role' },
{ id: 'hashed_subscriber_id', title: 'hashed_subscriber_id' }, { id: 'hashed_subscriber_id', title: 'hashed_subscriber_id' },
{ id: 'status', title: 'status' }, { id: 'laconic_pubkey', title: 'laconic_pubkey' },
{ id: 'premium', title: 'premium' }, { id: 'onboarding_height', title: 'onboarding_height' },
{ id: 'created_at', title: 'created_at' } ],
] alwaysQuote: true
}); });
await writer.writeRecords(onboardedSubscribers); await writer.writeRecords(onboardedSubscribers);

View File

@ -13,6 +13,7 @@
}, },
"dependencies": { "dependencies": {
"@cerc-io/registry-sdk": "^0.2.6", "@cerc-io/registry-sdk": "^0.2.6",
"@cosmjs/stargate": "^0.32.4",
"csv-parse": "^5.5.6", "csv-parse": "^5.5.6",
"csv-parser": "^3.0.0", "csv-parser": "^3.0.0",
"csv-writer": "^1.6.0", "csv-writer": "^1.6.0",

View File

@ -208,7 +208,7 @@
ws "^7" ws "^7"
xstream "^11.14.0" xstream "^11.14.0"
"@cosmjs/stargate@^0.32.2": "@cosmjs/stargate@^0.32.2", "@cosmjs/stargate@^0.32.4":
version "0.32.4" version "0.32.4"
resolved "https://registry.yarnpkg.com/@cosmjs/stargate/-/stargate-0.32.4.tgz#bd0e4d3bf613b629addbf5f875d3d3b50f640af1" resolved "https://registry.yarnpkg.com/@cosmjs/stargate/-/stargate-0.32.4.tgz#bd0e4d3bf613b629addbf5f875d3d3b50f640af1"
integrity sha512-usj08LxBSsPRq9sbpCeVdyLx2guEcOHfJS9mHGCLCXpdAPEIEQEtWLDpEUc0LEhWOx6+k/ChXTc5NpFkdrtGUQ== integrity sha512-usj08LxBSsPRq9sbpCeVdyLx2guEcOHfJS9mHGCLCXpdAPEIEQEtWLDpEUc0LEhWOx6+k/ChXTc5NpFkdrtGUQ==