diff --git a/packages/keychain/src/components/Auth/Login.tsx b/packages/keychain/src/components/Auth/Login.tsx index 24391ea72..cf0a7ad2c 100644 --- a/packages/keychain/src/components/Auth/Login.tsx +++ b/packages/keychain/src/components/Auth/Login.tsx @@ -2,7 +2,11 @@ import { Field } from "@cartridge/ui"; import { VStack, Button } from "@chakra-ui/react"; import { Container } from "../Container"; import { Form as FormikForm, Field as FormikField, Formik } from "formik"; -import { PORTAL_FOOTER_MIN_HEIGHT, PortalBanner, PortalFooter } from "components"; +import { + PORTAL_FOOTER_MIN_HEIGHT, + PortalBanner, + PortalFooter, +} from "components"; import { useCallback, useState } from "react"; import Controller from "utils/controller"; import { FormValues, LoginProps } from "./types"; @@ -43,12 +47,12 @@ export function Login({ } = await fetchAccount(values.username); address = contractAddress; - await doLogin(values.username, credentialId, publicKey) - onSuccess(new Controller(address, publicKey, credentialId)) + await doLogin(values.username, credentialId, publicKey); + onSuccess(new Controller(address, publicKey, credentialId)); log({ type: "webauthn_login", address }); } catch (e) { - setError(e) + setError(e); log({ type: "webauthn_login_error", @@ -56,10 +60,10 @@ export function Login({ error: e?.message, }, address, - }) + }); } - setIsLoading(false) + setIsLoading(false); }, [log, onSuccess], ); diff --git a/packages/keychain/src/components/Container/index.tsx b/packages/keychain/src/components/Container/index.tsx index 8e58c0552..3b0e58d02 100644 --- a/packages/keychain/src/components/Container/index.tsx +++ b/packages/keychain/src/components/Container/index.tsx @@ -60,7 +60,7 @@ export function Container({ ); } -export const FOOTER_HEIGHT = 40 +export const FOOTER_HEIGHT = 40; function Wrapper({ children }: React.PropsWithChildren) { return ( diff --git a/packages/keychain/src/components/Execute/LowEth.tsx b/packages/keychain/src/components/Execute/LowEth.tsx index f0bf29df2..f4e738f84 100644 --- a/packages/keychain/src/components/Execute/LowEth.tsx +++ b/packages/keychain/src/components/Execute/LowEth.tsx @@ -1,102 +1,96 @@ -import { Button, Circle, HStack, Spacer, Text, VStack } from "@chakra-ui/react"; -import { AlertIcon } from "@cartridge/ui"; +import { CopyIcon, EthereumIcon, StarknetIcon } from "@cartridge/ui"; +import { HStack, Spacer, Text, VStack } from "@chakra-ui/react"; +import { Container } from "components/Container"; +import { PortalBanner } from "components/PortalBanner"; +import { useState } from "react"; +import { BigNumberish, constants } from "starknet"; +import { formatAddress } from "utils/contracts"; -export interface LowEthInfo { - label: string; - balance: string; - max: string; - lowAmount: string; - reject: () => void; - onBridge: () => void; -} - -export function LowEth({ - label, +const NewLowEth = ({ + chainId, + address, balance, - max, - lowAmount, - reject, - onBridge, -}: LowEthInfo) { +}: { + chainId: constants.StarknetChainId; + address: BigNumberish; + balance: BigNumberish; +}) => { + const [copied, setCopied] = useState(false); return ( - - - - - {label} - - - - + + - - {`~${lowAmount}`} - - {`Bal: ${balance}`} - {`Max: ${max}`} + + + + BALANCE + + + + {" "} + {balance} + + + Sepolia + - - - - - - - - - Insufficient Funds + + + ADDRESS - - - - You do not have enough ETH to complete the above transaction - - - - - - - + { + navigator.clipboard.writeText(address.toString()); + setCopied(true); + }} + > + {formatAddress(address)} + + + + + {copied && ( + + + COPIED + + + )} + - + ); -} +}; + +export default NewLowEth; diff --git a/packages/keychain/src/components/Execute/index.tsx b/packages/keychain/src/components/Execute/index.tsx index c0695900c..25eeab225 100644 --- a/packages/keychain/src/components/Execute/index.tsx +++ b/packages/keychain/src/components/Execute/index.tsx @@ -1,5 +1,5 @@ import { useCallback, useEffect, useMemo, useState } from "react"; -import { Text, VStack, Spacer, Button } from "@chakra-ui/react"; +import { Text, VStack, Button } from "@chakra-ui/react"; import Controller from "utils/controller"; import { @@ -14,8 +14,6 @@ import { formatEther } from "viem"; import { ExecuteReply, ResponseCodes } from "@cartridge/controller"; import { Container } from "../Container"; import { Status } from "utils/account"; -import { LowEth, LowEthInfo } from "./LowEth"; -import { BridgeEth } from "../bridge/BridgeEth"; import { PortalBanner } from "../PortalBanner"; import { TransactionDuoIcon } from "@cartridge/ui"; import { Call } from "./Call"; @@ -23,6 +21,7 @@ import { PORTAL_FOOTER_MIN_HEIGHT, PortalFooter, } from "components/PortalFooter"; +import LowEth from "./LowEth"; export const CONTRACT_ETH = "0x049d36570d4e46f48e99674bd3fcc84644ddd6b96f7c741b1562b82f9e004dc7"; @@ -56,8 +55,7 @@ export function Execute({ const [isLoading, setLoading] = useState(false); const [ethBalance, setEthBalance] = useState(); const [ethApproved, setEthApproved] = useState(); - const [lowEthInfo, setLowEthInfo] = useState(); - const [bridging, setBridging] = useState(false); + const [lowEth, setLowEth] = useState(false); const account = controller.account(chainId); const calls = useMemo(() => { @@ -146,25 +144,9 @@ export function Execute({ } if (ethBalance < ethApproved) { - setLowEthInfo({ - label: "Approved Eth", - balance: format(ethBalance), - max: format(ethApproved), - lowAmount: format((ethBalance - ethApproved) * -1n), - reject: onCancel, - onBridge: () => setBridging(true), - }); - } else if (fees?.max && ethBalance < ethApproved + fees.max) { - setLowEthInfo({ - label: "Network Fee", - balance: format(ethBalance), - max: format(ethApproved + fees.max), - lowAmount: format(ethBalance - (ethApproved + fees.max) * -1n), - reject: onCancel, - onBridge: () => setBridging(true), - }); + setLowEth(true); } - }, [ethBalance, ethApproved, fees?.max, onCancel]); + }, [ethBalance, ethApproved]); const onSubmit = useCallback(async () => { setLoading(true); @@ -177,15 +159,13 @@ export function Execute({ }); }, [account, calls, fees, onExecute]); - const onBack = useCallback(() => { - setBridging(false); - }, []); - - if (bridging) { + if (lowEth) { return ( - - - + ); } @@ -193,7 +173,7 @@ export function Execute({ - + @@ -216,35 +196,28 @@ export function Execute({ - {lowEthInfo ? ( - <> - - - - ) : ( - - - - - - - - - - )} + + + + + + + + + ); diff --git a/packages/keychain/src/pages/index.tsx b/packages/keychain/src/pages/index.tsx index 9d9a485ab..5cb5efbb1 100644 --- a/packages/keychain/src/pages/index.tsx +++ b/packages/keychain/src/pages/index.tsx @@ -187,11 +187,18 @@ const Index: NextPage = () => { } if (!transactionsDetail.maxFee) { - transactionsDetail.maxFee = ( - await account.estimateInvokeFee(calls, { + try { + const estFee = await account.estimateInvokeFee(calls, { nonce: transactionsDetail.nonce, - }) - ).suggestedMaxFee; + }); + + transactionsDetail.maxFee = estFee.suggestedMaxFee; + } catch (e) { + return Promise.resolve({ + code: ResponseCodes.NOT_ALLOWED, + message: e.message, + }); + } } if (