Skip to content

Commit

Permalink
feat: Add mana from the actual output for Account/Anchor/Nft addresse…
Browse files Browse the repository at this point in the history
…s to Mana Balance
  • Loading branch information
msarcev committed Mar 1, 2024
1 parent 0fa7393 commit 71d9b13
Show file tree
Hide file tree
Showing 6 changed files with 68 additions and 13 deletions.
4 changes: 3 additions & 1 deletion client/src/helpers/nova/hooks/useAccountAddressState.ts
Original file line number Diff line number Diff line change
Expand Up @@ -94,13 +94,15 @@ export const useAccountAddressState = (address: AccountAddress): [IAccountAddres
);

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

const { totalBaseTokenBalance, availableBaseTokenBalance, totalManaBalance, availableManaBalance } = useAddressBalance(
network,
state.addressDetails,
accountOutput,
accountOutputMetadata,
manaRewards,
);
const { manaRewards } = useOutputManaRewards(network, accountOutputMetadata?.outputId ?? "");
const [addressBasicOutputs, isBasicOutputsLoading] = useAddressBasicOutputs(network, state.addressDetails?.bech32 ?? null);
const [addressNftOutputs, isNftOutputsLoading] = useAddressNftOutputs(network, state.addressDetails?.bech32 ?? null);
const [foundries, isFoundriesLoading] = useAccountControlledFoundries(network, state.addressDetails);
Expand Down
41 changes: 37 additions & 4 deletions client/src/helpers/nova/hooks/useAddressBalance.ts
Original file line number Diff line number Diff line change
@@ -1,11 +1,13 @@
import { AddressType, NftOutput, AccountOutput, AnchorOutput } from "@iota/sdk-wasm-nova/web";
import { AddressType, NftOutput, AccountOutput, AnchorOutput, IOutputMetadataResponse, ManaRewardsResponse } 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";
import { NovaApiClient } from "~/services/nova/novaApiClient";
import { ServiceFactory } from "~factories/serviceFactory";
import { useIsMounted } from "~helpers/hooks/useIsMounted";
import { useNetworkInfoNova } from "~/helpers/nova/networkInfo";
import { NOVA } from "~models/config/protocolVersion";
import { buildManaDetailsForOutput } from "../manaUtils";

/**
* Fetch the address balance from chronicle nova.
Expand All @@ -18,6 +20,8 @@ export function useAddressBalance(
network: string,
addressDetails: IAddressDetails | null,
output: AccountOutput | NftOutput | AnchorOutput | null,
outputMetadata?: IOutputMetadataResponse | null,
outputManaRewards?: ManaRewardsResponse | null,
): {
totalBaseTokenBalance: number | null;
availableBaseTokenBalance: number | null;
Expand All @@ -26,6 +30,7 @@ export function useAddressBalance(
isLoading: boolean;
} {
const isMounted = useIsMounted();
const { protocolInfo, latestConfirmedSlot } = useNetworkInfoNova((s) => s.networkInfo);
const [apiClient] = useState(ServiceFactory.get<NovaApiClient>(`api-client-${NOVA}`));
const [totalBaseTokenBalance, setTotalBaseTokenBalance] = useState<number | null>(null);
const [availableBaseTokenBalance, setAvailableBaseTokenBalance] = useState<number | null>(null);
Expand All @@ -40,7 +45,7 @@ export function useAddressBalance(
addressDetails?.type === AddressType.Account ||
addressDetails?.type === AddressType.Nft ||
addressDetails?.type === AddressType.Anchor;
const canLoad = address && (!needsOutputToProceed || (needsOutputToProceed && output !== null));
const canLoad = address && (!needsOutputToProceed || (needsOutputToProceed && output !== null && outputMetadata));

if (canLoad) {
// eslint-disable-next-line no-void
Expand All @@ -50,12 +55,40 @@ export function useAddressBalance(
if (isMounted) {
let totalBalance = response?.totalBalance?.amount ?? 0;
let availableBalance = response?.availableBalance?.amount ?? 0;
const totalManaBalance = response?.totalBalance?.mana ?? null;
const availableManaBalance = response?.availableBalance?.mana ?? null;
let totalManaBalance = response?.totalBalance?.mana ?? null;
let availableManaBalance = response?.availableBalance?.mana ?? null;

if (output) {
totalBalance = Number(totalBalance) + Number(output.amount);
availableBalance = Number(availableBalance) + Number(output.amount);

// Output mana
const { included, spent } = outputMetadata ?? {};
const createdSlotIndex = (included?.slot as number) ?? null;
const spentSlotIndex = (spent?.slot as number) ?? null;

if (output && createdSlotIndex && protocolInfo) {
const untilSlotIndex = spentSlotIndex ? spentSlotIndex : latestConfirmedSlot > 0 ? latestConfirmedSlot : null;
const outputManaDetails = untilSlotIndex
? buildManaDetailsForOutput(
output,
createdSlotIndex,
untilSlotIndex,
protocolInfo.parameters,
outputManaRewards ?? null,
)
: null;

totalManaBalance = {
stored: (totalManaBalance?.stored ?? 0) + Number(outputManaDetails?.storedMana ?? 0),
potential: (totalManaBalance?.potential ?? 0) + Number(outputManaDetails?.potentialMana ?? 0),
};

availableManaBalance = {
stored: (availableManaBalance?.stored ?? 0) + Number(outputManaDetails?.storedMana ?? 0),
potential: (availableManaBalance?.potential ?? 0) + Number(outputManaDetails?.potentialMana ?? 0),
};
}
}

setTotalBaseTokenBalance(totalBalance);
Expand Down
6 changes: 5 additions & 1 deletion client/src/helpers/nova/hooks/useAnchorAddressState.ts
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ import { useAddressBalance } from "./useAddressBalance";
import { useAddressBasicOutputs } from "~/helpers/nova/hooks/useAddressBasicOutputs";
import { useAddressNftOutputs } from "~/helpers/nova/hooks/useAddressNftOutputs";
import { IManaBalance } from "~/models/api/nova/address/IAddressBalanceResponse";
import { useOutputManaRewards } from "./useOutputManaRewards";

export interface IAnchorAddressState {
addressDetails: IAddressDetails | null;
Expand Down Expand Up @@ -61,11 +62,14 @@ export const useAnchorAddressState = (address: AnchorAddress): [IAnchorAddressSt
initialState,
);

const { anchorOutput, isLoading: isAnchorDetailsLoading } = useAnchorDetails(network, address.anchorId);
const { anchorOutput, anchorOutputMetadata, isLoading: isAnchorDetailsLoading } = useAnchorDetails(network, address.anchorId);
const { manaRewards } = useOutputManaRewards(network, anchorOutputMetadata?.outputId ?? "");
const { totalBaseTokenBalance, availableBaseTokenBalance, totalManaBalance, availableManaBalance } = useAddressBalance(
network,
state.addressDetails,
anchorOutput,
anchorOutputMetadata,
manaRewards,
);
const [addressBasicOutputs, isBasicOutputsLoading] = useAddressBasicOutputs(network, state.addressDetails?.bech32 ?? null);
const [addressNftOutputs, isNftOutputsLoading] = useAddressNftOutputs(network, state.addressDetails?.bech32 ?? null);
Expand Down
12 changes: 9 additions & 3 deletions client/src/helpers/nova/hooks/useAnchorDetails.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import { AnchorOutput } from "@iota/sdk-wasm-nova/web";
import { AnchorOutput, IOutputMetadataResponse } from "@iota/sdk-wasm-nova/web";
import { useEffect, useState } from "react";
import { ServiceFactory } from "~/factories/serviceFactory";
import { useIsMounted } from "~/helpers/hooks/useIsMounted";
Expand All @@ -12,10 +12,14 @@ import { NovaApiClient } from "~/services/nova/novaApiClient";
* @param anchorID The anchor id
* @returns The output response and loading bool.
*/
export function useAnchorDetails(network: string, anchorId: string | null): { anchorOutput: AnchorOutput | null; isLoading: boolean } {
export function useAnchorDetails(
network: string,
anchorId: string | null,
): { anchorOutput: AnchorOutput | null; anchorOutputMetadata: IOutputMetadataResponse | null; isLoading: boolean } {
const isMounted = useIsMounted();
const [apiClient] = useState(ServiceFactory.get<NovaApiClient>(`api-client-${NOVA}`));
const [anchorOutput, setAnchorOutput] = useState<AnchorOutput | null>(null);
const [anchorOutputMetadata, setAnchorOutputMetadata] = useState<IOutputMetadataResponse | null>(null);
const [isLoading, setIsLoading] = useState<boolean>(true);

useEffect(() => {
Expand All @@ -31,8 +35,10 @@ export function useAnchorDetails(network: string, anchorId: string | null): { an
.then((response) => {
if (!response?.error && isMounted) {
const output = response.anchorOutputDetails?.output as AnchorOutput;
const metadata = response.anchorOutputDetails?.metadata ?? null;

setAnchorOutput(output);
setAnchorOutputMetadata(metadata);
}
})
.finally(() => {
Expand All @@ -44,5 +50,5 @@ export function useAnchorDetails(network: string, anchorId: string | null): { an
}
}, [network, anchorId]);

return { anchorOutput, isLoading };
return { anchorOutput, anchorOutputMetadata, isLoading };
}
6 changes: 5 additions & 1 deletion client/src/helpers/nova/hooks/useNftAddressState.ts
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ import { useAddressBalance } from "./useAddressBalance";
import { useAddressBasicOutputs } from "~/helpers/nova/hooks/useAddressBasicOutputs";
import { useAddressNftOutputs } from "~/helpers/nova/hooks/useAddressNftOutputs";
import { IManaBalance } from "~/models/api/nova/address/IAddressBalanceResponse";
import { useOutputManaRewards } from "./useOutputManaRewards";

export interface INftAddressState {
addressDetails: IAddressDetails | null;
Expand Down Expand Up @@ -61,11 +62,14 @@ export const useNftAddressState = (address: NftAddress): [INftAddressState, Reac
initialState,
);

const { nftOutput, isLoading: isNftDetailsLoading } = useNftDetails(network, address.nftId);
const { nftOutput, nftOutputMetadata, isLoading: isNftDetailsLoading } = useNftDetails(network, address.nftId);
const { manaRewards } = useOutputManaRewards(network, nftOutputMetadata?.outputId ?? "");
const { totalBaseTokenBalance, availableBaseTokenBalance, totalManaBalance, availableManaBalance } = useAddressBalance(
network,
state.addressDetails,
nftOutput,
nftOutputMetadata,
manaRewards,
);
const [addressBasicOutputs, isBasicOutputsLoading] = useAddressBasicOutputs(network, state.addressDetails?.bech32 ?? null);
const [addressNftOutputs, isNftOutputsLoading] = useAddressNftOutputs(network, state.addressDetails?.bech32 ?? null);
Expand Down
12 changes: 9 additions & 3 deletions client/src/helpers/nova/hooks/useNftDetails.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import { NftOutput } from "@iota/sdk-wasm-nova/web";
import { IOutputMetadataResponse, NftOutput } from "@iota/sdk-wasm-nova/web";
import { useEffect, useState } from "react";
import { ServiceFactory } from "~/factories/serviceFactory";
import { useIsMounted } from "~/helpers/hooks/useIsMounted";
Expand All @@ -12,10 +12,14 @@ import { NovaApiClient } from "~/services/nova/novaApiClient";
* @param nftID The nft id
* @returns The output response and loading bool.
*/
export function useNftDetails(network: string, nftId: string | null): { nftOutput: NftOutput | null; isLoading: boolean } {
export function useNftDetails(
network: string,
nftId: string | null,
): { nftOutput: NftOutput | null; nftOutputMetadata: IOutputMetadataResponse | null; isLoading: boolean } {
const isMounted = useIsMounted();
const [apiClient] = useState(ServiceFactory.get<NovaApiClient>(`api-client-${NOVA}`));
const [nftOutput, setNftOutput] = useState<NftOutput | null>(null);
const [nftOutputMetadata, setNftOutputMetadata] = useState<IOutputMetadataResponse | null>(null);
const [isLoading, setIsLoading] = useState<boolean>(true);

useEffect(() => {
Expand All @@ -31,8 +35,10 @@ export function useNftDetails(network: string, nftId: string | null): { nftOutpu
.then((response) => {
if (!response?.error && isMounted) {
const output = response.nftOutputDetails?.output as NftOutput;
const metadata = response.nftOutputDetails?.metadata ?? null;

setNftOutput(output);
setNftOutputMetadata(metadata);
}
})
.finally(() => {
Expand All @@ -44,5 +50,5 @@ export function useNftDetails(network: string, nftId: string | null): { nftOutpu
}
}, [network, nftId]);

return { nftOutput, isLoading };
return { nftOutput, nftOutputMetadata, isLoading };
}

0 comments on commit 71d9b13

Please sign in to comment.