diff --git a/web-wallet/CHANGELOG.md b/web-wallet/CHANGELOG.md
index 6481471c8a..d706b92ea4 100644
--- a/web-wallet/CHANGELOG.md
+++ b/web-wallet/CHANGELOG.md
@@ -10,6 +10,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
### Added
- Added gas settings validation on Unstake / Widthdraw Rewards flows [#2000]
+- Added allocation (shield/unshield) page and UI [#2196]
### Changed
@@ -18,6 +19,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
- Update Transactions list design [#1922]
- Update Buttons to match the design system [#1606]
- Update `Stepper` component to new design [#2071]
+- Update dashboard to use routes instead of `Tabs` for navigation pattern [#2075]
### Fixed
diff --git a/web-wallet/README.md b/web-wallet/README.md
index ec583725a2..fd86c74669 100644
--- a/web-wallet/README.md
+++ b/web-wallet/README.md
@@ -33,6 +33,7 @@ N.B. the current `0.1.2` version of the library has no option to pick the networ
```
# can be empty string, must start with a slash otherwise, must not end with a slash
VITE_BASE_PATH=""
+VITE_CONTRACT_ALLOCATE_DISABLED=true
VITE_CONTRACT_STAKE_DISABLED=false
VITE_CONTRACT_TRANSFER_DISABLED=false
VITE_CURRENT_NODE=${VITE_LOCAL_NODE}
@@ -51,7 +52,6 @@ VITE_TESTNET_NODE="https://nodes.dusk.network/"
VITE_TESTNET_PROVER_NODE="https://provers.dusk.network/"
VITE_TRANSFER_CONTRACT="0100000000000000000000000000000000000000000000000000000000000000"
VITE_GET_QUOTE_API_ENDPOINT="https://api.dusk.network/v1/quote"
-VITE_MOONLIGHT_DISABLED=true
```
To run a local node different steps are needed, so please read the [related section](#running-a-local-rusk-node).
diff --git a/web-wallet/src/__mocks__/mockedOperationsStore.js b/web-wallet/src/__mocks__/mockedOperationsStore.js
new file mode 100644
index 0000000000..a28d7e379c
--- /dev/null
+++ b/web-wallet/src/__mocks__/mockedOperationsStore.js
@@ -0,0 +1,5 @@
+import { mockReadableStore } from "$lib/dusk/test-helpers";
+
+const content = { currentOperation: "something" };
+
+export default mockReadableStore(content);
diff --git a/web-wallet/src/routes/(app)/__mocks__/mockedWalletStore.js b/web-wallet/src/__mocks__/mockedWalletStore.js
similarity index 79%
rename from web-wallet/src/routes/(app)/__mocks__/mockedWalletStore.js
rename to web-wallet/src/__mocks__/mockedWalletStore.js
index 3d2c378327..bd2c41e7bd 100644
--- a/web-wallet/src/routes/(app)/__mocks__/mockedWalletStore.js
+++ b/web-wallet/src/__mocks__/mockedWalletStore.js
@@ -14,4 +14,6 @@ const content = {
isSyncing: false,
};
-export default mockReadableStore(content);
+const mockedWalletStore = mockReadableStore(content);
+
+export default mockedWalletStore;
diff --git a/web-wallet/src/lib/components/Allocate/Allocate.svelte b/web-wallet/src/lib/components/Allocate/Allocate.svelte
new file mode 100644
index 0000000000..e7714c5d07
--- /dev/null
+++ b/web-wallet/src/lib/components/Allocate/Allocate.svelte
@@ -0,0 +1,413 @@
+
+
+
+
+
+
+
+
+
+ Edit the value to change the allocation of your Dusk between your
+ shielded or public account.
+
+
+
+ Shielded
+
+
+
+ {middleEllipsis(
+ shieldedAddress,
+ calculateAdaptiveCharCount(screenWidth, 320, 640, 5, 20)
+ )}
+
+
+
+ {
+ unshieldedAmount = +(
+ shieldedBalance +
+ unshieldedBalance -
+ shieldedAmount
+ ).toFixed(9);
+ }}
+ />
+
+
+
+
+
+ Unshielded
+
+
+
+ {middleEllipsis(
+ unshieldedAddress,
+ calculateAdaptiveCharCount(screenWidth, 320, 640, 5, 20)
+ )}
+
+
+
+ {
+ shieldedAmount = +(
+ unshieldedBalance +
+ shieldedBalance -
+ unshieldedAmount
+ ).toFixed(9);
+ }}
+ />
+
+
+
+
+
{
+ isGasValid = areValidGasSettings(
+ event.detail.price,
+ event.detail.limit
+ );
+
+ if (isGasValid) {
+ gasPrice = event.detail.price;
+ gasLimit = event.detail.limit;
+ }
+ }}
+ />
+
+
+
+
+
+
+
+
+ Amount:
+
+
+
+ {isFromUnshielded
+ ? `${formatter(luxToDusk(duskToLux(unshieldedBalance) - duskToLux(unshieldedAmount)))} DUSK`
+ : `${formatter(luxToDusk(duskToLux(shieldedBalance) - duskToLux(shieldedAmount)))} DUSK`}
+
+
+
+
+
+
+
+ From
+
+
+
+ {isFromUnshielded ? unshieldedAddress : shieldedAddress}
+
+
+
+
+
+
+ To
+
+
+
+ {isFromShielded ? unshieldedAddress : shieldedAddress}
+
+
+
+
+
+
+
+
+
+ {#if hash}
+
+ {/if}
+
+
+
+
+
+
+
diff --git a/web-wallet/src/lib/components/GasFee/GasFee.svelte b/web-wallet/src/lib/components/GasFee/GasFee.svelte
index 205cb44020..020b3f8fdf 100644
--- a/web-wallet/src/lib/components/GasFee/GasFee.svelte
+++ b/web-wallet/src/lib/components/GasFee/GasFee.svelte
@@ -7,9 +7,9 @@
-
Max Gas Fee:
+
Fee:
-
{fee}
+
max {fee}
span:first-of-type {
+ font-weight: initial;
+ }
}
}
diff --git a/web-wallet/src/lib/components/__tests__/GasFee.spec.js b/web-wallet/src/lib/components/__tests__/GasFee.spec.js
index 311396e2dd..34b993001c 100644
--- a/web-wallet/src/lib/components/__tests__/GasFee.spec.js
+++ b/web-wallet/src/lib/components/__tests__/GasFee.spec.js
@@ -21,9 +21,10 @@ describe("GasFee", () => {
};
const { container } = render(GasFee, baseProps);
- expect(container.querySelector(".gas-fee__amount-value")?.innerHTML).toBe(
- fee
- );
+ expect(
+ container.querySelector(".gas-fee__amount-value span:nth-child(2)")
+ ?.innerHTML
+ ).toBe(fee);
expect(container.firstChild).toMatchSnapshot();
});
diff --git a/web-wallet/src/lib/components/__tests__/__snapshots__/GasFee.spec.js.snap b/web-wallet/src/lib/components/__tests__/__snapshots__/GasFee.spec.js.snap
index 3e98c31e82..6f8d22f8ed 100644
--- a/web-wallet/src/lib/components/__tests__/__snapshots__/GasFee.spec.js.snap
+++ b/web-wallet/src/lib/components/__tests__/__snapshots__/GasFee.spec.js.snap
@@ -2,20 +2,30 @@
exports[`GasFee > renders the GasFee component 1`] = `
- Max Gas Fee:
+ Fee:
-
- 0.020000000
-
+
+ max
+
+
+
+ 0.020000000
+
+
renders the GasSettings component closed 1`] = `
class="gas-settings__edit svelte-1daay07"
>
- Max Gas Fee:
+ Fee:
-
- 0.020000000
-
+
+ max
+
+
+
+ 0.020000000
+
+
renders the GasSettings component opened 1`] = `
class="gas-settings__edit svelte-1daay07"
>
- Max Gas Fee:
+ Fee:
-
- 0.020000000
-
+
+ max
+
+
+
+ 0.020000000
+
+
Amount step > should render the Send component Amount step 1`] =
class="gas-settings__edit svelte-1daay07"
>
- Max Gas Fee:
+ Fee:
-
- 0.020000000
-
+
+ max
+
+
+
+ 0.020000000
+
+
Review step > should render the Send component Review step 1`] =
- Max Gas Fee:
+ Fee:
-
- 0.020000000
-
+
+ max
+
+
+
+ 0.020000000
+
+
should render the Stake component 1`] = `
class="gas-settings__edit svelte-1daay07"
>
- Max Gas Fee:
+ Fee:
-
- 0.020000000
-
+
+ max
+
+
+
+ 0.020000000
+
+
should render the review step of the Stake component 1`] = `
- Max Gas Fee:
+ Fee:
-
- 0.020000000
-
+
+ max
+
+
+
+ 0.020000000
+
+
+
+
+
+
diff --git a/web-wallet/src/lib/containers/TransferContract/TransferContract.svelte b/web-wallet/src/lib/containers/TransferContract/TransferContract.svelte
index 2458419151..496fb0001a 100644
--- a/web-wallet/src/lib/containers/TransferContract/TransferContract.svelte
+++ b/web-wallet/src/lib/containers/TransferContract/TransferContract.svelte
@@ -11,9 +11,8 @@
setKey,
when,
} from "lamb";
-
+ import { executeSend } from "$lib/contracts";
import { createCurrencyFormatter } from "$lib/dusk/currency";
- import { getLastTransactionHash } from "$lib/transactions";
import {
gasStore,
operationsStore,
@@ -30,12 +29,6 @@
/** @type {ContractDescriptor} */
export let descriptor;
- /** @type {(to: string, amount: number, gasPrice:number, gasLimit:number) => Promise
} */
- const executeSend = (to, amount, gasPrice, gasLimit) =>
- walletStore
- .transfer(to, amount, gasPrice, gasLimit)
- .then(getLastTransactionHash);
-
const collectSettings = collect([
pick(["gasLimit", "gasPrice"]),
getKey("language"),
diff --git a/web-wallet/src/lib/containers/index.js b/web-wallet/src/lib/containers/index.js
index 2387cdbe37..0c1394e722 100644
--- a/web-wallet/src/lib/containers/index.js
+++ b/web-wallet/src/lib/containers/index.js
@@ -1,3 +1,4 @@
+export { default as AllocateContract } from "./AllocateContract/AllocateContract.svelte";
+export { default as MigrateContract } from "./MigrateContract/MigrateContract.svelte";
export { default as StakeContract } from "./StakeContract/StakeContract.svelte";
export { default as TransferContract } from "./TransferContract/TransferContract.svelte";
-export { default as MigrateContract } from "./MigrateContract/MigrateContract.svelte";
diff --git a/web-wallet/src/lib/contracts/__tests__/executeSend.spec.js b/web-wallet/src/lib/contracts/__tests__/executeSend.spec.js
new file mode 100644
index 0000000000..f6588c1f6b
--- /dev/null
+++ b/web-wallet/src/lib/contracts/__tests__/executeSend.spec.js
@@ -0,0 +1,58 @@
+import { afterAll, afterEach, describe, expect, it, vi } from "vitest";
+import { walletStore } from "$lib/stores";
+import { getLastTransactionHash } from "$lib/transactions";
+import { executeSend } from "..";
+
+vi.mock("$lib/stores", async (importOriginal) => {
+ /** @type {typeof import("$lib/stores")} */
+ const original = await importOriginal();
+
+ return {
+ ...original,
+ walletStore: {
+ ...original.walletStore,
+ transfer: vi.fn().mockResolvedValue(undefined),
+ },
+ };
+});
+
+vi.mock("$lib/transactions", async (importOriginal) => {
+ /** @type {typeof import("$lib/transactions")} */
+ const original = await importOriginal();
+
+ return {
+ ...original,
+ getLastTransactionHash: vi.fn(() => ""),
+ };
+});
+
+afterEach(() => {
+ vi.mocked(walletStore.transfer).mockClear();
+ vi.mocked(getLastTransactionHash).mockClear();
+});
+
+afterAll(() => {
+ vi.doUnmock("$lib/stores/walletStore");
+ vi.doUnmock("$lib/transactions");
+});
+
+describe("executeSend", () => {
+ it("should call the walletStore transfer method", async () => {
+ const args = ["abc", 1000, 1, 2];
+ // @ts-ignore
+ await executeSend(...args);
+
+ expect(walletStore.transfer).toHaveBeenCalledTimes(1);
+ expect(walletStore.transfer).toHaveBeenCalledWith(...args);
+ expect(getLastTransactionHash).toHaveBeenCalledTimes(1);
+ });
+
+ it("should not call the getLastTransactionHash function when an error is emitted from the transfer function", async () => {
+ const err = new Error("some error");
+
+ vi.mocked(walletStore.transfer).mockRejectedValueOnce(err);
+
+ await expect(executeSend("abc", 1000, 1, 2)).rejects.toBe(err);
+ expect(getLastTransactionHash).not.toHaveBeenCalled();
+ });
+});
diff --git a/web-wallet/src/lib/contracts/__tests__/updateOperation.spec.js b/web-wallet/src/lib/contracts/__tests__/updateOperation.spec.js
new file mode 100644
index 0000000000..cf461c3eb3
--- /dev/null
+++ b/web-wallet/src/lib/contracts/__tests__/updateOperation.spec.js
@@ -0,0 +1,11 @@
+import { describe, expect, it } from "vitest";
+import { updateOperation } from "..";
+import { get } from "svelte/store";
+import { operationsStore } from "$lib/stores";
+
+describe("updateOperation", () => {
+ it("should set the current operation in the operationStore", () => {
+ updateOperation("some operation");
+ expect(get(operationsStore).currentOperation).toBe("some operation");
+ });
+});
diff --git a/web-wallet/src/lib/contracts/contract-descriptors.js b/web-wallet/src/lib/contracts/contract-descriptors.js
index 50afc04304..49d4f75f96 100644
--- a/web-wallet/src/lib/contracts/contract-descriptors.js
+++ b/web-wallet/src/lib/contracts/contract-descriptors.js
@@ -54,4 +54,19 @@ export default [
},
],
},
+ {
+ disabled:
+ import.meta.env.VITE_CONTRACT_ALLOCATE_DISABLED &&
+ import.meta.env.VITE_CONTRACT_ALLOCATE_DISABLED === "true",
+ id: "allocate",
+ label: "Shield / Unshield",
+ operations: [
+ {
+ disabled: false,
+ id: "send",
+ label: "send",
+ primary: true,
+ },
+ ],
+ },
];
diff --git a/web-wallet/src/lib/contracts/executeSend.js b/web-wallet/src/lib/contracts/executeSend.js
new file mode 100644
index 0000000000..6bc3e4cc63
--- /dev/null
+++ b/web-wallet/src/lib/contracts/executeSend.js
@@ -0,0 +1,10 @@
+import { getLastTransactionHash } from "$lib/transactions";
+import { walletStore } from "$lib/stores";
+
+/** @type {(to: string, amount: number, gasPrice:number, gasLimit:number) => Promise} */
+const executeSend = (to, amount, gasPrice, gasLimit) =>
+ walletStore
+ .transfer(to, amount, gasPrice, gasLimit)
+ .then(getLastTransactionHash);
+
+export default executeSend;
diff --git a/web-wallet/src/lib/contracts/index.js b/web-wallet/src/lib/contracts/index.js
index e71743ccff..bb1d1ea387 100644
--- a/web-wallet/src/lib/contracts/index.js
+++ b/web-wallet/src/lib/contracts/index.js
@@ -1,3 +1,5 @@
export { default as contractDescriptors } from "./contract-descriptors";
export { default as deductLuxFeeFrom } from "./deductLuxFeeFrom";
+export { default as executeSend } from "./executeSend";
export { default as areValidGasSettings } from "./areValidGasSettings";
+export { default as updateOperation } from "./updateOperation";
diff --git a/web-wallet/src/lib/contracts/updateOperation.js b/web-wallet/src/lib/contracts/updateOperation.js
new file mode 100644
index 0000000000..a3ebdfe992
--- /dev/null
+++ b/web-wallet/src/lib/contracts/updateOperation.js
@@ -0,0 +1,11 @@
+import { operationsStore } from "$lib/stores";
+
+/** @param {string} id */
+function updateOperation(id) {
+ operationsStore.update((store) => ({
+ ...store,
+ currentOperation: id,
+ }));
+}
+
+export default updateOperation;
diff --git a/web-wallet/src/lib/stores/__tests__/walletStore.spec.js b/web-wallet/src/lib/stores/__tests__/walletStore.spec.js
index 2381c601ad..467f28910c 100644
--- a/web-wallet/src/lib/stores/__tests__/walletStore.spec.js
+++ b/web-wallet/src/lib/stores/__tests__/walletStore.spec.js
@@ -500,7 +500,7 @@ describe("walletStore", async () => {
walletStore.reset();
});
- it("should return a rejected promise with the operation error if an operation fails and try a sync afterwards nonetheless", async () => {
+ it("should return a rejected promise with the operation error if an operation fails and try a sync afterwards", async () => {
await walletStore.init(wallet);
await vi.advanceTimersToNextTimerAsync();
diff --git a/web-wallet/src/lib/stores/operationsStore.js b/web-wallet/src/lib/stores/operationsStore.js
index b0fa02b8ce..b6c5615f5b 100644
--- a/web-wallet/src/lib/stores/operationsStore.js
+++ b/web-wallet/src/lib/stores/operationsStore.js
@@ -1,6 +1,9 @@
import { writable } from "svelte/store";
-/** @type {import("svelte/store").Writable<{ currentOperation: string }>} */
-const count = writable({ currentOperation: "" });
+/** @type OperationsStoreContent */
+const initialState = { currentOperation: "" };
-export default count;
+/** @type OperationsStore */
+const store = writable(initialState);
+
+export default store;
diff --git a/web-wallet/src/lib/stores/stores.d.ts b/web-wallet/src/lib/stores/stores.d.ts
index 6a9d10678b..4f9abe431b 100644
--- a/web-wallet/src/lib/stores/stores.d.ts
+++ b/web-wallet/src/lib/stores/stores.d.ts
@@ -31,6 +31,10 @@ type TransactionsStoreContent = { transactions: Transaction[] };
type TransactionsStore = Readable;
+type OperationsStoreContent = { currentOperation: string };
+
+type OperationsStore = Writable;
+
type WalletStoreContent = {
balance: {
maximum: number;
diff --git a/web-wallet/src/routes/(app)/dashboard/+page.svelte b/web-wallet/src/routes/(app)/dashboard/+page.svelte
index 440bca589a..e7dc871644 100644
--- a/web-wallet/src/routes/(app)/dashboard/+page.svelte
+++ b/web-wallet/src/routes/(app)/dashboard/+page.svelte
@@ -2,7 +2,12 @@
+
+{#if !!import.meta.env.VITE_CONTRACT_ALLOCATE_DISABLED}
+
+ updateOperation(detail)}
+ />
+
+{/if}
diff --git a/web-wallet/src/routes/(app)/dashboard/allocate/__tests__/__snapshots__/page.spec.js.snap b/web-wallet/src/routes/(app)/dashboard/allocate/__tests__/__snapshots__/page.spec.js.snap
new file mode 100644
index 0000000000..12335431b5
--- /dev/null
+++ b/web-wallet/src/routes/(app)/dashboard/allocate/__tests__/__snapshots__/page.spec.js.snap
@@ -0,0 +1,291 @@
+// Vitest Snapshot v1, https://vitest.dev/guide/snapshot.html
+
+exports[`Allocate > should render the allocation page 1`] = `
+
+
+
+
+
+
+
+
+
+
+ Edit the value to change the allocation of your Dusk between your
+ shielded or public account.
+
+
+
+
+ Shielded
+
+
+
+
+
+
+
+
+
+ Unshielded
+
+
+
+
+
+
+
+
+
+
+
+ Fee:
+
+
+
+
+
+ max
+
+
+
+ 0.020000000
+
+
+
+
+
+
+
+
+
+
+
+
+ EDIT
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+`;
diff --git a/web-wallet/src/routes/(app)/dashboard/allocate/__tests__/page.spec.js b/web-wallet/src/routes/(app)/dashboard/allocate/__tests__/page.spec.js
new file mode 100644
index 0000000000..b78431b634
--- /dev/null
+++ b/web-wallet/src/routes/(app)/dashboard/allocate/__tests__/page.spec.js
@@ -0,0 +1,44 @@
+import { afterAll, afterEach, describe, expect, it, vi } from "vitest";
+import { get } from "svelte/store";
+import { cleanup, render } from "@testing-library/svelte";
+import { operationsStore } from "$lib/stores";
+import Allocation from "../+page.svelte";
+
+vi.mock("$lib/stores", async (importOriginal) => {
+ /** @type {typeof import("$lib/stores")} */
+ const original = await importOriginal();
+
+ return {
+ ...original,
+ operationsStore: {
+ ...original.operationsStore,
+ },
+ };
+});
+
+vi.useFakeTimers();
+
+describe("Allocate", () => {
+ afterEach(cleanup);
+ afterAll(() => {
+ vi.doUnmock("$lib/stores");
+ });
+
+ it("should render the allocation page", async () => {
+ const { container } = render(Allocation);
+
+ await vi.advanceTimersToNextTimerAsync();
+
+ expect(container.firstChild).toMatchSnapshot();
+ });
+
+ it("should set the current operation to an empty string when destroyed", async () => {
+ const { component } = render(Allocation);
+
+ component.$destroy();
+
+ expect(get(operationsStore)).toStrictEqual({
+ currentOperation: "",
+ });
+ });
+});
diff --git a/web-wallet/src/routes/(app)/dashboard/staking/+page.svelte b/web-wallet/src/routes/(app)/dashboard/staking/+page.svelte
index fec550b8b0..49d20d3081 100644
--- a/web-wallet/src/routes/(app)/dashboard/staking/+page.svelte
+++ b/web-wallet/src/routes/(app)/dashboard/staking/+page.svelte
@@ -5,16 +5,8 @@
import { mdiDatabaseOutline } from "@mdi/js";
import { StakeContract } from "$lib/containers";
import { IconHeadingCard } from "$lib/containers/Cards";
- import { contractDescriptors } from "$lib/contracts";
- import { operationsStore, settingsStore } from "$lib/stores";
-
- /** @param {string} id */
- function updateOperation(id) {
- operationsStore.update((store) => ({
- ...store,
- currentOperation: id,
- }));
- }
+ import { contractDescriptors, updateOperation } from "$lib/contracts";
+ import { settingsStore } from "$lib/stores";
/**
* @param {keyof SettingsStoreContent} property
@@ -32,15 +24,17 @@
});
-
- updateOperation(detail)}
- on:suppressStakingNotice={() => updateSetting("hideStakingNotice", true)}
- />
-
+{#if !!import.meta.env.VITE_CONTRACT_STAKE_DISABLED}
+
+ updateOperation(detail)}
+ on:suppressStakingNotice={() => updateSetting("hideStakingNotice", true)}
+ />
+
+{/if}
diff --git a/web-wallet/src/routes/(app)/dashboard/staking/__tests__/__snapshots__/page.spec.js.snap b/web-wallet/src/routes/(app)/dashboard/staking/__tests__/__snapshots__/page.spec.js.snap
new file mode 100644
index 0000000000..e3b506e309
--- /dev/null
+++ b/web-wallet/src/routes/(app)/dashboard/staking/__tests__/__snapshots__/page.spec.js.snap
@@ -0,0 +1,93 @@
+// Vitest Snapshot v1, https://vitest.dev/guide/snapshot.html
+
+exports[`Staking > should render the staking page 1`] = `
+
+`;
diff --git a/web-wallet/src/routes/(app)/dashboard/staking/__tests__/page.spec.js b/web-wallet/src/routes/(app)/dashboard/staking/__tests__/page.spec.js
new file mode 100644
index 0000000000..1d09dd3bb8
--- /dev/null
+++ b/web-wallet/src/routes/(app)/dashboard/staking/__tests__/page.spec.js
@@ -0,0 +1,17 @@
+import { afterEach, describe, expect, it, vi } from "vitest";
+import { cleanup, render } from "@testing-library/svelte";
+import Staking from "../+page.svelte";
+
+vi.useFakeTimers();
+
+describe("Staking", () => {
+ afterEach(cleanup);
+
+ it("should render the staking page", async () => {
+ const { container } = render(Staking);
+
+ await vi.advanceTimersToNextTimerAsync(); // Wait until the stakeInfo promise has resolved
+
+ expect(container.firstChild).toMatchSnapshot();
+ });
+});
diff --git a/web-wallet/src/routes/(app)/dashboard/transfer/+page.svelte b/web-wallet/src/routes/(app)/dashboard/transfer/+page.svelte
index 72a175d315..294176a919 100644
--- a/web-wallet/src/routes/(app)/dashboard/transfer/+page.svelte
+++ b/web-wallet/src/routes/(app)/dashboard/transfer/+page.svelte
@@ -4,31 +4,24 @@
import { onDestroy } from "svelte";
import { TransferContract } from "$lib/containers";
import { IconHeadingCard } from "$lib/containers/Cards";
- import { contractDescriptors } from "$lib/contracts";
- import { operationsStore } from "$lib/stores";
+ import { contractDescriptors, updateOperation } from "$lib/contracts";
import { mdiSwapVertical } from "@mdi/js";
- /** @param {string} id */
- function updateOperation(id) {
- operationsStore.update((store) => ({
- ...store,
- currentOperation: id,
- }));
- }
-
onDestroy(() => {
updateOperation("");
});
-
- updateOperation(detail)}
- />
-
+{#if !!import.meta.env.VITE_CONTRACT_TRANSFER_DISABLED}
+
+ updateOperation(detail)}
+ />
+
+{/if}
diff --git a/web-wallet/src/routes/(app)/dashboard/transfer/__tests__/__snapshots__/page.spec.js.snap b/web-wallet/src/routes/(app)/dashboard/transfer/__tests__/__snapshots__/page.spec.js.snap
new file mode 100644
index 0000000000..8e7202d565
--- /dev/null
+++ b/web-wallet/src/routes/(app)/dashboard/transfer/__tests__/__snapshots__/page.spec.js.snap
@@ -0,0 +1,161 @@
+// Vitest Snapshot v1, https://vitest.dev/guide/snapshot.html
+
+exports[`Transfer > should render the transfer page 1`] = `
+
+
+
+
+
+
+ Spendable
+
+
+
+
+ 0.000000000
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ Send
+
+
+
+
+
+
+
+
+
+
+
+
+ Receive
+
+
+
+
+
+
+
+
+
+
+
+
+
+ Back
+
+
+
+
+
+
+
+
+
+
+`;
diff --git a/web-wallet/src/routes/(app)/dashboard/transfer/__tests__/page.spec.js b/web-wallet/src/routes/(app)/dashboard/transfer/__tests__/page.spec.js
new file mode 100644
index 0000000000..ae84243208
--- /dev/null
+++ b/web-wallet/src/routes/(app)/dashboard/transfer/__tests__/page.spec.js
@@ -0,0 +1,15 @@
+import { afterEach, describe, expect, it, vi } from "vitest";
+import { cleanup, render } from "@testing-library/svelte";
+import Transfer from "../+page.svelte";
+
+vi.useFakeTimers();
+
+describe("Transfer", () => {
+ afterEach(cleanup);
+
+ it("should render the transfer page", async () => {
+ const { container } = render(Transfer);
+
+ expect(container.firstChild).toMatchSnapshot();
+ });
+});
diff --git a/web-wallet/src/routes/(app)/settings/__tests__/page.spec.js b/web-wallet/src/routes/(app)/settings/__tests__/page.spec.js
index dacf27d0bd..d6c16fbb16 100644
--- a/web-wallet/src/routes/(app)/settings/__tests__/page.spec.js
+++ b/web-wallet/src/routes/(app)/settings/__tests__/page.spec.js
@@ -9,7 +9,7 @@ import {
} from "vitest";
import { act, cleanup, fireEvent, render } from "@testing-library/svelte";
-import mockedWalletStore from "../../__mocks__/mockedWalletStore";
+import mockedWalletStore from "../../../../__mocks__/mockedWalletStore";
import * as navigation from "$lib/navigation";
import { settingsStore, walletStore } from "$lib/stores";
import loginInfoStorage from "$lib/services/loginInfoStorage";
diff --git a/web-wallet/src/style/app-components/horizontal-rules.css b/web-wallet/src/style/app-components/horizontal-rules.css
index 4d516c47f2..8c803e6383 100644
--- a/web-wallet/src/style/app-components/horizontal-rules.css
+++ b/web-wallet/src/style/app-components/horizontal-rules.css
@@ -1,5 +1,20 @@
hr {
+ text-align: center;
+ overflow: visible;
border: none;
border-top: 1px solid var(--divider-color-primary);
width: 100%;
+ height: 1px;
+ padding: 0;
+}
+
+hr.glyph:after {
+ display: inline-block;
+ position: relative;
+ top: -1.1em;
+ font-size: 1em;
+ border: solid thin var(--divider-border-color);
+ border-radius: 2em;
+ padding: 0.5em 1.25em;
+ background-color: var(--divider-background-color);
}
diff --git a/web-wallet/src/style/dusk/language.css b/web-wallet/src/style/dusk/language.css
index b26b9e0452..74aff3f4d6 100644
--- a/web-wallet/src/style/dusk/language.css
+++ b/web-wallet/src/style/dusk/language.css
@@ -109,9 +109,15 @@
--checkbox-control-border-color: var(--smokey-black);
--checkbox-control-checked-bg-color: var(--smokey-black);
+ /* Fieldset */
+ --fieldset-background-color: var(--light-grey);
+ --fieldset-border-radius: 1.5em;
+
/* Dividers */
- --divider-color-primary: var(--taupe-grey);
+ --divider-color-primary: var(--smokey-black);
+ --divider-background-color: var(--light-gray);
+ --divider-border-color: var(--smokey-black);
/* Home animation */
@@ -152,6 +158,16 @@
--checkbox-control-border-color: var(--light-grey);
--checkbox-control-checked-bg-color: var(--light-grey);
+ /* Fieldset */
+
+ --fieldset-background-color: var(--smokey-black);
+
+ /* Dividers */
+
+ --divider-color-primary: var(--magnolia);
+ --divider-background-color: var(--smokey-black);
+ --divider-border-color: var(--magnolia);
+
/* Home animation */
--home-grid-color: var(--smokey-black);
diff --git a/web-wallet/src/style/main.css b/web-wallet/src/style/main.css
index 3e99a04f9c..345fc9def8 100644
--- a/web-wallet/src/style/main.css
+++ b/web-wallet/src/style/main.css
@@ -92,6 +92,10 @@ svg {
fill: currentColor;
}
+fieldset {
+ border: none;
+}
+
#outer-container {
background-color: var(--background-color);
width: 60%;
diff --git a/web-wallet/vite.config.js b/web-wallet/vite.config.js
index 64861c573a..7029f9f94c 100644
--- a/web-wallet/vite.config.js
+++ b/web-wallet/vite.config.js
@@ -48,6 +48,7 @@ export default defineConfig(({ mode }) => {
TESTNET_NODE: env.VITE_TESTNET_NODE,
TESTNET_PROVER_NODE: env.VITE_TESTNET_PROVER_NODE,
TRANSFER_CONTRACT: env.VITE_TRANSFER_CONTRACT,
+ VITE_CONTRACT_ALLOCATE_DISABLED: env.VITE_CONTRACT_ALLOCATE_DISABLED,
VITE_CONTRACT_STAKE_DISABLED: env.VITE_CONTRACT_STAKE_DISABLED,
VITE_CONTRACT_TRANSFER_DISABLED: env.VITE_CONTRACT_TRANSFER_DISABLED,
VITE_GAS_LIMIT_DEFAULT: env.VITE_GAS_LIMIT_DEFAULT,
@@ -58,8 +59,6 @@ export default defineConfig(({ mode }) => {
VITE_GAS_PRICE_UPPER: env.VITE_GAS_PRICE_UPPER,
VITE_GET_QUOTE_API_ENDPOINT: env.VITE_GET_QUOTE_API_ENDPOINT,
VITE_MINIMUM_ALLOWED_STAKE: env.VITE_MINIMUM_ALLOWED_STAKE,
- VITE_STAKING_ENABLED: env.VITE_STAKING_ENABLED,
- VITE_TRANSFER_ENABLED: env.VITE_TRANSFER_ENABLED,
},
},
plugins:
@@ -98,6 +97,7 @@ export default defineConfig(({ mode }) => {
"0200000000000000000000000000000000000000000000000000000000000000",
TRANSFER_CONTRACT:
"0100000000000000000000000000000000000000000000000000000000000000",
+ VITE_CONTRACT_ALLOCATE_DISABLED: "false",
VITE_CONTRACT_STAKE_DISABLED: "false",
VITE_CONTRACT_TRANSFER_DISABLED: "false",
VITE_GAS_LIMIT_DEFAULT: "20000000",