Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
104 commits
Select commit Hold shift + click to select a range
3262817
Switch upstream GraphQL API endpoint
ankurdotb Sep 13, 2022
78071a0
ci: Update upstream API endpoints
ankurdotb Sep 14, 2022
45ddb06
Simplified get accounts query so that it doesn't break
drgomesp Sep 16, 2022
b627416
Fixed bad query
drgomesp Sep 19, 2022
27f81af
Improved error handling for graphql client
drgomesp Sep 21, 2022
158e10b
wip
drgomesp Sep 22, 2022
59e1bf5
Fixed circulating supply endpoint (still missing rewards and unbonding)
drgomesp Sep 22, 2022
b0b8081
Switch upstream GraphQL API endpoint
ankurdotb Sep 13, 2022
5dbe3e2
ci: Update upstream API endpoints
ankurdotb Sep 14, 2022
078d623
Fixed bad query
drgomesp Sep 19, 2022
6832756
Created new endpoint to update single account balance on KV for later…
drgomesp Sep 23, 2022
b191575
Added total balance as field on account balance cache
drgomesp Sep 23, 2022
88da7d3
Update bigDipperApi.ts
ankurdotb Sep 23, 2022
a50df0d
Revert "Update bigDipperApi.ts"
ankurdotb Sep 23, 2022
ed2491f
Refactoring for balance fetching from different sources
drgomesp Sep 26, 2022
935a679
Fixed account balance helper
drgomesp Sep 26, 2022
033132b
Started with new graphql query
drgomesp Sep 27, 2022
18720bb
Fixed update balance per account endpoint (temporary)
drgomesp Sep 27, 2022
39583e4
Fixed balance query checks
drgomesp Sep 27, 2022
2ec827f
Fixed circulating supply endpoint to work with new query
drgomesp Sep 27, 2022
9556b61
Fixed update all balances endpoint to feed KV (temporary endpoint)
drgomesp Sep 27, 2022
8cd17ca
Better error handling so that API doesn't crash
drgomesp Sep 27, 2022
ac8391e
Fixed all balances updater
drgomesp Sep 27, 2022
58ed4ea
Only updating missing balances (temp)
drgomesp Sep 27, 2022
871602e
Reactivating cron
drgomesp Sep 27, 2022
f5a5bf3
Removed single account balance updater temp endpoint
drgomesp Sep 28, 2022
9027ce6
Improved error logging for graphgl (workers requires a Map for loggin…
drgomesp Sep 28, 2022
97d6523
Removing duplicates from KV while procecssing
drgomesp Sep 28, 2022
c415557
Removed temporary account removal from KV
drgomesp Sep 28, 2022
d36bc4f
Better logging
drgomesp Sep 28, 2022
272d2cd
Fixed endpoint
drgomesp Sep 28, 2022
7fd96ca
Fixed endpoint
drgomesp Sep 28, 2022
77958ad
Added proper list of addresses to import (temp)
drgomesp Sep 30, 2022
4598741
Implementing requested changes from PR review
drgomesp Sep 30, 2022
1aa7d8b
Made group be random on cron
drgomesp Sep 30, 2022
2374092
Simplified record on KV
drgomesp Sep 30, 2022
a2d2395
Better naming and place for cron helper
drgomesp Sep 30, 2022
9403d2f
Better error handling
drgomesp Sep 30, 2022
a48af48
Removed unused code
drgomesp Sep 30, 2022
4b79e2f
Better yet error handling
drgomesp Sep 30, 2022
30d1978
Fixed error issue returning bad response
drgomesp Sep 30, 2022
a1b5229
Clean-up of addresses
drgomesp Oct 2, 2022
0e821e7
Reprocessing addresses
drgomesp Oct 2, 2022
84fde0b
Removed static account addresses
drgomesp Oct 2, 2022
ec730d9
Removed unecessary endpoint for processing balance groups
drgomesp Oct 3, 2022
f2d8a1c
Added check for null account on balance endpoint
drgomesp Oct 3, 2022
b83bd32
Added updated at to KV record
drgomesp Oct 3, 2022
ed201d1
Squashed commit of the following:
ankurdotb Oct 12, 2022
519f9d2
Update wrangler.toml
ankurdotb Oct 12, 2022
64c3ca7
Fixed broken trigger
ankurdotb Oct 12, 2022
a13332c
fix total delegations count per validatior
benyam7 Oct 13, 2022
3113a4e
fix totat delegators count
benyam7 Oct 13, 2022
ff56494
Merge branch 'fix-broken-api' of github.com:cheqd/data-api into fix-b…
benyam7 Oct 13, 2022
3c8b55a
fix total staked coins
benyam7 Oct 13, 2022
7a67d4d
Merge branch 'main' into fix-broken-api
benyam7 Oct 14, 2022
b66692c
Update wrangler.toml
ankurdotb Oct 14, 2022
61766fb
fix: total balance
benyam7 Oct 14, 2022
0640c16
Merge branch 'fix-broken-api' of github.com:cheqd/data-api into fix-b…
benyam7 Oct 14, 2022
86fb48f
Fix endpoint
ankurdotb Oct 14, 2022
2dc9fdb
Merge branch 'main' into fix-circulating-supply
ankurdotb Oct 14, 2022
5047784
fix total balance
benyam7 Oct 17, 2022
d7dfca0
fix circulating supply
benyam7 Oct 18, 2022
d07d0ee
chore refactor a bit
benyam7 Oct 18, 2022
74a67fb
fix node api (include unbounding/delegated free balance for totalBalance
benyam7 Oct 18, 2022
4528425
make total balance endpoint to consider unbounding balance
benyam7 Oct 18, 2022
921a886
Squashed commit of the following:
ankurdotb Oct 18, 2022
0a294b1
Merge branch 'main' into fix-circulating-supply
ankurdotb Oct 19, 2022
5f955e1
chore store account balance infos in KV
benyam7 Oct 19, 2022
168c67b
Merge branch 'fix-circulating-supply' of github.com:cheqd/data-api in…
benyam7 Oct 19, 2022
2e34644
fix total balance
benyam7 Oct 19, 2022
2573fa3
trigger cron based on current
benyam7 Oct 19, 2022
0c77937
remove CSW KV and change trigger interval for staging
benyam7 Oct 19, 2022
2597392
remove :delayed
benyam7 Oct 19, 2022
4a884e9
fix wrangler.toml
benyam7 Oct 19, 2022
61750fd
fix total balance
benyam7 Oct 19, 2022
0c07fde
decrease height by one
benyam7 Oct 20, 2022
014f3f3
lowwer chances of getting total balance to be 0
benyam7 Oct 20, 2022
11e3ffb
Fix typo in available balance
ankurdotb Oct 21, 2022
d8efedf
Fix typo in unbonding balance
ankurdotb Oct 21, 2022
cd310b6
Convert available balance to CHEQ
ankurdotb Oct 21, 2022
9b024c4
Update staging trigger to every hour
ankurdotb Oct 21, 2022
d4e36ec
get total delegations balance from node api
benyam7 Oct 21, 2022
a591b35
total unbonding balance for delegator from node api
benyam7 Oct 21, 2022
a835e11
Merge branch 'fix-circulating-supply' of github.com:cheqd/data-api in…
benyam7 Oct 21, 2022
2798e3e
fix calculate unbonding balance
benyam7 Oct 21, 2022
2ed09b8
get account balance infos from node for totalBalance
benyam7 Oct 21, 2022
89430c2
update account balance infos from node api
benyam7 Oct 21, 2022
e124c26
add a logic to calculate vesting and vested(taken form wallet app)
benyam7 Oct 21, 2022
160f271
update vesting and vested endpoints to get result from newly added logic
benyam7 Oct 21, 2022
284b746
review changes
benyam7 Oct 21, 2022
b5abbf9
fix a bug when calculating avaliable balance
benyam7 Oct 25, 2022
0439669
remove getting account details from gql
benyam7 Oct 25, 2022
a0a93ee
Squashed commit of the following:
ankurdotb Oct 25, 2022
44d7017
Remove total supply from
ankurdotb Oct 25, 2022
3b2023e
Update wrangler.toml
ankurdotb Oct 25, 2022
df99708
Add wrangler variable for watchlist groups
ankurdotb Oct 25, 2022
4e55ad0
Updated logic for dynamically selecting a random group
ankurdotb Oct 25, 2022
1ce38ee
Merge branch 'main' into fix-circulating-supply
ankurdotb Oct 25, 2022
8db90aa
revert back to node api for total supply
benyam7 Oct 25, 2022
b3ed9af
Updated KV pair
ankurdotb Oct 25, 2022
a30258b
Update KV again
ankurdotb Oct 25, 2022
2475c53
Update logging
ankurdotb Oct 25, 2022
ea9380e
Reset cron to hourly
ankurdotb Oct 25, 2022
91a2840
Remove unnecessary logging
ankurdotb Oct 25, 2022
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
48 changes: 0 additions & 48 deletions src/api/bigDipperApi.ts
Original file line number Diff line number Diff line change
Expand Up @@ -11,54 +11,6 @@ import { NodeApi } from './nodeApi';
export class BigDipperApi {
constructor(public readonly graphql_client: GraphQLClient) {}

async get_account(address: string): Promise<Account | null> {
let query = `query Account($address: String!, $where: vesting_account_bool_exp) {
accountBalance: action_account_balance(address: $address) {
coins
}
delegationBalance: action_delegation_total(address: $address) {
coins
}
unbondingBalance: action_unbonding_delegation_total(address: $address) {
coins
}
redelegationBalance: action_redelegation(address: $address) {
redelegations
}
rewardBalance: action_delegation_reward(address: $address) {
coins
}
vesting_account(where: $where) {
id
type
original_vesting
start_time
end_time
}
}`;

let params = {
address: address,
where: {
address: {
_eq: address,
},
},
};

try {
let resp = await this.graphql_client.query<{
data: any;
errors: any;
}>(query, params);

return resp.data as Account;
} catch (e: any) {
console.error(new Map(e));
return null;
}
}

async get_total_supply(): Promise<Coin[]> {
let query = `query Supply {
supply(order_by: {height:desc} limit: 1) {
Expand Down
44 changes: 43 additions & 1 deletion src/api/nodeApi.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,10 @@
import { Account, Coin, ValidatorDetailResponse } from '../types/node';
import {
Account,
Coin,
DelegationsResponse,
UnbondingResponse,
ValidatorDetailResponse,
} from '../types/node';

export class NodeApi {
constructor(public readonly base_rest_api_url: string) {}
Expand Down Expand Up @@ -51,4 +57,40 @@ export class NodeApi {

return await resp.json();
}

async staking_get_all_delegations_for_delegator(
address: string,
next_key?: string
) {
const resp = await fetch(
`${this.base_rest_api_url}/cosmos/staking/v1beta1/delegations/${address}${
next_key ? `?pagination.key=${next_key}` : ''
}`
);

return (await resp.json()) as DelegationsResponse;
}

async staking_get_all_unboding_delegations_for_delegator(
address: string,
next_key?: string
) {
const resp = await fetch(
`${
this.base_rest_api_url
}/cosmos/staking/v1beta1/delegators/${address}/unbonding_delegations${
next_key ? `?pagination.key=${next_key}` : ''
}`
);

return (await resp.json()) as UnbondingResponse;
}

async get_latest_block_height(): Promise<number> {
const resp = await fetch(`${this.base_rest_api_url}/blocks/latest`);
let respJson = (await resp.json()) as {
block: { header: { height: number } };
};
return Number(respJson.block.header.height);
}
}
1 change: 1 addition & 0 deletions src/bindings.d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ declare global {
const REST_API: string;
const GRAPHQL_API: string;
const CIRCULATING_SUPPLY_WATCHLIST: KVNamespace;
const CIRCULATING_SUPPLY_GROUPS: number;
const MARKET_MONITORING_API: string;
const WEBHOOK_URL: string;
}
Expand Down
87 changes: 38 additions & 49 deletions src/handlers/circulatingSupply.ts
Original file line number Diff line number Diff line change
@@ -1,57 +1,46 @@
import { GraphQLClient } from "../helpers/graphql";
import { BigDipperApi } from "../api/bigDipperApi";
import { Request } from "itty-router";
import { ncheq_to_cheq_fixed } from "../helpers/currency";
import { total_balance_ncheq } from "../helpers/node";
import { Account } from "../types/bigDipper";
import { Request } from 'itty-router';
import { ncheq_to_cheq_fixed } from '../helpers/currency';
import { NodeApi } from '../api/nodeApi';
import { AccountBalanceInfos } from '../types/node';

async function get_total_supply(): Promise<number> {
let node_api = new NodeApi(REST_API);
let total_supply_ncheq = await node_api.bank_get_total_supply_ncheq();
const total_supply = Number(ncheq_to_cheq_fixed(total_supply_ncheq));

return total_supply;
}

async function get_circulating_supply(): Promise<number> {
let gql_client = new GraphQLClient(GRAPHQL_API);
let bd_api = new BigDipperApi(gql_client);

let total_supply = await bd_api.get_total_supply();
let total_supply_ncheq = Number(total_supply.find(c => c.denom === "ncheq")?.amount || '0');

try {
const cached = await CIRCULATING_SUPPLY_WATCHLIST.list()
console.log(`found ${cached.keys.length} cached items`)

let non_circulating_supply_ncheq = Number(0);
for (const r of cached.keys) {
console.log(`looking for account: ${r.name} in cache`)
let data: any = await CIRCULATING_SUPPLY_WATCHLIST.get(r.name, { type: "json" });

if (data !== null) {
if (data.totalBalance === undefined) {
const balance = total_balance_ncheq(JSON.parse(data) as Account)
data = JSON.stringify({ totalBalance: balance, updatedAt: Date.now() })
console.log(`updating bad cache entry: ${JSON.stringify(data)} totalBalance=${data.totalBalance} data=${JSON.stringify(data)}`)
await CIRCULATING_SUPPLY_WATCHLIST.put(r.name, data)
}

console.log(`found cache entry: ${JSON.stringify(data)} totalBalance=${data.totalBalance}`)

if (data.totalBalance !== null) {
non_circulating_supply_ncheq += data.totalBalance;
}
}
}

console.log(`Non-circulating supply: ${non_circulating_supply_ncheq}`);
// Get total supply
let total_supply_ncheq = Number(total_supply.find(c => c.denom === "ncheq")?.amount || '0');
console.log(`Total supply: ${total_supply_ncheq}`);

// Calculate circulating supply
return total_supply_ncheq - non_circulating_supply_ncheq;
} catch (e: any) {
console.error(new Map(e))
return total_supply_ncheq
const total_supply = await get_total_supply();

try {
const cached = await CIRCULATING_SUPPLY_WATCHLIST.list();
console.log(`Total cached entries: ${cached.keys.length}`);

let shareholders_total_balance = Number(0);
for (const key of cached.keys) {
Comment thread
ankurdotb marked this conversation as resolved.
let data: AccountBalanceInfos | null =
await CIRCULATING_SUPPLY_WATCHLIST.get(key.name, {
type: 'json',
});

if (data !== null && data.totalBalance !== null) {
shareholders_total_balance += Number(data.totalBalance);
}
}

console.log('Total supply', total_supply);
console.log(`Watchlist total balance: ${shareholders_total_balance}`);

return total_supply - shareholders_total_balance;
} catch (e: any) {
throw new Error(e.toString);
}
}

export async function handler(request: Request): Promise<Response> {
let circulating_supply = await get_circulating_supply();
let circulating_supply = await get_circulating_supply();

return new Response(ncheq_to_cheq_fixed(circulating_supply));
return new Response(circulating_supply.toString());
}
50 changes: 5 additions & 45 deletions src/handlers/totalBalance.ts
Original file line number Diff line number Diff line change
@@ -1,50 +1,10 @@
import { Request } from 'itty-router';
import {
is_delayed_vesting_account_type,
validate_cheqd_address,
} from '../helpers/validate';
import { ncheq_to_cheq_fixed } from '../helpers/currency';
import { BigDipperApi } from '../api/bigDipperApi';
import { GraphQLClient } from '../helpers/graphql';
import { total_balance_ncheq } from '../helpers/node';
import { NodeApi } from '../api/nodeApi';
import { get_account_balance_infos_from_node_api } from '../helpers/balance';

export async function handler(request: Request): Promise<Response> {
const address = request.params?.['address'];

if (!address || !validate_cheqd_address(address)) {
throw new Error('No address specified or wrong address format.');
}

let node_api = new NodeApi(REST_API);
let auth_account = await node_api.auth_get_account(address);

if (is_delayed_vesting_account_type(auth_account?.['@type'])) {
let balance = Number(
(await (
await node_api.bank_get_account_balances(address)
).find((b) => b.denom === 'ncheq')?.amount) ?? '0'
);
let rewards = Number(
(await await node_api.distribution_get_total_rewards(address)) ?? '0'
);
let delegated = Number(
auth_account?.base_vesting_account?.delegated_vesting?.find(
(d) => d.denom === 'ncheq'
)?.amount ?? '0'
);

return new Response(ncheq_to_cheq_fixed(balance + rewards + delegated));
}

let gql_client = new GraphQLClient(GRAPHQL_API);
let bd_api = new BigDipperApi(gql_client);

let account = await bd_api.get_account(address);

if (!account) {
throw new Error('Account not found');
}

return new Response(ncheq_to_cheq_fixed(total_balance_ncheq(account)));
let account_balance_infos = await get_account_balance_infos_from_node_api(
address!!
);
return new Response(account_balance_infos?.totalBalance.toString());
}
12 changes: 6 additions & 6 deletions src/handlers/totalSupply.ts
Original file line number Diff line number Diff line change
@@ -1,10 +1,10 @@
import { NodeApi } from "../api/nodeApi";
import { Request } from "itty-router";
import { ncheq_to_cheq_fixed } from "../helpers/currency";
import { Request } from 'itty-router';
import { NodeApi } from '../api/nodeApi';
import { ncheq_to_cheq_fixed } from '../helpers/currency';

export async function handler(request: Request): Promise<Response> {
let nodeApi = new NodeApi(REST_API);
let totalSupply = await nodeApi.bank_get_total_supply_ncheq();
let nodeApi = new NodeApi(REST_API);
let totalSupply = await nodeApi.bank_get_total_supply_ncheq();

return new Response(ncheq_to_cheq_fixed(totalSupply));
return new Response(ncheq_to_cheq_fixed(totalSupply));
}
37 changes: 21 additions & 16 deletions src/handlers/vestedBalance.ts
Original file line number Diff line number Diff line change
@@ -1,24 +1,29 @@
import { Request } from "itty-router";
import { is_vesting_account_type, validate_cheqd_address } from "../helpers/validate";
import { NodeApi } from "../api/nodeApi";
import { calculate_vested_coins } from "../helpers/vesting";
import { ncheq_to_cheq_fixed } from "../helpers/currency";
import { Request } from 'itty-router';
import {
is_vesting_account_type,
validate_cheqd_address,
} from '../helpers/validate';
import { NodeApi } from '../api/nodeApi';
import { calculate_vested_coins, estimatedVesting } from '../helpers/vesting';
import { ncheq_to_cheq_fixed } from '../helpers/currency';

export async function handler(request: Request): Promise<Response> {
const address = request.params?.['address'];
const address = request.params?.['address'];

if (!address || !validate_cheqd_address(address)) {
throw new Error("No address specified or wrong address format.");
}
if (!address || !validate_cheqd_address(address)) {
throw new Error('No address specified or wrong address format.');
}

let api = new NodeApi(REST_API);
const account = await api.auth_get_account(address);
let api = new NodeApi(REST_API);
const account = await api.auth_get_account(address);

if (!is_vesting_account_type(account["@type"])) {
throw new Error(`Only vesting accounts are supported. Accounts type '${account["@type"]}'.`)
}
if (!is_vesting_account_type(account['@type'])) {
throw new Error(
`Only vesting accounts are supported. Accounts type '${account['@type']}'.`
);
}

let vested_coins = calculate_vested_coins(account);
let vested_coins = estimatedVesting(account)?.vested;

return new Response(ncheq_to_cheq_fixed(vested_coins));
return new Response(ncheq_to_cheq_fixed(vested_coins!!));
}
37 changes: 21 additions & 16 deletions src/handlers/vestingBalance.ts
Original file line number Diff line number Diff line change
@@ -1,24 +1,29 @@
import { Request } from "itty-router";
import { is_vesting_account_type, validate_cheqd_address } from "../helpers/validate";
import { NodeApi } from "../api/nodeApi";
import { calculate_vesting_coins } from "../helpers/vesting";
import { ncheq_to_cheq_fixed } from "../helpers/currency";
import { Request } from 'itty-router';
import {
is_vesting_account_type,
validate_cheqd_address,
} from '../helpers/validate';
import { NodeApi } from '../api/nodeApi';
import { calculate_vesting_coins, estimatedVesting } from '../helpers/vesting';
import { ncheq_to_cheq_fixed } from '../helpers/currency';

export async function handler(request: Request): Promise<Response> {
const address = request.params?.['address'];
const address = request.params?.['address'];

if (!address || !validate_cheqd_address(address)) {
throw new Error("No address specified or wrong address format.");
}
if (!address || !validate_cheqd_address(address)) {
throw new Error('No address specified or wrong address format.');
}

let api = new NodeApi(REST_API);
const account = await api.auth_get_account(address)
let api = new NodeApi(REST_API);
const account = await api.auth_get_account(address);

if (!is_vesting_account_type(account["@type"])) {
throw new Error(`Only vesting accounts are supported. Accounts type '${account["@type"]}'.`)
}
if (!is_vesting_account_type(account['@type'])) {
throw new Error(
`Only vesting accounts are supported. Accounts type '${account['@type']}'.`
);
}

let vestingCoins = calculate_vesting_coins(account);
let vestingCoins = estimatedVesting(account)?.vesting;

return new Response(ncheq_to_cheq_fixed(vestingCoins));
return new Response(ncheq_to_cheq_fixed(vestingCoins!!));
}
8 changes: 8 additions & 0 deletions src/handlers/webhookTriggers.ts
Original file line number Diff line number Diff line change
@@ -1,8 +1,10 @@
import { updateGroupBalances } from '../helpers/balanceGroup';
import { filterArbitrageOpportunities } from './arbitrageOpportunities';

export async function webhookTriggers(event: Event) {
console.log('Triggering webhook...');
await sendPriceDiscrepancies();
await updateGroupBalances(getRandomGroup());
}

export async function sendPriceDiscrepancies() {
Expand All @@ -29,3 +31,9 @@ export async function sendPriceDiscrepancies() {
}
}
}

function getRandomGroup(): number {
let min = 1;
let max = Math.floor(CIRCULATING_SUPPLY_GROUPS);
return Math.floor(Math.random() * (max - min + 1)) + min;
}
Loading