Skip to content

Commit

Permalink
feat: add delegation output rewards (#1264)
Browse files Browse the repository at this point in the history
Co-authored-by: Mario <[email protected]>
  • Loading branch information
brancoder and msarcev authored Mar 12, 2024
1 parent 6d9c4e1 commit f952389
Show file tree
Hide file tree
Showing 10 changed files with 87 additions and 40 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -51,7 +51,7 @@ const AccountAddressView: React.FC<AccountAddressViewProps> = ({ accountAddress
totalManaBalance={totalManaBalance}
availableManaBalance={availableManaBalance}
blockIssuanceCredits={congestion?.blockIssuanceCredits}
manaRewards={manaRewards?.rewards}
manaRewards={manaRewards}
/>
</div>
</div>
Expand Down
2 changes: 2 additions & 0 deletions client/src/app/components/nova/address/AnchorAddressView.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@ const AnchorAddressView: React.FC<AnchorAddressViewProps> = ({ anchorAddress })
availableBaseTokenBalance,
totalManaBalance,
availableManaBalance,
manaRewards,
isAnchorDetailsLoading,
isAssociatedOutputsLoading,
} = state;
Expand Down Expand Up @@ -49,6 +50,7 @@ const AnchorAddressView: React.FC<AnchorAddressViewProps> = ({ anchorAddress })
totalManaBalance={totalManaBalance}
availableManaBalance={availableManaBalance}
storageDeposit={null}
manaRewards={manaRewards}
/>
</div>
</div>
Expand Down
2 changes: 2 additions & 0 deletions client/src/app/components/nova/address/Ed25519AddressView.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@ const Ed25519AddressView: React.FC<Ed25519AddressViewProps> = ({ ed25519Address
availableBaseTokenBalance,
totalManaBalance,
availableManaBalance,
manaRewards,
isAssociatedOutputsLoading,
isBasicOutputsLoading,
} = state;
Expand Down Expand Up @@ -49,6 +50,7 @@ const Ed25519AddressView: React.FC<Ed25519AddressViewProps> = ({ ed25519Address
totalManaBalance={totalManaBalance}
availableManaBalance={availableManaBalance}
storageDeposit={null}
manaRewards={manaRewards}
/>
</div>
</div>
Expand Down
2 changes: 2 additions & 0 deletions client/src/app/components/nova/address/NftAddressView.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@ const NftAddressView: React.FC<NftAddressViewProps> = ({ nftAddress }) => {
availableBaseTokenBalance,
totalManaBalance,
availableManaBalance,
manaRewards,
isNftDetailsLoading,
isAssociatedOutputsLoading,
} = state;
Expand Down Expand Up @@ -49,6 +50,7 @@ const NftAddressView: React.FC<NftAddressViewProps> = ({ nftAddress }) => {
totalManaBalance={totalManaBalance}
availableManaBalance={availableManaBalance}
storageDeposit={null}
manaRewards={manaRewards}
/>
</div>
</div>
Expand Down
26 changes: 16 additions & 10 deletions client/src/helpers/nova/hooks/useAccountAddressState.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,6 @@ import {
CongestionResponse,
FeatureType,
OutputWithMetadataResponse,
ManaRewardsResponse,
StakingFeature,
ValidatorResponse,
} from "@iota/sdk-wasm-nova/web";
Expand Down Expand Up @@ -35,7 +34,7 @@ export interface IAccountAddressState {
totalManaBalance: IManaBalance | null;
availableManaBalance: IManaBalance | null;
blockIssuerFeature: BlockIssuerFeature | null;
manaRewards: ManaRewardsResponse | null;
manaRewards: bigint | null;
stakingFeature: StakingFeature | null;
validatorDetails: ValidatorResponse | null;
addressBasicOutputs: OutputWithMetadataResponse[] | null;
Expand Down Expand Up @@ -100,15 +99,8 @@ export const useAccountAddressState = (address: AccountAddress): [IAccountAddres
);

const { accountOutput, accountOutputMetadata, isLoading: isAccountDetailsLoading } = useAccountDetails(network, address.accountId);
const { manaRewards } = useOutputManaRewards(network, accountOutputMetadata?.outputId ?? "");
const { manaRewards: outputManaRewards } = useOutputManaRewards(network, accountOutputMetadata?.outputId ?? "");

const { totalBaseTokenBalance, availableBaseTokenBalance, totalManaBalance, availableManaBalance } = useAddressBalance(
network,
state.addressDetails,
accountOutput,
accountOutputMetadata,
manaRewards,
);
const [addressBasicOutputs, isBasicOutputsLoading] = useAddressBasicOutputs(network, state.addressDetails?.bech32 ?? null);
const [addressNftOutputs, isNftOutputsLoading] = useAddressNftOutputs(network, state.addressDetails?.bech32 ?? null);
const [addressDelegationOutputs, isDelegationOutputsLoading] = useAddressDelegationOutputs(
Expand All @@ -122,6 +114,20 @@ export const useAccountAddressState = (address: AccountAddress): [IAccountAddres
state.addressDetails?.hex ?? null,
);

const delegationRewards = addressDelegationOutputs?.map((output) => output.rewards?.manaRewards) ?? [];
const allManaRewards = [outputManaRewards, ...delegationRewards].filter(Boolean) ?? [];
const manaRewards =
allManaRewards && allManaRewards.length > 0
? allManaRewards.reduce((total, rewardsResponse) => total + BigInt(rewardsResponse?.rewards ?? 0), BigInt(0))
: null;
const { totalBaseTokenBalance, availableBaseTokenBalance, totalManaBalance, availableManaBalance } = useAddressBalance(
network,
state.addressDetails,
accountOutput,
accountOutputMetadata,
manaRewards,
);

useEffect(() => {
const locationState = location.state as IAddressPageLocationProps;
const { addressDetails } = locationState?.addressDetails
Expand Down
6 changes: 3 additions & 3 deletions client/src/helpers/nova/hooks/useAddressBalance.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import { AddressType, NftOutput, AccountOutput, AnchorOutput, OutputMetadataResponse, ManaRewardsResponse } from "@iota/sdk-wasm-nova/web";
import { AddressType, NftOutput, AccountOutput, AnchorOutput, OutputMetadataResponse } from "@iota/sdk-wasm-nova/web";
import { useEffect, useState } from "react";
import { IManaBalance } from "~/models/api/nova/address/IAddressBalanceResponse";
import { IAddressDetails } from "~/models/api/nova/IAddressDetails";
Expand All @@ -21,7 +21,7 @@ export function useAddressBalance(
addressDetails: IAddressDetails | null,
output: AccountOutput | NftOutput | AnchorOutput | null,
outputMetadata?: OutputMetadataResponse | null,
outputManaRewards?: ManaRewardsResponse | null,
manaRewards?: bigint | null,
): {
totalBaseTokenBalance: number | null;
availableBaseTokenBalance: number | null;
Expand Down Expand Up @@ -75,7 +75,7 @@ export function useAddressBalance(
createdSlotIndex,
untilSlotIndex,
protocolInfo.parameters,
outputManaRewards ?? null,
manaRewards ?? null,
)
: null;

Expand Down
23 changes: 17 additions & 6 deletions client/src/helpers/nova/hooks/useAnchorAddressState.ts
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@ export interface IAnchorAddressState {
availableBaseTokenBalance: number | null;
totalManaBalance: IManaBalance | null;
availableManaBalance: IManaBalance | null;
manaRewards: bigint | null;
addressDelegationOutputs: IDelegationWithDetails[] | null;
addressBasicOutputs: OutputWithMetadataResponse[] | null;
addressNftOutputs: OutputWithMetadataResponse[] | null;
Expand All @@ -39,6 +40,7 @@ const initialState = {
availableBaseTokenBalance: null,
totalManaBalance: null,
availableManaBalance: null,
manaRewards: null,
addressBasicOutputs: null,
addressNftOutputs: null,
addressDelegationOutputs: null,
Expand Down Expand Up @@ -68,19 +70,26 @@ export const useAnchorAddressState = (address: AnchorAddress): [IAnchorAddressSt
);

const { anchorOutput, anchorOutputMetadata, isLoading: isAnchorDetailsLoading } = useAnchorDetails(network, address.anchorId);
const { totalBaseTokenBalance, availableBaseTokenBalance, totalManaBalance, availableManaBalance } = useAddressBalance(
network,
state.addressDetails,
anchorOutput,
anchorOutputMetadata,
);
const [addressBasicOutputs, isBasicOutputsLoading] = useAddressBasicOutputs(network, state.addressDetails?.bech32 ?? null);
const [addressNftOutputs, isNftOutputsLoading] = useAddressNftOutputs(network, state.addressDetails?.bech32 ?? null);
const [addressDelegationOutputs, isDelegationOutputsLoading] = useAddressDelegationOutputs(
network,
state.addressDetails?.bech32 ?? null,
);

const delegationRewards = addressDelegationOutputs?.map((output) => output.rewards?.manaRewards) ?? [];
const manaRewards =
delegationRewards.length > 0
? delegationRewards.reduce((total, rewardsResponse) => total + BigInt(rewardsResponse?.rewards ?? 0), BigInt(0))
: null;

const { totalBaseTokenBalance, availableBaseTokenBalance, totalManaBalance, availableManaBalance } = useAddressBalance(
network,
state.addressDetails,
anchorOutput,
anchorOutputMetadata,
manaRewards,
);
useEffect(() => {
const locationState = location.state as IAddressPageLocationProps;
const { addressDetails } = locationState?.addressDetails
Expand All @@ -100,6 +109,7 @@ export const useAnchorAddressState = (address: AnchorAddress): [IAnchorAddressSt
availableBaseTokenBalance,
totalManaBalance,
availableManaBalance,
manaRewards,
addressBasicOutputs,
addressNftOutputs,
addressDelegationOutputs,
Expand All @@ -114,6 +124,7 @@ export const useAnchorAddressState = (address: AnchorAddress): [IAnchorAddressSt
availableBaseTokenBalance,
totalManaBalance,
availableManaBalance,
manaRewards,
addressBasicOutputs,
addressNftOutputs,
addressDelegationOutputs,
Expand Down
23 changes: 18 additions & 5 deletions client/src/helpers/nova/hooks/useEd25519AddressState.ts
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@ export interface IEd25519AddressState {
availableBaseTokenBalance: number | null;
totalManaBalance: IManaBalance | null;
availableManaBalance: IManaBalance | null;
manaRewards: bigint | null;
addressBasicOutputs: OutputWithMetadataResponse[] | null;
addressNftOutputs: OutputWithMetadataResponse[] | null;
addressDelegationOutputs: IDelegationWithDetails[] | null;
Expand All @@ -34,6 +35,7 @@ const initialState = {
availableBaseTokenBalance: null,
totalManaBalance: null,
availableManaBalance: null,
manaRewards: null,
addressBasicOutputs: null,
addressNftOutputs: null,
addressDelegationOutputs: null,
Expand All @@ -60,18 +62,27 @@ export const useEd25519AddressState = (address: Ed25519Address): [IEd25519Addres
initialState,
);

const { totalBaseTokenBalance, availableBaseTokenBalance, totalManaBalance, availableManaBalance } = useAddressBalance(
network,
state.addressDetails,
null,
);
const [addressBasicOutputs, isBasicOutputsLoading] = useAddressBasicOutputs(network, state.addressDetails?.bech32 ?? null);
const [addressNftOutputs, isNftOutputsLoading] = useAddressNftOutputs(network, state.addressDetails?.bech32 ?? null);
const [addressDelegationOutputs, isDelegationOutputsLoading] = useAddressDelegationOutputs(
network,
state.addressDetails?.bech32 ?? null,
);

const delegationRewards = addressDelegationOutputs?.map((output) => output.rewards?.manaRewards) ?? [];
const manaRewards =
delegationRewards.length > 0
? delegationRewards.reduce((total, rewardsResponse) => total + BigInt(rewardsResponse?.rewards ?? 0), BigInt(0))
: null;

const { totalBaseTokenBalance, availableBaseTokenBalance, totalManaBalance, availableManaBalance } = useAddressBalance(
network,
state.addressDetails,
null,
null,
manaRewards,
);

useEffect(() => {
const locationState = location.state as IAddressPageLocationProps;
const { addressDetails } = locationState?.addressDetails
Expand All @@ -90,6 +101,7 @@ export const useEd25519AddressState = (address: Ed25519Address): [IEd25519Addres
availableBaseTokenBalance,
totalManaBalance,
availableManaBalance,
manaRewards,
addressBasicOutputs,
addressNftOutputs,
addressDelegationOutputs,
Expand All @@ -102,6 +114,7 @@ export const useEd25519AddressState = (address: Ed25519Address): [IEd25519Addres
availableManaBalance,
totalBaseTokenBalance,
availableBaseTokenBalance,
manaRewards,
addressBasicOutputs,
addressNftOutputs,
addressDelegationOutputs,
Expand Down
24 changes: 18 additions & 6 deletions client/src/helpers/nova/hooks/useNftAddressState.ts
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@ export interface INftAddressState {
availableBaseTokenBalance: number | null;
totalManaBalance: IManaBalance | null;
availableManaBalance: IManaBalance | null;
manaRewards: bigint | null;
addressBasicOutputs: OutputWithMetadataResponse[] | null;
addressNftOutputs: OutputWithMetadataResponse[] | null;
addressDelegationOutputs: IDelegationWithDetails[] | null;
Expand All @@ -40,6 +41,7 @@ const initialState = {
availableBaseTokenBalance: null,
totalManaBalance: null,
availableManaBalance: null,
manaRewards: null,
addressBasicOutputs: null,
addressNftOutputs: null,
addressDelegationOutputs: null,
Expand Down Expand Up @@ -68,19 +70,27 @@ export const useNftAddressState = (address: NftAddress): [INftAddressState, Reac
);

const { nftOutput, nftOutputMetadata, isLoading: isNftDetailsLoading } = useNftDetails(network, address.nftId);
const { totalBaseTokenBalance, availableBaseTokenBalance, totalManaBalance, availableManaBalance } = useAddressBalance(
network,
state.addressDetails,
nftOutput,
nftOutputMetadata,
);
const [addressBasicOutputs, isBasicOutputsLoading] = useAddressBasicOutputs(network, state.addressDetails?.bech32 ?? null);
const [addressNftOutputs, isNftOutputsLoading] = useAddressNftOutputs(network, state.addressDetails?.bech32 ?? null);
const [addressDelegationOutputs, isDelegationOutputsLoading] = useAddressDelegationOutputs(
network,
state.addressDetails?.bech32 ?? null,
);

const delegationRewards = addressDelegationOutputs?.map((output) => output.rewards?.manaRewards) ?? [];
const manaRewards =
delegationRewards.length > 0
? delegationRewards.reduce((total, rewardsResponse) => total + BigInt(rewardsResponse?.rewards ?? 0), BigInt(0))
: null;

const { totalBaseTokenBalance, availableBaseTokenBalance, totalManaBalance, availableManaBalance } = useAddressBalance(
network,
state.addressDetails,
nftOutput,
nftOutputMetadata,
manaRewards,
);

useEffect(() => {
const locationState = location.state as IAddressPageLocationProps;
const { addressDetails } = locationState?.addressDetails
Expand All @@ -100,6 +110,7 @@ export const useNftAddressState = (address: NftAddress): [INftAddressState, Reac
availableBaseTokenBalance,
totalManaBalance,
availableManaBalance,
manaRewards,
isNftDetailsLoading,
addressBasicOutputs,
addressNftOutputs,
Expand All @@ -114,6 +125,7 @@ export const useNftAddressState = (address: NftAddress): [INftAddressState, Reac
availableBaseTokenBalance,
totalManaBalance,
availableManaBalance,
manaRewards,
isNftDetailsLoading,
addressBasicOutputs,
addressNftOutputs,
Expand Down
17 changes: 8 additions & 9 deletions client/src/helpers/nova/manaUtils.ts
Original file line number Diff line number Diff line change
@@ -1,36 +1,35 @@
import { BasicOutput, ManaRewardsResponse, Output, ProtocolParameters, Utils } from "@iota/sdk-wasm-nova/web";
import { BasicOutput, Output, ProtocolParameters, Utils } from "@iota/sdk-wasm-nova/web";
import { IKeyValueEntries } from "~/app/lib/interfaces";

export interface OutputManaDetails {
storedMana: string;
storedManaDecayed: string;
potentialMana: string;
totalMana: string;
delegationRewards?: string | null;
manaRewards?: string | null;
}

export function buildManaDetailsForOutput(
output: Output,
createdSlotIndex: number,
spentOrLatestSlotIndex: number,
protocolParameters: ProtocolParameters,
outputManaRewards: ManaRewardsResponse | null,
manaRewards: bigint | null,
): OutputManaDetails {
const decayedMana = Utils.outputManaWithDecay(output, createdSlotIndex, spentOrLatestSlotIndex, protocolParameters);
const storedManaDecayed = BigInt(decayedMana.stored).toString();
const potentialMana = BigInt(decayedMana.potential).toString();
const delegationRewards = outputManaRewards && BigInt(outputManaRewards?.rewards) > 0 ? BigInt(outputManaRewards?.rewards) : null;
let totalMana = BigInt(decayedMana.stored) + BigInt(decayedMana.potential);

if (delegationRewards !== null) {
totalMana += delegationRewards;
if (manaRewards !== null) {
totalMana += manaRewards;
}

return {
storedMana: (output as BasicOutput).mana?.toString(),
storedManaDecayed,
potentialMana,
delegationRewards: delegationRewards !== null ? delegationRewards?.toString() : undefined,
manaRewards: manaRewards?.toString() ?? undefined,
totalMana: totalMana.toString(),
};
}
Expand All @@ -56,8 +55,8 @@ export function getManaKeyValueEntries(manaDetails: OutputManaDetails | null): I
value: manaDetails?.potentialMana,
},
{
label: "Delegation Rewards:",
value: manaDetails?.delegationRewards,
label: "Mana Rewards:",
value: manaDetails?.manaRewards,
},
],
};
Expand Down

0 comments on commit f952389

Please sign in to comment.