diff --git a/apps/deploy-web/src/components/deployments/DeploymentDepositModal.tsx b/apps/deploy-web/src/components/deployments/DeploymentDepositModal.tsx index 66e9a6001..f83a59f08 100644 --- a/apps/deploy-web/src/components/deployments/DeploymentDepositModal.tsx +++ b/apps/deploy-web/src/components/deployments/DeploymentDepositModal.tsx @@ -30,11 +30,14 @@ import { UAKT_DENOM } from "@src/config/denom.config"; import { usePricing } from "@src/context/PricingProvider"; import { useSettings } from "@src/context/SettingsProvider"; import { useWallet } from "@src/context/WalletProvider"; +import { useAddFundsVerifiedLoginRequiredEventHandler } from "@src/hooks/useAddFundsVerifiedLoginRequiredEventHandler"; import { useDenomData, useWalletBalance } from "@src/hooks/useWalletBalance"; import { useGranteeGrants } from "@src/queries/useGrantsQuery"; +import { ServiceType } from "@src/types"; import { AnalyticsCategory, AnalyticsEvents } from "@src/types/analytics"; import { denomToUdenom, udenomToDenom } from "@src/utils/mathHelpers"; import { coinToUDenom } from "@src/utils/priceUtils"; +import { LeaseSpecDetail } from "../shared/LeaseSpecDetail"; import { LinkTo } from "../shared/LinkTo"; import { GranteeDepositMenuItem } from "./GranteeDepositMenuItem"; @@ -45,6 +48,8 @@ export type DeploymentDepositModalProps = { onDeploymentDeposit: (deposit: number, depositorAddress: string) => void; handleCancel: () => void; children?: ReactNode; + title?: string; + services?: ServiceType[]; }; const formSchema = z @@ -73,7 +78,9 @@ export const DeploymentDepositModal: React.FunctionComponent { const formRef = useRef(null); const { settings } = useSettings(); @@ -96,6 +103,17 @@ export const DeploymentDepositModal: React.FunctionComponent compareAsc(new Date(), new Date(x.expiration)) !== 1 && x.authorization.spend_limit.denom === denom) || []; + const whenLoggedInAndVerified = useAddFundsVerifiedLoginRequiredEventHandler(); + + const closePopupAndGoToCheckoutIfPossible = (event: React.MouseEvent) => { + handleCancel(); + + whenLoggedInAndVerified(goToCheckout)(event); + }; + + const goToCheckout = () => { + window.location.href = "/api/proxy/v1/checkout"; + }; useEffect(() => { if (depositData && amount === 0 && !disableMin) { @@ -225,10 +243,29 @@ export const DeploymentDepositModal: React.FunctionComponent + {services.length > 0 && ( +
+ {services.map(service => { + return ( + +
+ {service.title}:{service.image} +
+
+ + {!!service.profile?.gpu && } + + +
+
+ ); + })} +
+ )} +
{infoText} @@ -259,6 +296,13 @@ export const DeploymentDepositModal: React.FunctionComponent + {isManaged && ( +
+ + Buy more credits + +
+ )} {isCustodial && ( diff --git a/apps/deploy-web/src/components/new-deployment/ManifestEdit.tsx b/apps/deploy-web/src/components/new-deployment/ManifestEdit.tsx index e50d98e3b..46552504b 100644 --- a/apps/deploy-web/src/components/new-deployment/ManifestEdit.tsx +++ b/apps/deploy-web/src/components/new-deployment/ManifestEdit.tsx @@ -14,10 +14,8 @@ import { useSnackbar } from "notistack"; import { browserEnvConfig } from "@src/config/browser-env.config"; import { useCertificate } from "@src/context/CertificateProvider"; -import { useChainParam } from "@src/context/ChainParamProvider"; import { useSdlBuilder } from "@src/context/SdlBuilderProvider/SdlBuilderProvider"; import { useWallet } from "@src/context/WalletProvider"; -import { useManagedDeploymentConfirm } from "@src/hooks/useManagedDeploymentConfirm"; import { useManagedWalletDenom } from "@src/hooks/useManagedWalletDenom"; import { useWhen } from "@src/hooks/useWhen"; import { useDepositParams } from "@src/queries/useSettings"; @@ -37,6 +35,7 @@ import { domainName, handleDocClick, UrlService } from "@src/utils/urlUtils"; import { updateWallet } from "@src/utils/walletUtils"; import { useSettings } from "../../context/SettingsProvider"; import { DeploymentDepositModal } from "../deployments/DeploymentDepositModal"; +import { DeploymentMinimumEscrowAlertText } from "../sdl/DeploymentMinimumEscrowAlertText"; import { CustomNextSeo } from "../shared/CustomNextSeo"; import { DynamicMonacoEditor } from "../shared/DynamicMonacoEditor"; import { LinkTo } from "../shared/LinkTo"; @@ -67,6 +66,7 @@ export const ManifestEdit: React.FunctionComponent = ({ const [selectedSdlEditMode, setSelectedSdlEditMode] = useAtom(sdlStore.selectedSdlEditMode); const [isRepoInputValid, setIsRepoInputValid] = useState(false); const [sdlDenom, setSdlDenom] = useState("uakt"); + const { settings } = useSettings(); const { address, signAndBroadcastTx, isManaged, isTrialing } = useWallet(); const router = useRouter(); @@ -75,7 +75,6 @@ export const ManifestEdit: React.FunctionComponent = ({ const muiTheme = useMuiTheme(); const smallScreen = useMediaQuery(muiTheme.breakpoints.down("md")); const sdlBuilderRef = useRef(null); - const { minDeposit } = useChainParam(); const { hasComponent } = useSdlBuilder(); const searchParams = useSearchParams(); const templateId = searchParams.get("templateId"); @@ -83,8 +82,8 @@ export const ManifestEdit: React.FunctionComponent = ({ const defaultDeposit = depositParams || browserEnvConfig.NEXT_PUBLIC_DEFAULT_INITIAL_DEPOSIT; const wallet = useWallet(); const managedDenom = useManagedWalletDenom(); - const { createDeploymentConfirm } = useManagedDeploymentConfirm(); const { enqueueSnackbar } = useSnackbar(); + const services = importSimpleSdl(editedManifest as string); useWhen( wallet.isManaged && sdlDenom === "uakt" && editedManifest, @@ -192,18 +191,12 @@ export const ManifestEdit: React.FunctionComponent = ({ } if (isManaged) { - const services = importSimpleSdl(editedManifest as string); - if (!services) { setParsingError("Error while parsing SDL file"); return; } - const isConfirmed = await createDeploymentConfirm(services); - - if (isConfirmed) { - await handleCreateClick(defaultDeposit, browserEnvConfig.NEXT_PUBLIC_MASTER_WALLET_ADDRESS); - } + setIsDepositingDeployment(true); } else { setIsCheckingPrerequisites(true); } @@ -429,14 +422,16 @@ export const ManifestEdit: React.FunctionComponent = ({ handleCancel={() => setIsDepositingDeployment(false)} onDeploymentDeposit={onDeploymentDeposit} denom={sdlDenom} + title="Confirm deployment creation?" infoText={ - To create a deployment, you need to have at least {minDeposit.akt} AKT or {minDeposit.usdc} USDC in an escrow account.{" "} + handleDocClick(ev, "https://akash.network/docs/other-resources/payments/")}> Learn more. } + services={services} /> )} {isCheckingPrerequisites && setIsCheckingPrerequisites(false)} onContinue={onPrerequisiteContinue} />} diff --git a/apps/deploy-web/src/components/sdl/DeploymentMinimumEscrowAlertText.tsx b/apps/deploy-web/src/components/sdl/DeploymentMinimumEscrowAlertText.tsx new file mode 100644 index 000000000..15fd6a63c --- /dev/null +++ b/apps/deploy-web/src/components/sdl/DeploymentMinimumEscrowAlertText.tsx @@ -0,0 +1,22 @@ +import { FC, useState } from "react"; + +import { useChainParam } from "@src/context/ChainParamProvider"; +import { useWallet } from "@src/context/WalletProvider"; +import { useDenomData } from "@src/hooks/useWalletBalance"; + +export const DeploymentMinimumEscrowAlertText: FC = () => { + const { isManaged } = useWallet(); + const [sdlDenom] = useState("uakt"); + const depositData = useDenomData(sdlDenom); + const { minDeposit } = useChainParam(); + + return isManaged ? ( + <> + To create a deployment, you need to have at least ${depositData?.min} in an escrow account.{" "} + + ) : ( + <> + To create a deployment, you need to have at least {minDeposit.akt} AKT or {minDeposit.usdc} USDC in an escrow account.{" "} + + ); +}; diff --git a/apps/deploy-web/src/components/sdl/RentGpusForm.tsx b/apps/deploy-web/src/components/sdl/RentGpusForm.tsx index a54a1e43f..34f3f12c9 100644 --- a/apps/deploy-web/src/components/sdl/RentGpusForm.tsx +++ b/apps/deploy-web/src/components/sdl/RentGpusForm.tsx @@ -12,10 +12,8 @@ import { event } from "nextjs-google-analytics"; import { browserEnvConfig } from "@src/config/browser-env.config"; import { useCertificate } from "@src/context/CertificateProvider"; -import { useChainParam } from "@src/context/ChainParamProvider"; import { useSettings } from "@src/context/SettingsProvider"; import { useWallet } from "@src/context/WalletProvider"; -import { useManagedDeploymentConfirm } from "@src/hooks/useManagedDeploymentConfirm"; import { useManagedWalletDenom } from "@src/hooks/useManagedWalletDenom"; import { useWhen } from "@src/hooks/useWhen"; import { useGpuModels } from "@src/queries/useGpuQuery"; @@ -41,6 +39,7 @@ import { LinkTo } from "../shared/LinkTo"; import { PrerequisiteList } from "../shared/PrerequisiteList"; import { AdvancedConfig } from "./AdvancedConfig"; import { CpuFormControl } from "./CpuFormControl"; +import { DeploymentMinimumEscrowAlertText } from "./DeploymentMinimumEscrowAlertText"; import { FormPaper } from "./FormPaper"; import { GpuFormControl } from "./GpuFormControl"; import { ImageSelect } from "./ImageSelect"; @@ -75,9 +74,7 @@ export const RentGpusForm: React.FunctionComponent = () => { const { address, signAndBroadcastTx, isManaged } = useWallet(); const { loadValidCertificates, localCert, isLocalCertMatching, loadLocalCert, setSelectedCertificate } = useCertificate(); const [sdlDenom, setSdlDenom] = useState("uakt"); - const { minDeposit } = useChainParam(); const router = useRouter(); - const { createDeploymentConfirm } = useManagedDeploymentConfirm(); const managedDenom = useManagedWalletDenom(); const { data: depositParams } = useDepositParams(); const defaultDeposit = depositParams || browserEnvConfig.NEXT_PUBLIC_DEFAULT_INITIAL_DEPOSIT; @@ -207,13 +204,7 @@ export const RentGpusForm: React.FunctionComponent = () => { setRentGpuSdl(data); if (isManaged) { - const isConfirmed = await createDeploymentConfirm(rentGpuSdl?.services as ServiceType[]); - - if (!isConfirmed) { - return; - } - - await handleCreateClick(defaultDeposit, browserEnvConfig.NEXT_PUBLIC_MASTER_WALLET_ADDRESS); + setIsDepositingDeployment(true); } else { setIsCheckingPrerequisites(true); } @@ -298,13 +289,15 @@ export const RentGpusForm: React.FunctionComponent = () => { infoText={

- To create a deployment, you need to have at least {minDeposit.akt} AKT or {minDeposit.usdc} USDC in an escrow account.{" "} + handleDocClick(ev, "https://akash.network/docs/getting-started/intro-to-akash/bids-and-leases/#escrow-accounts")}> Learn more.

} + title="Confirm deployment creation?" + services={rentGpuSdl?.services} /> )} {isCheckingPrerequisites && setIsCheckingPrerequisites(false)} onContinue={onPrerequisiteContinue} />} diff --git a/apps/deploy-web/src/hooks/useManagedDeploymentConfirm.tsx b/apps/deploy-web/src/hooks/useManagedDeploymentConfirm.tsx index 366bdca64..2581fa119 100644 --- a/apps/deploy-web/src/hooks/useManagedDeploymentConfirm.tsx +++ b/apps/deploy-web/src/hooks/useManagedDeploymentConfirm.tsx @@ -1,16 +1,8 @@ -import { FormattedNumber } from "react-intl"; -import { Alert, AlertDescription, AlertTitle } from "@akashnetwork/ui/components"; import { usePopup } from "@akashnetwork/ui/context"; -import { LeaseSpecDetail } from "@src/components/shared/LeaseSpecDetail"; -import { useChainParam } from "@src/context/ChainParamProvider"; import { useWallet } from "@src/context/WalletProvider"; -import { ServiceType } from "@src/types"; -import { useWalletBalance } from "./useWalletBalance"; export const useManagedDeploymentConfirm = () => { - const { minDeposit } = useChainParam(); - const { balance: walletBalance } = useWalletBalance(); const { isManaged } = useWallet(); const { confirm } = usePopup(); @@ -36,69 +28,5 @@ export const useManagedDeploymentConfirm = () => { return true; }; - const createDeploymentConfirm = async (services: ServiceType[]) => { - if (isManaged) { - const hasEnoughForDeposit = (walletBalance?.totalDeploymentGrantsUSD || 0) >= minDeposit.usdc; - - const isConfirmed = await confirm({ - title: "Confirm deployment creation?", - message: ( -
- {!hasEnoughForDeposit && ( - - Insufficient funds - -

- You need more than{" "} - {" "} - available to create a deployment. -

-

- Current available balance:{" "} - - - -

-
-
- )} - - {services.map(service => { - return ( - -
- {service.title}:{service.image} -
-
- - {service.profile?.hasGpu && } - - -
-
- ); - })} -
- ) - }); - - if (!isConfirmed) { - return false; - } - } - - return true; - }; - - return { closeDeploymentConfirm, createDeploymentConfirm }; + return { closeDeploymentConfirm }; };