From 7a60a45357cf05ea4c2d11b4b13ff555b9732574 Mon Sep 17 00:00:00 2001 From: dan13ram Date: Tue, 22 Nov 2022 13:17:19 +0530 Subject: [PATCH 1/6] created a client class --- .gitignore | 1 + src/Client.ts | 83 +++++++++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 84 insertions(+) create mode 100644 src/Client.ts diff --git a/.gitignore b/.gitignore index 81a1521..a2942f8 100644 --- a/.gitignore +++ b/.gitignore @@ -3,3 +3,4 @@ node_modules dist src/graphql/types.ts +*.sw[a-z] diff --git a/src/Client.ts b/src/Client.ts new file mode 100644 index 0000000..01a79f6 --- /dev/null +++ b/src/Client.ts @@ -0,0 +1,83 @@ +import { providers, utils } from 'ethers'; +import { contracts } from '.'; +import { QuestChainCommons } from './contracts/v1/contracts/QuestChain'; +import { + getChainInfo, + getQuestChainInfo, + GlobalInfoFragment, + isSupportedNetwork, + QuestChainInfoFragment, +} from './graphql'; +import { getQuestChainAddressFromTx, waitUntilSubgraphIndexed } from './helpers'; +import EventEmitter from 'events'; + +export class QuestChainsClient extends EventEmitter { + private chainId: string; + private provider: providers.Web3Provider; + private globalInfo: GlobalInfoFragment | null = null; + + constructor(chainId: string, provider: providers.Web3Provider) { + if (!isSupportedNetwork(chainId)) { + throw new Error('Unsupported network'); + } + super(); + this.chainId = chainId; + this.provider = provider; + } + + getChainId(): string { + return this.chainId; + } + + async getGlobalInfo(): Promise { + if (this.globalInfo) { + return this.globalInfo; + } + + this.globalInfo = await getChainInfo(this.chainId); + + if (!this.globalInfo) { + throw new Error('Could not get global info'); + } + return this.globalInfo; + } + + async getQuestChain(chainAddress: string): Promise { + if (!utils.isAddress(chainAddress)) { + throw new Error('Invalid quest chain address'); + } + return getQuestChainInfo(this.chainId, chainAddress); + } + + async createQuestChain( + chainInfo: QuestChainCommons.QuestChainInfoStruct, + upgrade = false, + ): Promise { + const { factoryAddress } = await this.getGlobalInfo(); + + const factoryContract: contracts.V1.QuestChainFactory = contracts.V1.QuestChainFactory__factory.connect( + factoryAddress, + this.provider.getSigner(), + ); + + let tx: providers.TransactionResponse; + if (upgrade) { + tx = await factoryContract.createAndUpgrade(chainInfo, utils.randomBytes(32)); + } else { + tx = await factoryContract.create(chainInfo, utils.randomBytes(32)); + } + this.emit('txResponse', tx); + + const receipt = await tx.wait(); + + this.emit('txReceipt', receipt); + + const indexed = await waitUntilSubgraphIndexed(this.chainId, receipt.blockNumber); + + this.emit('txIndexed', indexed) + + const questChainAddress = await getQuestChainAddressFromTx(receipt); + + return this.getQuestChain(questChainAddress); + } +} From 229f0112eabfe0d91b873e450c7f39a1891d8ff8 Mon Sep 17 00:00:00 2001 From: dan13ram Date: Tue, 22 Nov 2022 13:40:52 +0530 Subject: [PATCH 2/6] added support for more methods --- src/Client.ts | 188 +++++++++++++++++++++++++++++++++++++++++++++++--- 1 file changed, 179 insertions(+), 9 deletions(-) diff --git a/src/Client.ts b/src/Client.ts index 01a79f6..1406cfb 100644 --- a/src/Client.ts +++ b/src/Client.ts @@ -8,9 +8,16 @@ import { isSupportedNetwork, QuestChainInfoFragment, } from './graphql'; -import { getQuestChainAddressFromTx, waitUntilSubgraphIndexed } from './helpers'; +import { waitUntilSubgraphIndexed } from './helpers'; import EventEmitter from 'events'; +export enum QuestChainRole { + OWNER = '0x0000000000000000000000000000000000000000000000000000000000000000', + ADMIN = '0xa49807205ce4d355092ef5a8a18f56e8913cf4a201fbe287825b095693c21775', + EDITOR = '0x21d1167972f621f75904fb065136bc8b53c7ba1c60ccd3a7758fbee465851e9c', + REVIEWER = '0xc10c77be35aff266144ed64c26a1fa104bae2f284ae99ac4a34203454704a185', +} + export class QuestChainsClient extends EventEmitter { private chainId: string; private provider: providers.Web3Provider; @@ -49,10 +56,23 @@ export class QuestChainsClient extends EventEmitter { return getQuestChainInfo(this.chainId, chainAddress); } + private async handleTx(tx: providers.TransactionResponse): Promise { + this.emit('txResponse', tx); + + const receipt = await tx.wait(); + + this.emit('txReceipt', receipt); + + const indexed = await waitUntilSubgraphIndexed(this.chainId, receipt.blockNumber); + + this.emit('txIndexed', indexed); + return receipt; + } + async createQuestChain( chainInfo: QuestChainCommons.QuestChainInfoStruct, upgrade = false, - ): Promise { + ): Promise { const { factoryAddress } = await this.getGlobalInfo(); const factoryContract: contracts.V1.QuestChainFactory = contracts.V1.QuestChainFactory__factory.connect( @@ -66,18 +86,168 @@ export class QuestChainsClient extends EventEmitter { } else { tx = await factoryContract.create(chainInfo, utils.randomBytes(32)); } - this.emit('txResponse', tx); + const receipt = await this.handleTx(tx); - const receipt = await tx.wait(); + return receipt; + } - this.emit('txReceipt', receipt); + async upgradeQuestChain(questChain: QuestChainInfoFragment): Promise { + if (questChain.premium) { + throw new Error('Quest chain is already upgraded'); + } + const { factoryAddress } = await this.getGlobalInfo(); - const indexed = await waitUntilSubgraphIndexed(this.chainId, receipt.blockNumber); + const factoryContract: contracts.V1.QuestChainFactory = contracts.V1.QuestChainFactory__factory.connect( + factoryAddress, + this.provider.getSigner(), + ); + + const tx: providers.TransactionResponse = await factoryContract.upgradeQuestChain(questChain.address); + + const receipt = await this.handleTx(tx); + + return receipt; + } + + async grantRole( + questChain: QuestChainInfoFragment, + userAddress: string, + roleHash: QuestChainRole, + ): Promise { + // role management is the same on all versions + const chainContract: contracts.V1.QuestChain = contracts.V1.QuestChain__factory.connect( + questChain.address, + this.provider.getSigner(), + ); + + const tx: providers.TransactionResponse = await chainContract.grantRole(roleHash, userAddress); + const receipt = await this.handleTx(tx); + + return receipt; + } + + async revokeRole( + questChain: QuestChainInfoFragment, + userAddress: string, + roleHash: QuestChainRole, + ): Promise { + // role management is the same on all versions + const chainContract: contracts.V1.QuestChain = contracts.V1.QuestChain__factory.connect( + questChain.address, + this.provider.getSigner(), + ); + + const tx: providers.TransactionResponse = await chainContract.revokeRole(roleHash, userAddress); + const receipt = await this.handleTx(tx); + + return receipt; + } + + async pauseQuestChain(questChain: QuestChainInfoFragment): Promise { + if (questChain.paused) { + throw new Error('Quest chain is already paused'); + } + // pausing is the same on all versions + const chainContract: contracts.V1.QuestChain = contracts.V1.QuestChain__factory.connect( + questChain.address, + this.provider.getSigner(), + ); + + const tx: providers.TransactionResponse = await chainContract.pause(); + const receipt = await this.handleTx(tx); + + return receipt; + } + + async unpauseQuestChain(questChain: QuestChainInfoFragment): Promise { + if (questChain.paused) { + throw new Error('Quest chain is already paused'); + } + // pausing is the same on all versions + const chainContract: contracts.V1.QuestChain = contracts.V1.QuestChain__factory.connect( + questChain.address, + this.provider.getSigner(), + ); + + const tx: providers.TransactionResponse = await chainContract.unpause(); + const receipt = await this.handleTx(tx); + + return receipt; + } + + async addQuests( + questChain: QuestChainInfoFragment, + questDetailsList: string[], + ): Promise { + if (questChain.paused) { + throw new Error('Quest chain is already paused'); + } + if (questDetailsList.length === 0) { + throw new Error('No quests provided'); + } + if (questChain.version === '0' && questDetailsList.length > 1) { + throw new Error('Adding multiple quests not supported on this quest chain version'); + } - this.emit('txIndexed', indexed) + if (questChain.version === '0') { + const chainContract: contracts.V0.QuestChain = contracts.V0.QuestChain__factory.connect( + questChain.address, + this.provider.getSigner(), + ); + + const tx: providers.TransactionResponse = await chainContract.createQuest(questDetailsList[0]); + const receipt = await this.handleTx(tx); + + return receipt; + } + const chainContract: contracts.V1.QuestChain = contracts.V1.QuestChain__factory.connect( + questChain.address, + this.provider.getSigner(), + ); + + const tx: providers.TransactionResponse = await chainContract.createQuests(questDetailsList); + const receipt = await this.handleTx(tx); + + return receipt; + } + + async editQuests( + questChain: QuestChainInfoFragment, + questIdList: string[], + questDetailsList: string[], + ): Promise { + if (questChain.paused) { + throw new Error('Quest chain is already paused'); + } + if (questDetailsList.length === 0) { + throw new Error('No quests provided'); + } + if (questIdList.length !== questDetailsList.length) { + throw new Error('Quest details lengths do not match'); + } + if (questChain.version === '0' && questDetailsList.length > 1) { + throw new Error('Editing multiple quests not supported on this quest chain version'); + } + + if (questChain.version === '0') { + const chainContract: contracts.V0.QuestChain = contracts.V0.QuestChain__factory.connect( + questChain.address, + this.provider.getSigner(), + ); + + const tx: providers.TransactionResponse = await chainContract.editQuest(questIdList[0], questDetailsList[0]); + const receipt = await this.handleTx(tx); + + return receipt; + } + const chainContract: contracts.V1.QuestChain = contracts.V1.QuestChain__factory.connect( + questChain.address, + this.provider.getSigner(), + ); - const questChainAddress = await getQuestChainAddressFromTx(receipt); + const tx: providers.TransactionResponse = await chainContract.editQuests(questIdList, questDetailsList); + const receipt = await this.handleTx(tx); - return this.getQuestChain(questChainAddress); + return receipt; } } From 7aea681e595bfd5129399f67bbd637fcebb9a8f4 Mon Sep 17 00:00:00 2001 From: dan13ram Date: Tue, 22 Nov 2022 14:07:06 +0530 Subject: [PATCH 3/6] rename client.ts --- src/{Client.ts => client.ts} | 0 1 file changed, 0 insertions(+), 0 deletions(-) rename src/{Client.ts => client.ts} (100%) diff --git a/src/Client.ts b/src/client.ts similarity index 100% rename from src/Client.ts rename to src/client.ts From c525b44636eb965ef070bc088d8920faf4cd2aeb Mon Sep 17 00:00:00 2001 From: dan13ram Date: Tue, 22 Nov 2022 14:08:11 +0530 Subject: [PATCH 4/6] exporting client --- src/index.ts | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/index.ts b/src/index.ts index 383e1d8..996aea9 100644 --- a/src/index.ts +++ b/src/index.ts @@ -2,5 +2,6 @@ import * as graphql from './graphql'; import * as contracts from './contracts'; import * as metadata from './metadata'; import * as helpers from './helpers'; +import { QuestChainsClient, QuestChainRole } from './client'; -export { graphql, contracts, metadata, helpers }; +export { graphql, contracts, metadata, helpers, QuestChainsClient, QuestChainRole }; From e628932235edba05fa628fd1b8383bc90b5206f5 Mon Sep 17 00:00:00 2001 From: dan13ram Date: Tue, 22 Nov 2022 14:10:25 +0530 Subject: [PATCH 5/6] fixed formatting bug --- package.json | 2 +- src/graphql/badgesForUser.ts | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/package.json b/package.json index 3451252..ba0f608 100644 --- a/package.json +++ b/package.json @@ -15,7 +15,7 @@ "start": "tsdx watch", "build": "rm -rf dist && yarn tsc", "test": "tsdx test --passWithNoTests", - "lint": "tsdx lint", + "lint": "tsdx lint src --fix", "typecheck": "tsc --noEmit", "prepare": "yarn generate", "prepublishOnly": "yarn build", diff --git a/src/graphql/badgesForUser.ts b/src/graphql/badgesForUser.ts index 4537113..29ca5f0 100644 --- a/src/graphql/badgesForUser.ts +++ b/src/graphql/badgesForUser.ts @@ -8,7 +8,7 @@ export type UserBadges = { imageUrl?: string | null | undefined; questChain?: { address: string | null | undefined; - } + }; }[]; chainId: string; }; From 897e0d1cb41ed51528074b0c91d07b92947c379e Mon Sep 17 00:00:00 2001 From: dan13ram Date: Wed, 1 Feb 2023 00:53:11 +0530 Subject: [PATCH 6/6] minor fix --- src/client.ts | 133 ++++++++++++++++++++++++++---------------- src/graphql/client.ts | 41 ++----------- src/networks.ts | 33 +++++++++++ 3 files changed, 120 insertions(+), 87 deletions(-) create mode 100644 src/networks.ts diff --git a/src/client.ts b/src/client.ts index 1406cfb..9148206 100644 --- a/src/client.ts +++ b/src/client.ts @@ -2,11 +2,11 @@ import { providers, utils } from 'ethers'; import { contracts } from '.'; import { QuestChainCommons } from './contracts/v1/contracts/QuestChain'; import { - getChainInfo, getQuestChainInfo, GlobalInfoFragment, isSupportedNetwork, QuestChainInfoFragment, + NetworkId, } from './graphql'; import { waitUntilSubgraphIndexed } from './helpers'; import EventEmitter from 'events'; @@ -19,11 +19,11 @@ export enum QuestChainRole { } export class QuestChainsClient extends EventEmitter { - private chainId: string; + private chainId: NetworkId; private provider: providers.Web3Provider; - private globalInfo: GlobalInfoFragment | null = null; + private globalInfo: Record | null = null; - constructor(chainId: string, provider: providers.Web3Provider) { + constructor(chainId: NetworkId, provider: providers.Web3Provider) { if (!isSupportedNetwork(chainId)) { throw new Error('Unsupported network'); } @@ -32,16 +32,14 @@ export class QuestChainsClient extends EventEmitter { this.provider = provider; } - getChainId(): string { + getNetworkId(): string { return this.chainId; } - async getGlobalInfo(): Promise { - if (this.globalInfo) { - return this.globalInfo; - } + async getGlobalInfo(): Promise> { + if (this.globalInfo) return this.globalInfo; - this.globalInfo = await getChainInfo(this.chainId); + this.globalInfo = await this.getGlobalInfo(); if (!this.globalInfo) { throw new Error('Could not get global info'); @@ -49,21 +47,32 @@ export class QuestChainsClient extends EventEmitter { return this.globalInfo; } - async getQuestChain(chainAddress: string): Promise { + async getChainInfo(chainId = this.chainId): Promise { + const globalInfo = await this.getGlobalInfo(); + if (globalInfo && globalInfo[chainId]) { + return globalInfo[chainId]; + } + throw new Error('Could not get chain info'); + } + + async getQuestChain(chainAddress: string, chainId = this.chainId): Promise { if (!utils.isAddress(chainAddress)) { throw new Error('Invalid quest chain address'); } - return getQuestChainInfo(this.chainId, chainAddress); + return getQuestChainInfo(chainId, chainAddress); } - private async handleTx(tx: providers.TransactionResponse): Promise { + private async handleTx( + tx: providers.TransactionResponse, + chainId = this.chainId, + ): Promise { this.emit('txResponse', tx); const receipt = await tx.wait(); this.emit('txReceipt', receipt); - const indexed = await waitUntilSubgraphIndexed(this.chainId, receipt.blockNumber); + const indexed = await waitUntilSubgraphIndexed(chainId, receipt.blockNumber); this.emit('txIndexed', indexed); return receipt; @@ -72,12 +81,14 @@ export class QuestChainsClient extends EventEmitter { async createQuestChain( chainInfo: QuestChainCommons.QuestChainInfoStruct, upgrade = false, + chainId = this.chainId, + provider = this.provider, ): Promise { - const { factoryAddress } = await this.getGlobalInfo(); + const { factoryAddress } = await this.getChainInfo(chainId); const factoryContract: contracts.V1.QuestChainFactory = contracts.V1.QuestChainFactory__factory.connect( factoryAddress, - this.provider.getSigner(), + provider.getSigner(), ); let tx: providers.TransactionResponse; @@ -86,25 +97,29 @@ export class QuestChainsClient extends EventEmitter { } else { tx = await factoryContract.create(chainInfo, utils.randomBytes(32)); } - const receipt = await this.handleTx(tx); + const receipt = await this.handleTx(tx, chainId); return receipt; } - async upgradeQuestChain(questChain: QuestChainInfoFragment): Promise { + async upgradeQuestChain( + questChain: QuestChainInfoFragment, + chainId = this.chainId, + provider = this.provider, + ): Promise { if (questChain.premium) { throw new Error('Quest chain is already upgraded'); } - const { factoryAddress } = await this.getGlobalInfo(); + const { factoryAddress } = await this.getChainInfo(chainId); const factoryContract: contracts.V1.QuestChainFactory = contracts.V1.QuestChainFactory__factory.connect( factoryAddress, - this.provider.getSigner(), + provider.getSigner(), ); const tx: providers.TransactionResponse = await factoryContract.upgradeQuestChain(questChain.address); - const receipt = await this.handleTx(tx); + const receipt = await this.handleTx(tx, chainId); return receipt; } @@ -113,15 +128,17 @@ export class QuestChainsClient extends EventEmitter { questChain: QuestChainInfoFragment, userAddress: string, roleHash: QuestChainRole, + chainId = this.chainId, + provider = this.provider, ): Promise { // role management is the same on all versions const chainContract: contracts.V1.QuestChain = contracts.V1.QuestChain__factory.connect( questChain.address, - this.provider.getSigner(), + provider.getSigner(), ); const tx: providers.TransactionResponse = await chainContract.grantRole(roleHash, userAddress); - const receipt = await this.handleTx(tx); + const receipt = await this.handleTx(tx, chainId); return receipt; } @@ -130,47 +147,57 @@ export class QuestChainsClient extends EventEmitter { questChain: QuestChainInfoFragment, userAddress: string, roleHash: QuestChainRole, + chainId = this.chainId, + provider = this.provider, ): Promise { // role management is the same on all versions const chainContract: contracts.V1.QuestChain = contracts.V1.QuestChain__factory.connect( questChain.address, - this.provider.getSigner(), + provider.getSigner(), ); const tx: providers.TransactionResponse = await chainContract.revokeRole(roleHash, userAddress); - const receipt = await this.handleTx(tx); + const receipt = await this.handleTx(tx, chainId); return receipt; } - async pauseQuestChain(questChain: QuestChainInfoFragment): Promise { + async pauseQuestChain( + questChain: QuestChainInfoFragment, + chainId = this.chainId, + provider = this.provider, + ): Promise { if (questChain.paused) { throw new Error('Quest chain is already paused'); } // pausing is the same on all versions const chainContract: contracts.V1.QuestChain = contracts.V1.QuestChain__factory.connect( questChain.address, - this.provider.getSigner(), + provider.getSigner(), ); const tx: providers.TransactionResponse = await chainContract.pause(); - const receipt = await this.handleTx(tx); + const receipt = await this.handleTx(tx, chainId); return receipt; } - async unpauseQuestChain(questChain: QuestChainInfoFragment): Promise { + async unpauseQuestChain( + questChain: QuestChainInfoFragment, + chainId = this.chainId, + provider = this.provider, + ): Promise { if (questChain.paused) { throw new Error('Quest chain is already paused'); } // pausing is the same on all versions const chainContract: contracts.V1.QuestChain = contracts.V1.QuestChain__factory.connect( questChain.address, - this.provider.getSigner(), + provider.getSigner(), ); const tx: providers.TransactionResponse = await chainContract.unpause(); - const receipt = await this.handleTx(tx); + const receipt = await this.handleTx(tx, chainId); return receipt; } @@ -178,6 +205,8 @@ export class QuestChainsClient extends EventEmitter { async addQuests( questChain: QuestChainInfoFragment, questDetailsList: string[], + chainId = this.chainId, + provider = this.provider, ): Promise { if (questChain.paused) { throw new Error('Quest chain is already paused'); @@ -189,24 +218,24 @@ export class QuestChainsClient extends EventEmitter { throw new Error('Adding multiple quests not supported on this quest chain version'); } + let tx: providers.TransactionResponse; if (questChain.version === '0') { const chainContract: contracts.V0.QuestChain = contracts.V0.QuestChain__factory.connect( questChain.address, - this.provider.getSigner(), + provider.getSigner(), ); - const tx: providers.TransactionResponse = await chainContract.createQuest(questDetailsList[0]); - const receipt = await this.handleTx(tx); + tx = await chainContract.createQuest(questDetailsList[0]); + } else { + const chainContract: contracts.V1.QuestChain = contracts.V1.QuestChain__factory.connect( + questChain.address, + provider.getSigner(), + ); - return receipt; + tx = await chainContract.createQuests(questDetailsList); } - const chainContract: contracts.V1.QuestChain = contracts.V1.QuestChain__factory.connect( - questChain.address, - this.provider.getSigner(), - ); - const tx: providers.TransactionResponse = await chainContract.createQuests(questDetailsList); - const receipt = await this.handleTx(tx); + const receipt = await this.handleTx(tx, chainId); return receipt; } @@ -215,6 +244,8 @@ export class QuestChainsClient extends EventEmitter { questChain: QuestChainInfoFragment, questIdList: string[], questDetailsList: string[], + chainId = this.chainId, + provider = this.provider, ): Promise { if (questChain.paused) { throw new Error('Quest chain is already paused'); @@ -229,24 +260,24 @@ export class QuestChainsClient extends EventEmitter { throw new Error('Editing multiple quests not supported on this quest chain version'); } + let tx: providers.TransactionResponse; if (questChain.version === '0') { const chainContract: contracts.V0.QuestChain = contracts.V0.QuestChain__factory.connect( questChain.address, - this.provider.getSigner(), + provider.getSigner(), ); - const tx: providers.TransactionResponse = await chainContract.editQuest(questIdList[0], questDetailsList[0]); - const receipt = await this.handleTx(tx); + tx = await chainContract.editQuest(questIdList[0], questDetailsList[0]); + } else { + const chainContract: contracts.V1.QuestChain = contracts.V1.QuestChain__factory.connect( + questChain.address, + provider.getSigner(), + ); - return receipt; + tx = await chainContract.editQuests(questIdList, questDetailsList); } - const chainContract: contracts.V1.QuestChain = contracts.V1.QuestChain__factory.connect( - questChain.address, - this.provider.getSigner(), - ); - const tx: providers.TransactionResponse = await chainContract.editQuests(questIdList, questDetailsList); - const receipt = await this.handleTx(tx); + const receipt = await this.handleTx(tx, chainId); return receipt; } diff --git a/src/graphql/client.ts b/src/graphql/client.ts index 220ec07..726a565 100644 --- a/src/graphql/client.ts +++ b/src/graphql/client.ts @@ -1,41 +1,10 @@ import { Client, createClient, dedupExchange, fetchExchange } from 'urql'; -export type NetworkInfo = { - [chainId: string]: { - chainId: string; - subgraphName: string; - subgraphUrl: string; - }; -}; - -export const SUPPORTED_NETWORK_INFO: NetworkInfo = { - '0x89': { - chainId: '0x89', - subgraphName: 'dan13ram/quest-chains-polygon', - subgraphUrl: 'https://api.thegraph.com/subgraphs/name/dan13ram/quest-chains-polygon', - }, - '0x64': { - chainId: '0x64', - subgraphName: 'dan13ram/quest-chains-xdai', - subgraphUrl: 'https://api.thegraph.com/subgraphs/name/dan13ram/quest-chains-xdai', - }, - '0x5': { - chainId: '0x5', - subgraphName: 'dan13ram/quest-chains-goerli', - subgraphUrl: 'https://api.thegraph.com/subgraphs/name/dan13ram/quest-chains-goerli', - }, - '0x13881': { - chainId: '0x13881', - subgraphName: 'dan13ram/quest-chains-mumbai', - subgraphUrl: 'https://api.thegraph.com/subgraphs/name/dan13ram/quest-chains-mumbai', - }, -}; - -export const SUPPORTED_NETWORKS = Object.keys(SUPPORTED_NETWORK_INFO); +import { NetworkIds, NetworkInfo } from '../networks'; -const clients: Record = Object.values(SUPPORTED_NETWORK_INFO).reduce>( - (o, info) => { - o[info.chainId] = createClient({ +const clients: Record = Object.entries(NetworkInfo).reduce>( + (o, [chainId, info]) => { + o[chainId] = createClient({ url: info.subgraphUrl, exchanges: [dedupExchange, fetchExchange], }); @@ -45,7 +14,7 @@ const clients: Record = Object.values(SUPPORTED_NETWORK_INFO).re ); export const isSupportedNetwork = (chainId: string | undefined | null) => - chainId ? SUPPORTED_NETWORKS.includes(chainId) : false; + chainId ? NetworkIds.includes(chainId) : false; export const getClient = (chainId: string | undefined | null): Client => { if (!chainId || !isSupportedNetwork(chainId)) { diff --git a/src/networks.ts b/src/networks.ts new file mode 100644 index 0000000..c8089fb --- /dev/null +++ b/src/networks.ts @@ -0,0 +1,33 @@ +export const Networks: Record = { + POLYGON: '0x89', + GNOSIS_CHAIN: '0x64', + GOERLI: '0x5', + MUMBAI: '0x13881', +}; + +export type Values = T[keyof T]; + +export type Network = keyof typeof Networks; + +export type NetworkId = Values; + +export const NetworkInfo: Record = { + [Networks.POLYGON]: { + subgraphName: 'dan13ram/quest-chains-polygon', + subgraphUrl: 'https://api.thegraph.com/subgraphs/name/dan13ram/quest-chains-polygon', + }, + [Networks.GNOSIS_CHAIN]: { + subgraphName: 'dan13ram/quest-chains-xdai', + subgraphUrl: 'https://api.thegraph.com/subgraphs/name/dan13ram/quest-chains-xdai', + }, + [Networks.GOERLI]: { + subgraphName: 'dan13ram/quest-chains-goerli', + subgraphUrl: 'https://api.thegraph.com/subgraphs/name/dan13ram/quest-chains-goerli', + }, + [Networks.MUMBAI]: { + subgraphName: 'dan13ram/quest-chains-mumbai', + subgraphUrl: 'https://api.thegraph.com/subgraphs/name/dan13ram/quest-chains-mumbai', + }, +}; + +export const NetworkIds: Array = Object.values(Networks);