Skip to content

Commit

Permalink
feat!: components no longer need to accept wagmi values as props (#9)
Browse files Browse the repository at this point in the history
  • Loading branch information
fadeev authored Aug 1, 2024
1 parent a428313 commit ab34040
Show file tree
Hide file tree
Showing 10 changed files with 207 additions and 127 deletions.
16 changes: 11 additions & 5 deletions src/app/page.tsx
Original file line number Diff line number Diff line change
@@ -1,14 +1,20 @@
"use client";

import { ConnectButton } from "@rainbow-me/rainbowkit";
import { ConnectBitcoin } from "@/index";
import { useAccount, useChainId, useWalletClient } from "wagmi";
import { Balances, ConnectBitcoin } from "@/index";

const Page = () => {
return (
<div>
<ConnectBitcoin />
<ConnectButton />
<div className="m-4">
<div className="flex justify-end gap-2 mb-10">
<ConnectBitcoin />
<ConnectButton label="Connect EVM" showBalance={false} />
</div>
<div className="flex justify-center">
<div className="w-[400px]">
<Balances />
</div>
</div>
</div>
);
};
Expand Down
4 changes: 3 additions & 1 deletion src/app/providers.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -42,7 +42,9 @@ export const Providers = ({ children }: { children: React.ReactNode }) => {
disableTransitionOnChange
>
<ThemeProvider>
<UniversalKitProvider>{children}</UniversalKitProvider>
<UniversalKitProvider config={config} client={queryClient}>
{children}
</UniversalKitProvider>
</ThemeProvider>
</NextThemesProvider>
</QueryClientProvider>
Expand Down
69 changes: 38 additions & 31 deletions src/components/Balances/index.tsx
Original file line number Diff line number Diff line change
@@ -1,12 +1,16 @@
"use client";

import { useState, useEffect } from "react";
import { useState, useEffect, useCallback } from "react";
import { Card } from "@/components/ui/card";
import { Input } from "@/components/ui/input";
import { Button } from "@/components/ui/button";
import { Search, RefreshCw } from "lucide-react";
import { Skeleton } from "@/components/ui/skeleton";
import { roundNumber } from "@/lib/utils";
import { useBitcoinWallet } from "@/index";
import { useAccount, useWalletClient } from "wagmi";
import { useEthersSigner } from "@/hooks/useEthersSigner";
import { useZetaChainClient } from "@/providers/UniversalKitProvider";

interface Token {
id: string;
Expand All @@ -16,52 +20,55 @@ interface Token {
}

interface BalancesProps {
client: {
getBalances: (params: any) => Promise<Token[]>;
};
account: any;
bitcoin?: string | null;
config?: any;
balances?: any;
onBalanceClick?: (balance: Token) => void;
}

export const Balances = ({
client,
account,
bitcoin,
config,
balances: balancesProp,
onBalanceClick = () => {},
}: BalancesProps) => {
const { address, status } = useAccount();

const { address: bitcoin } = useBitcoinWallet();
const client = useZetaChainClient();

const [balances, setBalances] = useState<Token[]>([]);
const [error, setError] = useState<string | null>(null);
const [search, setSearch] = useState("");
const [selectedChain, setSelectedChain] = useState("");
const { address, status } = account;
const [isReloading, setIsReloading] = useState(false);

const fetchBalances = async (reloading = false) => {
if (reloading) setIsReloading(true);
try {
const result = await client.getBalances({
evmAddress: address,
btcAddress: bitcoin,
});
setBalances(result);
} catch (err: any) {
setError(err.message);
} finally {
if (reloading) setIsReloading(false);
}
};
const fetchBalances = useCallback(
async (reloading = true) => {
if (reloading) setIsReloading(true);
try {
if (client && address) {
const result = await client.getBalances({
evmAddress: address,
btcAddress: bitcoin,
});
setBalances(result);
}
} catch (error: any) {
console.error("Error fetching local balances:", error);
} finally {
setIsReloading(false);
}
},
[client, address, bitcoin]
);

useEffect(() => {
if (client && address) {
if (balancesProp) {
setBalances(balancesProp);
setIsReloading(false);
} else if (address) {
fetchBalances();
}
}, [client, address]);

useEffect(() => {
setBalances([]);
setError(null);
}, [address]);
}, [balancesProp, address, bitcoin, fetchBalances]);

const uniqueChains = Array.from(
new Set(balances.map((token: Token) => token.chain_name))
Expand Down
63 changes: 39 additions & 24 deletions src/components/StakingRewards/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -6,21 +6,34 @@ import { Card } from "@/components/ui/card";
import { Button } from "@/components/ui/button";
import { roundNumber, hexToBech32Address } from "@/lib/utils";
import { Skeleton } from "@/components/ui/skeleton";
import { useAccount, useWalletClient } from "wagmi";
import { useEthersSigner } from "@/hooks/useEthersSigner";
import { useZetaChainClient } from "@/providers/UniversalKitProvider";

export const StakingRewards = ({ client, account }: any) => {
const { sendCosmosTx } = useSendCosmosTx(account.address, client);
const { address, isConnected, isDisconnected } = account;
export const StakingRewards = () => {
const { address, chainId, isConnected, isDisconnected }: any = useAccount();
const { data: walletClient } = useWalletClient({ chainId });
const signer = useEthersSigner({ walletClient });
const client = useZetaChainClient();

const { sendCosmosTx } = useSendCosmosTx(address, client);

const [unbondingDelegations, setUnbondingDelegations] = useState([]);
const [stakingDelegations, setStakingDelegations] = useState([]);
const [stakingRewards, setStakingRewards] = useState([]);
const [loading, setLoading] = useState(false);
const [apiEndpoint, setApiEndpoint] = useState("");

const api = client.getEndpoint("cosmos-http", "zeta_testnet");
useEffect(() => {
if (client) {
const api = client.getEndpoint("cosmos-http", "zeta_testnet");
setApiEndpoint(api);
}
}, [client]);

const fetchUnbondingDelegations = async () => {
const fetchUnbondingDelegations = async (api: string) => {
try {
const addr = hexToBech32Address(account.address, "zeta");
const addr = hexToBech32Address(address, "zeta");
const url = `${api}/cosmos/staking/v1beta1/delegators/${addr}/unbonding_delegations`;
const response = await fetch(url);
const data = await response.json();
Expand All @@ -30,9 +43,9 @@ export const StakingRewards = ({ client, account }: any) => {
}
};

const fetchStakingDelegations = async () => {
const fetchStakingDelegations = async (api: string) => {
try {
const addr = hexToBech32Address(account.address, "zeta");
const addr = hexToBech32Address(address, "zeta");
const url = `${api}/cosmos/staking/v1beta1/delegations/${addr}`;
const response = await fetch(url);
const data = await response.json();
Expand All @@ -42,9 +55,9 @@ export const StakingRewards = ({ client, account }: any) => {
}
};

const fetchStakingRewards = async () => {
const fetchStakingRewards = async (api: string) => {
try {
const addr = hexToBech32Address(account.address, "zeta");
const addr = hexToBech32Address(address, "zeta");
const url = `${api}/cosmos/distribution/v1beta1/delegators/${addr}/rewards`;
const response = await fetch(url);
const stakingRewards = await response.json();
Expand All @@ -56,20 +69,22 @@ export const StakingRewards = ({ client, account }: any) => {

useEffect(() => {
const fetchData = async () => {
console.log("fetching data...");
const [unbondingDelegations, stakingDelegations, stakingRewards] =
await Promise.all([
fetchUnbondingDelegations(),
fetchStakingDelegations(),
fetchStakingRewards(),
]);
if (apiEndpoint) {
console.log("fetching data...");
const [unbondingDelegations, stakingDelegations, stakingRewards] =
await Promise.all([
fetchUnbondingDelegations(apiEndpoint),
fetchStakingDelegations(apiEndpoint),
fetchStakingRewards(apiEndpoint),
]);

setUnbondingDelegations(unbondingDelegations);
setStakingDelegations(stakingDelegations);
setStakingRewards(stakingRewards);
setUnbondingDelegations(unbondingDelegations);
setStakingDelegations(stakingDelegations);
setStakingRewards(stakingRewards);
}
};
if (account.address) fetchData();
}, [account.address]);
if (address && apiEndpoint) fetchData();
}, [address, apiEndpoint]);

const stakingAmountTotal = stakingDelegations?.reduce((a: any, c: any) => {
const amount = BigInt(c.balance.amount);
Expand Down Expand Up @@ -100,12 +115,12 @@ export const StakingRewards = ({ client, account }: any) => {
const claimRewards = async () => {
try {
setLoading(true);
const addr = hexToBech32Address(account.address, "zeta");
const addr = hexToBech32Address(address, "zeta");
if (!addr) {
console.error("Invalid address");
return;
}
const url = `${api}/cosmos/distribution/v1beta1/delegators/${addr}/rewards`;
const url = `${apiEndpoint}/cosmos/distribution/v1beta1/delegators/${addr}/rewards`;
const response = await fetch(url);
const stakingRewards = await response.json();
const validatorAddresses = stakingRewards.rewards.map(
Expand Down
2 changes: 1 addition & 1 deletion src/components/Swap/hooks/useDestinationAddress.ts
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ import type { Token } from "./types";
const useDestinationAddress = (
address: `0x${string}` | undefined,
destinationTokenSelected: Token | null,
bitcoinAddress: string | undefined
bitcoinAddress: string | null
) => {
const [addressSelected, setAddressSelected] = useState<string>("");
const [isAddressSelectedValid, setIsAddressSelectedValid] = useState(false);
Expand Down
44 changes: 23 additions & 21 deletions src/components/Swap/index.tsx
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
"use client";

import { useEffect, useState } from "react";
import { useEffect, useState, useCallback } from "react";

import SwapLayout from "./Layout";
import useAmountValidation from "./hooks/useAmountValidation";
Expand All @@ -12,47 +12,49 @@ import { computeSendType, sendTypeDetails } from "./hooks/computeSendType";
import useSwapErrors from "./hooks/useSwapErrors";
import useTokenSelection from "./hooks/useTokenSelection";
import { formatAddress } from "@/lib/utils";
import { useAccount } from "wagmi";
import { useZetaChainClient } from "@/providers/UniversalKitProvider";
import { useBitcoinWallet } from "@/index";

interface SwapProps {
contract: string;
client: any;
account: any;
track?: any;
balances?: any;
bitcoin?: any;
config?: any;
}

export const Swap: React.FC<SwapProps> = ({
contract,
track,
balances: balancesProp,
client,
account,
bitcoin,
config,
}) => {
const { address, chainId } = account;
const { address, chainId } = useAccount();
const { address: bitcoin } = useBitcoinWallet();
const client = useZetaChainClient();

const [sourceAmount, setSourceAmount] = useState<string>("");
const [sourceAmount, setSourceAmount] = useState("");
const [isRightChain, setIsRightChain] = useState(true);
const [sendButtonText, setSendButtonText] = useState("Send tokens");
const [balances, setBalances] = useState(balancesProp || []);
const [balancesLoading, setBalancesLoading] = useState(true);

const [balances, setBalances] = useState<any>(balancesProp || []);
const [balancesLoading, setBalancesLoading] = useState<boolean>(true);

const fetchBalances = async () => {
const fetchBalances = useCallback(async () => {
setBalancesLoading(true);
try {
const result = await client.getBalances({
evmAddress: address,
btcAddress: bitcoin,
});
setBalances(result);
} catch (error) {
if (client && address) {
const result = await client.getBalances({
evmAddress: address,
btcAddress: bitcoin,
});
setBalances(result);
}
} catch (error: any) {
console.error("Error fetching local balances:", error);
} finally {
setBalancesLoading(false);
}
};
}, [client, address, bitcoin]);

useEffect(() => {
if (balancesProp) {
Expand All @@ -61,7 +63,7 @@ export const Swap: React.FC<SwapProps> = ({
} else if (address) {
fetchBalances();
}
}, [address, bitcoin]);
}, [balancesProp, address, bitcoin, fetchBalances]);

const {
setSourceToken,
Expand Down
22 changes: 13 additions & 9 deletions src/hooks/useEthersSigner.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,15 +2,19 @@ import * as React from "react";
import { providers } from "ethers";

export function walletClientToSigner(walletClient: any) {
const { account, chain, transport } = walletClient;
const network = {
chainId: chain.id,
name: chain.name,
ensAddress: chain.contracts?.ensRegistry?.address,
};
const provider = new providers.Web3Provider(transport, network);
const signer = provider.getSigner(account.address);
return signer;
try {
const { account, chain, transport } = walletClient;
const network = {
chainId: chain.id,
name: chain.name,
ensAddress: chain.contracts?.ensRegistry?.address,
};
const provider = new providers.Web3Provider(transport, network);
const signer = provider.getSigner(account.address);
return signer;
} catch (e) {
console.error(e);
}
}

export function useEthersSigner({ walletClient }: { walletClient: any }) {
Expand Down
Loading

0 comments on commit ab34040

Please sign in to comment.