make reward destinations more flexible for the user
Signed-off-by: Uncle Fatso <uncle.fatso@ghostchain.io>
This commit is contained in:
parent
0d2c700e1a
commit
7822556988
@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "ghost-lite",
|
||||
"version": "0.1.5",
|
||||
"version": "0.1.6",
|
||||
"description": "Web application for Ghost and Casper chain.",
|
||||
"author": "Uncle f4ts0 <f4ts0@ghostchain.io>",
|
||||
"maintainers": [
|
||||
|
@ -1,5 +1,5 @@
|
||||
import React, { useEffect, useState, useMemo, useCallback } from "react"
|
||||
import { Nut, NutOff, Users, PiggyBank } from "lucide-react"
|
||||
import { Nut, NutOff, Users, PiggyBank, RefreshCcw } from "lucide-react"
|
||||
|
||||
import { ss58Decode } from "@polkadot-labs/hdkd-helpers"
|
||||
import { toHex } from "@polkadot-api/utils"
|
||||
@ -7,6 +7,14 @@ import { toHex } from "@polkadot-api/utils"
|
||||
import { lastValueFrom, tap } from "rxjs"
|
||||
import { submitTransaction$ } from "../api"
|
||||
|
||||
import {
|
||||
Select,
|
||||
SelectValue,
|
||||
SelectTrigger,
|
||||
SelectContent,
|
||||
SelectGroup,
|
||||
SelectItem,
|
||||
} from "../components/ui/select"
|
||||
import {
|
||||
Accordion,
|
||||
AccordionContent,
|
||||
@ -37,6 +45,7 @@ import {
|
||||
useUnstableProvider,
|
||||
RewardPoints,
|
||||
Unlocking,
|
||||
RewardDestination,
|
||||
} from "../hooks"
|
||||
|
||||
import {
|
||||
@ -62,7 +71,6 @@ interface ItemProps {
|
||||
nominated: boolean
|
||||
checkedAddresses: string[]
|
||||
setIsCheckedAddresses: React.Dispatch<React.SetStateAction<string[]>>
|
||||
|
||||
}
|
||||
|
||||
const Item: React.FC<ItemProps> = (props) => {
|
||||
@ -191,6 +199,8 @@ export const Nominations = () => {
|
||||
|
||||
const [interestingValidator, setInterestingValidator] = useState<string | undefined>(undefined)
|
||||
const [amount, setAmount] = useState<string>("")
|
||||
const [destinationReceiver, setDestinationReceiver] = useState<string>("")
|
||||
const [expectedPayee, setExpectedPayee] = useState<string | undefined>(undefined)
|
||||
|
||||
const {
|
||||
provider,
|
||||
@ -221,6 +231,19 @@ export const Nominations = () => {
|
||||
: undefined
|
||||
})
|
||||
|
||||
const destinationReceiverIsValid = useMemo(() => {
|
||||
try {
|
||||
const [, prefix] = ss58Decode(destinationReceiver)
|
||||
if (prefix !== 1995 && prefix !== 1996) {
|
||||
throw new Error("bad prefix")
|
||||
}
|
||||
return true
|
||||
} catch {
|
||||
return false
|
||||
}
|
||||
|
||||
}, [destinationReceiver])
|
||||
|
||||
const convertedAmount = useMemo(() => {
|
||||
try {
|
||||
return BigInt(Number(amount) * Math.pow(10, tokenDecimals))
|
||||
@ -240,24 +263,24 @@ export const Nominations = () => {
|
||||
convertedAmount > 0n ? convertedAmount : undefined
|
||||
)
|
||||
|
||||
const payeeDescription = useMemo(() => {
|
||||
const payeeDescription = (destination: string | undefined) => {
|
||||
let description = "Unknown reward destination"
|
||||
switch (payee?.type) {
|
||||
switch (destination) {
|
||||
case "Staked":
|
||||
description = "Re-stake rewards"
|
||||
description = "Re-stake upcoming rewards"
|
||||
break;
|
||||
case "Stash":
|
||||
description = "Withdraw rewards to free"
|
||||
break;
|
||||
case "Account":
|
||||
description = `Rewards to => ${payee?.value}`
|
||||
description = `Rewards to account`
|
||||
break;
|
||||
case "None":
|
||||
description = "Refuse to receive rewards"
|
||||
break;
|
||||
}
|
||||
return description
|
||||
}, [payee])
|
||||
}
|
||||
|
||||
const readyToWithdraw = useMemo(() => {
|
||||
return ledger?.unlocking.reduce((acc: bigint, item: Unlocking) => {
|
||||
@ -285,6 +308,10 @@ export const Nominations = () => {
|
||||
setIsCheckedAddresses([])
|
||||
}, [account])
|
||||
|
||||
useEffect(() => {
|
||||
if (!expectedPayee) setExpectedPayee(payee?.type)
|
||||
}, [expectedPayee, setExpectedPayee, payee])
|
||||
|
||||
useEffect(() => {
|
||||
if (checkedAddresses.length === 0 && nominations) {
|
||||
setIsCheckedAddresses(nominations?.targets ?? [])
|
||||
@ -531,13 +558,53 @@ export const Nominations = () => {
|
||||
</div>
|
||||
</AccordionTrigger>
|
||||
<AccordionContent className="flex flex-col gap-2 pl-8">
|
||||
<Row title="Destination" element={<Input
|
||||
readOnly
|
||||
aria-label="Destination"
|
||||
type="text"
|
||||
className="sm:w-[300px] w-full"
|
||||
placeholder={payeeDescription}
|
||||
/>} />
|
||||
{payee && (<Row title="Destination" element={<Select
|
||||
value={expectedPayee}
|
||||
onValueChange={(payeeType) => setExpectedPayee(payeeType)}
|
||||
>
|
||||
<SelectTrigger
|
||||
className={"text-muted-foreground sm:w-[300px] w-full"}
|
||||
data-testid="destination-select"
|
||||
>
|
||||
<SelectValue placeholder="Select Destination" />
|
||||
</SelectTrigger>
|
||||
<SelectContent>
|
||||
<SelectGroup>
|
||||
{Object.keys(RewardDestination()).map((destinationType, index) => (
|
||||
<SelectItem
|
||||
key={index}
|
||||
data-testid={`destination-${destinationType}`}
|
||||
value={destinationType}
|
||||
>
|
||||
{payeeDescription(destinationType)}
|
||||
</SelectItem>
|
||||
))}
|
||||
</SelectGroup>
|
||||
</SelectContent>
|
||||
</Select>
|
||||
} />)}
|
||||
{expectedPayee !== payee?.type && expectedPayee === "Account" && (
|
||||
<Row title="Receiver" element={<Input
|
||||
aria-label="Destination Account"
|
||||
type="text"
|
||||
className="sm:w-[300px] w-full"
|
||||
placeholder="Input destination account"
|
||||
onChange={e => setDestinationReceiver(e.target.value)}
|
||||
value={destinationReceiver}
|
||||
/>} />
|
||||
)}
|
||||
{expectedPayee !== payee?.type && (
|
||||
<Button
|
||||
type="button"
|
||||
variant="secondary"
|
||||
className="text-sm my-4 w-full"
|
||||
onClick={() => alert("not ready yet")}
|
||||
disabled={isSubmittingTransaction || !destinationReceiverIsValid}
|
||||
>
|
||||
<RefreshCcw className="w-4 h-4 inline-block mr-2" />
|
||||
Change Destination
|
||||
</Button>
|
||||
)}
|
||||
<Row title="Total Bond" element={<Input
|
||||
readOnly
|
||||
aria-label="Total Bond"
|
||||
|
@ -15,13 +15,41 @@ const AccountId = (value: SS58String) => Enum<
|
||||
"Id"
|
||||
>("Id", value)
|
||||
|
||||
const RewardDestination = () => Enum<
|
||||
{
|
||||
type: "Staked"
|
||||
value: []
|
||||
},
|
||||
"Staked"
|
||||
>("Staked", [])
|
||||
export const RewardDestination = (account: SS58String | undefined) => {
|
||||
return {
|
||||
Staked: () => Enum<
|
||||
{
|
||||
type: "Staked"
|
||||
value: []
|
||||
},
|
||||
"Staked"
|
||||
>("Staked", []),
|
||||
|
||||
Stash: () => Enum<
|
||||
{
|
||||
type: "Stash"
|
||||
value: []
|
||||
},
|
||||
"Stash"
|
||||
>("Stash", []),
|
||||
|
||||
Account: (account: SS58String) => Enum<
|
||||
{
|
||||
type: "Account"
|
||||
value: account
|
||||
},
|
||||
"Account"
|
||||
>("Account", account),
|
||||
|
||||
None: () => Enum<
|
||||
{
|
||||
type: "None"
|
||||
value: []
|
||||
},
|
||||
"None"
|
||||
>("None", []),
|
||||
}
|
||||
}
|
||||
|
||||
export const useTransferCalldata = (destination: SS58String | undefined, amount: bigint | undefined) => {
|
||||
const { client, chainId } = useUnstableProvider()
|
||||
@ -86,7 +114,7 @@ export const useBondCalldata = (amount: bigint | undefined) => {
|
||||
new Uint8Array(location),
|
||||
codec.enc({
|
||||
value: amount,
|
||||
payee: RewardDestination(),
|
||||
payee: RewardDestination.Staked(),
|
||||
}),
|
||||
),
|
||||
)
|
||||
|
Loading…
Reference in New Issue
Block a user