-
Notifications
You must be signed in to change notification settings - Fork 202
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
feat: Tally data provider addition (#2176)
- Loading branch information
1 parent
66cdfdd
commit 8aed57f
Showing
8 changed files
with
315 additions
and
2 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,33 @@ | ||
import { dataProviders } from "@group-generators/helpers/data-providers"; | ||
import { GroupWithData, Tags, ValueType } from "topics/group"; | ||
import { GenerationContext, GenerationFrequency, GroupGenerator } from "topics/group-generator"; | ||
|
||
// Generated from factory.sismo.io | ||
|
||
const generator: GroupGenerator = { | ||
generationFrequency: GenerationFrequency.Daily, | ||
|
||
generate: async (context: GenerationContext): Promise<GroupWithData[]> => { | ||
const TallyProvider = new dataProviders.TallyProvider(); | ||
|
||
const input = { | ||
name: "Aave", | ||
// proposalId: 315, | ||
}; | ||
const tallyGetGovernanceProposers = await TallyProvider.getGovernanceProposers(input); | ||
|
||
return [ | ||
{ | ||
name: "example-tally", | ||
timestamp: context.timestamp, | ||
description: "Tally governance", | ||
specs: "", | ||
data: tallyGetGovernanceProposers, | ||
valueType: ValueType.Score, | ||
tags: [Tags.Vote], | ||
}, | ||
]; | ||
}, | ||
}; | ||
|
||
export default generator; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,5 @@ | ||
import TallyProvider from "./provider"; | ||
|
||
import { ITallyProvider } from "./types"; | ||
|
||
export { TallyProvider, ITallyProvider }; |
59 changes: 59 additions & 0 deletions
59
group-generators/helpers/data-providers/tally/interface-schema.json
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,59 @@ | ||
{ | ||
"name": "Tally", | ||
"iconUrl": "", | ||
"providerClassName": "TallyProvider", | ||
"functions": [ | ||
{ | ||
"name": "Get voters of proposal", | ||
"functionName": "getProposalVoters", | ||
"countFunctionName": "getProposalVotersCount", | ||
"description": "Returns all voters of a specific proposal on Tally.", | ||
"args": [ | ||
{ | ||
"name": "DAO", | ||
"argName": "governance", | ||
"type": "string", | ||
"example": "aave", | ||
"description": "A specific DAO" | ||
}, | ||
{ | ||
"name": "proposal ID", | ||
"argName": "proposalId", | ||
"type": "number", | ||
"example": "193", | ||
"description": "A specific proposal identifier" | ||
} | ||
] | ||
}, | ||
{ | ||
"name": "Get voters of a DAO", | ||
"functionName": "getGovernanceVoters", | ||
"countFunctionName": "getGovernanceVotersCount", | ||
"description": "Returns all voters of a specific governance on Tally. The values of the accounts correspond to their number of votes.", | ||
"args": [ | ||
{ | ||
"name": "DAO", | ||
"argName": "governance", | ||
"type": "string", | ||
"example": "aave", | ||
"description": "A specific DAO" | ||
} | ||
] | ||
}, | ||
{ | ||
"name": "Get proposers of a DAO", | ||
"functionName": "getGovernanceProposers", | ||
"countFunctionName": "getGovernanceProposersCount", | ||
"description": "Returns all proposals proposers of a specific DAO on Tally. The values of the accounts correspond to their number of proposal proposed.", | ||
"args": [ | ||
{ | ||
"name": "DAO", | ||
"argName": "governance", | ||
"type": "string", | ||
"example": "aave", | ||
"description": "A specific DAO" | ||
} | ||
] | ||
} | ||
] | ||
} |
172 changes: 172 additions & 0 deletions
172
group-generators/helpers/data-providers/tally/provider.ts
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,172 @@ | ||
import { gql } from "graphql-request"; | ||
|
||
import { | ||
ITallyProvider, | ||
inputGetGovernanceProposers, | ||
inputGetProposalVoters, | ||
queryData, | ||
} from "./types"; | ||
import { GraphQLProvider } from "@group-generators/helpers/data-providers/graphql"; | ||
import { FetchedData } from "topics/group"; | ||
|
||
export default class TallyProvider extends GraphQLProvider implements ITallyProvider { | ||
public constructor() { | ||
super({ | ||
url: "https://api.tally.xyz/query", | ||
headers: { | ||
"Api-Key": process.env.TALLY_API_KEY as string, | ||
accept: "application/json", | ||
}, | ||
}); | ||
} | ||
|
||
private async _queryNameToGovernorAddress(): Promise<queryData> { | ||
return this.query( | ||
gql` | ||
query Governors { | ||
governors(chainIds: "eip155:1") { | ||
id | ||
type | ||
name | ||
proposals { | ||
id | ||
title | ||
description | ||
proposer { | ||
address | ||
} | ||
votes { | ||
id | ||
voter { | ||
id | ||
address | ||
} | ||
} | ||
} | ||
} | ||
} | ||
`, | ||
{} | ||
); | ||
} | ||
|
||
public async getProposalVoters({ | ||
name, | ||
proposalId, | ||
}: inputGetProposalVoters): Promise<FetchedData> { | ||
const data = await this._queryNameToGovernorAddress(); | ||
|
||
const fetchedData: { [address: string]: number } = {}; | ||
|
||
if (data && Array.isArray(data.governors)) { | ||
const matchingGovernors = data.governors.filter( | ||
(governor: { name: string }) => governor.name === name | ||
); | ||
|
||
for (const governor of matchingGovernors) { | ||
for (const proposals of governor.proposals) { | ||
const propId = proposals.id; | ||
|
||
if (parseInt(propId) === proposalId) { | ||
const allVotes = proposals.votes; | ||
|
||
allVotes.forEach((voteItem: { id: string; voter: any }) => { | ||
const { voter } = voteItem; | ||
const { address } = voter; | ||
if (fetchedData[address]) { | ||
fetchedData[address]++; | ||
} else { | ||
fetchedData[address] = 1; | ||
} | ||
}); | ||
} | ||
} | ||
} | ||
|
||
return fetchedData; | ||
} | ||
|
||
return fetchedData; | ||
} | ||
|
||
public async getProposalVotersCount({ | ||
name, | ||
proposalId, | ||
}: inputGetProposalVoters): Promise<number> { | ||
const ProposalVoterData = await this.getProposalVoters({ name, proposalId }); | ||
|
||
const ProposalVoterCount = Object.keys(ProposalVoterData).length; | ||
return ProposalVoterCount; | ||
} | ||
|
||
public async getGovernanceVoters({ name }: inputGetGovernanceProposers): Promise<FetchedData> { | ||
const data: queryData = await this._queryNameToGovernorAddress(); | ||
const fetchedData: { [address: string]: number } = {}; | ||
|
||
if (data && Array.isArray(data.governors)) { | ||
const matchingGovernors = data.governors.filter( | ||
(governor: { name: string }) => governor.name === name | ||
); | ||
|
||
for (const governor of matchingGovernors) { | ||
for (const proposals of governor.proposals) { | ||
const votesArray = proposals?.votes; | ||
|
||
votesArray.forEach((item: { id: string; voter: any }) => { | ||
const { voter } = item; | ||
const { address } = voter; | ||
if (fetchedData[address]) { | ||
fetchedData[address]++; | ||
} else { | ||
fetchedData[address] = 1; | ||
} | ||
}); | ||
} | ||
} | ||
|
||
return fetchedData; | ||
} | ||
|
||
return fetchedData; | ||
} | ||
|
||
public async getGovernanceVotersCount({ name }: inputGetGovernanceProposers): Promise<number> { | ||
const VoterData = await this.getGovernanceVoters({ name }); | ||
|
||
const VoterCount = Object.keys(VoterData).length; | ||
return VoterCount; | ||
} | ||
|
||
public async getGovernanceProposers({ name }: inputGetGovernanceProposers): Promise<FetchedData> { | ||
const data: queryData = await this._queryNameToGovernorAddress(); | ||
const fetchedData: { [address: string]: number } = {}; | ||
|
||
if (data && Array.isArray(data.governors)) { | ||
const matchingGovernors = data.governors.filter( | ||
(governor: { name: string }) => governor.name === name | ||
); | ||
|
||
for (const governor of matchingGovernors) { | ||
for (const proposal of governor.proposals) { | ||
const proposerAddress = proposal.proposer.address; | ||
|
||
if (fetchedData[proposerAddress]) { | ||
fetchedData[proposerAddress]++; | ||
} else { | ||
fetchedData[proposerAddress] = 1; | ||
} | ||
} | ||
} | ||
|
||
return fetchedData; | ||
} | ||
return fetchedData; | ||
} | ||
|
||
public async getGovernanceProposersCount({ name }: inputGetGovernanceProposers): Promise<number> { | ||
const proposersData = await this.getGovernanceProposers({ name }); | ||
|
||
const proposerCount = Object.keys(proposersData).length; | ||
return proposerCount; | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,32 @@ | ||
import { IGraphQLProvider } from "@group-generators/helpers/data-providers/graphql/types"; | ||
|
||
export type ITallyProvider = IGraphQLProvider; | ||
|
||
export interface inputGetGovernanceProposers { | ||
name: string; | ||
} | ||
|
||
export interface inputGetProposalVoters { | ||
name: string; | ||
proposalId: number; | ||
} | ||
|
||
export interface Delegate { | ||
id: string; | ||
account: { address: string }; | ||
stats: { | ||
voteCount: number; | ||
}; | ||
} | ||
|
||
export interface govArray { | ||
id: string; | ||
type: string; | ||
name: string; | ||
proposals: any[]; | ||
delegates: Delegate[]; | ||
} | ||
|
||
export interface queryData { | ||
governors?: govArray[]; | ||
} |