Skip to content

Commit

Permalink
add prize pool subgraph methods
Browse files Browse the repository at this point in the history
  • Loading branch information
chuckbergeron committed May 18, 2023
1 parent a8c7712 commit 1406d68
Show file tree
Hide file tree
Showing 8 changed files with 153 additions and 7 deletions.
2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@
"description": "Utility library for PoolTogether V5 off-chain computations.",
"author": "PoolTogether Inc",
"license": "GPL-3.0-only",
"version": "0.0.1-beta.9",
"version": "0.0.1-beta.10",
"homepage": "https://github.com/pooltogether/v5-utils-js",
"bugs": {
"url": "https://github.com/pooltogether/issues",
Expand Down
7 changes: 7 additions & 0 deletions src/types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -68,3 +68,10 @@ export interface MulticallResults {
export interface Amounts {
[tier: string]: BigNumber;
}

export interface ClaimedPrize {
id: string;
payout: string;
fee: string;
timestamp: string;
}
9 changes: 7 additions & 2 deletions src/utils/constants.ts
Original file line number Diff line number Diff line change
@@ -1,9 +1,14 @@
const CHAIN_ID = {
goerli: 5,
mumbai: 80001
mumbai: 80001,
};

export const TWAB_CONTROLLER_SUBGRAPH_URIS = {
[CHAIN_ID.goerli]: `https://api.thegraph.com/subgraphs/name/pooltogether/v5-eth-goerli-twab-controller`,
[CHAIN_ID.mumbai]: `https://api.thegraph.com/subgraphs/name/pooltogether/v5-polygon-mumbai-twab-control`
[CHAIN_ID.mumbai]: `https://api.thegraph.com/subgraphs/name/pooltogether/v5-polygon-mumbai-twab-control`,
};

export const PRIZE_POOL_SUBGRAPH_URIS = {
[CHAIN_ID.goerli]: `https://api.thegraph.com/subgraphs/name/pooltogether/v5-eth-goerli-prize-pool`,
[CHAIN_ID.mumbai]: `https://api.thegraph.com/subgraphs/name/pooltogether/v5-polygon-mumbai-prize-pool`,
};
80 changes: 80 additions & 0 deletions src/utils/filterClaimedPrizes.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,80 @@
import { Provider } from "@ethersproject/providers";
import { ContractCallContext } from "ethereum-multicall";

import { MulticallResults, Claim, ContractsBlob, Vault } from "../types";
import { getComplexMulticallResults } from "./multicall";

/**
* Returns claims
* @param readProvider a read-capable provider for the chain that should be queried
* @param contracts blob of contracts to pull PrizePool abi/etc from
* @param vaults vaults to query through
* @param tiersArray an easily iterable range of numbers for each tier available (ie. [0, 1, 2])
* @returns
*/
export const filterClaimedPrizes = async (
readProvider: Provider,
contracts: ContractsBlob,
vaults: Vault[],
tiersArray: number[]
): Promise<Claim[]> => {
const prizePoolContractBlob = contracts.contracts.find(
(contract) => contract.type === "PrizePool"
);
if (!prizePoolContractBlob) {
throw new Error("Contracts: No prize pool found in provided contracts blob");
}

const calls: ContractCallContext["calls"] = [];

vaults.forEach((vault) => {
vault.accounts.forEach((account) => {
const address = account.id.split("-")[1];

tiersArray.forEach((tierNum) => {
calls.push({
reference: `${vault.id}-${address}-${tierNum}`,
methodName: "isWinner",
methodParameters: [vault.id, address, tierNum],
});
});
});
});

const prizePoolAddress: string | undefined = prizePoolContractBlob?.address;

const queries: ContractCallContext[] = [
{
reference: prizePoolAddress,
contractAddress: prizePoolAddress,
abi: prizePoolContractBlob.abi,
calls,
},
];

const multicallResults: MulticallResults = await getComplexMulticallResults(
readProvider,
queries
);

// Builds the array of claims
return getClaims(prizePoolAddress, multicallResults);
};

const getClaims = (prizePoolAddress: string, multicallResults: MulticallResults): Claim[] => {
const claims: Claim[] = [];

Object.entries(multicallResults[prizePoolAddress]).forEach((vaultUserTierResult) => {
const key = vaultUserTierResult[0];
const value = vaultUserTierResult[1];
const isWinner = value[0];

const [vault, winner, tier] = key.split("-");

if (isWinner) {
claims.push({ vault, tier: Number(tier), winner });
}
});

return claims;
};
56 changes: 56 additions & 0 deletions src/utils/getSubgraphClaimedPrizes.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,56 @@
import { gql, GraphQLClient } from "graphql-request";

import { PRIZE_POOL_SUBGRAPH_URIS } from "./constants";
import { ClaimedPrize } from "../types";

/**
* Subgraphs to query for depositors
*/
export const getPrizePoolSubgraphUri = (chainId: number) => {
return PRIZE_POOL_SUBGRAPH_URIS[chainId];
};

export const getPrizePoolSubgraphClient = (chainId: number) => {
const uri = getPrizePoolSubgraphUri(chainId);

return new GraphQLClient(uri);
};

/**
* Pulls from the subgraph all of the claimed prizes for a specific draw
*
* @returns {Promise} Promise of an array of ClaimedPrize objects
*/
export const getSubgraphClaimedPrizes = async (
chainId: number,
drawId: string
): Promise<ClaimedPrize[]> => {
const client = getPrizePoolSubgraphClient(chainId);

const query = drawQuery();
const variables = { id: drawId };

// @ts-ignore: ignore types from GraphQL client lib
const claimedPrizesResponse: any = await client.request(query, variables).catch((e) => {
console.error(e.message);
throw e;
});

return claimedPrizesResponse?.draw?.prizeClaims || [];
};

const drawQuery = () => {
return gql`
query drawQuery($id: String!) {
draw(id: $id) {
id
prizeClaims {
id
payout
fee
timestamp
}
}
}
`;
};
4 changes: 1 addition & 3 deletions src/utils/getSubgraphVaults.ts
Original file line number Diff line number Diff line change
Expand Up @@ -32,9 +32,7 @@ export const getSubgraphVaults = async (chainId: number): Promise<Vault[]> => {
throw e;
});

const vaults = vaultsResponse?.vaults;

return vaults;
return vaultsResponse?.vaults || [];
};

const vaultsQuery = () => {
Expand Down
1 change: 0 additions & 1 deletion src/utils/getTierPrizeAmounts.ts
Original file line number Diff line number Diff line change
Expand Up @@ -57,7 +57,6 @@ const getTierAmounts = (prizePoolAddress: string, multicallResults: MulticallRes

Object.entries(multicallResults[prizePoolAddress]).forEach((tierResult) => {
const [key, value] = tierResult;

amounts[key] = value[0];
});

Expand Down
1 change: 1 addition & 0 deletions src/utils/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,3 +4,4 @@ export * from "./getContracts";
export { getTierPrizeAmounts } from "./getTierPrizeAmounts";
export { getWinnersClaims } from "./getWinnersClaims";
export { getSubgraphVaults } from "./getSubgraphVaults";
export { getSubgraphClaimedPrizes } from "./getSubgraphClaimedPrizes";

0 comments on commit 1406d68

Please sign in to comment.