- 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..0ed2b2f10d
--- /dev/null
+++ b/web-wallet/src/lib/contracts/__tests__/executeSend.spec.js
@@ -0,0 +1,18 @@
+import { describe, expect, it } from "vitest";
+import { executeSend } from "..";
+
+describe("executeSend", () => {
+ it("should attempt to call the transfer method on the wallet ", async () => {
+ try {
+ await executeSend(
+ "abc",
+ 1000,
+ import.meta.env.VITE_GAS_PRICE_DEFAULT,
+ import.meta.env.VITE_GAS_LIMIT_DEFAULT
+ );
+ } catch (e) {
+ // @ts-ignore
+ expect(e.message).toBe("No wallet instance to sync");
+ }
+ });
+});
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..64b45145c6
--- /dev/null
+++ b/web-wallet/src/lib/contracts/__tests__/updateOperation.spec.js
@@ -0,0 +1,16 @@
+import { describe, expect, it } from "vitest";
+import { updateOperation } from "..";
+import { get } from "svelte/store";
+import { operationsStore } from "$lib/stores";
+
+describe("updateOperation", () => {
+ it("should check to see if the store is writeable", () => {
+ // @ts-ignore
+ expect(() => operationsStore.set("value")).toBeTruthy();
+ });
+
+ 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..806ba7a140 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: "" };
+
+/** @type OperationsStore */
+const count = writable(initialState);
export default count;
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)/__mocks__/mockedOperationsStore.js b/web-wallet/src/routes/(app)/__mocks__/mockedOperationsStore.js
new file mode 100644
index 0000000000..a28d7e379c
--- /dev/null
+++ b/web-wallet/src/routes/(app)/__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)/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..dd9179cff4
--- /dev/null
+++ b/web-wallet/src/routes/(app)/dashboard/allocate/__tests__/page.spec.js
@@ -0,0 +1,31 @@
+import { afterAll, afterEach, describe, expect, it, vi } from "vitest";
+import { cleanup, render } from "@testing-library/svelte";
+import Allocation from "../+page.svelte";
+// import mockedOperationsStore from "../../../__mocks__/mockedOperationsStore";
+
+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 call the destroy method when the component is unmounted", async () => {
+ const { component, unmount } = render(Allocation);
+ const spy = vi.spyOn(component, "$destroy");
+
+ unmount();
+
+ expect(spy).toHaveBeenCalled();
+ });
+});
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..66293807ff
--- /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();
+
+ 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..a164a2ae59
--- /dev/null
+++ b/web-wallet/src/routes/(app)/dashboard/transfer/__tests__/page.spec.js
@@ -0,0 +1,17 @@
+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);
+
+ await vi.advanceTimersToNextTimerAsync();
+
+ expect(container.firstChild).toMatchSnapshot();
+ });
+});
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..9cd3066d13 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: