Skip to content

Commit

Permalink
web-wallet: Integration with latest wallet-js and Sync improvements
Browse files Browse the repository at this point in the history
Resolves #1561, Resolves #1567, Resolves #1568, Resolves #1570, Resolves #1595

Changelog:
- Integration with the latest wallet-js library (v.0.5.3)
- Display of the current network block height during wallet creation
- Prevention of full sync for newly created wallets
- Option for users to restore a wallet from either genesis or a specific block height
- Relocation of the initial sync to the wallet restore flow
- A sync indicator that displays progress for both initial and subsequent syncs
  • Loading branch information
ascartabelli authored and nortonandreev committed Sep 6, 2024
1 parent 73be96e commit 1187d36
Show file tree
Hide file tree
Showing 48 changed files with 1,591 additions and 281 deletions.
3 changes: 2 additions & 1 deletion web-wallet/.eslintignore
Original file line number Diff line number Diff line change
Expand Up @@ -4,10 +4,11 @@ node_modules
/.svelte-kit
/package
.env
.env.*
.env.\*
!.env.example

# Ignore files for PNPM, NPM and YARN

pnpm-lock.yaml
package-lock.json
yarn.lock
6 changes: 6 additions & 0 deletions web-wallet/CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -9,12 +9,15 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0

### Added

- 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]
- Added allocation (shield/unshield) page and UI [#2196]
- Added token migration contract bindings [#2014]

### Changed

- Newly created Wallet does not sync from genesis [#1567]
- Update font-display to swap for custom fonts to improve performance [#2026]
- Update anchor colors to ensure better accessibility [#1765]
- Update Transactions list design [#1922]
Expand Down Expand Up @@ -229,7 +232,10 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
[#1545]: https://github.com/dusk-network/rusk/issues/1545
[#1547]: https://github.com/dusk-network/rusk/issues/1547
[#1552]: https://github.com/dusk-network/rusk/issues/1552
[#1561]: https://github.com/dusk-network/rusk/issues/1561
[#1565]: https://github.com/dusk-network/rusk/issues/1565
[#1568]: https://github.com/dusk-network/rusk/issues/1568
[#1567]: https://github.com/dusk-network/rusk/issues/1567
[#1576]: https://github.com/dusk-network/rusk/issues/1576
[#1591]: https://github.com/dusk-network/rusk/issues/1591
[#1598]: https://github.com/dusk-network/rusk/issues/1598
Expand Down
10 changes: 5 additions & 5 deletions web-wallet/__mocks__/Wallet.js
Original file line number Diff line number Diff line change
@@ -1,13 +1,13 @@
class Wallet {
constructor(seed, gasLimit = 2900000000, gasPrice = 1) {
this.gasLimit = gasLimit;
this.gasPrice = gasPrice;
constructor(seed) {
this.seed = seed;
this.wasm = {};
}

gasLimit;
gasPrice;
static get networkBlockHeight() {
return Promise.resolve(0);
}

seed;
wasm;

Expand Down
16 changes: 8 additions & 8 deletions web-wallet/package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 1 addition & 1 deletion web-wallet/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -35,7 +35,7 @@
"type": "module",
"version": "0.5.0",
"dependencies": {
"@dusk-network/dusk-wallet-js": "0.4.2",
"@dusk-network/dusk-wallet-js": "0.5.3",
"@floating-ui/dom": "1.6.5",
"@mdi/js": "7.4.47",
"@wagmi/connectors": "5.1.6",
Expand Down
3 changes: 1 addition & 2 deletions web-wallet/src/__mocks__/mockedWalletStore.js
Original file line number Diff line number Diff line change
Expand Up @@ -9,9 +9,8 @@ const content = {
addresses,
balance,
currentAddress,
error: null,
initialized: true,
isSyncing: false,
syncStatus: { current: 0, error: null, isInProgress: false, last: 0 },
};

const mockedWalletStore = mockReadableStore(content);
Expand Down
9 changes: 9 additions & 0 deletions web-wallet/src/lib/components/CopyField/CopyField.css
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
.copy-field {
display: flex;
align-items: center;
gap: var(--default-gap);
}

.copy-field__content {
flex: 1;
}
55 changes: 55 additions & 0 deletions web-wallet/src/lib/components/CopyField/CopyField.svelte
Original file line number Diff line number Diff line change
@@ -0,0 +1,55 @@
<svelte:options immutable={true} />

<script>
import "./CopyField.css";
import { mdiAlertOutline, mdiContentCopy } from "@mdi/js";
import { Button, Textbox } from "$lib/dusk/components";
import { toast } from "$lib/dusk/components/Toast/store";
/** @type {string} */
export let name;
/** @type {string} */
export let displayValue;
/** @type {string} */
export let rawValue;
/** @type {boolean} */
export let disabled = false;
function copyToClipboard() {
navigator.clipboard
.writeText(rawValue)
.then(() => {
toast("success", `${name} copied`, mdiContentCopy);
})
.catch((err) => {
toast(
"error",
err.name === "NotAllowedError"
? "Clipboard access denied"
: err.message,
mdiAlertOutline
);
});
}
</script>

<div class="copy-field">
<Textbox
className="copy-field__content"
value={displayValue}
type="text"
readOnly
/>
<Button
aria-label="Copy Address"
className="copy-field__button"
icon={{ path: mdiContentCopy }}
on:click={copyToClipboard}
variant="primary"
{disabled}
/>
</div>
54 changes: 54 additions & 0 deletions web-wallet/src/lib/components/__tests__/CopyField.spec.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,54 @@
import { afterEach, describe, expect, it, vi } from "vitest";
import { cleanup, fireEvent, render } from "@testing-library/svelte";
import { CopyField } from "..";

Object.assign(navigator, {
clipboard: {
writeText: vi.fn().mockResolvedValue(""),
},
});

describe("CopyField", () => {
const baseProps = {
disabled: false,
displayValue: "1,234,567",
name: "Sample Information",
rawValue: "1234567",
};

const baseOptions = {
props: baseProps,
target: document.body,
};

afterEach(cleanup);

it("renders the CopyField component", () => {
const { container } = render(CopyField, baseOptions);

expect(container.firstChild).toMatchSnapshot();
});

it("renders the CopyField component with the copy button disabled", () => {
const { container, getByRole } = render(CopyField, {
...baseOptions,
props: { ...baseProps, disabled: true },
});

const copyButton = getByRole("button");

expect(copyButton).toBeDisabled();

expect(container.firstChild).toMatchSnapshot();
});

it("copies the raw value on pressing the copy button", async () => {
const { getByRole } = render(CopyField, baseOptions);

const copyButton = getByRole("button");

await fireEvent.click(copyButton);

expect(navigator.clipboard.writeText).toHaveBeenCalledWith("1234567");
});
});
Original file line number Diff line number Diff line change
@@ -0,0 +1,66 @@
// Vitest Snapshot v1, https://vitest.dev/guide/snapshot.html

exports[`CopyField > renders the CopyField component 1`] = `
<div
class="copy-field"
>
<input
class="dusk-textbox dusk-textbox-text copy-field__content"
readonly=""
type="text"
/>
<button
aria-label="Copy Address"
class="dusk-button dusk-button--type--button dusk-button--variant--primary dusk-button--size--default dusk-icon-button copy-field__button"
type="button"
>
<svg
class="dusk-icon dusk-icon--size--default dusk-button__icon"
role="graphics-symbol"
viewBox="0 0 24 24"
>
<path
d="M19,21H8V7H19M19,5H8A2,2 0 0,0 6,7V21A2,2 0 0,0 8,23H19A2,2 0 0,0 21,21V7A2,2 0 0,0 19,5M16,1H4A2,2 0 0,0 2,3V17H4V3H16V1Z"
/>
</svg>
</button>
</div>
`;

exports[`CopyField > renders the CopyField component with the copy button disabled 1`] = `
<div
class="copy-field"
>
<input
class="dusk-textbox dusk-textbox-text copy-field__content"
readonly=""
type="text"
/>
<button
aria-label="Copy Address"
class="dusk-button dusk-button--type--button dusk-button--variant--primary dusk-button--size--default dusk-icon-button copy-field__button"
disabled=""
type="button"
>
<svg
class="dusk-icon dusk-icon--size--default dusk-button__icon"
role="graphics-symbol"
viewBox="0 0 24 24"
>
<path
d="M19,21H8V7H19M19,5H8A2,2 0 0,0 6,7V21A2,2 0 0,0 8,23H19A2,2 0 0,0 21,21V7A2,2 0 0,0 19,5M16,1H4A2,2 0 0,0 2,3V17H4V3H16V1Z"
/>
</svg>
</button>
</div>
`;
1 change: 1 addition & 0 deletions web-wallet/src/lib/components/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ export { default as ApproveMigration } from "./ApproveMigration/ApproveMigration
export { default as Balance } from "./Balance/Balance.svelte";
export { default as ContractOperations } from "./ContractOperations/ContractOperations.svelte";
export { default as ContractStatusesList } from "./ContractStatusesList/ContractStatusesList.svelte";
export { default as CopyField } from "./CopyField/CopyField.svelte";
export { default as DashboardNav } from "./DashboardNav/DashboardNav.svelte";
export { default as ExecuteMigration } from "./ExecuteMigration/ExecuteMigration.svelte";
export { default as ExistingWalletNotice } from "./ExistingWalletNotice/ExistingWalletNotice.svelte";
Expand Down
5 changes: 4 additions & 1 deletion web-wallet/src/lib/containers/Cards/IconHeadingCard.svelte
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,9 @@
/** @type {string} */
export let heading;
/** @type {string | Undefined} */
export let className = undefined;
/** @type {CardGap} */
export let gap = "default";
Expand All @@ -19,7 +22,7 @@
export let reverse = false;
</script>

<Card {...$$restProps} {gap} {onSurface}>
<Card {...$$restProps} {className} {gap} {onSurface}>
<header slot="header" class="dusk-card__header">
<div
class="dusk-card__heading-container"
Expand Down
9 changes: 8 additions & 1 deletion web-wallet/src/lib/containers/Cards/ToggleableCard.svelte
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
<script>
import { Card, Icon, Switch } from "$lib/dusk/components";
import { createEventDispatcher } from "svelte";
import "./Card.css";
Expand All @@ -17,6 +18,12 @@
/** @type {boolean} */
export let isToggled = false;
const dispatch = createEventDispatcher();
function dispatchToggleEvent() {
dispatch("toggle", { isToggled });
}
</script>

<Card {...$$restProps} {gap} {onSurface}>
Expand All @@ -27,7 +34,7 @@
{/if}
<h3 class="h4">{heading}</h3>
</div>
<Switch onSurface bind:value={isToggled} />
<Switch onSurface bind:value={isToggled} on:change={dispatchToggleEvent} />
</header>
{#if isToggled}
<slot />
Expand Down
Loading

0 comments on commit 1187d36

Please sign in to comment.