diff --git a/web-wallet/CHANGELOG.md b/web-wallet/CHANGELOG.md
index 226559d9cd..c904d53912 100644
--- a/web-wallet/CHANGELOG.md
+++ b/web-wallet/CHANGELOG.md
@@ -9,6 +9,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
### Added
+- Add validation for "Use Max" button on Send / Stake flows [#2310]
- Add option to sync from a custom block height on Wallet Restoration [#1568]
- Show current block height on Wallet Creation [#1561]
- Added gas settings validation on Unstake / Widthdraw Rewards flows [#2000]
@@ -253,6 +254,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
[#2196]: https://github.com/dusk-network/rusk/issues/2196
[#2014]: https://github.com/dusk-network/rusk/issues/2014
[#2303]: https://github.com/dusk-network/rusk/issues/2303
+[#2310]: https://github.com/dusk-network/rusk/issues/2310
diff --git a/web-wallet/src/lib/components/Send/Send.svelte b/web-wallet/src/lib/components/Send/Send.svelte
index 948708226c..82ffa20b9d 100644
--- a/web-wallet/src/lib/components/Send/Send.svelte
+++ b/web-wallet/src/lib/components/Send/Send.svelte
@@ -3,7 +3,11 @@
@@ -102,13 +129,7 @@
diff --git a/web-wallet/src/lib/components/Stake/Stake.svelte b/web-wallet/src/lib/components/Stake/Stake.svelte
index ff665cc767..5a55a02341 100644
--- a/web-wallet/src/lib/components/Stake/Stake.svelte
+++ b/web-wallet/src/lib/components/Stake/Stake.svelte
@@ -22,7 +22,7 @@
Wizard,
WizardStep,
} from "$lib/dusk/components";
-
+ import { toast } from "$lib/dusk/components/Toast/store";
import {
AppAnchor,
AppAnchorButton,
@@ -146,6 +146,28 @@
return 2;
}
+
+ function setMaxAmount() {
+ if (!isGasValid) {
+ toast("error", "Please set valid gas settings first", mdiAlertOutline);
+ return;
+ }
+
+ if (spendable < luxToDusk(luxFee)) {
+ toast(
+ "error",
+ "You don't have enough DUSK to cover the transaction fee",
+ mdiAlertOutline
+ );
+ return;
+ }
+
+ if (stakeInput) {
+ stakeInput.value = maxSpendable.toString();
+ }
+
+ stakeAmount = maxSpendable;
+ }
@@ -215,13 +237,7 @@
diff --git a/web-wallet/src/lib/components/__tests__/Send.spec.js b/web-wallet/src/lib/components/__tests__/Send.spec.js
index 62c8820a8a..c13d1a2d65 100644
--- a/web-wallet/src/lib/components/__tests__/Send.spec.js
+++ b/web-wallet/src/lib/components/__tests__/Send.spec.js
@@ -81,6 +81,44 @@ describe("Send", () => {
expect(nextButton).toBeEnabled();
});
+ it("should not change the default amount (1) in the textbox if the user clicks the related button and the balance is zero", async () => {
+ const props = {
+ ...baseProps,
+ spendable: 0,
+ };
+ const { getByRole } = render(Send, props);
+
+ const useMaxButton = getByRole("button", { name: "USE MAX" });
+ const amountInput = getByRole("spinbutton");
+
+ expect(amountInput).toHaveValue(1);
+
+ await fireEvent.click(useMaxButton);
+
+ expect(amountInput).toHaveValue(1);
+ });
+
+ it("should not change the default amount (1) in the textbox if the user clicks the related button and the gas settings are invalid", async () => {
+ const props = {
+ ...baseProps,
+ gasSettings: {
+ ...baseProps.gasSettings,
+ gasLimit: 40000000,
+ gasPrice: 40000000,
+ },
+ };
+
+ const { getByRole } = render(Send, props);
+ const useMaxButton = getByRole("button", { name: "USE MAX" });
+ const amountInput = getByRole("spinbutton");
+
+ expect(amountInput).toHaveValue(1);
+
+ await fireEvent.click(useMaxButton);
+
+ expect(amountInput).toHaveValue(1);
+ });
+
it("should disable the next button if the user enters an invalid amount", async () => {
const { getByRole } = render(Send, baseProps);
const nextButton = getByRole("button", { name: "Next" });
diff --git a/web-wallet/src/lib/components/__tests__/Stake.spec.js b/web-wallet/src/lib/components/__tests__/Stake.spec.js
index f8a4b95545..1e21b8535a 100644
--- a/web-wallet/src/lib/components/__tests__/Stake.spec.js
+++ b/web-wallet/src/lib/components/__tests__/Stake.spec.js
@@ -142,6 +142,45 @@ describe("Stake", () => {
expect(amountInput).toHaveValue(maxSpendable);
});
+ it("should not change the default amount (min stake amount) in the textbox if the user clicks the related button and the balance is zero", async () => {
+ const props = {
+ ...baseProps,
+ spendable: 0,
+ };
+
+ const { getByRole } = render(Stake, props);
+
+ const useMaxButton = getByRole("button", { name: "USE MAX" });
+ const amountInput = getByRole("spinbutton");
+
+ expect(amountInput).toHaveValue(baseProps.minAllowedStake);
+
+ await fireEvent.click(useMaxButton);
+
+ expect(amountInput).toHaveValue(baseProps.minAllowedStake);
+ });
+
+ it("should not change the default amount (1) in the textbox if the user clicks the related button and the gas settings are invalid", async () => {
+ const props = {
+ ...baseProps,
+ gasSettings: {
+ ...baseProps.gasSettings,
+ gasLimit: 40000000,
+ gasPrice: 40000000,
+ },
+ };
+
+ const { getByRole } = render(Stake, props);
+ const useMaxButton = getByRole("button", { name: "USE MAX" });
+ const amountInput = getByRole("spinbutton");
+
+ expect(amountInput).toHaveValue(baseProps.minAllowedStake);
+
+ await fireEvent.click(useMaxButton);
+
+ expect(amountInput).toHaveValue(baseProps.minAllowedStake);
+ });
+
it("should disable the next button if the user enters an invalid amount", async () => {
const { getByRole } = render(Stake, baseOptions);
const nextButton = getByRole("button", { name: "Next" });