Skip to content

Commit

Permalink
cleanup
Browse files Browse the repository at this point in the history
  • Loading branch information
minaxolone committed May 27, 2024
1 parent 0349305 commit 7e1baa4
Show file tree
Hide file tree
Showing 9 changed files with 160 additions and 142 deletions.
File renamed without changes.
66 changes: 10 additions & 56 deletions api/src/ol/community-wallets/community-wallets.resolver.ts
Original file line number Diff line number Diff line change
@@ -1,66 +1,20 @@
import { Query, Resolver } from "@nestjs/graphql";
import _ from "lodash";
import { GqlCommunityWallet } from "../models/community-wallet.model.js";
import { communityWallets } from "./community-wallets.js";
import { OlService } from "../ol.service.js";
import { parseAddress } from "../../utils.js";
import { Inject } from "@nestjs/common";

import { GqlCommunityWallet } from "./community-wallet.model.js";
import { ICommunityWalletsService } from "./interfaces.js";
import { Types } from "../../types.js";

@Resolver()
export class CommunityWalletsResolver {
public constructor(private readonly olService: OlService) {}
public constructor(
@Inject(Types.ICommunityWalletsService)
private readonly communityWalletsService: ICommunityWalletsService,
) {}

@Query(() => [GqlCommunityWallet])
async communityWallets(): Promise<GqlCommunityWallet[]> {
const donorVoiceRegistry =
(await this.olService.aptosClient.getAccountResource(
"0x1",
"0x1::donor_voice::Registry",
)) as {
type: "0x1::donor_voice::Registry";
data: {
liquidation_queue: [];
list: string[];
};
};

const addresses = donorVoiceRegistry.data.list.map((address) =>
parseAddress(address).toString("hex").toUpperCase(),
);

const res = addresses.map((address) => {
const addrBuff = parseAddress(address);
const addr = addrBuff.toString("hex").toUpperCase();
const info = communityWallets.get(addr);

return new GqlCommunityWallet({
address: addrBuff,
name: info?.name,
description: info?.description,
});
});

const groups = _.groupBy(res, (wallet) => {
if (wallet.name && wallet.description) {
return "nameAndDescription";
}
if (wallet.name) {
return "nameOnly";
}
if (wallet.description) {
return "descriptionOnly";
}
return "rest";
});

const { nameAndDescription, nameOnly, descriptionOnly, rest } = groups;
const sorter = (wallet: GqlCommunityWallet) =>
wallet.address.toString("hex");

return [
..._.sortBy(nameAndDescription, sorter),
..._.sortBy(nameOnly, sorter),
..._.sortBy(descriptionOnly, sorter),
..._.sortBy(rest, sorter),
];
return this.communityWalletsService.getCommunityWallets();
}
}
67 changes: 67 additions & 0 deletions api/src/ol/community-wallets/community-wallets.service.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,67 @@
import { Injectable } from "@nestjs/common";
import _ from "lodash";

import { OlService } from "../ol.service.js";
import { GqlCommunityWallet } from "./community-wallet.model.js";
import { parseAddress } from "../../utils.js";
import { communityWallets } from "./community-wallets.js";
import { ICommunityWalletsService } from "./interfaces.js";

@Injectable()
export class CommunityWalletsService implements ICommunityWalletsService {
public constructor(private readonly olService: OlService) {}

public async getCommunityWallets(): Promise<GqlCommunityWallet[]> {
const donorVoiceRegistry =
(await this.olService.aptosClient.getAccountResource(
"0x1",
"0x1::donor_voice::Registry",
)) as {
type: "0x1::donor_voice::Registry";
data: {
liquidation_queue: [];
list: string[];
};
};

const addresses = donorVoiceRegistry.data.list.map((address) =>
parseAddress(address).toString("hex").toUpperCase(),
);

const res = addresses.map((address) => {
const addrBuff = parseAddress(address);
const addr = addrBuff.toString("hex").toUpperCase();
const info = communityWallets.get(addr);

return new GqlCommunityWallet({
address: addrBuff,
name: info?.name,
description: info?.description,
});
});

const groups = _.groupBy(res, (wallet) => {
if (wallet.name && wallet.description) {
return "nameAndDescription";
}
if (wallet.name) {
return "nameOnly";
}
if (wallet.description) {
return "descriptionOnly";
}
return "rest";
});

const { nameAndDescription, nameOnly, descriptionOnly, rest } = groups;
const sorter = (wallet: GqlCommunityWallet) =>
wallet.address.toString("hex");

return [
..._.sortBy(nameAndDescription, sorter),
..._.sortBy(nameOnly, sorter),
..._.sortBy(descriptionOnly, sorter),
..._.sortBy(rest, sorter),
];
}
}
5 changes: 5 additions & 0 deletions api/src/ol/community-wallets/interfaces.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
import { GqlCommunityWallet } from "./community-wallet.model.js";

export interface ICommunityWalletsService {
getCommunityWallets(): Promise<GqlCommunityWallet[]>;
}
8 changes: 7 additions & 1 deletion api/src/ol/ol.module.ts
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,7 @@ import { MovementsResolver } from "./movements/movements.resolver.js";
import { MovementsService } from "./movements/movements.service.js";

import { CommunityWalletsResolver } from "./community-wallets/community-wallets.resolver.js";
import { CommunityWalletsService } from "./community-wallets/community-wallets.service.js";

import { TransactionsResolver } from "./transactions/TransactionsResolver.js";
import { TransactionResolver } from "./transactions/TransactionResolver.js";
Expand Down Expand Up @@ -107,7 +108,12 @@ for (const role of roles) {

ValidatorResolver,
ValidatorsResolver,

CommunityWalletsResolver,
{
provide: Types.ICommunityWalletsService,
useClass: CommunityWalletsService,
},

OlService,
MovementsService,
Expand Down Expand Up @@ -141,6 +147,6 @@ for (const role of roles) {
...workers,
],
controllers: [OlController],
exports: [OlService, TransformerService, CommunityWalletsResolver],
exports: [OlService, TransformerService, Types.ICommunityWalletsService],
})
export class OlModule {}
46 changes: 9 additions & 37 deletions api/src/stats/stats.service.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import { Injectable } from "@nestjs/common";
import { Inject, Injectable } from "@nestjs/common";
import { ConfigService } from "@nestjs/config";
import axios from "axios";

Expand All @@ -14,8 +14,9 @@ import {
} from "./types.js";
import { ClickhouseService } from "../clickhouse/clickhouse.service.js";
import { OlService } from "../ol/ol.service.js";
import { ICommunityWalletsService } from "../ol/community-wallets/interfaces.js";
import { Types } from "../types.js";
import _ from "lodash";
import { CommunityWalletsResolver } from "../ol/community-wallets.resolver.js";

@Injectable()
export class StatsService {
Expand All @@ -24,7 +25,10 @@ export class StatsService {
public constructor(
private readonly clickhouseService: ClickhouseService,
private readonly olService: OlService,
private readonly communityWalletsResolver: CommunityWalletsResolver,

@Inject(Types.ICommunityWalletsService)
private readonly communityWalletsService: ICommunityWalletsService,

config: ConfigService,
) {
this.dataApiHost = config.get("dataApiHost")!;
Expand Down Expand Up @@ -236,39 +240,6 @@ export class StatsService {
return rows;
}

// Calculates the libra balances of all accounts
private async getTotalLibraBalances(): Promise<number> {
try {
const query = `
SELECT
SUM(latest_balance) / 1e6 AS total_balance
FROM (
SELECT
argMax(balance, version) AS latest_balance
FROM coin_balance
WHERE coin_module = 'libra_coin'
GROUP BY address
)
`;

const resultSet = await this.clickhouseService.client.query({
query: query,
format: "JSONEachRow",
});

const result = await resultSet.json<{ total_balance: number }>();

// Assuming there's only one row returned
if (result.length > 0) {
return result[0].total_balance;
}
return 0;
} catch (error) {
console.error("Error in getTotalBalances:", error);
throw error;
}
}

private async getCommunityWalletsBalanceBreakdown(): Promise<NameValue[]> {
// List of addresses and their names
const addressNames = [
Expand Down Expand Up @@ -1286,7 +1257,8 @@ export class StatsService {
}

// Get the list of community wallets
const communityWallets = await this.communityWalletsResolver.communityWallets();
const communityWallets =
await this.communityWalletsService.getCommunityWallets();
const communityAddresses = new Set(communityWallets.map(wallet => wallet.address.toString('hex').toUpperCase()));

// Query to get the latest balances and versions from coin_balance
Expand Down
1 change: 1 addition & 0 deletions api/src/types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,4 +5,5 @@ export enum Types {
ITransactionsFactory = "ITransactionsFactory",
ITransaction = "ITransaction",
IOnChainTransactionsRepository = "IOnChainTransactionsRepository",
ICommunityWalletsService = "ICommunityWalletsService",
}
107 changes: 60 additions & 47 deletions web-app/src/modules/core/routes/Stats/Stats.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -231,55 +231,68 @@ const Coinstats = () => {
</div>
</dl>
</div>

<div className="mt-5">
<h3 className="text-base font-semibold text-gray-900 mb-5">Top 100 Liquid accounts</h3>
<div className="overflow-x-auto">
<table className="min-w-full divide-y divide-gray-200">
<thead className="bg-gray-50">
<tr>
<th
scope="col"
className="px-6 py-3 text-left text-xs font-medium text-gray-500 uppercase tracking-wider"
>
Address
</th>
<th
scope="col"
className="px-6 py-3 text-left text-xs font-medium text-gray-500 uppercase tracking-wider"
>
Liquid Balance
</th>
<th
scope="col"
className="px-6 py-3 text-left text-xs font-medium text-gray-500 uppercase tracking-wider"
>
% of Circulating Supply
</th>
</tr>
</thead>
<tbody className="bg-white divide-y divide-gray-200">
{data.topAccounts.map((account: { address: string; unlockedBalance: number; percentOfCirculating: number }, index: number) => (
<tr key={index}>
<td className="px-6 py-4 whitespace-nowrap text-sm font-medium text-gray-900">
<a
href={`https://0l.fyi/accounts/${account.address}`}
target="_blank"
rel="noopener noreferrer"
className="text-blue-500 hover:text-blue-700"
>
{account.address}
</a>
</td>
<td className="px-6 py-4 whitespace-nowrap text-sm text-gray-500">
<Money>{account.unlockedBalance}</Money>
</td>
<td className="px-6 py-4 whitespace-nowrap text-sm text-gray-500">
{account.percentOfCirculating.toFixed(4)}%
</td>
<h3 className="text-base font-semibold text-gray-900">Top 100 Liquid accounts</h3>

<div className="relative overflow-hidden rounded-lg bg-white shadow mt-2">
<div className="overflow-x-auto">
<table className="min-w-full divide-y divide-gray-200">
<thead className="bg-gray-50">
<tr>
<th
scope="col"
className="px-6 py-3 text-left text-xs font-medium text-gray-500 uppercase tracking-wider"
>
Address
</th>
<th
scope="col"
className="px-6 py-3 text-left text-xs font-medium text-gray-500 uppercase tracking-wider"
>
Liquid Balance
</th>
<th
scope="col"
className="px-6 py-3 text-xs font-medium text-gray-500 uppercase tracking-wider text-right"
>
% of Circulating Supply
</th>
</tr>
))}
</tbody>
</table>
</thead>
<tbody className="bg-white divide-y divide-gray-200">
{data.topAccounts.map(
(
account: {
address: string;
unlockedBalance: number;
percentOfCirculating: number;
},
index: number,
) => (
<tr key={index}>
<td className="px-6 py-4 whitespace-nowrap text-sm font-medium text-gray-900">
<a
href={`https://0l.fyi/accounts/${account.address}`}
target="_blank"
rel="noopener noreferrer"
className="text-blue-500 hover:text-blue-700"
>
{account.address}
</a>
</td>
<td className="px-6 py-4 whitespace-nowrap text-sm text-gray-500">
<Money>{account.unlockedBalance}</Money>
</td>
<td className="px-6 py-4 whitespace-nowrap text-sm text-right text-gray-500">
{account.percentOfCirculating.toFixed(4)}%
</td>
</tr>
),
)}
</tbody>
</table>
</div>
</div>
</div>
</>
Expand Down
2 changes: 1 addition & 1 deletion web-app/src/modules/ui/Layout/Footer/Footer.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ const CI_COMMIT_SHA: string = import.meta.env.VITE_CI_COMMIT_SHA;

const Footer: React.FC = () => {
return (
<footer className="bg-[#0A0A0A] text-white mt-32">
<footer className="bg-[#0A0A0A] text-white">
<div className="pt-14 pb-8 px-3 max-w-[1280px] mx-auto flex flex-col gap-32">
<div className="flex flex-col items-center justify-center gap-8 text-center">
<Logo withText={false} className="h-14 w-14" />
Expand Down

0 comments on commit 7e1baa4

Please sign in to comment.