Skip to content

Commit 1e9be5f

Browse files
committed
Index dao-voting-token-staked queries.
1 parent 8da5cc0 commit 1e9be5f

File tree

4 files changed

+174
-0
lines changed

4 files changed

+174
-0
lines changed
Lines changed: 140 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,140 @@
1+
import { ContractFormula } from '@/core'
2+
3+
interface StakerBalance {
4+
address: string
5+
balance: string
6+
}
7+
8+
type Config = {
9+
denom: string
10+
}
11+
12+
export const votingPower: ContractFormula<string, { address: string }> = {
13+
compute: async ({
14+
contractAddress,
15+
getTransformationMatch,
16+
args: { address },
17+
}) => {
18+
if (!address) {
19+
throw new Error('missing `address`')
20+
}
21+
22+
return (
23+
(
24+
await getTransformationMatch<string>(
25+
contractAddress,
26+
`stakedBalance:${address}`
27+
)
28+
)?.value ?? '0'
29+
)
30+
},
31+
}
32+
33+
export const totalPower: ContractFormula<string> = {
34+
compute: async ({ contractAddress, getTransformationMatch }) =>
35+
(await getTransformationMatch<string>(contractAddress, 'totalStaked'))
36+
?.value || '0',
37+
}
38+
39+
export const dao: ContractFormula<string | undefined> = {
40+
compute: async ({ contractAddress, getTransformationMatch }) =>
41+
(await getTransformationMatch<string | undefined>(contractAddress, 'dao'))
42+
?.value,
43+
}
44+
45+
export const denom: ContractFormula<string | undefined> = {
46+
compute: async ({ contractAddress, getTransformationMatch }) =>
47+
(await getTransformationMatch<string | undefined>(contractAddress, 'denom'))
48+
?.value,
49+
}
50+
51+
export const tokenIssuerContract: ContractFormula<string | undefined> = {
52+
compute: async ({ contractAddress, getTransformationMatch }) =>
53+
(
54+
await getTransformationMatch<string | undefined>(
55+
contractAddress,
56+
'tokenIssuerContract'
57+
)
58+
)?.value,
59+
}
60+
61+
export const claims: ContractFormula<
62+
{ claims: any[] } | undefined,
63+
{ address: string }
64+
> = {
65+
compute: async ({ contractAddress, get, args: { address } }) => {
66+
if (!address) {
67+
throw new Error('missing `address`')
68+
}
69+
70+
const claims = await get<any[]>(contractAddress, 'claims', address)
71+
return claims && { claims }
72+
},
73+
}
74+
75+
export const config: ContractFormula<Config | undefined> = {
76+
compute: async ({ contractAddress, getTransformationMatch }) =>
77+
(await getTransformationMatch<Config>(contractAddress, 'config'))?.value,
78+
}
79+
80+
export const listStakers: ContractFormula<
81+
{ stakers: StakerBalance[] },
82+
{
83+
limit?: string
84+
startAfter?: string
85+
}
86+
> = {
87+
compute: async ({ contractAddress, getMap, args: { limit, startAfter } }) => {
88+
const limitNum = limit ? Math.max(0, Number(limit)) : Infinity
89+
90+
const stakers =
91+
(await getMap<string, string>(contractAddress, 'staked_balances')) ?? {}
92+
const stakes = Object.entries(stakers)
93+
// Ascending by address.
94+
.sort(([a], [b]) => a.localeCompare(b))
95+
.filter(
96+
([address]) => !startAfter || address.localeCompare(startAfter) > 0
97+
)
98+
.slice(0, limitNum)
99+
100+
return {
101+
stakers: stakes.map(([address, balance]) => ({
102+
address,
103+
balance,
104+
})),
105+
}
106+
},
107+
}
108+
109+
type Staker = StakerBalance & {
110+
votingPowerPercent: number
111+
}
112+
113+
export const topStakers: ContractFormula<Staker[] | undefined> = {
114+
compute: async (env) => {
115+
const { contractAddress, getMap } = env
116+
// Get stakers.
117+
const stakerBalances =
118+
(await getMap<string, string>(contractAddress, 'staked_balances')) ?? {}
119+
120+
// Get total power.
121+
const totalVotingPower = Number(await totalPower.compute(env))
122+
123+
// Compute voting power for each staker.
124+
const stakers = Object.entries(stakerBalances)
125+
.map(
126+
([address, balance]): Staker => ({
127+
address,
128+
balance,
129+
votingPowerPercent:
130+
totalVotingPower === 0
131+
? 0
132+
: (Number(balance) / totalVotingPower) * 100,
133+
})
134+
)
135+
// Descending by voting power.
136+
.sort((a, b) => b.votingPowerPercent - a.votingPowerPercent)
137+
138+
return stakers
139+
},
140+
}

src/data/formulas/contract/voting/index.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,3 +2,4 @@ export * as daoVotingCw20Staked from './daoVotingCw20Staked'
22
export * as daoVotingCw4 from './daoVotingCw4'
33
export * as daoVotingCw721Staked from './daoVotingCw721Staked'
44
export * as daoVotingNativeStaked from './daoVotingNativeStaked'
5+
export * as daoVotingTokenStaked from './daoVotingTokenStaked'
Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,31 @@
1+
import { makeTransformer, makeTransformerForMap } from '../utils'
2+
3+
const CODE_IDS_KEYS = ['dao-voting-token-staked']
4+
5+
const config = makeTransformer(CODE_IDS_KEYS, 'config')
6+
const dao = makeTransformer(CODE_IDS_KEYS, 'dao')
7+
const denom = makeTransformer(CODE_IDS_KEYS, 'denom')
8+
const tokenIssuerContract = makeTransformer(
9+
CODE_IDS_KEYS,
10+
'tokenIssuerContract',
11+
'token_issuer_contract'
12+
)
13+
const stakedBalance = makeTransformerForMap(
14+
CODE_IDS_KEYS,
15+
'stakedBalance',
16+
'staked_balances'
17+
)
18+
const totalStaked = makeTransformer(
19+
CODE_IDS_KEYS,
20+
'totalStaked',
21+
'total_staked'
22+
)
23+
24+
export default [
25+
config,
26+
dao,
27+
denom,
28+
tokenIssuerContract,
29+
stakedBalance,
30+
totalStaked,
31+
]

src/data/transformers/voting/index.ts

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,10 +2,12 @@ import daoVotingCw20Staked from './daoVotingCw20Staked'
22
import daoVotingCw4 from './daoVotingCw4'
33
import daoVotingCw721Staked from './daoVotingCw721Staked'
44
import daoVotingNativeStaked from './daoVotingNativeStaked'
5+
import daoVotingTokenStaked from './daoVotingTokenStaked'
56

67
export default [
78
...daoVotingCw20Staked,
89
...daoVotingCw4,
910
...daoVotingCw721Staked,
1011
...daoVotingNativeStaked,
12+
...daoVotingTokenStaked,
1113
]

0 commit comments

Comments
 (0)