diff --git a/src/accounts/superfluid.ts b/src/accounts/superfluid.ts index bdfec4a2..2d34b91b 100644 --- a/src/accounts/superfluid.ts +++ b/src/accounts/superfluid.ts @@ -2,7 +2,12 @@ import { Framework, SuperToken } from "@superfluid-finance/sdk-core"; import { AvalancheAccount } from "./avalanche"; import { ChainData, ChangeRpcParam, decToHex, JsonRPCWallet, RpcId } from "./providers/JsonRPCWallet"; import { BigNumber, ethers, providers } from "ethers"; -import { ALEPH_SUPERFLUID_FUJI_TESTNET, ALEPH_SUPERFLUID_MAINNET } from "../global"; +import { + ALEPH_SUPERFLUID_FUJI_TESTNET, + ALEPH_SUPERFLUID_MAINNET, + SUPERFLUID_FUJI_TESTNET_SUBGRAPH_URL, + SUPERFLUID_MAINNET_SUBGRAPH_URL, +} from "../global"; import { Decimal } from "decimal.js"; /** @@ -109,6 +114,94 @@ export class SuperfluidAccount extends AvalancheAccount { return this.flowRateToAlephPerHour(flow); } + public async getAllALEPHxOutflows(): Promise> { + if (!this.wallet) throw Error("PublicKey Error: No providers are set up"); + if (!this.framework || !this.alephx) throw new Error("SuperfluidAccount not initialized"); + // make a graphql query to Superfluid Subgraph + const query = ` + query { + accounts(where: {outflows_: {sender: ${this.address}}}) { + id + outflows(where: {currentFlowRate_not: "0"}) { + sender { + id + } + receiver { + id + } + createdAtTimestamp + currentFlowRate + } + } + } + `; + const data = await this.querySubgraph(query); + const accounts = data.data.accounts; + const outflows: Record = {}; + for (const account of accounts) { + for (const outflow of account.outflows) { + const flowRate = this.flowRateToAlephPerHour(outflow.currentFlowRate); + if (outflow.sender.id === this.address) { + outflows[outflow.sender.id] = flowRate; + } + } + } + return outflows; + } + + private async querySubgraph(query: string) { + const response = await fetch(await this.getSubgraphUrl(), { + method: "POST", + body: JSON.stringify({ query }), + }); + return await response.json(); + } + + public async getAllALEPHxInflows(): Promise> { + if (!this.wallet) throw Error("PublicKey Error: No providers are set up"); + if (!this.framework || !this.alephx) throw new Error("SuperfluidAccount not initialized"); + // make a graphql query to Superfluid Subgraph + const query = ` + query { + accounts(where: {inflows_: {receiver: ${this.address}}}) { + id + inflows(where: {currentFlowRate_not: "0"}) { + sender { + id + } + receiver { + id + } + createdAtTimestamp + currentFlowRate + } + } + } + `; + const data = await this.querySubgraph(query); + const accounts = data.data.accounts; + const inflows: Record = {}; + for (const account of accounts) { + for (const inflow of account.inflows) { + const flowRate = this.flowRateToAlephPerHour(inflow.currentFlowRate); + if (inflow.receiver.id === this.address) { + inflows[inflow.sender.id] = flowRate; + } + } + } + return inflows; + } + + private async getSubgraphUrl() { + if (ChainData[RpcId.AVAX_TESTNET].chainId === decToHex(await this.getChainId())) { + return SUPERFLUID_FUJI_TESTNET_SUBGRAPH_URL; + } else if (ChainData[RpcId.AVAX].chainId === decToHex(await this.getChainId())) { + return SUPERFLUID_MAINNET_SUBGRAPH_URL; + } else { + throw new Error(`ChainID ${await this.getChainId()} not supported`); + } + } + /** * Increase the ALEPHx flow rate to a given receiver. Creates a new flow if none exists. * @param receiver The receiver address. diff --git a/src/global.ts b/src/global.ts index 3affa12a..7b2e61c2 100644 --- a/src/global.ts +++ b/src/global.ts @@ -2,3 +2,5 @@ export const DEFAULT_API_V2 = "https://api2.aleph.im"; export const DEFAULT_API_WS_V2 = "ws://api2.aleph.im"; export const ALEPH_SUPERFLUID_FUJI_TESTNET = "0x1290248E01ED2F9f863A9752A8aAD396ef3a1B00"; export const ALEPH_SUPERFLUID_MAINNET = "0xc0Fbc4967259786C743361a5885ef49380473dCF"; +export const SUPERFLUID_FUJI_TESTNET_SUBGRAPH_URL = "https://avalanche-fuji.subgraph.x.superfluid.dev/"; +export const SUPERFLUID_MAINNET_SUBGRAPH_URL = "https://avalanche-c.subgraph.x.superfluid.dev/";