Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

web-wallet: Add support for partial unstake/claim rewards #3092

Draft
wants to merge 1 commit into
base: master
Choose a base branch
from
Draft
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 web-wallet/CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
### Added

- Add "Support" section under Settings [#3071]
- Add support for partial unstake/claim rewards [#3009]

### Changed

Expand Down
104 changes: 97 additions & 7 deletions web-wallet/src/lib/components/Stake/Unstake.svelte
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,10 @@
import {
AnchorButton,
Badge,
Button,
Icon,
Stepper,
Textbox,
Wizard,
WizardStep,
} from "$lib/dusk/components";
Expand All @@ -22,6 +25,9 @@
} from "$lib/components";

import StakeOverview from "./StakeOverview.svelte";
import { logo } from "$lib/dusk/icons";
import { toast } from "$lib/dusk/components/Toast/store";
import { mdiAlertOutline } from "@mdi/js";

/** @type {(...args: any[]) => Promise<string>} */
export let execute;
Expand Down Expand Up @@ -59,9 +65,9 @@
* as number if we want to use
* Svelte's binding.
*/
const amount = luxToDusk(maxAmount);
let amount = luxToDusk(maxAmount);

const steps = [{ label: "Overview" }, { label: "Done" }];
const steps = [{ label: "Amount" }, { label: "Overview" }, { label: "Done" }];

const dispatch = createEventDispatcher();
const resetOperation = () => dispatch("operationChange", "");
Expand All @@ -78,6 +84,24 @@
}
};

function setMaxAmount() {
if (!isGasValid) {
toast("error", "Please set valid gas settings first", mdiAlertOutline);
return;
}

// if (spendable < fee) {
// toast(
// "error",
// "You don't have enough DUSK to cover the transaction fee",
// mdiAlertOutline
// );
// return;
// }

amount = luxToDusk(maxAmount);
}

onMount(() => {
isGasValid = areValidGasSettings(gasPrice, gasLimit);
});
Expand All @@ -86,17 +110,68 @@
</script>

<div class="operation">
<Wizard steps={2} let:key>
<Wizard steps={3} let:key>
<div slot="stepper">
<Stepper {activeStep} {steps} showStepLabelWhenInactive={false} />
</div>

<!-- OPERATION OVERVIEW STEP -->
<WizardStep
step={0}
{key}
backButton={{
action: () => resetOperation(),
action: resetOperation,
disabled: false,
}}
nextButton={{
action: () => activeStep++,
disabled: amount === 0,
}}
>
<ContractStatusesList {statuses} />
<div class="operation__amount-wrapper">
<p>Amount:</p>
<Button
size="small"
variant="tertiary"
on:click={setMaxAmount}
text="USE MAX"
/>
</div>

<div class="operation__input-wrapper">
<Textbox
className="operation__input-field"
bind:value={amount}
type="number"
max={luxToDusk(maxAmount)}
required
step="0.000000001"
/>
<Icon
data-tooltip-id="main-tooltip"
data-tooltip-text="DUSK"
path={logo}
/>
</div>

<GasSettings
{formatter}
{fee}
limit={gasSettings.gasLimit}
limitLower={gasLimits.gasLimitLower}
limitUpper={gasLimits.gasLimitUpper}
price={gasSettings.gasPrice}
priceLower={gasLimits.gasPriceLower}
on:gasSettings={setGasValues}
/>
</WizardStep>

<!-- OPERATION OVERVIEW STEP -->
<WizardStep
step={1}
{key}
backButton={{
action: () => activeStep--,
disabled: false,
}}
nextButton={{
Expand Down Expand Up @@ -132,11 +207,11 @@
</WizardStep>

<!-- OPERATION RESULT STEP -->
<WizardStep step={1} {key} showNavigation={false}>
<WizardStep step={2} {key} showNavigation={false}>
<OperationResult
errorMessage="Transaction failed"
onBeforeLeave={resetOperation}
operation={execute(gasPrice, gasLimit)}
operation={execute(amount, gasPrice, gasLimit)}
pendingMessage="Processing transaction"
successMessage="Transaction created"
>
Expand Down Expand Up @@ -164,5 +239,20 @@
flex-direction: column;
gap: 1.2em;
}

&__amount-wrapper,
&__input-wrapper {
display: flex;
align-items: center;
width: 100%;
}

&__amount-wrapper {
justify-content: space-between;
}

&__input-wrapper {
column-gap: var(--default-gap);
}
}
</style>
11 changes: 4 additions & 7 deletions web-wallet/src/lib/containers/StakeContract/StakeContract.svelte
Original file line number Diff line number Diff line change
Expand Up @@ -67,20 +67,17 @@

/** @type {Record<StakeType, (...args: any[]) => Promise<string>>} */
const executeOperations = {
"claim-rewards": (gasPrice, gasLimit) =>
"claim-rewards": (amount, gasPrice, gasLimit) =>
walletStore
.claimRewards(
$walletStore.stakeInfo.reward,
new Gas({ limit: gasLimit, price: gasPrice })
)
.claimRewards(amount, new Gas({ limit: gasLimit, price: gasPrice }))
.then(getKey("hash")),
stake: (amount, gasPrice, gasLimit) =>
walletStore
.stake(amount, new Gas({ limit: gasLimit, price: gasPrice }))
.then(getKey("hash")),
unstake: (gasPrice, gasLimit) =>
unstake: (amount, gasPrice, gasLimit) =>
walletStore
.unstake(new Gas({ limit: gasLimit, price: gasPrice }))
.unstake(amount, new Gas({ limit: gasLimit, price: gasPrice }))
.then(getKey("hash")),
};

Expand Down
1 change: 1 addition & 0 deletions web-wallet/src/lib/stores/stores.d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -141,6 +141,7 @@ type WalletStoreServices = {
) => Promise<TransactionInfo>;

unstake: (
amount: bigint,
gas: import("$lib/vendor/w3sper.js/src/mod").Gas
) => Promise<TransactionInfo>;

Expand Down
2 changes: 1 addition & 1 deletion web-wallet/src/routes/(app)/dashboard/staking/+page.svelte
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,7 @@
{#if import.meta.env.VITE_FEATURE_STAKE || false}
<IconHeadingCard
gap="medium"
heading="Staking"
heading="Stake"
icons={[mdiDatabaseOutline]}
reverse
>
Expand Down
Loading