Skip to content

Commit

Permalink
changed wallet connect from wallet status to wallet provider
Browse files Browse the repository at this point in the history
  • Loading branch information
jigar-arc10 committed Oct 15, 2024
1 parent 8df762a commit d4288b3
Show file tree
Hide file tree
Showing 11 changed files with 191 additions and 59 deletions.
5 changes: 2 additions & 3 deletions apps/provider-console/next.config.js
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
/** @type {import('next').NextConfig} */

const { withSentryConfig } = require('@sentry/nextjs');
const { withSentryConfig } = require("@sentry/nextjs");
const nextConfig = {
reactStrictMode: false,
compiler: {
Expand Down Expand Up @@ -33,8 +33,7 @@ const nextConfig = {
});
config.externals.push("pino-pretty");
return config;
},
}
};

module.exports = withSentryConfig(nextConfig);

7 changes: 7 additions & 0 deletions apps/provider-console/sentry.client.config.js
Original file line number Diff line number Diff line change
Expand Up @@ -6,3 +6,10 @@ Sentry.init({
replaysSessionSampleRate: 0.1,
replaysOnErrorSampleRate: 1.0
});

const originalConsoleError = console.error;

console.error = (...args) => {
Sentry.captureMessage(args.join(" "), "error");
originalConsoleError(...args);
};
Original file line number Diff line number Diff line change
Expand Up @@ -75,6 +75,7 @@ export const WalletImport: React.FunctionComponent<WalletImportProps> = ({ stepC
const [showSeedForm, setShowSeedForm] = useState(false);
const [isMounted, setIsMounted] = useState(false);
const [isLoading, setIsLoading] = useState(false);
const [error, setError] = useState<string | null>(null);

const [providerProcess, setProviderProcess] = useAtom(providerProcessStore.providerProcessAtom);

Expand All @@ -96,6 +97,7 @@ export const WalletImport: React.FunctionComponent<WalletImportProps> = ({ stepC

const submitForm = async (data: SeedFormValues) => {
setIsLoading(true);
setError(null); // Reset error state
try {
if (providerProcess.machines && providerProcess.machines.length > 0) {
const publicKey = providerProcess.machines[0].systemInfo.public_key;
Expand Down Expand Up @@ -137,14 +139,15 @@ export const WalletImport: React.FunctionComponent<WalletImportProps> = ({ stepC
}
}));
stepChange();
} else {
throw new Error("Invalid response from server");
}
} else {
console.error("No machine information available");
// Handle the case when machine information is not available
throw new Error("No machine information available");
}
} catch (error) {
console.error("Error during wallet verification:", error);
// Handle any errors that occurred during the process
setError("An error occurred while processing your request. Please try again.");
} finally {
setIsLoading(false);
}
Expand Down Expand Up @@ -277,6 +280,11 @@ export const WalletImport: React.FunctionComponent<WalletImportProps> = ({ stepC
{isLoading ? "Loading..." : "Next"}
</Button>
</div>
{error && (
<div className="w-full mt-4">
<p className="text-red-500 text-sm">{error.message || "An error occurred during wallet import."}</p>
</div>
)}
</div>
</div>
</form>
Expand Down
33 changes: 8 additions & 25 deletions apps/provider-console/src/components/home/HomeContainer.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -16,44 +16,27 @@ import providerProcessStore from "@src/store/providerProcessStore";
export function HomeContainer() {
const [, resetProcess] = useAtom(providerProcessStore.resetProviderProcess);
const router = useRouter();
const { isWalletConnected, isWalletArbitrarySigned } = useWallet();
const { isWalletConnected, isWalletArbitrarySigned, isProvider, isOnline, isProviderStatusFetched } = useWallet();
const [isLoading, setIsLoading] = useState(false);
const [isProvider, setIsProvider] = useState(false);
const [, setProvider] = useState<any>(null);
const [isOnline, setIsOnline] = useState(false);
const [actions, setActions] = useState<any>(null);
const selectedNetwork = useAtomValue(networkStore.selectedNetwork); // or similar method to get the value
const [loadingMessage, setLoadingMessage] = useState<string | null>(null);

useEffect(() => {
if (isWalletConnected) {
if (isProvider && isOnline) {
setIsLoading(true);
if (isWalletArbitrarySigned) {
fetchProviderStatus();
}
fetchActions();
}
}, [isWalletConnected, isWalletArbitrarySigned]);
console.log("isProviderStatusFetched", isProviderStatusFetched);
}, [isProvider, isOnline]);

const fetchProviderStatus = async () => {
const fetchActions = async () => {
try {
setLoadingMessage("Checking provider status...");
const isProviderResponse: any = await restClient.get(`/provider/status/onchain?chainid=${selectedNetwork.chainId}`);
setIsProvider(isProviderResponse.provider ? true : false);
setProvider(isProviderResponse.provider);

if (isProviderResponse.provider) {
setLoadingMessage("Provider found, Checking online status...");
const isOnlineResponse: any = await restClient.get(`/provider/status/online?chainid=${selectedNetwork.chainId}`);
setIsOnline(isOnlineResponse.online);
}
setLoadingMessage("Checking actions...");
const actionsResponse: any = await restClient.get(`/actions`);
setActions(actionsResponse.actions);
} catch (error) {
setLoadingMessage("Error fetching provider status");
} finally {
setIsLoading(false);
setLoadingMessage(null);
setLoadingMessage("Error fetching actions");
}
};

Expand All @@ -69,7 +52,7 @@ export function HomeContainer() {
};

return (
<Layout containerClassName="flex h-full flex-col justify-between" isLoading={isLoading}>
<Layout containerClassName="flex h-full flex-col justify-between" isLoading={!isProviderStatusFetched || isLoading}>
<div className="flex flex-grow items-center justify-center">
<div className="mb-4">
{isLoading ? (
Expand Down
8 changes: 0 additions & 8 deletions apps/provider-console/src/components/layout/WalletStatus.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -80,14 +80,6 @@ export function WalletStatus() {
}
};

useEffect(() => {
if (isWalletConnected && address) {
handleWalletConnectSuccess();
} else if (!isWalletConnected) {
console.log("Wallet disconnected");
}
}, [isWalletConnected, address]);

const onDisconnectClick = () => logout();

const WalletInfo = () => (
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,14 +5,16 @@ import { Wallet } from "iconoir-react";

import { useSelectedChain } from "@src/context/CustomChainProvider";
import { cn } from "@src/utils/styleUtils";
import { useWallet } from "@src/context/WalletProvider";

interface Props extends ButtonProps {
children?: ReactNode;
className?: string;
}

export const ConnectWalletButton: React.FunctionComponent<Props> = ({ className = "", ...rest }) => {
const { connect, status, isWalletConnected, address } = useSelectedChain();
const { status, isWalletConnected, address } = useSelectedChain();
const { connectWallet } = useWallet();

// Define your custom function to call on successful connection
const onWalletConnectSuccess = () => {
Expand All @@ -29,7 +31,7 @@ export const ConnectWalletButton: React.FunctionComponent<Props> = ({ className
}, [status, address]); // Ensure to include address as a dependency if needed

return (
<Button variant="outline" onClick={connect} className={cn("border-primary", className)} {...rest} data-testid="connect-wallet-btn">
<Button variant="outline" onClick={connectWallet} className={cn("border-primary", className)} {...rest} data-testid="connect-wallet-btn">
<Wallet className="text-xs" />
<span className="ml-2 whitespace-nowrap">Connect Wallet</span>
</Button>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -46,7 +46,7 @@ export function CustomChainProvider({ children }: Props) {
}}
signerOptions={{
preferredSignType: () => "direct",
signingStargate: () => ({
signingStargate: (): any => ({
registry: customRegistry,
gasPrice: GasPrice.fromString("0.025uakt")
})
Expand Down
116 changes: 111 additions & 5 deletions apps/provider-console/src/context/WalletProvider/WalletProvider.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -4,10 +4,11 @@ import { useEffect, useState } from "react";
import { Snackbar } from "@akashnetwork/ui/components";
import { EncodeObject } from "@cosmjs/proto-signing";
import { SigningStargateClient } from "@cosmjs/stargate";
import { useManager } from "@cosmos-kit/react";
import { useChainWallet, useManager } from "@cosmos-kit/react";
import axios from "axios";
import { useRouter } from "next/navigation";
import { SnackbarKey, useSnackbar } from "notistack";
import { useSelectedNetwork } from "@src/hooks/useSelectedNetwork";

import { TransactionModal } from "@src/components/layout/TransactionModal";
import { useUsdcDenom } from "@src/hooks/useDenom";
Expand All @@ -20,6 +21,9 @@ import { useSelectedChain } from "../CustomChainProvider";
import { useSettings } from "../SettingsProvider";
import { jwtDecode } from "jwt-decode";
import { checkAndRefreshToken } from "@src/utils/tokenUtils";
import restClient from "@src/utils/restClient";
import { getNonceMessage, leapSignArbitrary, keplrSignArbitrary } from "@src/utils/walletUtils";
import authClient from "@src/utils/authClient";

type Balances = {
uakt: number;
Expand All @@ -39,13 +43,22 @@ type ContextType = {
setIsWalletArbitrarySigned: React.Dispatch<React.SetStateAction<boolean>>;
signAndBroadcastTx: (msgs: EncodeObject[]) => Promise<any>;
refreshBalances: (address?: string) => Promise<Balances>;
isProvider: boolean;
isOnline: boolean;
provider: any; // Replace 'any' with a more specific type if available
isProviderStatusFetched: boolean;
handleArbitrarySigning: () => Promise<void>;
};

const WalletProviderContext = React.createContext<ContextType>({} as ContextType);

export const WalletProvider = ({ children }) => {
const [walletBalances, setWalletBalances] = useState<Balances | null>(null);
const [isWalletLoaded, setIsWalletLoaded] = useState<boolean>(true);
const [isWalletProvider, setIsWalletProvider] = useState<boolean>(false);
const [isWalletProviderOnline, setIsWalletProviderOnline] = useState<boolean>(false);
const [provider, setProvider] = useState<any>(null);
const [isProviderStatusFetched, setIsProviderStatusFetched] = useState<boolean>(false);
const [isBroadcastingTx, setIsBroadcastingTx] = useState<boolean>(false);
const [isWaitingForApproval, setIsWaitingForApproval] = useState<boolean>(false);
const [isWalletArbitrarySigned, setIsWalletArbitrarySigned] = useState<boolean>(false);
Expand All @@ -54,8 +67,23 @@ export const WalletProvider = ({ children }) => {
const router = useRouter();
const { settings } = useSettings();
const usdcIbcDenom = useUsdcDenom();
const { disconnect, getOfflineSigner, isWalletConnected, address: walletAddress, connect, username, estimateFee, sign, broadcast } = useSelectedChain();
const {
disconnect,
getOfflineSigner,
isWalletConnected,
address: walletAddress,
connect,
username,
estimateFee,
sign,
broadcast,
wallet,
signArbitrary
} = useSelectedChain();
const { addEndpoints } = useManager();
const selectedNetwork = useSelectedNetwork();
// const { signArbitrary: keplrSignArbitrary } = useChainWallet("akash", "keplr-extension");
// const { signArbitrary: leapSignArbitrary } = useChainWallet("akash", "leap-extension");
// const {
// fee: { default: feeGranter }
// } = useAllowance();
Expand All @@ -80,6 +108,10 @@ export const WalletProvider = ({ children }) => {
if (validAccessToken) {
console.log("Access token is valid");
setIsWalletArbitrarySigned(true);
await fetchProviderStatus();

await fetchProviderStatus();
setIsProviderStatusFetched(true);
} else {
console.log("No valid access token found");
setIsWalletArbitrarySigned(false);
Expand All @@ -93,6 +125,20 @@ export const WalletProvider = ({ children }) => {
})();
}, [settings?.rpcEndpoint, isWalletConnected]);

const fetchProviderStatus = async () => {
try {
const isProviderResponse: any = await restClient.get(`/provider/status/onchain?chainid=${selectedNetwork.chainId}`);
setIsWalletProvider(isProviderResponse.provider ? true : false);
setProvider(isProviderResponse.provider);
if (isProviderResponse.provider) {
const isOnlineResponse: any = await restClient.get(`/provider/status/online?chainid=${selectedNetwork.chainId}`);
setIsWalletProviderOnline(isOnlineResponse.online);
}
} catch (error) {
console.error("Error fetching provider status:", error);
}
};

async function createStargateClient() {
const selectedNetwork = getSelectedNetwork();

Expand Down Expand Up @@ -130,25 +176,78 @@ export const WalletProvider = ({ children }) => {
localStorage.removeItem("walletAddress");
setWalletBalances(null);
disconnect();
setIsWalletArbitrarySigned(false);
setIsProviderStatusFetched(false);
setIsWalletProvider(false);
setIsWalletProviderOnline(false);
setProvider(null);
router.push(UrlService.home());
}

async function connectWallet() {
console.log("Connecting wallet with CosmosKit...");
connect();
await connect();
// console.log("Connected wallet with CosmosKit");
// await loadWallet();
// await handleArbitrarySigning();
// console.log("Wallet address", walletAddress);
}

await loadWallet();
async function handleArbitrarySigning() {
console.log("Access token", localStorage.getItem("accessToken"));
console.log("Wallet address", walletAddress);
if (!localStorage.getItem("accessToken") && walletAddress) {
console.log("Handling arbitrary signing");
try {
const response: any = await authClient.get(`users/nonce/${walletAddress}`);
if (response?.data?.nonce) {
const message = getNonceMessage(response.data.nonce, walletAddress);

// const signArbitrary = username === "leap-extension" ? leapSignArbitrary : keplrSignArbitrary;
// const signArbitrary = wallet?.name === "leap-extension" ? leapSignArbitrary : keplrSignArbitrary;

const result = await signArbitrary(walletAddress, message);

if (result) {
const verifySign = await authClient.post("auth/verify", { signer: walletAddress, ...result });
if (verifySign.data) {
localStorage.setItem("accessToken", verifySign.data.access_token);
localStorage.setItem("refreshToken", verifySign.data.refresh_token);
localStorage.setItem("walletAddress", walletAddress);
setIsWalletArbitrarySigned(true);
} else {
throw new Error("Verification failed");
}
} else {
throw new Error("Signing failed");
}
} else {
if (response.status === "error" && response.error.code === "N4040") {
await authClient.post("users", { address: walletAddress });
await handleArbitrarySigning();
} else {
throw new Error("Invalid nonce response");
}
}
} catch (error) {
console.error("Error during arbitrary signing:", error);
logout();
setIsWalletArbitrarySigned(false);
}
}
}

// Update balances on wallet address change
useEffect(() => {
if (walletAddress) {
loadWallet();
handleArbitrarySigning();
}
}, [walletAddress]);

async function loadWallet(): Promise<void> {
const selectedNetwork = getSelectedNetwork();
console.log("selectedNetwork", selectedNetwork);
const storageWallets = JSON.parse(localStorage.getItem(`${selectedNetwork.id}/wallets`) || "[]") as LocalWalletDataType[];

let currentWallets = storageWallets ?? [];
Expand Down Expand Up @@ -269,6 +368,8 @@ export const WalletProvider = ({ children }) => {
const _address = address || walletAddress;
const client = await getStargateClient();

console.log("client", client);
// console.log("address", _address);
if (client) {
const balances = await client.getAllBalances(_address as string);
const uaktBalance = balances.find(b => b.denom === uAktDenom);
Expand Down Expand Up @@ -304,7 +405,12 @@ export const WalletProvider = ({ children }) => {
logout,
setIsWalletLoaded,
signAndBroadcastTx,
refreshBalances
refreshBalances,
isProvider: isWalletProvider,
isOnline: isWalletProviderOnline,
provider: provider,
isProviderStatusFetched,
handleArbitrarySigning
}}
>
{children}
Expand Down
Loading

0 comments on commit d4288b3

Please sign in to comment.