From 6e7290cdf47fec097b3e1d4ad8d2dee3e59798ca Mon Sep 17 00:00:00 2001 From: Marc-Aurele Besner <82244926+marc-aurele-besner@users.noreply.github.com> Date: Wed, 24 Apr 2024 13:05:59 -0400 Subject: [PATCH 1/8] add UnlockFunds and UnlockOperator to Actions Modal&Dropdown --- .../components/Operator/ActionsDropdown.tsx | 7 +- .../src/components/Operator/ActionsModal.tsx | 85 +++++++++++++++++-- 2 files changed, 84 insertions(+), 8 deletions(-) diff --git a/explorer/src/components/Operator/ActionsDropdown.tsx b/explorer/src/components/Operator/ActionsDropdown.tsx index 8e00ec3a6..6cece1740 100644 --- a/explorer/src/components/Operator/ActionsDropdown.tsx +++ b/explorer/src/components/Operator/ActionsDropdown.tsx @@ -3,7 +3,7 @@ import { Listbox, Transition } from '@headlessui/react' import { ChevronDownIcon } from '@heroicons/react/20/solid' import { FC, Fragment, useMemo } from 'react' -import { OperatorAction, OperatorActionType } from './ActionsModal' +import { ActionsInRed, OperatorAction, OperatorActionType } from './ActionsModal' export type ActionsDropdownRow = { original: { @@ -84,8 +84,9 @@ export const ActionsDropdown: FC = ({ {({ selected }) => ( {OperatorActionType[actionType as keyof typeof OperatorActionType]} diff --git a/explorer/src/components/Operator/ActionsModal.tsx b/explorer/src/components/Operator/ActionsModal.tsx index 58d22b176..40aa345ef 100644 --- a/explorer/src/components/Operator/ActionsModal.tsx +++ b/explorer/src/components/Operator/ActionsModal.tsx @@ -13,7 +13,14 @@ export enum OperatorActionType { AddFunds = 'Add Funds', Withdraw = 'Withdraw', Deregister = 'Deregister', + UnlockFunds = 'Unlock Funds', + UnlockOperator = 'Unlock Operator', } +export const ActionsInRed = [ + OperatorActionType.Deregister, + OperatorActionType.UnlockFunds, + OperatorActionType.UnlockOperator, +] export type OperatorAction = { type: OperatorActionType @@ -188,6 +195,46 @@ export const ActionsModal: FC = ({ isOpen, action, onClose }) => { } }, [actingAccount, action.operatorId, api, injector, handleClose, selectedChain]) + const handleUnlockFunds = useCallback(async () => { + if (!api || !actingAccount || !injector || !api[selectedChain.urls.page]) + return setFormError('We are not able to connect to the blockchain') + + try { + const block = await api[selectedChain.urls.page].rpc.chain.getBlock() + const hash = await api[selectedChain.urls.page].tx.domains + .unlockFunds(action.operatorId) + .signAndSend(actingAccount.address, { signer: injector.signer }) + + console.log('block', block) + console.log('hash', hash) + + handleClose() + } catch (error) { + setFormError('There was an error while de-registering the operator') + console.error('Error', error) + } + }, [actingAccount, action.operatorId, api, injector, handleClose, selectedChain]) + + const handleUnlockOperator = useCallback(async () => { + if (!api || !actingAccount || !injector || !api[selectedChain.urls.page]) + return setFormError('We are not able to connect to the blockchain') + + try { + const block = await api[selectedChain.urls.page].rpc.chain.getBlock() + const hash = await api[selectedChain.urls.page].tx.domains + .unlockOperator(action.operatorId) + .signAndSend(actingAccount.address, { signer: injector.signer }) + + console.log('block', block) + console.log('hash', hash) + + handleClose() + } catch (error) { + setFormError('There was an error while de-registering the operator') + console.error('Error', error) + } + }, [actingAccount, action.operatorId, api, injector, handleClose, selectedChain]) + const ErrorPlaceholder = useMemo( () => formError ? ( @@ -305,19 +352,47 @@ export const ActionsModal: FC = ({ isOpen, action, onClose }) => { ) + case OperatorActionType.UnlockFunds: + case OperatorActionType.UnlockOperator: + return ( +
+ + Do you really want to{' '} + {OperatorActionType[action.type as keyof typeof OperatorActionType] === + OperatorActionType.UnlockFunds + ? 'unlock the funds in your nomination' + : 'unlock the funds in your operator'}{' '} + ? + + {ErrorPlaceholder} + +
+ ) default: return null } }, [ - ErrorPlaceholder, - actingAccount, action.type, - maxAmountToAdd, + initialValues, fundsFormValidationSchema, - handleAddFunds, + ErrorPlaceholder, handleDeregister, + handleUnlockFunds, + handleUnlockOperator, + handleAddFunds, handleWithdraw, - initialValues, + maxAmountToAdd, + actingAccount, maxAmount, ]) From 070ce8a1a5fdd4b9835ca100dc85ece21752eeff Mon Sep 17 00:00:00 2001 From: Marc-Aurele Besner <82244926+marc-aurele-besner@users.noreply.github.com> Date: Wed, 24 Apr 2024 13:06:20 -0400 Subject: [PATCH 2/8] fix operator status for mobile card --- .../src/components/Operator/OperatorsListCard.tsx | 13 ++++++++++++- 1 file changed, 12 insertions(+), 1 deletion(-) diff --git a/explorer/src/components/Operator/OperatorsListCard.tsx b/explorer/src/components/Operator/OperatorsListCard.tsx index d0509f13e..33d86cc6a 100644 --- a/explorer/src/components/Operator/OperatorsListCard.tsx +++ b/explorer/src/components/Operator/OperatorsListCard.tsx @@ -1,12 +1,15 @@ import { bigNumberToNumber, numberWithCommas } from '@/utils/number' import { shortString } from '@/utils/string' import { MobileCard, Row } from 'components/common/MobileCard' +import { Chains } from 'constants/' import { INTERNAL_ROUTES } from 'constants/routes' import { OperatorsConnectionQuery } from 'gql/graphql' import useDomains from 'hooks/useDomains' import useWallet from 'hooks/useWallet' import Link from 'next/link' import { FC, useMemo } from 'react' +import { operatorStatus } from 'utils/operator' +import { capitalizeFirstLetter } from 'utils/string' import { ActionsDropdown } from './ActionsDropdown' import { OperatorAction, OperatorActionType } from './ActionsModal' @@ -41,7 +44,14 @@ export const OperatorsListCard: FC = ({ { name: 'Nominator Tax', value: `${operator.nominationTax}%` }, { name: 'Total Stake', value: `${bigNumberToNumber(operator.currentTotalStake)} tSSC` }, { name: 'Total Shares', value: numberWithCommas(operator.totalShares) }, - { name: 'Status', value: operator.status ? operator.status : 'unknown' }, + { + name: 'Status', + value: operator.status + ? selectedChain.urls.page === Chains.gemini3g + ? operator.status + : capitalizeFirstLetter(operatorStatus(operator.status)) + : 'unknown', + }, ] if (actingAccount) rows.push({ @@ -77,6 +87,7 @@ export const OperatorsListCard: FC = ({ operator.signingKey, operator.status, operator.totalShares, + selectedChain.urls.page, ]) return ( From 91462ead10fa450b4224c8956c77c11a09fae162 Mon Sep 17 00:00:00 2001 From: Marc-Aurele Besner <82244926+marc-aurele-besner@users.noreply.github.com> Date: Wed, 24 Apr 2024 13:06:49 -0400 Subject: [PATCH 3/8] improve excludeActions to hide non-relevant actions --- .../components/Operator/NominationManagement.tsx | 3 ++- .../src/components/Operator/NominatorsList.tsx | 9 +++++++-- .../components/Operator/OperatorManagement.tsx | 2 ++ .../src/components/Operator/OperatorsList.tsx | 15 ++++++++++++--- 4 files changed, 23 insertions(+), 6 deletions(-) diff --git a/explorer/src/components/Operator/NominationManagement.tsx b/explorer/src/components/Operator/NominationManagement.tsx index 20225b624..ed42d607f 100644 --- a/explorer/src/components/Operator/NominationManagement.tsx +++ b/explorer/src/components/Operator/NominationManagement.tsx @@ -217,7 +217,7 @@ export const NominationManagement: FC = () => { }, } as ActionsDropdownRow } - excludeActions={[OperatorActionType.Deregister]} + excludeActions={[OperatorActionType.Deregister, OperatorActionType.UnlockOperator]} nominatorMaxStake={( (BigInt(row.original.operator.currentTotalStake) * BigInt(row.original.shares)) / BigInt(row.original.operator.totalShares) @@ -424,6 +424,7 @@ const MobileComponent: FC = ({ nominators, action, handleA index={index} nominator={nominator} action={action} + excludeActions={[OperatorActionType.Deregister, OperatorActionType.UnlockOperator]} handleAction={handleAction} key={`nominator-list-card-${nominator.id}`} /> diff --git a/explorer/src/components/Operator/NominatorsList.tsx b/explorer/src/components/Operator/NominatorsList.tsx index 91759ec7e..07c1ffb33 100644 --- a/explorer/src/components/Operator/NominatorsList.tsx +++ b/explorer/src/components/Operator/NominatorsList.tsx @@ -220,7 +220,7 @@ export const NominatorsList: FC = () => { }, } as ActionsDropdownRow } - excludeActions={[OperatorActionType.Deregister]} + excludeActions={[OperatorActionType.Deregister, OperatorActionType.UnlockOperator]} nominatorMaxStake={( (BigInt(row.original.operator.currentTotalStake) * BigInt(row.original.shares)) / BigInt(row.original.operator.totalShares) @@ -341,7 +341,12 @@ const MobileComponent: FC = ({ nominators, action, handleA action={action} handleAction={handleAction} index={index} - excludeActions={[OperatorActionType.Deregister]} + excludeActions={[ + OperatorActionType.Deregister, + OperatorActionType.Withdraw, + OperatorActionType.UnlockFunds, + OperatorActionType.UnlockOperator, + ]} nominatorMaxStake={ nominator && ( diff --git a/explorer/src/components/Operator/OperatorManagement.tsx b/explorer/src/components/Operator/OperatorManagement.tsx index 51a696197..804b1e79e 100644 --- a/explorer/src/components/Operator/OperatorManagement.tsx +++ b/explorer/src/components/Operator/OperatorManagement.tsx @@ -161,6 +161,7 @@ export const OperatorManagement: FC = () => { action={action} handleAction={handleAction} row={row as ActionsDropdownRow} + excludeActions={[OperatorActionType.UnlockFunds]} /> ), }, @@ -456,6 +457,7 @@ const MobileComponent: FC = ({ operators, action, handleAc index={index} operator={operator} action={action} + excludeActions={[OperatorActionType.UnlockFunds]} handleAction={handleAction} key={`operator-list-card-${operator.id}`} /> diff --git a/explorer/src/components/Operator/OperatorsList.tsx b/explorer/src/components/Operator/OperatorsList.tsx index 5cb1f4e5f..0932ddf4d 100644 --- a/explorer/src/components/Operator/OperatorsList.tsx +++ b/explorer/src/components/Operator/OperatorsList.tsx @@ -183,7 +183,11 @@ export const OperatorsList: FC = () => { excludeActions={ nominator ? [OperatorActionType.Deregister] - : [OperatorActionType.Deregister, OperatorActionType.Withdraw] + : [ + OperatorActionType.Deregister, + OperatorActionType.Withdraw, + OperatorActionType.UnlockFunds, + ] } nominatorMaxStake={ nominator && @@ -325,8 +329,13 @@ const MobileComponent: FC = ({ index={index} excludeActions={ nominator - ? [OperatorActionType.Deregister] - : [OperatorActionType.Deregister, OperatorActionType.Withdraw] + ? [OperatorActionType.Deregister, OperatorActionType.UnlockOperator] + : [ + OperatorActionType.Deregister, + OperatorActionType.Withdraw, + OperatorActionType.UnlockFunds, + OperatorActionType.UnlockOperator, + ] } nominatorMaxStake={ nominator && From 8f4408359de66462cf62accffe435367bfc9b79a Mon Sep 17 00:00:00 2001 From: Marc-Aurele Besner <82244926+marc-aurele-besner@users.noreply.github.com> Date: Thu, 25 Apr 2024 16:31:11 -0400 Subject: [PATCH 4/8] add last block to operators query --- explorer/gql/gql.ts | 4 ++-- explorer/gql/graphql.ts | 4 ++-- explorer/src/components/Operator/query.ts | 3 +++ 3 files changed, 7 insertions(+), 4 deletions(-) diff --git a/explorer/gql/gql.ts b/explorer/gql/gql.ts index aa064ffb8..680bc733d 100644 --- a/explorer/gql/gql.ts +++ b/explorer/gql/gql.ts @@ -42,7 +42,7 @@ const documents = { "\n query OperatorsConnectionRewards(\n $first: Int!\n $after: String\n $orderBy: [OperatorRewardsOrderByInput!]!\n $where: OperatorRewardsWhereInput\n ) {\n operatorRewardsConnection(orderBy: $orderBy, first: $first, after: $after, where: $where) {\n edges {\n cursor\n node {\n amount\n id\n updatedAt\n }\n }\n totalCount\n pageInfo {\n endCursor\n hasNextPage\n hasPreviousPage\n startCursor\n }\n }\n }\n": types.OperatorsConnectionRewardsDocument, "\n query LogsConnection($first: Int!, $after: String, $where: LogWhereInput) {\n logsConnection(orderBy: id_DESC, first: $first, after: $after, where: $where) {\n totalCount\n pageInfo {\n endCursor\n hasNextPage\n hasPreviousPage\n startCursor\n }\n edges {\n node {\n id\n kind\n value\n block {\n id\n height\n timestamp\n }\n }\n cursor\n }\n }\n logTypesQuery {\n result\n }\n }\n": types.LogsConnectionDocument, "\n query LogById($logId: String!) {\n logById(id: $logId) {\n id\n kind\n value\n block {\n id\n height\n timestamp\n events(limit: 10, orderBy: id_DESC) {\n id\n args\n name\n phase\n indexInBlock\n timestamp\n block {\n height\n hash\n }\n }\n }\n }\n }\n": types.LogByIdDocument, - "\n query OperatorsConnection(\n $first: Int!\n $after: String\n $orderBy: [OperatorOrderByInput!]!\n $where: OperatorWhereInput\n ) {\n operatorsConnection(orderBy: $orderBy, first: $first, after: $after, where: $where) {\n edges {\n node {\n id\n operatorOwner\n currentDomainId\n currentEpochRewards\n currentTotalStake\n minimumNominatorStake\n nextDomainId\n nominationTax\n signingKey\n status\n totalShares\n updatedAt\n nominators(limit: 256) {\n id\n shares\n }\n }\n }\n pageInfo {\n endCursor\n hasNextPage\n hasPreviousPage\n startCursor\n }\n totalCount\n }\n }\n": types.OperatorsConnectionDocument, + "\n query OperatorsConnection(\n $first: Int!\n $after: String\n $orderBy: [OperatorOrderByInput!]!\n $where: OperatorWhereInput\n ) {\n lastBlock: blocks(limit: 1, orderBy: height_DESC) {\n height\n }\n operatorsConnection(orderBy: $orderBy, first: $first, after: $after, where: $where) {\n edges {\n node {\n id\n operatorOwner\n currentDomainId\n currentEpochRewards\n currentTotalStake\n minimumNominatorStake\n nextDomainId\n nominationTax\n signingKey\n status\n totalShares\n updatedAt\n nominators(limit: 256) {\n id\n shares\n }\n }\n }\n pageInfo {\n endCursor\n hasNextPage\n hasPreviousPage\n startCursor\n }\n totalCount\n }\n }\n": types.OperatorsConnectionDocument, "\n query OperatorById($operatorId: String!) {\n operatorById(id: $operatorId) {\n id\n operatorOwner\n currentDomainId\n currentEpochRewards\n currentTotalStake\n minimumNominatorStake\n nextDomainId\n nominationTax\n signingKey\n status\n totalShares\n updatedAt\n nominators(limit: 300) {\n id\n shares\n account {\n id\n }\n }\n }\n }\n": types.OperatorByIdDocument, "\n query NominatorsConnection(\n $first: Int!\n $after: String\n $orderBy: [NominatorOrderByInput!]!\n $where: NominatorWhereInput\n ) {\n nominatorsConnection(orderBy: $orderBy, first: $first, after: $after, where: $where) {\n edges {\n node {\n id\n shares\n account {\n id\n }\n operator {\n id\n operatorOwner\n currentDomainId\n currentEpochRewards\n currentTotalStake\n minimumNominatorStake\n nextDomainId\n nominationTax\n signingKey\n status\n totalShares\n updatedAt\n }\n updatedAt\n }\n }\n pageInfo {\n endCursor\n hasNextPage\n hasPreviousPage\n startCursor\n }\n totalCount\n }\n }\n": types.NominatorsConnectionDocument, "\n query AccountsTopLeaderboard($first: Int!) {\n farmers: accountRewardsConnection(\n orderBy: amount_DESC\n first: $first\n where: { vote_gt: 0, vote_isNull: false, OR: { block_gt: 0, block_isNull: false } }\n ) {\n edges {\n cursor\n node {\n id\n }\n }\n }\n operators: operatorRewardsConnection(orderBy: amount_DESC, first: $first, where: {}) {\n edges {\n cursor\n node {\n amount\n id\n }\n }\n }\n nominators: accountRewardsConnection(\n orderBy: operator_DESC\n first: $first\n where: { operator_gt: 0, operator_isNull: false }\n ) {\n edges {\n cursor\n node {\n id\n }\n }\n }\n }\n": types.AccountsTopLeaderboardDocument, @@ -185,7 +185,7 @@ export function graphql(source: "\n query LogById($logId: String!) {\n logBy /** * The graphql function is used to parse GraphQL queries into a document that can be used by GraphQL clients. */ -export function graphql(source: "\n query OperatorsConnection(\n $first: Int!\n $after: String\n $orderBy: [OperatorOrderByInput!]!\n $where: OperatorWhereInput\n ) {\n operatorsConnection(orderBy: $orderBy, first: $first, after: $after, where: $where) {\n edges {\n node {\n id\n operatorOwner\n currentDomainId\n currentEpochRewards\n currentTotalStake\n minimumNominatorStake\n nextDomainId\n nominationTax\n signingKey\n status\n totalShares\n updatedAt\n nominators(limit: 256) {\n id\n shares\n }\n }\n }\n pageInfo {\n endCursor\n hasNextPage\n hasPreviousPage\n startCursor\n }\n totalCount\n }\n }\n"): (typeof documents)["\n query OperatorsConnection(\n $first: Int!\n $after: String\n $orderBy: [OperatorOrderByInput!]!\n $where: OperatorWhereInput\n ) {\n operatorsConnection(orderBy: $orderBy, first: $first, after: $after, where: $where) {\n edges {\n node {\n id\n operatorOwner\n currentDomainId\n currentEpochRewards\n currentTotalStake\n minimumNominatorStake\n nextDomainId\n nominationTax\n signingKey\n status\n totalShares\n updatedAt\n nominators(limit: 256) {\n id\n shares\n }\n }\n }\n pageInfo {\n endCursor\n hasNextPage\n hasPreviousPage\n startCursor\n }\n totalCount\n }\n }\n"]; +export function graphql(source: "\n query OperatorsConnection(\n $first: Int!\n $after: String\n $orderBy: [OperatorOrderByInput!]!\n $where: OperatorWhereInput\n ) {\n lastBlock: blocks(limit: 1, orderBy: height_DESC) {\n height\n }\n operatorsConnection(orderBy: $orderBy, first: $first, after: $after, where: $where) {\n edges {\n node {\n id\n operatorOwner\n currentDomainId\n currentEpochRewards\n currentTotalStake\n minimumNominatorStake\n nextDomainId\n nominationTax\n signingKey\n status\n totalShares\n updatedAt\n nominators(limit: 256) {\n id\n shares\n }\n }\n }\n pageInfo {\n endCursor\n hasNextPage\n hasPreviousPage\n startCursor\n }\n totalCount\n }\n }\n"): (typeof documents)["\n query OperatorsConnection(\n $first: Int!\n $after: String\n $orderBy: [OperatorOrderByInput!]!\n $where: OperatorWhereInput\n ) {\n lastBlock: blocks(limit: 1, orderBy: height_DESC) {\n height\n }\n operatorsConnection(orderBy: $orderBy, first: $first, after: $after, where: $where) {\n edges {\n node {\n id\n operatorOwner\n currentDomainId\n currentEpochRewards\n currentTotalStake\n minimumNominatorStake\n nextDomainId\n nominationTax\n signingKey\n status\n totalShares\n updatedAt\n nominators(limit: 256) {\n id\n shares\n }\n }\n }\n pageInfo {\n endCursor\n hasNextPage\n hasPreviousPage\n startCursor\n }\n totalCount\n }\n }\n"]; /** * The graphql function is used to parse GraphQL queries into a document that can be used by GraphQL clients. */ diff --git a/explorer/gql/graphql.ts b/explorer/gql/graphql.ts index bccad5a01..b12f2e75c 100644 --- a/explorer/gql/graphql.ts +++ b/explorer/gql/graphql.ts @@ -2778,7 +2778,7 @@ export type OperatorsConnectionQueryVariables = Exact<{ }>; -export type OperatorsConnectionQuery = { __typename?: 'Query', operatorsConnection: { __typename?: 'OperatorsConnection', totalCount: number, edges: Array<{ __typename?: 'OperatorEdge', node: { __typename?: 'Operator', id: string, operatorOwner?: string | null, currentDomainId?: number | null, currentEpochRewards?: any | null, currentTotalStake?: any | null, minimumNominatorStake?: any | null, nextDomainId?: number | null, nominationTax?: number | null, signingKey: string, status?: string | null, totalShares?: any | null, updatedAt?: any | null, nominators: Array<{ __typename?: 'Nominator', id: string, shares?: any | null }> } }>, pageInfo: { __typename?: 'PageInfo', endCursor: string, hasNextPage: boolean, hasPreviousPage: boolean, startCursor: string } } }; +export type OperatorsConnectionQuery = { __typename?: 'Query', lastBlock: Array<{ __typename?: 'Block', height: any }>, operatorsConnection: { __typename?: 'OperatorsConnection', totalCount: number, edges: Array<{ __typename?: 'OperatorEdge', node: { __typename?: 'Operator', id: string, operatorOwner?: string | null, currentDomainId?: number | null, currentEpochRewards?: any | null, currentTotalStake?: any | null, minimumNominatorStake?: any | null, nextDomainId?: number | null, nominationTax?: number | null, signingKey: string, status?: string | null, totalShares?: any | null, updatedAt?: any | null, nominators: Array<{ __typename?: 'Nominator', id: string, shares?: any | null }> } }>, pageInfo: { __typename?: 'PageInfo', endCursor: string, hasNextPage: boolean, hasPreviousPage: boolean, startCursor: string } } }; export type OperatorByIdQueryVariables = Exact<{ operatorId: Scalars['String']['input']; @@ -2870,7 +2870,7 @@ export const AccountsNominatorsConnectionRewardsDocument = {"kind":"Document","d export const OperatorsConnectionRewardsDocument = {"kind":"Document","definitions":[{"kind":"OperationDefinition","operation":"query","name":{"kind":"Name","value":"OperatorsConnectionRewards"},"variableDefinitions":[{"kind":"VariableDefinition","variable":{"kind":"Variable","name":{"kind":"Name","value":"first"}},"type":{"kind":"NonNullType","type":{"kind":"NamedType","name":{"kind":"Name","value":"Int"}}}},{"kind":"VariableDefinition","variable":{"kind":"Variable","name":{"kind":"Name","value":"after"}},"type":{"kind":"NamedType","name":{"kind":"Name","value":"String"}}},{"kind":"VariableDefinition","variable":{"kind":"Variable","name":{"kind":"Name","value":"orderBy"}},"type":{"kind":"NonNullType","type":{"kind":"ListType","type":{"kind":"NonNullType","type":{"kind":"NamedType","name":{"kind":"Name","value":"OperatorRewardsOrderByInput"}}}}}},{"kind":"VariableDefinition","variable":{"kind":"Variable","name":{"kind":"Name","value":"where"}},"type":{"kind":"NamedType","name":{"kind":"Name","value":"OperatorRewardsWhereInput"}}}],"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"operatorRewardsConnection"},"arguments":[{"kind":"Argument","name":{"kind":"Name","value":"orderBy"},"value":{"kind":"Variable","name":{"kind":"Name","value":"orderBy"}}},{"kind":"Argument","name":{"kind":"Name","value":"first"},"value":{"kind":"Variable","name":{"kind":"Name","value":"first"}}},{"kind":"Argument","name":{"kind":"Name","value":"after"},"value":{"kind":"Variable","name":{"kind":"Name","value":"after"}}},{"kind":"Argument","name":{"kind":"Name","value":"where"},"value":{"kind":"Variable","name":{"kind":"Name","value":"where"}}}],"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"edges"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"cursor"}},{"kind":"Field","name":{"kind":"Name","value":"node"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"amount"}},{"kind":"Field","name":{"kind":"Name","value":"id"}},{"kind":"Field","name":{"kind":"Name","value":"updatedAt"}}]}}]}},{"kind":"Field","name":{"kind":"Name","value":"totalCount"}},{"kind":"Field","name":{"kind":"Name","value":"pageInfo"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"endCursor"}},{"kind":"Field","name":{"kind":"Name","value":"hasNextPage"}},{"kind":"Field","name":{"kind":"Name","value":"hasPreviousPage"}},{"kind":"Field","name":{"kind":"Name","value":"startCursor"}}]}}]}}]}}]} as unknown as DocumentNode; export const LogsConnectionDocument = {"kind":"Document","definitions":[{"kind":"OperationDefinition","operation":"query","name":{"kind":"Name","value":"LogsConnection"},"variableDefinitions":[{"kind":"VariableDefinition","variable":{"kind":"Variable","name":{"kind":"Name","value":"first"}},"type":{"kind":"NonNullType","type":{"kind":"NamedType","name":{"kind":"Name","value":"Int"}}}},{"kind":"VariableDefinition","variable":{"kind":"Variable","name":{"kind":"Name","value":"after"}},"type":{"kind":"NamedType","name":{"kind":"Name","value":"String"}}},{"kind":"VariableDefinition","variable":{"kind":"Variable","name":{"kind":"Name","value":"where"}},"type":{"kind":"NamedType","name":{"kind":"Name","value":"LogWhereInput"}}}],"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"logsConnection"},"arguments":[{"kind":"Argument","name":{"kind":"Name","value":"orderBy"},"value":{"kind":"EnumValue","value":"id_DESC"}},{"kind":"Argument","name":{"kind":"Name","value":"first"},"value":{"kind":"Variable","name":{"kind":"Name","value":"first"}}},{"kind":"Argument","name":{"kind":"Name","value":"after"},"value":{"kind":"Variable","name":{"kind":"Name","value":"after"}}},{"kind":"Argument","name":{"kind":"Name","value":"where"},"value":{"kind":"Variable","name":{"kind":"Name","value":"where"}}}],"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"totalCount"}},{"kind":"Field","name":{"kind":"Name","value":"pageInfo"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"endCursor"}},{"kind":"Field","name":{"kind":"Name","value":"hasNextPage"}},{"kind":"Field","name":{"kind":"Name","value":"hasPreviousPage"}},{"kind":"Field","name":{"kind":"Name","value":"startCursor"}}]}},{"kind":"Field","name":{"kind":"Name","value":"edges"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"node"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"id"}},{"kind":"Field","name":{"kind":"Name","value":"kind"}},{"kind":"Field","name":{"kind":"Name","value":"value"}},{"kind":"Field","name":{"kind":"Name","value":"block"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"id"}},{"kind":"Field","name":{"kind":"Name","value":"height"}},{"kind":"Field","name":{"kind":"Name","value":"timestamp"}}]}}]}},{"kind":"Field","name":{"kind":"Name","value":"cursor"}}]}}]}},{"kind":"Field","name":{"kind":"Name","value":"logTypesQuery"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"result"}}]}}]}}]} as unknown as DocumentNode; export const LogByIdDocument = {"kind":"Document","definitions":[{"kind":"OperationDefinition","operation":"query","name":{"kind":"Name","value":"LogById"},"variableDefinitions":[{"kind":"VariableDefinition","variable":{"kind":"Variable","name":{"kind":"Name","value":"logId"}},"type":{"kind":"NonNullType","type":{"kind":"NamedType","name":{"kind":"Name","value":"String"}}}}],"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"logById"},"arguments":[{"kind":"Argument","name":{"kind":"Name","value":"id"},"value":{"kind":"Variable","name":{"kind":"Name","value":"logId"}}}],"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"id"}},{"kind":"Field","name":{"kind":"Name","value":"kind"}},{"kind":"Field","name":{"kind":"Name","value":"value"}},{"kind":"Field","name":{"kind":"Name","value":"block"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"id"}},{"kind":"Field","name":{"kind":"Name","value":"height"}},{"kind":"Field","name":{"kind":"Name","value":"timestamp"}},{"kind":"Field","name":{"kind":"Name","value":"events"},"arguments":[{"kind":"Argument","name":{"kind":"Name","value":"limit"},"value":{"kind":"IntValue","value":"10"}},{"kind":"Argument","name":{"kind":"Name","value":"orderBy"},"value":{"kind":"EnumValue","value":"id_DESC"}}],"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"id"}},{"kind":"Field","name":{"kind":"Name","value":"args"}},{"kind":"Field","name":{"kind":"Name","value":"name"}},{"kind":"Field","name":{"kind":"Name","value":"phase"}},{"kind":"Field","name":{"kind":"Name","value":"indexInBlock"}},{"kind":"Field","name":{"kind":"Name","value":"timestamp"}},{"kind":"Field","name":{"kind":"Name","value":"block"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"height"}},{"kind":"Field","name":{"kind":"Name","value":"hash"}}]}}]}}]}}]}}]}}]} as unknown as DocumentNode; -export const OperatorsConnectionDocument = {"kind":"Document","definitions":[{"kind":"OperationDefinition","operation":"query","name":{"kind":"Name","value":"OperatorsConnection"},"variableDefinitions":[{"kind":"VariableDefinition","variable":{"kind":"Variable","name":{"kind":"Name","value":"first"}},"type":{"kind":"NonNullType","type":{"kind":"NamedType","name":{"kind":"Name","value":"Int"}}}},{"kind":"VariableDefinition","variable":{"kind":"Variable","name":{"kind":"Name","value":"after"}},"type":{"kind":"NamedType","name":{"kind":"Name","value":"String"}}},{"kind":"VariableDefinition","variable":{"kind":"Variable","name":{"kind":"Name","value":"orderBy"}},"type":{"kind":"NonNullType","type":{"kind":"ListType","type":{"kind":"NonNullType","type":{"kind":"NamedType","name":{"kind":"Name","value":"OperatorOrderByInput"}}}}}},{"kind":"VariableDefinition","variable":{"kind":"Variable","name":{"kind":"Name","value":"where"}},"type":{"kind":"NamedType","name":{"kind":"Name","value":"OperatorWhereInput"}}}],"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"operatorsConnection"},"arguments":[{"kind":"Argument","name":{"kind":"Name","value":"orderBy"},"value":{"kind":"Variable","name":{"kind":"Name","value":"orderBy"}}},{"kind":"Argument","name":{"kind":"Name","value":"first"},"value":{"kind":"Variable","name":{"kind":"Name","value":"first"}}},{"kind":"Argument","name":{"kind":"Name","value":"after"},"value":{"kind":"Variable","name":{"kind":"Name","value":"after"}}},{"kind":"Argument","name":{"kind":"Name","value":"where"},"value":{"kind":"Variable","name":{"kind":"Name","value":"where"}}}],"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"edges"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"node"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"id"}},{"kind":"Field","name":{"kind":"Name","value":"operatorOwner"}},{"kind":"Field","name":{"kind":"Name","value":"currentDomainId"}},{"kind":"Field","name":{"kind":"Name","value":"currentEpochRewards"}},{"kind":"Field","name":{"kind":"Name","value":"currentTotalStake"}},{"kind":"Field","name":{"kind":"Name","value":"minimumNominatorStake"}},{"kind":"Field","name":{"kind":"Name","value":"nextDomainId"}},{"kind":"Field","name":{"kind":"Name","value":"nominationTax"}},{"kind":"Field","name":{"kind":"Name","value":"signingKey"}},{"kind":"Field","name":{"kind":"Name","value":"status"}},{"kind":"Field","name":{"kind":"Name","value":"totalShares"}},{"kind":"Field","name":{"kind":"Name","value":"updatedAt"}},{"kind":"Field","name":{"kind":"Name","value":"nominators"},"arguments":[{"kind":"Argument","name":{"kind":"Name","value":"limit"},"value":{"kind":"IntValue","value":"256"}}],"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"id"}},{"kind":"Field","name":{"kind":"Name","value":"shares"}}]}}]}}]}},{"kind":"Field","name":{"kind":"Name","value":"pageInfo"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"endCursor"}},{"kind":"Field","name":{"kind":"Name","value":"hasNextPage"}},{"kind":"Field","name":{"kind":"Name","value":"hasPreviousPage"}},{"kind":"Field","name":{"kind":"Name","value":"startCursor"}}]}},{"kind":"Field","name":{"kind":"Name","value":"totalCount"}}]}}]}}]} as unknown as DocumentNode; +export const OperatorsConnectionDocument = {"kind":"Document","definitions":[{"kind":"OperationDefinition","operation":"query","name":{"kind":"Name","value":"OperatorsConnection"},"variableDefinitions":[{"kind":"VariableDefinition","variable":{"kind":"Variable","name":{"kind":"Name","value":"first"}},"type":{"kind":"NonNullType","type":{"kind":"NamedType","name":{"kind":"Name","value":"Int"}}}},{"kind":"VariableDefinition","variable":{"kind":"Variable","name":{"kind":"Name","value":"after"}},"type":{"kind":"NamedType","name":{"kind":"Name","value":"String"}}},{"kind":"VariableDefinition","variable":{"kind":"Variable","name":{"kind":"Name","value":"orderBy"}},"type":{"kind":"NonNullType","type":{"kind":"ListType","type":{"kind":"NonNullType","type":{"kind":"NamedType","name":{"kind":"Name","value":"OperatorOrderByInput"}}}}}},{"kind":"VariableDefinition","variable":{"kind":"Variable","name":{"kind":"Name","value":"where"}},"type":{"kind":"NamedType","name":{"kind":"Name","value":"OperatorWhereInput"}}}],"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","alias":{"kind":"Name","value":"lastBlock"},"name":{"kind":"Name","value":"blocks"},"arguments":[{"kind":"Argument","name":{"kind":"Name","value":"limit"},"value":{"kind":"IntValue","value":"1"}},{"kind":"Argument","name":{"kind":"Name","value":"orderBy"},"value":{"kind":"EnumValue","value":"height_DESC"}}],"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"height"}}]}},{"kind":"Field","name":{"kind":"Name","value":"operatorsConnection"},"arguments":[{"kind":"Argument","name":{"kind":"Name","value":"orderBy"},"value":{"kind":"Variable","name":{"kind":"Name","value":"orderBy"}}},{"kind":"Argument","name":{"kind":"Name","value":"first"},"value":{"kind":"Variable","name":{"kind":"Name","value":"first"}}},{"kind":"Argument","name":{"kind":"Name","value":"after"},"value":{"kind":"Variable","name":{"kind":"Name","value":"after"}}},{"kind":"Argument","name":{"kind":"Name","value":"where"},"value":{"kind":"Variable","name":{"kind":"Name","value":"where"}}}],"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"edges"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"node"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"id"}},{"kind":"Field","name":{"kind":"Name","value":"operatorOwner"}},{"kind":"Field","name":{"kind":"Name","value":"currentDomainId"}},{"kind":"Field","name":{"kind":"Name","value":"currentEpochRewards"}},{"kind":"Field","name":{"kind":"Name","value":"currentTotalStake"}},{"kind":"Field","name":{"kind":"Name","value":"minimumNominatorStake"}},{"kind":"Field","name":{"kind":"Name","value":"nextDomainId"}},{"kind":"Field","name":{"kind":"Name","value":"nominationTax"}},{"kind":"Field","name":{"kind":"Name","value":"signingKey"}},{"kind":"Field","name":{"kind":"Name","value":"status"}},{"kind":"Field","name":{"kind":"Name","value":"totalShares"}},{"kind":"Field","name":{"kind":"Name","value":"updatedAt"}},{"kind":"Field","name":{"kind":"Name","value":"nominators"},"arguments":[{"kind":"Argument","name":{"kind":"Name","value":"limit"},"value":{"kind":"IntValue","value":"256"}}],"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"id"}},{"kind":"Field","name":{"kind":"Name","value":"shares"}}]}}]}}]}},{"kind":"Field","name":{"kind":"Name","value":"pageInfo"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"endCursor"}},{"kind":"Field","name":{"kind":"Name","value":"hasNextPage"}},{"kind":"Field","name":{"kind":"Name","value":"hasPreviousPage"}},{"kind":"Field","name":{"kind":"Name","value":"startCursor"}}]}},{"kind":"Field","name":{"kind":"Name","value":"totalCount"}}]}}]}}]} as unknown as DocumentNode; export const OperatorByIdDocument = {"kind":"Document","definitions":[{"kind":"OperationDefinition","operation":"query","name":{"kind":"Name","value":"OperatorById"},"variableDefinitions":[{"kind":"VariableDefinition","variable":{"kind":"Variable","name":{"kind":"Name","value":"operatorId"}},"type":{"kind":"NonNullType","type":{"kind":"NamedType","name":{"kind":"Name","value":"String"}}}}],"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"operatorById"},"arguments":[{"kind":"Argument","name":{"kind":"Name","value":"id"},"value":{"kind":"Variable","name":{"kind":"Name","value":"operatorId"}}}],"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"id"}},{"kind":"Field","name":{"kind":"Name","value":"operatorOwner"}},{"kind":"Field","name":{"kind":"Name","value":"currentDomainId"}},{"kind":"Field","name":{"kind":"Name","value":"currentEpochRewards"}},{"kind":"Field","name":{"kind":"Name","value":"currentTotalStake"}},{"kind":"Field","name":{"kind":"Name","value":"minimumNominatorStake"}},{"kind":"Field","name":{"kind":"Name","value":"nextDomainId"}},{"kind":"Field","name":{"kind":"Name","value":"nominationTax"}},{"kind":"Field","name":{"kind":"Name","value":"signingKey"}},{"kind":"Field","name":{"kind":"Name","value":"status"}},{"kind":"Field","name":{"kind":"Name","value":"totalShares"}},{"kind":"Field","name":{"kind":"Name","value":"updatedAt"}},{"kind":"Field","name":{"kind":"Name","value":"nominators"},"arguments":[{"kind":"Argument","name":{"kind":"Name","value":"limit"},"value":{"kind":"IntValue","value":"300"}}],"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"id"}},{"kind":"Field","name":{"kind":"Name","value":"shares"}},{"kind":"Field","name":{"kind":"Name","value":"account"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"id"}}]}}]}}]}}]}}]} as unknown as DocumentNode; export const NominatorsConnectionDocument = {"kind":"Document","definitions":[{"kind":"OperationDefinition","operation":"query","name":{"kind":"Name","value":"NominatorsConnection"},"variableDefinitions":[{"kind":"VariableDefinition","variable":{"kind":"Variable","name":{"kind":"Name","value":"first"}},"type":{"kind":"NonNullType","type":{"kind":"NamedType","name":{"kind":"Name","value":"Int"}}}},{"kind":"VariableDefinition","variable":{"kind":"Variable","name":{"kind":"Name","value":"after"}},"type":{"kind":"NamedType","name":{"kind":"Name","value":"String"}}},{"kind":"VariableDefinition","variable":{"kind":"Variable","name":{"kind":"Name","value":"orderBy"}},"type":{"kind":"NonNullType","type":{"kind":"ListType","type":{"kind":"NonNullType","type":{"kind":"NamedType","name":{"kind":"Name","value":"NominatorOrderByInput"}}}}}},{"kind":"VariableDefinition","variable":{"kind":"Variable","name":{"kind":"Name","value":"where"}},"type":{"kind":"NamedType","name":{"kind":"Name","value":"NominatorWhereInput"}}}],"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"nominatorsConnection"},"arguments":[{"kind":"Argument","name":{"kind":"Name","value":"orderBy"},"value":{"kind":"Variable","name":{"kind":"Name","value":"orderBy"}}},{"kind":"Argument","name":{"kind":"Name","value":"first"},"value":{"kind":"Variable","name":{"kind":"Name","value":"first"}}},{"kind":"Argument","name":{"kind":"Name","value":"after"},"value":{"kind":"Variable","name":{"kind":"Name","value":"after"}}},{"kind":"Argument","name":{"kind":"Name","value":"where"},"value":{"kind":"Variable","name":{"kind":"Name","value":"where"}}}],"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"edges"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"node"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"id"}},{"kind":"Field","name":{"kind":"Name","value":"shares"}},{"kind":"Field","name":{"kind":"Name","value":"account"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"id"}}]}},{"kind":"Field","name":{"kind":"Name","value":"operator"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"id"}},{"kind":"Field","name":{"kind":"Name","value":"operatorOwner"}},{"kind":"Field","name":{"kind":"Name","value":"currentDomainId"}},{"kind":"Field","name":{"kind":"Name","value":"currentEpochRewards"}},{"kind":"Field","name":{"kind":"Name","value":"currentTotalStake"}},{"kind":"Field","name":{"kind":"Name","value":"minimumNominatorStake"}},{"kind":"Field","name":{"kind":"Name","value":"nextDomainId"}},{"kind":"Field","name":{"kind":"Name","value":"nominationTax"}},{"kind":"Field","name":{"kind":"Name","value":"signingKey"}},{"kind":"Field","name":{"kind":"Name","value":"status"}},{"kind":"Field","name":{"kind":"Name","value":"totalShares"}},{"kind":"Field","name":{"kind":"Name","value":"updatedAt"}}]}},{"kind":"Field","name":{"kind":"Name","value":"updatedAt"}}]}}]}},{"kind":"Field","name":{"kind":"Name","value":"pageInfo"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"endCursor"}},{"kind":"Field","name":{"kind":"Name","value":"hasNextPage"}},{"kind":"Field","name":{"kind":"Name","value":"hasPreviousPage"}},{"kind":"Field","name":{"kind":"Name","value":"startCursor"}}]}},{"kind":"Field","name":{"kind":"Name","value":"totalCount"}}]}}]}}]} as unknown as DocumentNode; export const AccountsTopLeaderboardDocument = {"kind":"Document","definitions":[{"kind":"OperationDefinition","operation":"query","name":{"kind":"Name","value":"AccountsTopLeaderboard"},"variableDefinitions":[{"kind":"VariableDefinition","variable":{"kind":"Variable","name":{"kind":"Name","value":"first"}},"type":{"kind":"NonNullType","type":{"kind":"NamedType","name":{"kind":"Name","value":"Int"}}}}],"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","alias":{"kind":"Name","value":"farmers"},"name":{"kind":"Name","value":"accountRewardsConnection"},"arguments":[{"kind":"Argument","name":{"kind":"Name","value":"orderBy"},"value":{"kind":"EnumValue","value":"amount_DESC"}},{"kind":"Argument","name":{"kind":"Name","value":"first"},"value":{"kind":"Variable","name":{"kind":"Name","value":"first"}}},{"kind":"Argument","name":{"kind":"Name","value":"where"},"value":{"kind":"ObjectValue","fields":[{"kind":"ObjectField","name":{"kind":"Name","value":"vote_gt"},"value":{"kind":"IntValue","value":"0"}},{"kind":"ObjectField","name":{"kind":"Name","value":"vote_isNull"},"value":{"kind":"BooleanValue","value":false}},{"kind":"ObjectField","name":{"kind":"Name","value":"OR"},"value":{"kind":"ObjectValue","fields":[{"kind":"ObjectField","name":{"kind":"Name","value":"block_gt"},"value":{"kind":"IntValue","value":"0"}},{"kind":"ObjectField","name":{"kind":"Name","value":"block_isNull"},"value":{"kind":"BooleanValue","value":false}}]}}]}}],"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"edges"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"cursor"}},{"kind":"Field","name":{"kind":"Name","value":"node"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"id"}}]}}]}}]}},{"kind":"Field","alias":{"kind":"Name","value":"operators"},"name":{"kind":"Name","value":"operatorRewardsConnection"},"arguments":[{"kind":"Argument","name":{"kind":"Name","value":"orderBy"},"value":{"kind":"EnumValue","value":"amount_DESC"}},{"kind":"Argument","name":{"kind":"Name","value":"first"},"value":{"kind":"Variable","name":{"kind":"Name","value":"first"}}},{"kind":"Argument","name":{"kind":"Name","value":"where"},"value":{"kind":"ObjectValue","fields":[]}}],"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"edges"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"cursor"}},{"kind":"Field","name":{"kind":"Name","value":"node"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"amount"}},{"kind":"Field","name":{"kind":"Name","value":"id"}}]}}]}}]}},{"kind":"Field","alias":{"kind":"Name","value":"nominators"},"name":{"kind":"Name","value":"accountRewardsConnection"},"arguments":[{"kind":"Argument","name":{"kind":"Name","value":"orderBy"},"value":{"kind":"EnumValue","value":"operator_DESC"}},{"kind":"Argument","name":{"kind":"Name","value":"first"},"value":{"kind":"Variable","name":{"kind":"Name","value":"first"}}},{"kind":"Argument","name":{"kind":"Name","value":"where"},"value":{"kind":"ObjectValue","fields":[{"kind":"ObjectField","name":{"kind":"Name","value":"operator_gt"},"value":{"kind":"IntValue","value":"0"}},{"kind":"ObjectField","name":{"kind":"Name","value":"operator_isNull"},"value":{"kind":"BooleanValue","value":false}}]}}],"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"edges"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"cursor"}},{"kind":"Field","name":{"kind":"Name","value":"node"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"id"}}]}}]}}]}}]}}]} as unknown as DocumentNode; diff --git a/explorer/src/components/Operator/query.ts b/explorer/src/components/Operator/query.ts index b8019a669..3982f2938 100644 --- a/explorer/src/components/Operator/query.ts +++ b/explorer/src/components/Operator/query.ts @@ -7,6 +7,9 @@ export const QUERY_OPERATOR_CONNECTION_LIST = gql` $orderBy: [OperatorOrderByInput!]! $where: OperatorWhereInput ) { + lastBlock: blocks(limit: 1, orderBy: height_DESC) { + height + } operatorsConnection(orderBy: $orderBy, first: $first, after: $after, where: $where) { edges { node { From cbb65193fce501eabf50512dc7787b8874e42cc6 Mon Sep 17 00:00:00 2001 From: Marc-Aurele Besner <82244926+marc-aurele-besner@users.noreply.github.com> Date: Thu, 25 Apr 2024 16:31:39 -0400 Subject: [PATCH 5/8] display operator unlock status if deregistered status --- .../Operator/OperatorManagement.tsx | 200 +++++++++--------- explorer/src/utils/operator.ts | 36 +++- 2 files changed, 138 insertions(+), 98 deletions(-) diff --git a/explorer/src/components/Operator/OperatorManagement.tsx b/explorer/src/components/Operator/OperatorManagement.tsx index 804b1e79e..470d3445c 100644 --- a/explorer/src/components/Operator/OperatorManagement.tsx +++ b/explorer/src/components/Operator/OperatorManagement.tsx @@ -18,7 +18,7 @@ import { FC, useCallback, useEffect, useMemo, useState } from 'react' import { useErrorHandler } from 'react-error-boundary' import type { Cell } from 'types/table' import { downloadFullData } from 'utils/downloadFullData' -import { operatorStatus } from 'utils/operator' +import { operatorReadyToUnlock, operatorStatus } from 'utils/operator' import { capitalizeFirstLetter } from 'utils/string' import { ActionsDropdown, ActionsDropdownRow } from './ActionsDropdown' import { ActionsModal, OperatorAction, OperatorActionType } from './ActionsModal' @@ -54,6 +54,102 @@ export const OperatorManagement: FC = () => { setAction({ type: OperatorActionType.None, operatorId: null, maxAmount: null }) }, []) + const variables = useMemo( + () => ({ + first: pagination.pageSize, + after: + pagination.pageIndex > 0 + ? (pagination.pageIndex * pagination.pageSize).toString() + : undefined, + orderBy: sorting.map((s) => `${s.id}_${s.desc ? 'DESC' : 'ASC'}`).join(',') || 'id_ASC', + // eslint-disable-next-line camelcase + where: searchOperator ? { operatorOwner_eq: searchOperator } : {}, + }), + [sorting, pagination, searchOperator], + ) + + const { data, error, loading } = useQuery( + QUERY_OPERATOR_CONNECTION_LIST, + { + variables: variables, + pollInterval: 6000, + }, + ) + + useErrorHandler(error) + + const fullDataDownloader = useCallback( + () => downloadFullData(apolloClient, QUERY_OPERATOR_CONNECTION_LIST), + [apolloClient], + ) + + const handleSearch = useCallback( + (value: string) => { + setSearch(value) + setPagination({ ...pagination, pageIndex: 0 }) + }, + [pagination], + ) + + const lastBlock = useMemo( + () => data && data.lastBlock && (data.lastBlock[0].height as number), + [data], + ) + const operators = useMemo(() => data && data.operatorsConnection, [data]) + const operatorsConnection = useMemo( + () => (operators && operators.edges ? operators.edges.map((operator) => operator.node) : []), + [operators], + ) + const totalCount = useMemo(() => (operators ? operators.totalCount : 0), [operators]) + const totalLabel = useMemo(() => numberWithCommas(Number(totalCount)), [totalCount]) + + const totalNominators = useMemo( + () => + operators && operators.edges + ? operators.edges.reduce((acc, operator) => acc + operator.node.nominators.length, 0) + : 0, + [operators], + ) + const totalOperatorStake = useMemo( + () => + operators && operators.edges + ? operators.edges + .reduce((acc, operator) => acc + BigInt(operator.node.currentTotalStake), BigInt(0)) + .toString() + : '0', + [operators], + ) + const totalNominatorsStake = useMemo( + () => + operators && operators.edges + ? operators.edges + .reduce((acc, operator) => { + const nominators = operator.node.nominators + const totalShares = operator.node.totalShares + const currentTotalStake = operator.node.currentTotalStake + const subTotalNominatorsShares = nominators.reduce((acc, nominator) => { + if (nominator.id === `${operator.node.id}-${operator.node.operatorOwner}`) + return acc + return acc + BigInt(nominator.shares) + }, BigInt(0)) + const subTotalNominatorsStake = + (BigInt(currentTotalStake) * BigInt(subTotalNominatorsShares)) / BigInt(totalShares) + return acc + subTotalNominatorsStake + }, BigInt(0)) + .toString() + : '0', + [operators], + ) + const totalInStake = useMemo( + () => (BigInt(totalOperatorStake) + BigInt(totalNominatorsStake)).toString(), + [totalOperatorStake, totalNominatorsStake], + ) + + const pageCount = useMemo( + () => Math.floor(totalCount / pagination.pageSize), + [totalCount, pagination], + ) + const columns = useMemo(() => { return [ { @@ -146,7 +242,7 @@ export const OperatorManagement: FC = () => {
{selectedChain.urls.page === Chains.gemini3g ? row.original.status - : capitalizeFirstLetter(operatorStatus(row.original.status))} + : capitalizeFirstLetter(operatorStatus(row.original.status, lastBlock))}
), }, @@ -161,104 +257,16 @@ export const OperatorManagement: FC = () => { action={action} handleAction={handleAction} row={row as ActionsDropdownRow} - excludeActions={[OperatorActionType.UnlockFunds]} + excludeActions={ + operatorReadyToUnlock(row.original.status, lastBlock) + ? [OperatorActionType.UnlockFunds] + : [OperatorActionType.UnlockFunds, OperatorActionType.UnlockOperator] + } /> ), }, ] - }, [selectedChain.urls.page, selectedDomain, action, handleAction]) - - const variables = useMemo( - () => ({ - first: pagination.pageSize, - after: - pagination.pageIndex > 0 - ? (pagination.pageIndex * pagination.pageSize).toString() - : undefined, - orderBy: sorting.map((s) => `${s.id}_${s.desc ? 'DESC' : 'ASC'}`).join(',') || 'id_ASC', - // eslint-disable-next-line camelcase - where: searchOperator ? { operatorOwner_eq: searchOperator } : {}, - }), - [sorting, pagination, searchOperator], - ) - - const { data, error, loading } = useQuery( - QUERY_OPERATOR_CONNECTION_LIST, - { - variables: variables, - pollInterval: 6000, - }, - ) - - useErrorHandler(error) - - const fullDataDownloader = useCallback( - () => downloadFullData(apolloClient, QUERY_OPERATOR_CONNECTION_LIST), - [apolloClient], - ) - - const handleSearch = useCallback( - (value: string) => { - setSearch(value) - setPagination({ ...pagination, pageIndex: 0 }) - }, - [pagination], - ) - - const operators = useMemo(() => data && data.operatorsConnection, [data]) - const operatorsConnection = useMemo( - () => (operators && operators.edges ? operators.edges.map((operator) => operator.node) : []), - [operators], - ) - const totalCount = useMemo(() => (operators ? operators.totalCount : 0), [operators]) - const totalLabel = useMemo(() => numberWithCommas(Number(totalCount)), [totalCount]) - - const totalNominators = useMemo( - () => - operators && operators.edges - ? operators.edges.reduce((acc, operator) => acc + operator.node.nominators.length, 0) - : 0, - [operators], - ) - const totalOperatorStake = useMemo( - () => - operators && operators.edges - ? operators.edges - .reduce((acc, operator) => acc + BigInt(operator.node.currentTotalStake), BigInt(0)) - .toString() - : '0', - [operators], - ) - const totalNominatorsStake = useMemo( - () => - operators && operators.edges - ? operators.edges - .reduce((acc, operator) => { - const nominators = operator.node.nominators - const totalShares = operator.node.totalShares - const currentTotalStake = operator.node.currentTotalStake - const subTotalNominatorsShares = nominators.reduce((acc, nominator) => { - if (nominator.id === `${operator.node.id}-${operator.node.operatorOwner}`) - return acc - return acc + BigInt(nominator.shares) - }, BigInt(0)) - const subTotalNominatorsStake = - (BigInt(currentTotalStake) * BigInt(subTotalNominatorsShares)) / BigInt(totalShares) - return acc + subTotalNominatorsStake - }, BigInt(0)) - .toString() - : '0', - [operators], - ) - const totalInStake = useMemo( - () => (BigInt(totalOperatorStake) + BigInt(totalNominatorsStake)).toString(), - [totalOperatorStake, totalNominatorsStake], - ) - - const pageCount = useMemo( - () => Math.floor(totalCount / pagination.pageSize), - [totalCount, pagination], - ) + }, [selectedChain.urls.page, selectedDomain, action, handleAction, lastBlock]) useEffect(() => { if (subspaceAccount) handleSearch(subspaceAccount) diff --git a/explorer/src/utils/operator.ts b/explorer/src/utils/operator.ts index 2ab9eea4b..7999646f3 100644 --- a/explorer/src/utils/operator.ts +++ b/explorer/src/utils/operator.ts @@ -1,5 +1,37 @@ +type OperatorDeregisteredStatus = { deregistered: { unlockAtConfirmedDomainBlockNumber: number } } + // eslint-disable-next-line @typescript-eslint/no-explicit-any -export const operatorStatus = (status: any) => { +export const operatorStatus = (status: any, lastBlock?: number) => { if (!status) return 'Unknown' - return typeof status === 'string' ? Object.keys(JSON.parse(status))[0] : Object.keys(status)[0] + if (typeof status === 'string') { + const statusParsed = JSON.parse(status) + const statusKey = Object.keys(statusParsed)[0] + + if (lastBlock && statusKey === 'deregistered') { + const unlockBlock = (statusParsed as OperatorDeregisteredStatus).deregistered + .unlockAtConfirmedDomainBlockNumber + + if (unlockBlock > lastBlock) + return statusKey + ', unlock in ' + (unlockBlock - lastBlock) + ' blocks' + + return statusKey + ', funds ready to unlock' + } + return statusKey + } + return Object.keys(status)[0] +} + +// eslint-disable-next-line @typescript-eslint/no-explicit-any +export const operatorReadyToUnlock = (status: any, lastBlock?: number) => { + if (typeof status === 'string') { + const statusParsed = JSON.parse(status) + if ( + lastBlock && + Object.keys(statusParsed)[0] === 'deregistered' && + (statusParsed as OperatorDeregisteredStatus).deregistered + .unlockAtConfirmedDomainBlockNumber <= lastBlock + ) + return true + } + return false } From 7789bcb7ba43e81e435b1b35f4c656023bd90067 Mon Sep 17 00:00:00 2001 From: Marc-Aurele Besner <82244926+marc-aurele-besner@users.noreply.github.com> Date: Thu, 25 Apr 2024 16:36:27 -0400 Subject: [PATCH 6/8] add same logic for operator card (mobile) --- .../components/Operator/OperatorManagement.tsx | 16 ++++++++++++++-- .../components/Operator/OperatorsListCard.tsx | 4 +++- 2 files changed, 17 insertions(+), 3 deletions(-) diff --git a/explorer/src/components/Operator/OperatorManagement.tsx b/explorer/src/components/Operator/OperatorManagement.tsx index 470d3445c..19b047961 100644 --- a/explorer/src/components/Operator/OperatorManagement.tsx +++ b/explorer/src/components/Operator/OperatorManagement.tsx @@ -323,6 +323,7 @@ export const OperatorManagement: FC = () => { operators={operatorsConnection} action={action} handleAction={handleAction} + lastBlock={lastBlock} /> } /> @@ -456,17 +457,28 @@ type MobileComponentProps = { operators: OperatorsConnectionQuery['operatorsConnection']['edges'][0]['node'][] action: OperatorAction handleAction: (value: OperatorAction) => void + lastBlock?: number } -const MobileComponent: FC = ({ operators, action, handleAction }) => ( +const MobileComponent: FC = ({ + operators, + action, + handleAction, + lastBlock, +}) => (
{operators.map((operator, index) => ( ))} diff --git a/explorer/src/components/Operator/OperatorsListCard.tsx b/explorer/src/components/Operator/OperatorsListCard.tsx index 33d86cc6a..fc7bac974 100644 --- a/explorer/src/components/Operator/OperatorsListCard.tsx +++ b/explorer/src/components/Operator/OperatorsListCard.tsx @@ -20,6 +20,7 @@ type Props = { index: number excludeActions?: OperatorActionType[] nominatorMaxStake?: string + lastBlock?: number } export const OperatorsListCard: FC = ({ @@ -28,6 +29,7 @@ export const OperatorsListCard: FC = ({ handleAction, excludeActions, nominatorMaxStake, + lastBlock, }) => { const { selectedChain, selectedDomain } = useDomains() const { actingAccount } = useWallet() @@ -49,7 +51,7 @@ export const OperatorsListCard: FC = ({ value: operator.status ? selectedChain.urls.page === Chains.gemini3g ? operator.status - : capitalizeFirstLetter(operatorStatus(operator.status)) + : capitalizeFirstLetter(operatorStatus(operator.status, lastBlock)) : 'unknown', }, ] From 61c61e5ffbf0e474a9542605f8e865910a2df43d Mon Sep 17 00:00:00 2001 From: Marc-Aurele Besner <82244926+marc-aurele-besner@users.noreply.github.com> Date: Thu, 25 Apr 2024 16:43:03 -0400 Subject: [PATCH 7/8] hide deregistration when unlock ready --- explorer/src/components/Operator/OperatorManagement.tsx | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/explorer/src/components/Operator/OperatorManagement.tsx b/explorer/src/components/Operator/OperatorManagement.tsx index 19b047961..a66b37b16 100644 --- a/explorer/src/components/Operator/OperatorManagement.tsx +++ b/explorer/src/components/Operator/OperatorManagement.tsx @@ -259,7 +259,7 @@ export const OperatorManagement: FC = () => { row={row as ActionsDropdownRow} excludeActions={ operatorReadyToUnlock(row.original.status, lastBlock) - ? [OperatorActionType.UnlockFunds] + ? [OperatorActionType.Deregister, OperatorActionType.UnlockFunds] : [OperatorActionType.UnlockFunds, OperatorActionType.UnlockOperator] } /> @@ -474,7 +474,7 @@ const MobileComponent: FC = ({ action={action} excludeActions={ operatorReadyToUnlock(operator.status, lastBlock) - ? [OperatorActionType.UnlockFunds] + ? [OperatorActionType.Deregister, OperatorActionType.UnlockFunds] : [OperatorActionType.UnlockFunds, OperatorActionType.UnlockOperator] } handleAction={handleAction} From 58a1facde52fd8199b0582f1a84243e2d5590984 Mon Sep 17 00:00:00 2001 From: Marc-Aurele Besner <82244926+marc-aurele-besner@users.noreply.github.com> Date: Thu, 25 Apr 2024 16:47:15 -0400 Subject: [PATCH 8/8] add to-do comment --- explorer/src/utils/operator.ts | 2 ++ 1 file changed, 2 insertions(+) diff --git a/explorer/src/utils/operator.ts b/explorer/src/utils/operator.ts index 7999646f3..3b64ade09 100644 --- a/explorer/src/utils/operator.ts +++ b/explorer/src/utils/operator.ts @@ -1,5 +1,7 @@ type OperatorDeregisteredStatus = { deregistered: { unlockAtConfirmedDomainBlockNumber: number } } +// To-Do: After we end support for Gemini 3g on Astral: Properly type the operator status + // eslint-disable-next-line @typescript-eslint/no-explicit-any export const operatorStatus = (status: any, lastBlock?: number) => { if (!status) return 'Unknown'