Skip to content

Commit

Permalink
feat: improve address outputs balances
Browse files Browse the repository at this point in the history
  • Loading branch information
begonaalvarezd committed Jan 31, 2024
1 parent ac12b06 commit 59fd086
Show file tree
Hide file tree
Showing 5 changed files with 50 additions and 31 deletions.
13 changes: 3 additions & 10 deletions client/src/app/components/stardust/address/AddressBalance.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -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<AddressBalanceProps> = ({ balance, spendableBalance, storageRentBalance }) => {
const AddressBalance: React.FC<AddressBalanceProps> = ({ balance, spendableBalance, storageDeposit }) => {
const { name: network, tokenInfo } = useContext(NetworkContext);
const [formatBalanceFull, setFormatBalanceFull] = useState(false);
const [formatConditionalBalanceFull, setFormatConditionalBalanceFull] = useState(false);
Expand Down Expand Up @@ -101,14 +101,7 @@ const AddressBalance: React.FC<AddressBalanceProps> = ({ balance, spendableBalan
false,
conditionalBalance,
)}
{buildBalanceView(
"Storage Deposit",
formatStorageBalanceFull,
setFormatStorageBalanceFull,
false,
false,
storageRentBalance,
)}
{buildBalanceView("Storage Deposit", formatStorageBalanceFull, setFormatStorageBalanceFull, false, false, storageDeposit)}
</div>
</div>
);
Expand Down
4 changes: 2 additions & 2 deletions client/src/app/routes/stardust/AddressPage.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,7 @@ const AddressPage: React.FC<RouteComponentProps<AddressRouteProps>> = ({
bech32AddressDetails,
balance,
availableBalance,
storageRentBalance,
storageDeposit,
isBasicOutputsLoading,
isAliasOutputsLoading,
isNftOutputsLoading,
Expand Down Expand Up @@ -88,7 +88,7 @@ const AddressPage: React.FC<RouteComponentProps<AddressRouteProps>> = ({
<AddressBalance
balance={balance}
spendableBalance={availableBalance}
storageRentBalance={storageRentBalance}
storageDeposit={storageDeposit}
/>
)}
</div>
Expand Down
36 changes: 23 additions & 13 deletions client/src/app/routes/stardust/AddressState.ts
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand Down Expand Up @@ -70,7 +70,7 @@ const initialState = {
bech32AddressDetails: null,
balance: null,
availableBalance: null,
storageRentBalance: null,
storageDeposit: null,
addressOutputs: null,
addressBasicOutputs: null,
isBasicOutputsLoading: true,
Expand Down Expand Up @@ -121,13 +121,20 @@ export const useAddressPageState = (): [IAddressState, React.Dispatch<Partial<IA
const [addressBasicOutputs, isBasicOutputsLoading] = useAddressBasicOutputs(network, addressBech32);
const [addressAliasOutputs, isAliasOutputsLoading] = useAddressAliasOutputs(network, addressBech32);
const [addressNftOutputs, isNftOutputsLoading] = useAddressNftOutputs(network, addressBech32);
const [, nftMetadata, issuerId, isNftDetailsLoading] = useNftDetails(network, addressType === AddressType.Nft ? addressHex : null);
const [nftOutput, nftMetadata, issuerId, isNftDetailsLoading] = useNftDetails(
network,
addressType === AddressType.Nft ? addressHex : null,
);
const [aliasOutput, isAliasDetailsLoading] = useAliasDetails(network, addressType === AddressType.Alias ? addressHex : null);
const [aliasFoundries, isAliasFoundriesLoading] = useAliasControlledFoundries(
network,
addressType === AddressType.Alias ? state.bech32AddressDetails : null,
);
const [balance, availableBalance] = useAddressBalance(network, state.bech32AddressDetails?.bech32 ?? null);
const [balance, availableBalance] = useAddressBalance(
network,
state.bech32AddressDetails?.bech32 ?? null,
aliasOutput ?? nftOutput ?? null,
);
const [eventDetails] = useParticipationEventDetails(state.participations ?? undefined);

const [aliasContainsDID] = useAliasContainsDID(aliasOutput);
Expand Down Expand Up @@ -197,16 +204,19 @@ export const useAddressPageState = (): [IAddressState, React.Dispatch<Partial<IA
]);

useEffect(() => {
if (addressBasicOutputs && addressAliasOutputs && addressNftOutputs) {
const mergedOutputResponses = [...addressBasicOutputs, ...addressAliasOutputs, ...addressNftOutputs];
const outputs = mergedOutputResponses.map<Output>((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<Output>((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) {
Expand Down
26 changes: 21 additions & 5 deletions client/src/helpers/hooks/useAddressBalance.ts
Original file line number Diff line number Diff line change
Expand Up @@ -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<StardustApiClient>(`api-client-${STARDUST}`));
const [balance, setBalance] = useState<number | null>(null);
Expand All @@ -25,22 +31,32 @@ 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);
}
}
})();
} else {
setIsLoading(false);
}
}, [network, address]);
}, [network, address, output]);

return [balance, availableBalance, isLoading];
}
2 changes: 1 addition & 1 deletion client/src/helpers/stardust/transactionsHelper.ts
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand Down

0 comments on commit 59fd086

Please sign in to comment.