mirror of
https://github.com/lux-tel/websites.git
synced 2026-10-30 20:31:36 +00:00
381 lines
9.9 KiB
TypeScript
381 lines
9.9 KiB
TypeScript
'use client';
|
|
|
|
import { useWallet } from '@session/wallet/hooks/useWallet';
|
|
import { useMemo } from 'react';
|
|
import type { Address } from 'viem';
|
|
import { arbitrum, arbitrumSepolia } from 'viem/chains';
|
|
import type { ReadContractData } from 'wagmi/query';
|
|
import type { ServiceNodeRewardsAbi } from '../abis';
|
|
import {
|
|
encodeBlsPubKey,
|
|
encodeBlsSignature,
|
|
encodeED25519PubKey,
|
|
encodeED25519Signature,
|
|
} from '../util';
|
|
import {
|
|
type ContractReadQueryProps,
|
|
mergeContractReadStatuses,
|
|
useContractReadQuery,
|
|
} from './useContractReadQuery';
|
|
import { type ContractWriteQueryProps, useContractWriteQuery } from './useContractWriteQuery';
|
|
import { useEstimateContractFee } from './useEstimateContractFee';
|
|
|
|
export type ClaimRewardsQuery = ContractWriteQueryProps & {
|
|
/** Claim rewards */
|
|
claimRewards: () => void;
|
|
};
|
|
|
|
export function useClaimRewardsQuery({
|
|
vestingContractAddress,
|
|
}: {
|
|
vestingContractAddress?: Address;
|
|
}): ClaimRewardsQuery {
|
|
const { simulateAndWriteContract, ...rest } = useContractWriteQuery({
|
|
contract: vestingContractAddress ? 'TokenVestingStaking' : 'ServiceNodeRewards',
|
|
functionName: 'claimRewards',
|
|
addressOverride: vestingContractAddress,
|
|
});
|
|
|
|
return {
|
|
claimRewards: simulateAndWriteContract,
|
|
...rest,
|
|
};
|
|
}
|
|
|
|
export type UpdateRewardsBalanceArgs = {
|
|
address: Address;
|
|
rewards: bigint;
|
|
blsSignature: string;
|
|
excludedSigners: Array<bigint>;
|
|
};
|
|
|
|
export type UpdateRewardsBalanceQuery = ContractWriteQueryProps & {
|
|
/** Update rewards balance */
|
|
updateRewardsBalance: (args?: UpdateRewardsBalanceArgs) => void;
|
|
};
|
|
|
|
export function useUpdateRewardsBalanceQuery(
|
|
// NOTE: default args are required to get the gas estimate
|
|
defaultArgs?: UpdateRewardsBalanceArgs
|
|
): UpdateRewardsBalanceQuery {
|
|
const defaultBlsSignature = useMemo(
|
|
() => (defaultArgs?.blsSignature ? encodeBlsSignature(defaultArgs.blsSignature) : null),
|
|
[defaultArgs]
|
|
);
|
|
|
|
const { simulateAndWriteContract, ...rest } = useContractWriteQuery({
|
|
contract: 'ServiceNodeRewards',
|
|
functionName: 'updateRewardsBalance',
|
|
...(defaultArgs && defaultBlsSignature
|
|
? {
|
|
args: [
|
|
defaultArgs.address,
|
|
defaultArgs.rewards,
|
|
defaultBlsSignature,
|
|
defaultArgs.excludedSigners,
|
|
],
|
|
}
|
|
: {}),
|
|
});
|
|
|
|
const updateRewardsBalance = (args?: UpdateRewardsBalanceArgs) => {
|
|
const _args = args ?? defaultArgs;
|
|
if (!_args) {
|
|
throw new Error('updateRewardsBalance called without args');
|
|
}
|
|
|
|
return simulateAndWriteContract([
|
|
_args.address,
|
|
_args.rewards,
|
|
encodeBlsSignature(_args.blsSignature),
|
|
_args.excludedSigners,
|
|
] as const);
|
|
};
|
|
|
|
return {
|
|
updateRewardsBalance,
|
|
...rest,
|
|
};
|
|
}
|
|
|
|
export type TotalNodesQuery = ContractReadQueryProps & {
|
|
/** The total number of nodes */
|
|
totalNodes: ReadContractData<typeof ServiceNodeRewardsAbi, 'totalNodes', []>;
|
|
};
|
|
|
|
export function useTotalNodesQuery(): TotalNodesQuery {
|
|
const { chainId } = useWallet();
|
|
|
|
const { data: totalNodes, ...rest } = useContractReadQuery({
|
|
contract: 'ServiceNodeRewards',
|
|
functionName: 'totalNodes',
|
|
chainIdOverride: chainId === arbitrumSepolia.id ? arbitrumSepolia.id : arbitrum.id,
|
|
});
|
|
|
|
return {
|
|
totalNodes,
|
|
...rest,
|
|
};
|
|
}
|
|
|
|
export type UseAddBLSPubKeyReturn = ContractWriteQueryProps & {
|
|
addBLSPubKey: () => void;
|
|
};
|
|
|
|
export type RegisterNodeContributor = {
|
|
staker: { addr: Address; beneficiary: Address };
|
|
stakedAmount: bigint;
|
|
};
|
|
|
|
export type UseAddBlsPubKeyParams = {
|
|
blsPubKey: string;
|
|
blsSignature: string;
|
|
nodePubKey: string;
|
|
userSignature: string;
|
|
fee?: number;
|
|
/** Contributors to the node, requires at least one contributor */
|
|
contributors: Array<RegisterNodeContributor> & { [0]: RegisterNodeContributor };
|
|
};
|
|
|
|
export function encodeAddBlsPubKeyArgs({
|
|
blsPubKey,
|
|
blsSignature,
|
|
nodePubKey,
|
|
userSignature,
|
|
fee,
|
|
}: Omit<Required<UseAddBlsPubKeyParams>, 'contributors'>) {
|
|
const encodedBlsPubKey = encodeBlsPubKey(blsPubKey);
|
|
const encodedBlsSignature = encodeBlsSignature(blsSignature);
|
|
const { pubKey } = encodeED25519PubKey(nodePubKey);
|
|
const { sigs0, sigs1 } = encodeED25519Signature(userSignature);
|
|
|
|
const encodedNodeParams = {
|
|
serviceNodePubkey: pubKey,
|
|
serviceNodeSignature1: sigs0,
|
|
serviceNodeSignature2: sigs1,
|
|
fee,
|
|
};
|
|
|
|
return {
|
|
encodedBlsPubKey,
|
|
encodedBlsSignature,
|
|
encodedNodeParams,
|
|
};
|
|
}
|
|
|
|
export function useAddBLSPubKey({
|
|
blsPubKey,
|
|
blsSignature,
|
|
nodePubKey,
|
|
userSignature,
|
|
fee = 0,
|
|
contributors,
|
|
}: UseAddBlsPubKeyParams): UseAddBLSPubKeyReturn {
|
|
const { encodedBlsPubKey, encodedBlsSignature, encodedNodeParams } = useMemo(() => {
|
|
return encodeAddBlsPubKeyArgs({
|
|
blsPubKey,
|
|
blsSignature,
|
|
nodePubKey,
|
|
userSignature,
|
|
fee,
|
|
});
|
|
}, [blsPubKey, blsSignature, nodePubKey, userSignature, fee]);
|
|
|
|
const { simulateAndWriteContract, ...rest } = useContractWriteQuery({
|
|
contract: 'ServiceNodeRewards',
|
|
functionName: 'addBLSPublicKey',
|
|
args: [encodedBlsPubKey, encodedBlsSignature, encodedNodeParams, contributors],
|
|
});
|
|
|
|
return {
|
|
addBLSPubKey: simulateAndWriteContract,
|
|
...rest,
|
|
};
|
|
}
|
|
|
|
export function useAddBlsPubKeyFeeEstimate({
|
|
blsPubKey,
|
|
blsSignature,
|
|
nodePubKey,
|
|
userSignature,
|
|
fee = 0,
|
|
contributors,
|
|
}: UseAddBlsPubKeyParams) {
|
|
const { encodedBlsPubKey, encodedBlsSignature, encodedNodeParams } = useMemo(() => {
|
|
return encodeAddBlsPubKeyArgs({
|
|
blsPubKey,
|
|
blsSignature,
|
|
nodePubKey,
|
|
userSignature,
|
|
fee,
|
|
});
|
|
}, [blsPubKey, blsSignature, nodePubKey, userSignature, fee]);
|
|
|
|
return useEstimateContractFee({
|
|
contract: 'ServiceNodeRewards',
|
|
functionName: 'addBLSPublicKey',
|
|
args: [encodedBlsPubKey, encodedBlsSignature, encodedNodeParams, contributors],
|
|
});
|
|
}
|
|
|
|
export type UseInitiateRemoveBLSPublicKeyReturn = ContractWriteQueryProps & {
|
|
initiateRemoveBLSPublicKey: () => void;
|
|
};
|
|
|
|
export function useInitiateRemoveBLSPublicKey({
|
|
contractId,
|
|
vestingContractAddress,
|
|
}: {
|
|
contractId: number;
|
|
vestingContractAddress?: Address;
|
|
}): UseInitiateRemoveBLSPublicKeyReturn {
|
|
const defaultArgs = useMemo(() => [BigInt(contractId ?? 0)] as [bigint], [contractId]);
|
|
|
|
const { simulateAndWriteContract, ...rest } = useContractWriteQuery({
|
|
contract: vestingContractAddress ? 'TokenVestingStaking' : 'ServiceNodeRewards',
|
|
functionName: 'initiateExitBLSPublicKey',
|
|
args: defaultArgs,
|
|
addressOverride: vestingContractAddress,
|
|
});
|
|
|
|
return {
|
|
initiateRemoveBLSPublicKey: simulateAndWriteContract,
|
|
...rest,
|
|
};
|
|
}
|
|
|
|
export type UseRemoveBLSPublicKeyWithSignatureReturn = ContractWriteQueryProps & {
|
|
removeBLSPublicKeyWithSignature: () => void;
|
|
};
|
|
|
|
export function useRemoveBLSPublicKeyWithSignature({
|
|
blsPubKey,
|
|
timestamp,
|
|
blsSignature,
|
|
excludedSigners = [],
|
|
}: {
|
|
blsPubKey: string;
|
|
timestamp: number;
|
|
blsSignature: string;
|
|
excludedSigners?: Array<bigint>;
|
|
}): UseRemoveBLSPublicKeyWithSignatureReturn {
|
|
const defaultArgs = useMemo(() => {
|
|
const encodedBlsPubKey = encodeBlsPubKey(blsPubKey);
|
|
const encodedBlsSignature = encodeBlsSignature(blsSignature);
|
|
const encodedTimestamp = BigInt(timestamp);
|
|
|
|
return [encodedBlsPubKey, encodedTimestamp, encodedBlsSignature, excludedSigners] as const;
|
|
}, [blsPubKey, timestamp, blsSignature, excludedSigners]);
|
|
|
|
const { simulateAndWriteContract, ...rest } = useContractWriteQuery({
|
|
contract: 'ServiceNodeRewards',
|
|
functionName: 'exitBLSPublicKeyWithSignature',
|
|
args: defaultArgs,
|
|
});
|
|
|
|
return {
|
|
removeBLSPublicKeyWithSignature: simulateAndWriteContract,
|
|
...rest,
|
|
};
|
|
}
|
|
|
|
export function useGetRecipients({ address }: { address: Address }) {
|
|
const { data: recipients, ...rest } = useContractReadQuery({
|
|
contract: 'ServiceNodeRewards',
|
|
functionName: 'recipients',
|
|
args: [address],
|
|
enabled: !!address,
|
|
});
|
|
|
|
const [rewards, claimed] = useMemo(() => {
|
|
if (!recipients || recipients.length !== 2) return [undefined, undefined];
|
|
return recipients;
|
|
}, [recipients]);
|
|
|
|
return {
|
|
rewards,
|
|
claimed,
|
|
...rest,
|
|
};
|
|
}
|
|
|
|
export function useClaimThreshold({ enabled }: { enabled?: boolean }) {
|
|
const { data: claimThreshold, ...rest } = useContractReadQuery({
|
|
contract: 'ServiceNodeRewards',
|
|
functionName: 'claimThreshold',
|
|
enabled,
|
|
});
|
|
|
|
return {
|
|
claimThreshold,
|
|
...rest,
|
|
};
|
|
}
|
|
|
|
export function useClaimCycle({ enabled }: { enabled?: boolean }) {
|
|
const { data: claimCycle, ...rest } = useContractReadQuery({
|
|
contract: 'ServiceNodeRewards',
|
|
functionName: 'claimCycle',
|
|
enabled,
|
|
});
|
|
|
|
return {
|
|
claimCycle,
|
|
...rest,
|
|
};
|
|
}
|
|
|
|
export function useCurrentClaimTotal({ enabled }: { enabled?: boolean }) {
|
|
const { data: currentClaimTotal, ...rest } = useContractReadQuery({
|
|
contract: 'ServiceNodeRewards',
|
|
functionName: 'currentClaimTotal',
|
|
enabled,
|
|
});
|
|
|
|
return {
|
|
currentClaimTotal,
|
|
...rest,
|
|
};
|
|
}
|
|
|
|
export function useCurrentClaimCycle({ enabled }: { enabled?: boolean }) {
|
|
const { data: currentClaimCycle, ...rest } = useContractReadQuery({
|
|
contract: 'ServiceNodeRewards',
|
|
functionName: 'currentClaimCycle',
|
|
enabled,
|
|
});
|
|
|
|
return {
|
|
currentClaimCycle,
|
|
...rest,
|
|
};
|
|
}
|
|
|
|
export function useClaimCycleDetails({ enabled }: { enabled?: boolean }) {
|
|
const claimThresholdHook = useClaimThreshold({ enabled });
|
|
const claimCycleHook = useClaimCycle({ enabled });
|
|
const currentClaimTotalHook = useCurrentClaimTotal({ enabled });
|
|
|
|
const status = mergeContractReadStatuses(
|
|
mergeContractReadStatuses(claimThresholdHook.status, claimCycleHook.status),
|
|
currentClaimTotalHook.status
|
|
);
|
|
|
|
const refetch = async () => {
|
|
return await Promise.allSettled([
|
|
claimThresholdHook.refetch(),
|
|
claimCycleHook.refetch(),
|
|
currentClaimTotalHook.refetch(),
|
|
]);
|
|
};
|
|
|
|
return {
|
|
claimThreshold: claimThresholdHook.claimThreshold,
|
|
claimCycle: claimCycleHook.claimCycle,
|
|
currentClaimTotal: currentClaimTotalHook.currentClaimTotal,
|
|
refetch,
|
|
status,
|
|
enabled,
|
|
};
|
|
}
|