Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

support getIndexerWithOption() #159

Closed
wants to merge 1 commit into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
38 changes: 36 additions & 2 deletions .eslintrc
Original file line number Diff line number Diff line change
@@ -1,12 +1,14 @@
{
"parser": "@typescript-eslint/parser",
"parserOptions": {
"project": "tsconfig.json",
"sourceType": "module"
},
"plugins": ["@typescript-eslint/eslint-plugin", "header"],
"plugins": ["@typescript-eslint", "header", "import", "sort-destructure-keys"],
"extends": [
"eslint:recommended",
"plugin:@typescript-eslint/recommended"
"plugin:@typescript-eslint/recommended",
"plugin:@typescript-eslint/recommended-requiring-type-checking"
],
"root": true,
"env": {
Expand All @@ -17,9 +19,41 @@
"ignorePatterns": ["**/packages/**/dist/**", "/test/jest-setup.ts"],
"rules": {
"@typescript-eslint/interface-name-prefix": "off",
"@typescript-eslint/restrict-template-expressions": "off",
"@typescript-eslint/explicit-function-return-type": "off",
"@typescript-eslint/explicit-module-boundary-types": "off",
"@typescript-eslint/no-explicit-any": "off",
"@typescript-eslint/ban-ts-comment": "off",
"@typescript-eslint/explicit-member-accessibility": [
"error",
{
"accessibility": "no-public"
}
],
"@typescript-eslint/no-unsafe-argument": "off",
"@typescript-eslint/no-unsafe-assignment": "off",
"@typescript-eslint/no-unsafe-call": "off",
"@typescript-eslint/no-unsafe-member-access": "off",
"@typescript-eslint/no-unsafe-return": "off",
"complexity": [
"error", 20],
"curly": [
"error", "multi-line"
],
"default-case": "error",
"eqeqeq": [
"error", "always"
],
"import/no-extraneous-dependencies": "off",
"import/order": [
"error",
{
"alphabetize": {
"order": "asc" /* sort in ascending order. Options: ['ignore', 'asc', 'desc'] */,
"caseInsensitive": true /* ignore case. Options: [true, false] */
}
}
],
"header/header": [2, "line", [
{
"pattern": " Copyright \\d{4}(-\\d{4})? SubQuery Pte Ltd authors & contributors",
Expand Down
4 changes: 4 additions & 0 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -25,8 +25,12 @@
"ctix": "^1.5.4",
"dotenv": "^16.0.3",
"eslint": "^8.17.0",
"eslint-config-prettier": "^8.3.0",
"eslint-import-resolver-typescript": "^2.5.0",
"eslint-plugin-header": "^3.1.1",
"eslint-plugin-import": "^2.25.4",
"eslint-plugin-prettier": "^4.0.0",
"eslint-plugin-sort-destructure-keys": "^1.4.0",
"flag": "^5.0.1",
"graphql": "^16.5.0",
"graphql-language-service-server": "^2.8.9",
Expand Down
76 changes: 59 additions & 17 deletions packages/network-clients/src/clients/networkClient.ts
Original file line number Diff line number Diff line change
@@ -1,25 +1,28 @@
// Copyright 2020-2022 SubQuery Pte Ltd authors & contributors
// SPDX-License-Identifier: Apache-2.0

import { ContractSDK } from '@subql/contract-sdk';
import assert from 'assert';
import { ApolloClient, ApolloClientOptions, NormalizedCacheObject } from '@apollo/client/core';
import type { Provider as AbstractProvider } from '@ethersproject/abstract-provider';
import { Signer, providers } from 'ethers';
import { BigNumber } from '@ethersproject/bignumber';
import { ContractSDK } from '@subql/contract-sdk';
import { DEFAULT_IPFS_URL, NETWORK_CONFIGS, SQNetworks } from '@subql/network-config';
import { providers, Signer } from 'ethers';

import { Indexer, IndexerDetail, IndexerWithController, IndexerWithMetadata } from '../models';
import { bytes32ToCid, isCID, min } from '../utils';
import { parseRawEraValue } from '../utils/parseEraValue';
import { ContractClient } from './contractClient';
import { IPFSClient } from './ipfsClient';
import { GraphqlQueryClient } from './queryClient';

import { isCID, min } from '../utils';
import { DEFAULT_IPFS_URL, NETWORK_CONFIGS } from '@subql/network-config';
import assert from 'assert';
import { Indexer } from '../models/indexer';
import { parseRawEraValue } from '../utils/parseEraValue';
import { SQNetworks } from '@subql/network-config';
import { ApolloClient, ApolloClientOptions, NormalizedCacheObject } from '@apollo/client/core';

type Provider = AbstractProvider | Signer;

type GetIndexerOption = {
withMetadata: boolean;
withController: boolean;
};

export class NetworkClient {
private _contractClient: ContractClient;
private _ipfs: IPFSClient;
Expand All @@ -29,7 +32,7 @@ export class NetworkClient {
this._contractClient = new ContractClient(_sdk);
}

public static create(
static create(
network: SQNetworks,
provider?: Provider,
ipfsUrl?: string,
Expand All @@ -49,7 +52,45 @@ export class NetworkClient {
return new NetworkClient(sdk, gqlClient, ipfsUrl);
}

public async getIndexer(address: string): Promise<Indexer | undefined> {
async getIndexerWithOption<T extends GetIndexerOption>(
address: string,
{ withMetadata, withController }: T
): Promise<
T['withMetadata'] extends true
? T['withController'] extends true
? IndexerWithMetadata & IndexerWithController
: IndexerWithMetadata
: Indexer
> {
const metadataCidBytes = await this._sdk.indexerRegistry.metadata(address);

const indexer = {
address,
metadataCid: bytes32ToCid(metadataCidBytes),
};
const promises = [];
if (withMetadata) {
promises.push(
this._ipfs
.getJSON<{
name: string;
url: string;
}>(indexer.metadataCid)
.then((metadata) => ((indexer as IndexerWithMetadata).metadata = metadata))
);
}
if (withController) {
promises.push(
this._sdk.indexerRegistry
.getController(address)
.then((controller) => ((indexer as IndexerWithController).controller = controller))
);
}
await Promise.all(promises);
return indexer as any;
}

async getIndexer(address: string): Promise<IndexerDetail | undefined> {
const currentEra = await this._sdk.eraManager.eraNumber();
const leverageLimit = await this._sdk.staking.indexerLeverageLimit();

Expand Down Expand Up @@ -101,14 +142,14 @@ export class NetworkClient {
};
}

public async maxUnstakeAmount(address: string): Promise<BigNumber> {
async maxUnstakeAmount(address: string): Promise<BigNumber> {
const leverageLimit = await this._sdk.staking.indexerLeverageLimit();
const minStakingAmount = await this._sdk.indexerRegistry.minimumStakingAmount();
const indexer = await this.getIndexer(address);

if (!indexer) return BigNumber.from(0);

const { totalStake, ownStake } = await indexer;
const { totalStake, ownStake } = indexer;

const totalStakingAmountAfter = BigNumber.from(totalStake?.after ?? 0);
const ownStakeAfter = BigNumber.from(ownStake?.after ?? 0);
Expand All @@ -123,7 +164,7 @@ export class NetworkClient {
return maxUnstakeAmount.isNegative() ? BigNumber.from(0) : maxUnstakeAmount;
}

public async getDelegating(address: string): Promise<BigNumber> {
async getDelegating(address: string): Promise<BigNumber> {
const currentEra = await this._sdk.eraManager.eraNumber();
const ownDelegation = await this._gqlClient.getDelegation(address, address);
const delegator = await this._gqlClient.getDelegator(address);
Expand All @@ -141,13 +182,14 @@ export class NetworkClient {
return sortedTotalDelegations.sub(sortedOwnStake);
}

public async projectMetadata(cid: string) {
// eslint-disable-next-line @typescript-eslint/require-await
async projectMetadata(cid: string) {
if (!isCID(cid)) throw new Error(`Invalid cid: ${cid}`);
// get project metadata
// cat project metadata
}

public setGqlClient(gqlClient: GraphqlQueryClient) {
setGqlClient(gqlClient: GraphqlQueryClient) {
this._gqlClient = gqlClient;
}
}
13 changes: 12 additions & 1 deletion packages/network-clients/src/models/indexer.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@

import { CurrentEraValue } from './eraValue';

export interface Indexer {
export interface IndexerDetail {
metadata?: IndexerMetadata;
address: string;
controller: string | null;
Expand All @@ -14,6 +14,17 @@ export interface Indexer {
capacity: CurrentEraValue;
}

export interface Indexer {
address: string;
metadataCid: string;
}
export interface IndexerWithMetadata extends Indexer {
metadata: IndexerMetadata;
}
export interface IndexerWithController extends Indexer {
controller: string;
}

export type IndexerMetadata = {
name: string;
image?: string;
Expand Down
Loading
Loading