diff --git a/client/src/app/components/stardust/address/AddressBalance.tsx b/client/src/app/components/stardust/address/AddressBalance.tsx index c548a674f..432690d4f 100644 --- a/client/src/app/components/stardust/address/AddressBalance.tsx +++ b/client/src/app/components/stardust/address/AddressBalance.tsx @@ -21,13 +21,13 @@ interface AddressBalanceProps { /** * The storage rent balance. */ - readonly storageRentBalance: number | null; + readonly storageDeposit: number | null; } const CONDITIONAL_BALANCE_INFO = "These funds reside within outputs with additional unlock conditions which might be potentially un-lockable"; -const AddressBalance: React.FC = ({ balance, spendableBalance, storageRentBalance }) => { +const AddressBalance: React.FC = ({ balance, spendableBalance, storageDeposit }) => { const { name: network, tokenInfo } = useContext(NetworkContext); const [formatBalanceFull, setFormatBalanceFull] = useState(false); const [formatConditionalBalanceFull, setFormatConditionalBalanceFull] = useState(false); @@ -101,14 +101,7 @@ const AddressBalance: React.FC = ({ balance, spendableBalan false, conditionalBalance, )} - {buildBalanceView( - "Storage Deposit", - formatStorageBalanceFull, - setFormatStorageBalanceFull, - false, - false, - storageRentBalance, - )} + {buildBalanceView("Storage Deposit", formatStorageBalanceFull, setFormatStorageBalanceFull, false, false, storageDeposit)} ); diff --git a/client/src/app/routes/stardust/AddressPage.tsx b/client/src/app/routes/stardust/AddressPage.tsx index 8972379d8..f5a8deeb5 100644 --- a/client/src/app/routes/stardust/AddressPage.tsx +++ b/client/src/app/routes/stardust/AddressPage.tsx @@ -24,7 +24,7 @@ const AddressPage: React.FC> = ({ bech32AddressDetails, balance, availableBalance, - storageRentBalance, + storageDeposit, isBasicOutputsLoading, isAliasOutputsLoading, isNftOutputsLoading, @@ -88,7 +88,7 @@ const AddressPage: React.FC> = ({ )} diff --git a/client/src/app/routes/stardust/AddressState.ts b/client/src/app/routes/stardust/AddressState.ts index 19d7ec90b..f40cf5099 100644 --- a/client/src/app/routes/stardust/AddressState.ts +++ b/client/src/app/routes/stardust/AddressState.ts @@ -38,7 +38,7 @@ export interface IAddressState { bech32AddressDetails: IBech32AddressDetails | null; balance: number | null; availableBalance: number | null; - storageRentBalance: number | null; + storageDeposit: number | null; addressOutputs: OutputResponse[] | null; addressBasicOutputs: OutputResponse[] | null; isBasicOutputsLoading: boolean; @@ -70,7 +70,7 @@ const initialState = { bech32AddressDetails: null, balance: null, availableBalance: null, - storageRentBalance: null, + storageDeposit: null, addressOutputs: null, addressBasicOutputs: null, isBasicOutputsLoading: true, @@ -121,13 +121,20 @@ export const useAddressPageState = (): [IAddressState, React.Dispatch { - if (addressBasicOutputs && addressAliasOutputs && addressNftOutputs) { - const mergedOutputResponses = [...addressBasicOutputs, ...addressAliasOutputs, ...addressNftOutputs]; - const outputs = mergedOutputResponses.map((or) => or.output); - const storageRentBalanceUpdate = TransactionsHelper.computeStorageRentBalance(outputs, rentStructure); - - setState({ - addressOutputs: mergedOutputResponses, - storageRentBalance: storageRentBalanceUpdate, - }); + const addressOutputs = + [...(addressBasicOutputs ?? []), ...(addressAliasOutputs ?? []), ...(addressNftOutputs ?? [])].filter((o) => o !== null) ?? []; + let outputsComputedInStorageDeposit = addressOutputs?.map((or) => or.output); + const addressOutputItself = nftOutput ?? aliasOutput; + if (addressOutputItself) { + outputsComputedInStorageDeposit = [...outputsComputedInStorageDeposit, addressOutputItself]; } + const storageDeposit = TransactionsHelper.computeStorageDeposit(outputsComputedInStorageDeposit, rentStructure); + + setState({ + addressOutputs, + storageDeposit, + }); if (addressBasicOutputs && !state.participations) { let foundParticipations: IParticipation[] = []; for (const outputResponse of addressBasicOutputs) { diff --git a/client/src/helpers/hooks/useAddressBalance.ts b/client/src/helpers/hooks/useAddressBalance.ts index 7d647d72a..e966285f1 100644 --- a/client/src/helpers/hooks/useAddressBalance.ts +++ b/client/src/helpers/hooks/useAddressBalance.ts @@ -3,14 +3,20 @@ import { useIsMounted } from "./useIsMounted"; import { ServiceFactory } from "~factories/serviceFactory"; import { STARDUST } from "~models/config/protocolVersion"; import { StardustApiClient } from "~services/stardust/stardustApiClient"; +import { AliasOutput, NftOutput } from "@iota/sdk-wasm/web"; /** * Fetch the address balance * @param network The Network in context * @param address The bech32 address + * @param output The output wrapping the address, used to add the output amount to the balance * @returns The address balance, signature locked balance and a loading bool. */ -export function useAddressBalance(network: string, address: string | null): [number | null, number | null, boolean] { +export function useAddressBalance( + network: string, + address: string | null, + output: AliasOutput | NftOutput | null, +): [number | null, number | null, boolean] { const isMounted = useIsMounted(); const [apiClient] = useState(ServiceFactory.get(`api-client-${STARDUST}`)); const [balance, setBalance] = useState(null); @@ -25,14 +31,24 @@ export function useAddressBalance(network: string, address: string | null): [num const response = await apiClient.addressBalanceChronicle({ network, address }); if (response?.totalBalance !== undefined && isMounted) { - setBalance(response.totalBalance); - setAvailableBalance(response.availableBalance ?? null); + let totalBalance = response.totalBalance; + let availableBalance = response.availableBalance ?? 0; + if (output) { + totalBalance = totalBalance + Number(output.amount); + availableBalance = availableBalance + Number(output.amount); + } + setBalance(totalBalance); + setAvailableBalance(availableBalance > 0 ? availableBalance : null); } else if (isMounted) { // Fallback balance from iotajs (node) const addressDetailsWithBalance = await apiClient.addressBalance({ network, address }); if (addressDetailsWithBalance && isMounted) { - setBalance(Number(addressDetailsWithBalance.balance)); + let totalBalance = Number(addressDetailsWithBalance.balance); + if (output) { + totalBalance = totalBalance + Number(output.amount); + } + setBalance(totalBalance); setAvailableBalance(null); } } @@ -40,7 +56,7 @@ export function useAddressBalance(network: string, address: string | null): [num } else { setIsLoading(false); } - }, [network, address]); + }, [network, address, output]); return [balance, availableBalance, isLoading]; } diff --git a/client/src/helpers/stardust/transactionsHelper.ts b/client/src/helpers/stardust/transactionsHelper.ts index 3fd705069..1a04615db 100644 --- a/client/src/helpers/stardust/transactionsHelper.ts +++ b/client/src/helpers/stardust/transactionsHelper.ts @@ -237,7 +237,7 @@ export class TransactionsHelper { return HexHelper.toBigInt256(nftId).eq(bigInt.zero) ? Utils.computeNftId(outputId) : nftId; } - public static computeStorageRentBalance(outputs: Output[], rentStructure: IRent): number { + public static computeStorageDeposit(outputs: Output[], rentStructure: IRent): number { const outputsWithoutSdruc = outputs.filter((output) => { if (output.type === OutputType.Treasury) { return false;