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

feat: allow to allot mana to account #8231

Merged
merged 18 commits into from
Apr 18, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
18 commits
Select commit Hold shift + click to select a range
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
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
<script lang="ts">
import { OnboardingButton } from '@ui'
import { localize } from '@core/i18n'
import { closePopup, openPopup, PopupId } from '@auxiliary/popup'

function allotMana(): void {
closePopup()
}

function onAllotManaClick(): void {
openPopup({
id: PopupId.AllotMana,
props: {
title: localize('actions.allotMana'),
confirmText: localize('actions.send'),
onConfirm: allotMana,
},
})
}
</script>

<OnboardingButton
primaryText={localize('actions.allotMana')}
secondaryText={localize('general.allotManaDescription')}
onClick={onAllotManaClick}
/>
1 change: 1 addition & 0 deletions packages/desktop/components/buttons/popup-buttons/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -4,3 +4,4 @@ export { default as MintNativeTokenButton } from './MintNativeTokenButton.svelte
export { default as MintNftButton } from './MintNftButton.svelte'
export { default as RefreshTokenMetadataButton } from './RefreshTokenMetadataButton.svelte'
export { default as TestDeepLinkButton } from './TestDeepLinkButton.svelte'
export { default as AllotManaButton } from './AllotManaButton.svelte'
145 changes: 145 additions & 0 deletions packages/desktop/components/popups/AllotManaPopup.svelte
Original file line number Diff line number Diff line change
@@ -0,0 +1,145 @@
<script lang="ts">
import { localize } from '@core/i18n'
import { closePopup, updatePopupProps } from '@auxiliary/popup'
import { Button, Text, FontWeight, TextType, TextInput, AssetAmountInput } from '@ui'
import { handleError } from '@core/error/handlers'
import {
selectedWallet,
visibleSelectedWalletAssets,
convertToRawAmount,
getDefaultTransactionOptions,
AddressConverter,
} from '@core/wallet'
import { activeProfile, checkActiveProfileAuth } from '@core/profile'
import { ITransactionInfoToCalculateManaCost, getManaBalance } from '@core/network'
import { onMount } from 'svelte'
import { ManaBox } from '@components'

export let _onMount: (..._: any[]) => Promise<void> = async () => {}
export let rawAmount: string = getManaBalance($selectedWallet?.balances?.mana?.available)?.toString()
export let accountAddress: string

let isBusy = false
let error: string
let amount: string
let assetAmountInput: AssetAmountInput
let confirmDisabled = false

const transactionInfo: ITransactionInfoToCalculateManaCost = {}
let hasEnoughMana = false

$: hasTransactionInProgress =
$selectedWallet?.hasConsolidatingOutputsTransactionInProgress || $selectedWallet?.isTransferring
$: amount, accountAddress, hasTransactionInProgress, setConfirmDisabled()
$: asset = $visibleSelectedWalletAssets[$activeProfile?.network?.id].mana

function setConfirmDisabled(): void {
if (!amount || !accountAddress) {
confirmDisabled = true
return
}
const convertedSliderAmount = convertToRawAmount(amount, asset?.metadata)?.toString()
confirmDisabled = convertedSliderAmount === rawAmount || hasTransactionInProgress || !hasEnoughMana
}

async function onSubmit(): Promise<void> {
try {
await assetAmountInput?.validate(true)
if (!rawAmount || !accountAddress) return
updatePopupProps({ rawAmount, accountAddress })
await checkActiveProfileAuth(allotMana, { stronghold: true, ledger: false })
} catch (err) {
error = err.error
handleError(err)
} finally {
isBusy = false
}
}

async function preparedOutput() {
try {
const prepareOutput = await $selectedWallet.prepareOutput(
{
recipientAddress: $selectedWallet.depositAddress,
amount: '0',
},
getDefaultTransactionOptions()
)
transactionInfo.preparedTransaction = await $selectedWallet.prepareSendOutputs(
[prepareOutput],
getDefaultTransactionOptions()
)
} catch (error) {
transactionInfo.preparedTransactionError = error
}
}

async function allotMana(): Promise<void> {
try {
const accountId = AddressConverter.parseBech32Address(accountAddress)
// Send 0 amount transaction to accountAddress with amount in the allotMana
const prepareOutput = await $selectedWallet.prepareOutput(
{ recipientAddress: accountAddress, amount: '0' },
getDefaultTransactionOptions()
)
await $selectedWallet.sendOutputs([prepareOutput], {
...getDefaultTransactionOptions(accountId),
manaAllotments: { [accountId]: Number(rawAmount) }, // if manaAllotments amount passed as bigint it is transformed to string in the sdk
})
closePopup()
} catch (err) {
handleError(err)
}
}

function onBackClick(): void {
closePopup()
}

onMount(async () => {
try {
await _onMount()
await preparedOutput()
} catch (err) {
handleError(err.error)
}
})
</script>

<allot-mana-popup class="w-full h-full space-y-6 flex flex-auto flex-col shrink-0">
<Text type={TextType.h3} fontWeight={FontWeight.semibold} classes="text-left">
{localize('popups.allotMana.title')}
</Text>
<div class="w-full flex-col space-y-4">
<form id="allot-mana" on:submit|preventDefault={onSubmit} class="flex flex-col space-y-5">
<div class="space-y-4">
<AssetAmountInput
bind:this={assetAmountInput}
bind:rawAmount
bind:amount
bind:asset
containsSlider
disableAssetSelection
disabled={hasTransactionInProgress}
/>
<TextInput
{error}
bind:value={accountAddress}
placeholder={localize('general.accountAddress')}
label={localize('popups.allotMana.body')}
submitHandler={onSubmit}
disabled={isBusy}
/>
<ManaBox {transactionInfo} bind:hasEnoughMana />
</div>
<popup-buttons class="flex flex-row flex-nowrap w-full space-x-4">
<Button classes="w-full" outline onClick={onBackClick} disabled={isBusy}
>{localize('actions.back')}</Button
>
<Button classes="w-full" onClick={onSubmit} disabled={isBusy} {isBusy}>
{localize('actions.send')}
</Button>
</popup-buttons>
</form>
</div>
</allot-mana-popup>
2 changes: 2 additions & 0 deletions packages/desktop/components/popups/Popup.svelte
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@
import { clickOutside } from '@core/utils/ui'

// Popups
import AllotManaPopup from './AllotManaPopup.svelte'
import WalletSwitcherPopup from './WalletSwitcherPopup.svelte'
import ActivityDetailsPopup from './ActivityDetailsPopup.svelte'
import AddNodePopup from './AddNodePopup.svelte'
Expand Down Expand Up @@ -101,6 +102,7 @@
let popupContent

const POPUP_MAP: PopupComponentMap = {
[PopupId.AllotMana]: AllotManaPopup,
[PopupId.WalletSwitcher]: WalletSwitcherPopup,
[PopupId.ActivityDetails]: ActivityDetailsPopup,
[PopupId.AddNode]: AddNodePopup,
Expand Down
3 changes: 3 additions & 0 deletions packages/desktop/features/developer-tools.features.ts
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,9 @@ const developerToolsFeatures: IDeveloperFeatures = {
deeplink: {
enabled: false,
},
allotMana: {
enabled: true,
},
}

export default developerToolsFeatures
4 changes: 4 additions & 0 deletions packages/desktop/views/dashboard/developer/Developer.svelte
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
<script lang="ts">
import {
AllotManaButton,
CreateAccountButton,
FaucetRequestButton,
MintNativeTokenButton,
Expand Down Expand Up @@ -50,6 +51,9 @@
{#if features.developerTools.refreshTokens.enabled}
<RefreshTokenMetadataButton />
{/if}
{#if features.developerTools.allotMana.enabled}
<AllotManaButton />
{/if}
</div>
</Pane>
</div>
Expand Down
1 change: 1 addition & 0 deletions packages/shared/lib/auxiliary/popup/enums/popup-id.enum.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
export enum PopupId {
AllotMana = 'allotMana',
WalletSwitcher = 'WalletSwitcher',
ActivityDetails = 'activityDetails',
AddNode = 'addNode',
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@ function convertToRawAmountFromMetadata(
tokenMetadata: TokenMetadata,
selectedUnit?: string
): Big | undefined {
if (tokenMetadata?.standard === TokenStandard.BaseToken) {
if (tokenMetadata?.standard === TokenStandard.BaseToken || tokenMetadata?.standard === TokenStandard.Mana) {
if (selectedUnit === tokenMetadata.unit) {
const decimals = Math.min(tokenMetadata.decimals, MAX_SUPPORTED_DECIMALS)
return convertAmountToMatchUnit(amount, decimals)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -7,4 +7,5 @@ export interface IDeveloperFeatures extends IFeatureFlag {
account: IFeatureFlag
refreshTokens: IFeatureFlag
deeplink: IFeatureFlag
allotMana: IFeatureFlag
}
6 changes: 6 additions & 0 deletions packages/shared/locales/en.json
Original file line number Diff line number Diff line change
Expand Up @@ -1223,6 +1223,10 @@
"title": "Faucet request",
"body": "Are you sure you want to request {token} tokens from the {network} faucet?"
},
"allotMana": {
"title": "Allot Mana",
"body": "Select the account address to allot mana."
},
"manageVotingPower": {
"title": "Manage voting power",
"body": "Define your voting power to vote on proposals.",
Expand Down Expand Up @@ -1475,6 +1479,7 @@
"burnToken": "Burn token",
"faucetRequest": "Get {token} tokens",
"refreshTokenMetadata": "Refresh token metadata",
"allotMana": "Allot mana",
"test": "Test",
"testDeepLink": "Test deep link",
"initialize": "Initialize",
Expand Down Expand Up @@ -1703,6 +1708,7 @@
"mintNativeTokenDescription": "Mint native token following IRC30 standard",
"mintNftDescription": "Mint NFT following IRC27 standard",
"faucetRequestDescription": "Request tokens from the {network} faucet",
"allotManaDescription": "Allot mana to an account",
"refreshTokenMetadataDescription": "Reset and refresh all token metadata",
"refreshTokenMetadataHint" : "This will reset all your tokens' metadata including the verification status and unhide any hidden assets.",
"giftStorageDeposit": "Gift storage deposit",
Expand Down
Loading