Skip to content

Commit

Permalink
feat(ui-ux): move evm data inside redux store
Browse files Browse the repository at this point in the history
  • Loading branch information
lykalabrada committed Oct 10, 2023
1 parent 6acf6d9 commit 0129ddd
Show file tree
Hide file tree
Showing 4 changed files with 108 additions and 79 deletions.
2 changes: 1 addition & 1 deletion mobile-app/app/api/transaction/transfer_domain.ts
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ import { fromAddress, Eth } from "@defichain/jellyfish-address";
import { NetworkName } from "@defichain/jellyfish-network";
import { ConvertDirection } from "@screens/enum";
import { parseUnits } from "ethers/lib/utils";
import { getEthRpcUrl } from "@store/evmApi";
import { getEthRpcUrl } from "@store/evm";
import TransferDomainV1 from "../../contracts/TransferDomainV1.json";

const TD_CONTRACT_ADDR = "0xdf00000000000000000000000000000000000001";
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,17 +2,15 @@ import { useEffect, useState } from "react";
import { formatEther, formatUnits } from "viem";
import { WalletToken, useNetworkContext } from "@waveshq/walletkit-ui";
import { utils } from "ethers";
import {
useGetEvmAddressDetailsMutation,
useGetEvmTokenBalancesMutation,
} from "@store/evmApi";
import { DomainType, useDomainContext } from "@contexts/DomainContext";
import { useSelector } from "react-redux";
import { RootState } from "@store";
import { useIsFocused } from "@react-navigation/native";
import { TokenData } from "@defichain/whale-api-client/dist/api/tokens";
import { useLogger } from "@shared-contexts/NativeLoggingProvider";
import { useWalletContext } from "@shared-contexts/WalletContext";
import { useAppDispatch } from "@hooks/useAppDispatch";
import { fetchEvmWalletDetails, fetchEvmTokenBalances } from "@store/evm";

interface AssociatedToken {
[key: string]: TokenData;
Expand All @@ -23,15 +21,22 @@ export function useEvmTokenBalances(): { evmTokens: WalletToken[] } {
const [evmTokens, setEvmTokens] = useState<WalletToken[]>([]);
const [allTokensWithAddress, setAllTokensWithAddress] =
useState<AssociatedToken>({});
const [getEvmAddressDetails] = useGetEvmAddressDetailsMutation();
const [getTokenBalances] = useGetEvmTokenBalancesMutation();
const blockCount = useSelector((state: RootState) => state.block.count);
const { network } = useNetworkContext();
const isFocused = useIsFocused();
const { domain } = useDomainContext();
const logger = useLogger();

const { allTokens } = useSelector((state: RootState) => state.wallet);
const { evmWalletDetails, evmTokenBalances } = useSelector(
(state: RootState) => state.evm,
);
const dispatch = useAppDispatch();

useEffect(() => {
dispatch(fetchEvmWalletDetails({ network, evmAddress }));
dispatch(fetchEvmTokenBalances({ network, evmAddress }));
}, [network, evmAddress, blockCount]);

useEffect(() => {
setAllTokensWithAddress(
Expand All @@ -42,6 +47,7 @@ export function useEvmTokenBalances(): { evmTokens: WalletToken[] } {
}, {}),
);
}, [allTokens]);

const getEvmTokens = async () => {
const dfiToken: WalletToken = {
id: "0-EVM",
Expand All @@ -56,18 +62,12 @@ export function useEvmTokenBalances(): { evmTokens: WalletToken[] } {
avatarSymbol: "EvmDFI",
};
try {
const details = await getEvmAddressDetails({
network,
evmAddress,
}).unwrap();
const evmDfiBalance = formatEther(BigInt(details.coin_balance ?? 0));
const tokensBalances = await getTokenBalances({
network,
evmAddress,
}).unwrap();
const evmDfiBalance = formatEther(
BigInt(evmWalletDetails?.coin_balance ?? 0),
);
dfiToken.amount = evmDfiBalance;
setEvmTokens(
tokensBalances.reduce(
evmTokenBalances.reduce(
(current: WalletToken[], each) => {
const tokenAddress = each?.token?.address;
const tokenDetails = allTokensWithAddress[tokenAddress] ?? null;
Expand Down Expand Up @@ -106,7 +106,7 @@ export function useEvmTokenBalances(): { evmTokens: WalletToken[] } {
if (isFocused && domain === DomainType.EVM) {
getEvmTokens();
}
}, [evmAddress, blockCount, isFocused, domain]);
}, [evmAddress, blockCount, isFocused, domain, evmWalletDetails]);

return { evmTokens };
}
Expand Down
144 changes: 87 additions & 57 deletions shared/store/evmApi.ts → shared/store/evm.ts
Original file line number Diff line number Diff line change
@@ -1,38 +1,93 @@
import { createApi, fetchBaseQuery } from "@reduxjs/toolkit/query/react";
import { EnvironmentNetwork } from "@waveshq/walletkit-core";
import { SecuredStoreAPI } from "@api";
import { PayloadAction, createAsyncThunk, createSlice } from "@reduxjs/toolkit";
import { EnvironmentNetwork } from "@waveshq/walletkit-core";

export const evmApi = createApi({
reducerPath: "evmApi",
baseQuery: fetchBaseQuery({ baseUrl: "" }),
endpoints: (builder) => ({
getEvmAddressDetails: builder.mutation<
EvmAddressDetails,
{ network: EnvironmentNetwork; evmAddress: string }
>({
query: ({ network = EnvironmentNetwork.TestNet, evmAddress }) => ({
url: `${getBlockscoutUrl(network)}/api/v2/addresses/${evmAddress}`,
method: "GET",
}),
}),
getEvmTokenBalances: builder.mutation<
EvmTokenBalance[],
{ network: EnvironmentNetwork; evmAddress: string }
>({
query: ({ network = EnvironmentNetwork.TestNet, evmAddress }) => ({
url: `${getBlockscoutUrl(
network,
)}/api/v2/addresses/${evmAddress}/token-balances`,
method: "GET",
}),
}),
}),
});
interface EvmWalletDetails {
hash: string;
name: string;
coin_balance: string;
exchange_rate: string;
implementation_address: string;
block_number_balance_updated_at: number;
creator_address_hash: string;
creation_tx_hash: string;
}

export const {
useGetEvmAddressDetailsMutation,
useGetEvmTokenBalancesMutation,
} = evmApi;
interface EvmToken {
address: string;
decimals: string;
name: string;
symbol: string;
type: string;
}

interface EvmTokenBalance {
token_id: string;
value: string;
token: EvmToken;
}

interface EvmState {
evmWalletDetails: EvmWalletDetails | null;
evmTokenBalances: EvmTokenBalance[];
}

const initialState: EvmState = {
evmWalletDetails: null,
evmTokenBalances: [],
};

export const fetchEvmWalletDetails = createAsyncThunk(
"wallet/fetchEvmWalletDetails",
async ({
network,
evmAddress,
}: {
network: EnvironmentNetwork;
evmAddress: string;
}) => {
const url = getBlockscoutUrl(network);
const response = await fetch(`${url}/api/v2/addresses/${evmAddress}`);
return await response.json();
},
);

export const fetchEvmTokenBalances = createAsyncThunk(
"wallet/fetchEvmTokenBalances",
async ({
network,
evmAddress,
}: {
network: EnvironmentNetwork;
evmAddress: string;
}) => {
const url = getBlockscoutUrl(network);
const response = await fetch(
`${url}/api/v2/addresses/${evmAddress}/token-balances`,
);
return await response.json();
},
);

export const evm = createSlice({
name: "evm",
initialState,
reducers: {},
extraReducers: (builder) => {
builder.addCase(
fetchEvmWalletDetails.fulfilled,
(state, action: PayloadAction<EvmWalletDetails>) => {
state.evmWalletDetails = action.payload;
},
);
builder.addCase(
fetchEvmTokenBalances.fulfilled,
(state, action: PayloadAction<EvmTokenBalance[]>) => {
state.evmTokenBalances = action.payload;
},
);
},
});

const getBlockscoutUrl = (network: EnvironmentNetwork) => {
// TODO: Add proper blockscout url for each network
Expand Down Expand Up @@ -67,28 +122,3 @@ export const getEthRpcUrl = async () => {
return "https://changi.dfi.team"; // TODO: add final eth rpc url for mainnet, with proper domain name
}
};

interface EvmToken {
address: string;
decimals: string;
name: string;
symbol: string;
type: string;
}

interface EvmTokenBalance {
token_id: string;
value: string;
token: EvmToken;
}

interface EvmAddressDetails {
hash: string;
name: string;
coin_balance: string;
exchange_rate: string;
implementation_address: string;
block_number_balance_updated_at: number;
creator_address_hash: string;
creation_tx_hash: string;
}
7 changes: 3 additions & 4 deletions shared/store/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ import { authentication } from "./authentication";
import { loans } from "./loans";
import { auctions } from "./auctions";
import { futureSwaps } from "./futureSwap";
import { evmApi } from "./evmApi";
import { evm } from "./evm";
/**
* RootState for DeFiChain Wallet App
*
Expand All @@ -37,13 +37,12 @@ export function initializeStore() {
[statusWebsiteSlice.reducerPath]: statusWebsiteSlice.reducer,
userPreferences: userPreferences.reducer,
futureSwaps: futureSwaps.reducer,
[evmApi.reducerPath]: evmApi.reducer,
evm: evm.reducer,
},
middleware: (getDefaultMiddleware) =>
getDefaultMiddleware({ serializableCheck: false })
.concat(announcementWebsiteSlice.middleware)
.concat(statusWebsiteSlice.middleware)
.concat(evmApi.middleware),
.concat(statusWebsiteSlice.middleware),
});
}

Expand Down

0 comments on commit 0129ddd

Please sign in to comment.