Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions .eslintrc.js
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ const nextConfig = require("@akashnetwork/dev-config/.eslintrc.next");

module.exports = {
...baseConfig,
root: true,
settings: {
next: {
rootDir: "apps/*"
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -109,22 +109,13 @@ describe(DeploymentDetailTopBar.name, () => {
expect(screen.queryByText("Redeploy")).not.toBeInTheDocument();
});

it("renders auto top-up section when wallet is managed", () => {
setup({
deployment: createDeployment({ state: "active" }),
wallet: { isManaged: true }
it("renders auto top-up section", () => {
const deps = setup({
deployment: createDeployment({ state: "active" })
});

expect(screen.getByText("Auto top-up")).toBeInTheDocument();
});

it("does not render auto top-up section when wallet is not managed", () => {
setup({
deployment: createDeployment({ state: "active" }),
wallet: { isManaged: false }
});

expect(screen.queryByText("Auto top-up")).not.toBeInTheDocument();
expect(deps.Switch).toHaveBeenCalledWith(expect.objectContaining({ checked: false, disabled: false, onCheckedChange: expect.any(Function) }), {});
});
Comment thread
coderabbitai[bot] marked this conversation as resolved.

it("renders DeploymentDepositModal after Add funds click", () => {
Expand Down Expand Up @@ -244,18 +235,18 @@ describe(DeploymentDetailTopBar.name, () => {
})) as typeof DEPENDENCIES.useLocalNotes,
useWallet: vi.fn(() => ({
signAndBroadcastTx: input?.wallet?.signAndBroadcastTx ?? vi.fn(() => Promise.resolve(true)),
isManaged: input?.wallet?.isManaged ?? false,
denom: input?.wallet?.denom ?? "uakt",
isManaged: true,
denom: input?.wallet?.denom ?? "uact",
address: "akash1test",
walletName: "test",
isWalletConnected: true,
isWalletLoaded: true,
connectManagedWallet: vi.fn(),
logout: vi.fn(),
isCustodial: false,
isWalletLoading: false,
isTrialing: false,
isOnboarding: false,
topUpMinAmountUsd: 20,
hasManagedWallet: false
})) as typeof DEPENDENCIES.useWallet,
usePricing: vi.fn(() => ({
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -244,28 +244,26 @@ export const DeploymentDetailTopBar: React.FunctionComponent<Props> = ({
Add funds
</d.Button>

{wallet.isManaged && (
<div className="ml-4 flex items-center gap-2">
<d.Switch checked={deploymentSetting.data?.autoTopUpEnabled} onCheckedChange={setAutoTopUpEnabled} disabled={deploymentSetting.isLoading} />
<span>Auto top-up</span>
<d.CustomTooltip
title={
<div className="space-y-2">
<div>
<div>Estimated amount: ${udenomToUsd(deploymentSetting.data?.estimatedTopUpAmount || 0, wallet.denom)}</div>
<div>Check period: {formatDuration(intervalToDuration({ start: 0, end: deploymentSetting.data?.topUpFrequencyMs || 0 }))}</div>
</div>
<div className="text-xs text-muted-foreground">
Auto top-up will only occur if there are insufficient funds to maintain the deployment until the next scheduled check.
</div>
<div className="ml-4 flex items-center gap-2">
<d.Switch checked={deploymentSetting.data?.autoTopUpEnabled} onCheckedChange={setAutoTopUpEnabled} disabled={deploymentSetting.isLoading} />
<span>Auto top-up</span>
<d.CustomTooltip
title={
<div className="space-y-2">
<div>
<div>Estimated amount: ${udenomToUsd(deploymentSetting.data?.estimatedTopUpAmount || 0, wallet.denom)}</div>
<div>Check period: {formatDuration(intervalToDuration({ start: 0, end: deploymentSetting.data?.topUpFrequencyMs || 0 }))}</div>
</div>
}
>
<span className="cursor-help text-muted-foreground">ⓘ</span>
</d.CustomTooltip>
{deploymentSetting.isLoading && <d.Spinner size="small" />}
</div>
)}
<div className="text-xs text-muted-foreground">
Auto top-up will only occur if there are insufficient funds to maintain the deployment until the next scheduled check.
</div>
</div>
}
>
<span className="cursor-help text-muted-foreground">ⓘ</span>
</d.CustomTooltip>
{deploymentSetting.isLoading && <d.Spinner size="small" />}
</div>
</div>
)}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ import type { ReactNode } from "react";
import { CustomTooltip } from "@akashnetwork/ui/components";
import formatDistanceToNow from "date-fns/formatDistanceToNow";
import isValid from "date-fns/isValid";
import { InfoCircle, WarningCircle } from "iconoir-react";
import { WarningCircle } from "iconoir-react";

import { CopyTextToClipboardButton } from "@src/components/shared/CopyTextToClipboardButton";
import { LabelValue } from "@src/components/shared/LabelValue";
Expand All @@ -15,10 +15,8 @@ import { useServices } from "@src/context/ServicesProvider";
import { useWallet } from "@src/context/WalletProvider";
import { useDeploymentMetrics } from "@src/hooks/useDeploymentMetrics";
import { useTrialDeploymentTimeRemaining } from "@src/hooks/useTrialDeploymentTimeRemaining";
import { useDenomData } from "@src/hooks/useWalletBalance";
import type { DeploymentDto, LeaseDto } from "@src/types/deployment";
import { udenomToDenom } from "@src/utils/mathHelpers";
import { getAvgCostPerMonth } from "@src/utils/priceUtils";

type Props = {
deployment: DeploymentDto;
Expand All @@ -28,13 +26,11 @@ type Props = {

export const DeploymentSubHeader: React.FunctionComponent<Props> = ({ deployment, leases }) => {
const { deploymentCost, realTimeLeft } = useDeploymentMetrics({ deployment, leases });
const avgCost = udenomToDenom(getAvgCostPerMonth(deploymentCost));
const isActive = deployment.state === "active";
const hasLeases = !!leases && leases.length > 0;
const hasActiveLeases = hasLeases && leases.some(l => l.state === "active");
const hasGpu = leases?.some(l => l.state === "active" && l.gpuAmount && l.gpuAmount > 0);
const denomData = useDenomData(deployment.escrowAccount.state.funds[0]?.denom || "");
const { isCustodial, isTrialing } = useWallet();
const { isTrialing } = useWallet();
const { publicConfig: appConfig } = useServices();

const trialDuration = appConfig.NEXT_PUBLIC_TRIAL_DEPLOYMENTS_DURATION_HOURS;
Expand All @@ -56,22 +52,6 @@ export const DeploymentSubHeader: React.FunctionComponent<Props> = ({ deployment
denom={deployment.escrowAccount.state.funds[0]?.denom || ""}
value={udenomToDenom(isActive && hasActiveLeases && realTimeLeft ? realTimeLeft?.escrow : deployment.escrowBalance, 6)}
/>
{isCustodial && (
<CustomTooltip
title={
<>
<strong>
{udenomToDenom(isActive && hasActiveLeases && realTimeLeft ? realTimeLeft?.escrow : deployment.escrowBalance, 6)}&nbsp;
{denomData?.label}
</strong>
<br />
The escrow account balance will be fully returned to your wallet balance when the deployment is closed.{" "}
</>
}
>
<InfoCircle className="text-xs text-muted-foreground" />
</CustomTooltip>
)}

{isActive && hasActiveLeases && !!realTimeLeft && realTimeLeft.escrow <= 0 && (
<CustomTooltip title="Your deployment is out of funds and can be closed by your provider at any time now. You can add funds to keep active.">
Expand All @@ -92,18 +72,6 @@ export const DeploymentSubHeader: React.FunctionComponent<Props> = ({ deployment
perBlockValue={udenomToDenom(deploymentCost, 10)}
showAsHourly={hasGpu}
/>

{isCustodial && (
<CustomTooltip
title={
<span>
{avgCost} {denomData?.label} / month
</span>
}
>
<InfoCircle className="text-xs text-muted-foreground" />
</CustomTooltip>
)}
</div>
)
}
Expand All @@ -117,19 +85,6 @@ export const DeploymentSubHeader: React.FunctionComponent<Props> = ({ deployment
denom={deployment.escrowAccount.state.funds[0]?.denom || ""}
value={udenomToDenom(isActive && hasActiveLeases && realTimeLeft ? realTimeLeft?.amountSpent : parseFloat(deployment.transferred.amount), 6)}
/>

{isCustodial && (
<CustomTooltip
title={
<span>
{udenomToDenom(isActive && hasActiveLeases && realTimeLeft ? realTimeLeft?.amountSpent : parseFloat(deployment.transferred.amount), 6)}{" "}
{denomData?.label}
</span>
}
>
<InfoCircle className="text-xs text-muted-foreground" />
</CustomTooltip>
)}
</div>
}
/>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -326,16 +326,16 @@ describe(ManifestUpdate.name, () => {
({
address: input?.wallet?.address || "akash1test",
signAndBroadcastTx: input?.wallet?.signAndBroadcastTx || vi.fn(),
isManaged: input?.wallet?.isManaged ?? false,
isManaged: true,
walletName: "",
isWalletConnected: true,
isWalletLoaded: true,
connectManagedWallet: vi.fn(),
logout: vi.fn(),
isCustodial: false,
isWalletLoading: false,
isTrialing: false,
isOnboarding: false,
topUpMinAmountUsd: 20,
hasManagedWallet: false,
denom: "uact"
}) as ReturnType<typeof DEPENDENCIES.useWallet>;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -70,10 +70,10 @@ export const ManifestUpdate: React.FunctionComponent<Props> = ({
const [deploymentVersion, setDeploymentVersion] = useState<string | null>(null);
const [showOutsideDeploymentMessage, setShowOutsideDeploymentMessage] = useState(false);
const [isSendingManifest, setIsSendingManifest] = useState(false);
const { address, signAndBroadcastTx, isManaged: isManagedWallet } = d.useWallet();
const { address, signAndBroadcastTx } = d.useWallet();
const { data: providers } = d.useProviderList();
const providerCredentials = d.useProviderCredentials();
const { enqueueSnackbar, closeSnackbar } = d.useSnackbar();
const { enqueueSnackbar } = d.useSnackbar();
const { settings } = d.useSettings();

useEffect(() => {
Expand Down Expand Up @@ -126,7 +126,7 @@ export const ManifestUpdate: React.FunctionComponent<Props> = ({
}

async function handleUpdateClick() {
let response, sendManifestKey;
let response;

try {
const doc = yaml.load(editedManifest);
Expand All @@ -150,13 +150,6 @@ export const ManifestUpdate: React.FunctionComponent<Props> = ({
manifestVersion: dd.hash
});

sendManifestKey =
!isManagedWallet &&
enqueueSnackbar(<d.Snackbar title="Deploying! 🚀" subTitle="Please wait a few seconds..." showLoading />, {
variant: "info",
autoHideDuration: null
});

const leaseProviders = leases.map(lease => lease.provider).filter((v, i, s) => s.indexOf(v) === i);

for (const provider of leaseProviders) {
Expand All @@ -170,11 +163,6 @@ export const ManifestUpdate: React.FunctionComponent<Props> = ({
});

setIsSendingManifest(false);

if (sendManifestKey) {
closeSnackbar(sendManifestKey);
}

closeManifestEditor();
}
} catch (error: any) {
Expand All @@ -185,10 +173,6 @@ export const ManifestUpdate: React.FunctionComponent<Props> = ({
console.error(error);
}
setIsSendingManifest(false);

if (sendManifestKey) {
closeSnackbar(sendManifestKey);
}
}
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -34,7 +34,7 @@ describe(YourAccount.name, () => {

expect(AccountHeaderMock).toHaveBeenCalledWith(
expect.objectContaining({
isManagedWallet: false,
isManagedWallet: true,
isBlockchainDown: false
}),
expect.anything()
Expand Down Expand Up @@ -71,7 +71,7 @@ describe(YourAccount.name, () => {
expect.objectContaining({
walletBalance,
activeDeploymentsCount: 0,
isManagedWallet: false
isManagedWallet: true
}),
expect.anything()
);
Expand Down Expand Up @@ -304,11 +304,12 @@ describe(YourAccount.name, () => {
connectManagedWallet: vi.fn(),
logout: vi.fn(),
signAndBroadcastTx: vi.fn(),
isManaged: input.wallet?.isManaged ?? false,
isCustodial: false,
isManaged: true,
denom: "uact",
isWalletLoading: false,
isTrialing: false,
isOnboarding: false,
topUpMinAmountUsd: 20,
hasManagedWallet: false
}) as ReturnType<typeof DEPENDENCIES.useWallet>;

Expand Down
10 changes: 3 additions & 7 deletions apps/deploy-web/src/components/layout/AccountMenu.spec.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,6 @@ import { AccountMenu } from "./AccountMenu";

import { render, screen } from "@testing-library/react";
import userEvent from "@testing-library/user-event";
import { buildWallet } from "@tests/seeders/wallet";
import { TestContainerProvider } from "@tests/unit/TestContainerProvider";

describe(AccountMenu.name, () => {
Expand Down Expand Up @@ -57,11 +56,10 @@ describe(AccountMenu.name, () => {
expect(authService.logout).toHaveBeenCalledTimes(1);
});

it("shows Billing & Usage when flag, userId, and managed wallet are all present", async () => {
it("shows Billing & Usage when flag and userId are both present", async () => {
setup({
username: "carol",
userId: "user-1",
isManagedWallet: true,
isBillingUsageEnabled: true
});

Expand All @@ -74,7 +72,6 @@ describe(AccountMenu.name, () => {
setup({
username: "dan",
userId: "user-1",
isManagedWallet: true,
isBillingUsageEnabled: false
});

Expand All @@ -84,7 +81,7 @@ describe(AccountMenu.name, () => {
expect(screen.queryByText("Billing & Usage")).not.toBeInTheDocument();
});

function setup(input: { isLoading?: boolean; username?: string; userId?: string; isManagedWallet?: boolean; isBillingUsageEnabled?: boolean }) {
function setup(input: { isLoading?: boolean; username?: string; userId?: string; isBillingUsageEnabled?: boolean }) {
const push = vi.fn();
const authService = mock<AuthService>();

Expand All @@ -95,8 +92,7 @@ describe(AccountMenu.name, () => {
isLoading: input.isLoading ?? false
}),
useRouter: () => mock<ReturnType<typeof DEPENDENCIES.useRouter>>({ push }),
useFlag: flagName => (flagName === "billing_usage" && input.isBillingUsageEnabled) ?? false,
useWallet: () => buildWallet({ isManaged: input.isManagedWallet ?? false })
useFlag: flagName => (flagName === "billing_usage" && input.isBillingUsageEnabled) ?? false
};

render(
Expand Down
6 changes: 2 additions & 4 deletions apps/deploy-web/src/components/layout/AccountMenu.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -14,12 +14,11 @@ import { GraphUp, Key, LogOut, MultiplePages, Settings, Star, User } from "icono
import { useRouter } from "next/navigation";

import { useServices } from "@src/context/ServicesProvider";
import { useWallet } from "@src/context/WalletProvider";
import { useCustomUser } from "@src/hooks/useCustomUser";
import { useFlag } from "@src/hooks/useFlag";
import { CustomDropdownLinkItem } from "../shared/CustomDropdownLinkItem";

export const DEPENDENCIES = { useCustomUser, useRouter, useFlag, useWallet };
export const DEPENDENCIES = { useCustomUser, useRouter, useFlag };

interface Props {
dependencies?: typeof DEPENDENCIES;
Expand All @@ -30,7 +29,6 @@ export function AccountMenu({ dependencies: d = DEPENDENCIES }: Props = {}) {
const username = user?.username;
const router = d.useRouter();
const isBillingUsageEnabled = d.useFlag("billing_usage");
const wallet = d.useWallet();
const { authService, urlService } = useServices();

return (
Expand Down Expand Up @@ -81,7 +79,7 @@ export function AccountMenu({ dependencies: d = DEPENDENCIES }: Props = {}) {
<CustomDropdownLinkItem onClick={() => router.push(urlService.userFavorites())} icon={<Star />}>
Favorites
</CustomDropdownLinkItem>
{isBillingUsageEnabled && user?.userId && wallet.isManaged && (
{isBillingUsageEnabled && user?.userId && (
<CustomDropdownLinkItem onClick={() => router.push(urlService.billing())} icon={<GraphUp />}>
Billing & Usage
</CustomDropdownLinkItem>
Expand Down
Loading
Loading