Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add customer usage data #10

Merged
merged 12 commits into from
Jan 24, 2024
68 changes: 61 additions & 7 deletions main.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ import { HttpBatchClient, Tendermint34Client } from "npm:@cosmjs/tendermint-rpc"
import * as promclient from "npm:prom-client";
import express from "npm:[email protected]";
import settings from "./settings.ts";
import { communityPoolFunds, totalSupply } from "./queries.ts";
import { communityPoolFunds, getContractUsage, getIbcChannels, totalSupply } from "./queries.ts";

function printableCoin(coin: Coin): string {
if (coin.denom?.startsWith("u")) {
Expand All @@ -17,6 +17,12 @@ function printableCoin(coin: Coin): string {
}
}


function mapChannelToDescription(chainId: string, channelId: string): string {
// Default to a unknown if the channel is not found
return settings[chainId].mappingChannels[channelId] || "unknown-proxy";
}

export interface Account {
readonly name: string;
readonly address: string;
Expand All @@ -32,7 +38,6 @@ function errorLog(msg: string) {
}

if (import.meta.main) {

const app = express();

const balances = new Map<string, string>();
Expand All @@ -43,6 +48,18 @@ if (import.meta.main) {
labelNames: ["account", "rpcEndpoint", "chainId"] as const,
});

const customerUsageGauge = new promclient.Gauge({
name: "customer_usage",
help: "Usage data per customer chain",
labelNames: [
"channel",
"rpcEndpoint",
"chainId",
"description",
"address",
] as const,
});

// Updates all gauges with the current balances
const gaugify = () => {
for (const [key, val] of balances.entries()) {
Expand All @@ -53,6 +70,7 @@ if (import.meta.main) {
// deno-lint-ignore no-explicit-any
app.get("/metrics", (_req: any, res: any) => {
gaugify();
updateContractUsage();

res.set("Content-Type", promclient.register.contentType);
promclient.register.metrics().then((metrics) => res.end(metrics));
Expand Down Expand Up @@ -91,21 +109,57 @@ if (import.meta.main) {
};

const updateCommunityPool = () => {
communityPoolFunds(tmClient, "unois").then((balance) => {
const exportAccountName = "community pool";
debugLog(`${exportAccountName}: ${printableCoin(balance)}`);
balances.set(exportAccountName, balance.amount);
}, (err) => errorLog(err.toString()));
communityPoolFunds(tmClient, "unois").then(
(balance) => {
const exportAccountName = "community pool";
debugLog(`${exportAccountName}: ${printableCoin(balance)}`);
balances.set(exportAccountName, balance.amount);
},
(err) => errorLog(err.toString())
);
};

const updateContractUsage = async () => {
try {
const contractState = await getContractUsage(
tmClient,
settings[chainId].gatewayAddr
);

// get an array of channels infos
const channelsInfo = await getIbcChannels(tmClient);

// array of customer data
for (const customer of contractState.customers) {
const description = mapChannelToDescription(chainId, customer.channel_id);
const connection = channelsInfo.filter(channel => channel.channelId === customer.channel_id);

customerUsageGauge.set(
{
channel: customer.channel_id,
rpcEndpoint: rpcEndpoint,
chainId: chainId,
description: description,
address: connection[0].counterparty?.portId?.slice(5)
},
customer.requested_beacons
);
}
} catch (err) {
errorLog(err.toString());
}
};

// Initial call
updateAccounts();
updateTotalSupply();
updateCommunityPool();
updateContractUsage();

setInterval(updateAccounts, 10_000);
setInterval(updateTotalSupply, 45_000);
setInterval(updateCommunityPool, 100_000);
setInterval(updateContractUsage, 60_000);

const port = 3000;
app.listen(port, function () {
Expand Down
33 changes: 32 additions & 1 deletion queries.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,9 @@ import {
QueryClient,
setupBankExtension,
setupDistributionExtension,
setupIbcExtension
} from "npm:@cosmjs/stargate";
import { setupWasmExtension } from "npm:@cosmjs/cosmwasm-stargate";

export async function totalSupply(tmClient: TendermintClient, searchDenom: string): Promise<Coin> {
const queryClient = QueryClient.withExtensions(tmClient, setupBankExtension);
Expand All @@ -16,7 +18,7 @@ export async function totalSupply(tmClient: TendermintClient, searchDenom: strin
/* Queries the community pool funds in full unois. */
export async function communityPoolFunds(
tmClient: TendermintClient,
searchDenom: string,
searchDenom: string
): Promise<Coin> {
const queryClient = QueryClient.withExtensions(tmClient, setupDistributionExtension);
const resp = await queryClient.distribution.communityPool();
Expand All @@ -28,3 +30,32 @@ export async function communityPoolFunds(
return coin(amount, searchDenom);
}
}

export async function getContractUsage(
tmClient: TendermintClient,
contractAddress: string,
) {
const queryClient = QueryClient.withExtensions(tmClient, setupWasmExtension);
let res: any;
try {
res = await queryClient.wasm.queryContractSmart(contractAddress, {
customers: {},
});
} catch (error) {
console.error(error);
}
return res;
}

export async function getIbcChannels(
tmClient: TendermintClient
) {
const queryClient = QueryClient.withExtensions(tmClient, setupIbcExtension);
let res, filteredChannels;
try {
res = await queryClient.ibc.channel.channels();
} catch (error) {
console.error(error);
}
return res.channels;
}
17 changes: 17 additions & 0 deletions settings.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,8 @@ import { Account } from "./main.ts";

export interface ChainSettings {
accounts: Account[];
gatewayAddr: string;
mappingChannels: Record<string, string>
}

const settings: Record<string, ChainSettings> = {
Expand Down Expand Up @@ -33,6 +35,16 @@ const settings: Record<string, ChainSettings> = {
denom: "unois",
},
],
gatewayAddr: "nois1acyc05v6fgcdgj88nmz2t40aex9nlnptqpwp5hf8hwg7rhce9uuqgqz5wp",
mappingChannels: {
"channel-11": "gelotto-proxy",
"channel-2": "juno-nois-team",
"channel-20": "injective-governance",
"channel-22": "architech",
"channel-35": "aura-team",
"channel-38": "stargaze-governance",
"channel-41": "osmosis-nois-team",
}
},
"nois-testnet-005": {
accounts: [
Expand All @@ -52,6 +64,11 @@ const settings: Record<string, ChainSettings> = {
denom: "unois",
},
],
gatewayAddr: "nois1xwde9rzqk5u36fke0r9ddmtwvh43n4fv53c5vc462wz8xlnqjhls6d90xc",
mappingChannels: {
"channel-17": "juno-nois-team",
"channel-36": "injective-nois-team",
}
},
};

Expand Down
Loading