Fetch participants pubkey and onboarding tx height
This commit is contained in:
parent
5bfd263dcc
commit
4dc1387559
8
.env.example
Normal file
8
.env.example
Normal 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=
|
@ -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
|
||||||
```
|
```
|
||||||
|
@ -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);
|
@ -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",
|
||||||
|
@ -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==
|
||||||
|
Loading…
Reference in New Issue
Block a user