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: add countdown logic for mana generation in implicit account creation #8222

Merged
Merged
Show file tree
Hide file tree
Changes from 26 commits
Commits
Show all changes
36 commits
Select commit Hold shift + click to select a range
ff44d76
feat: implement logic to allow tx or not based on mana cost for the X…
cpl121 Mar 6, 2024
46aa693
fixes and clean up
marc2332 Mar 7, 2024
357cedd
Merge branch 'develop-iota2.0' into feat/add-buffer-to-show-mana-cost
cpl121 Mar 8, 2024
0c25980
Merge branch 'develop-iota2.0' into feat/add-buffer-to-show-mana-cost
cpl121 Mar 8, 2024
24899df
Merge branch 'develop-iota2.0' into feat/add-buffer-to-show-mana-cost
marc2332 Mar 11, 2024
37dfe97
Merge branch 'develop-iota2.0' into feat/add-buffer-to-show-mana-cost
cpl121 Mar 12, 2024
f327b18
Merge branch 'develop-iota2.0' into feat/add-buffer-to-show-mana-cost
cpl121 Mar 12, 2024
9f959e7
Merge branch 'develop-iota2.0' into feat/add-buffer-to-show-mana-cost
cpl121 Mar 12, 2024
5b3ce04
Merge branches 'feat/add-buffer-to-show-mana-cost' and 'develop-iota2…
cpl121 Mar 12, 2024
719d742
feat: add mana cost to mint, burn, send and implicitTransition
cpl121 Mar 13, 2024
ba4c3dd
feat: improvements in mana box component
cpl121 Mar 14, 2024
c106747
feat: add mana cost to claim activity
cpl121 Mar 14, 2024
331bddd
feat: add mana cost to create delegation
cpl121 Mar 14, 2024
e46319b
feat: add mana cost to claim shimmer
cpl121 Mar 14, 2024
39bd5f9
Merge branch 'develop-iota2.0' into feat/add-buffer-to-show-mana-cost
cpl121 Mar 14, 2024
efb799c
Merge branch 'feat/add-buffer-to-show-mana-cost' into feat/add-mana-c…
cpl121 Mar 14, 2024
f8e1472
fixes
cpl121 Mar 18, 2024
b40de0c
Merge branches 'feat/add-mana-cost-everywhere' and 'feat/add-buffer-t…
cpl121 Mar 18, 2024
5dfbdca
feat: add countdown logic for mana generation in implicit account cre…
cpl121 Mar 19, 2024
9a428ba
Merge branches 'feat/add-mana-cost-everywhere' and 'develop-iota2.0' …
cpl121 Mar 19, 2024
d837904
fix: add conditional chaining
cpl121 Mar 19, 2024
e252c6c
Merge branches 'feat/add-countdown-logic-for-mana-generation' and 'fe…
cpl121 Mar 19, 2024
a0d5fb5
fix: improvements
cpl121 Mar 20, 2024
1e7af29
Merge branches 'feat/add-mana-cost-everywhere' and 'develop-iota2.0' …
cpl121 Mar 20, 2024
cc5effe
Merge branches 'feat/add-countdown-logic-for-mana-generation' and 'fe…
cpl121 Mar 20, 2024
1b99c7b
fix: improvements
cpl121 Mar 20, 2024
0f34d7c
Merge branch 'develop-iota2.0' into feat/add-mana-cost-everywhere
begonaalvarezd Mar 21, 2024
e4000d1
fix: update mana box with new transactionInfo interface
cpl121 Mar 21, 2024
2f4d16f
Merge branch 'develop-iota2.0' of github.com:iotaledger/firefly into …
cpl121 Mar 21, 2024
8feb268
fix: json literal and seconds in fund confirmation view
cpl121 Mar 21, 2024
3f90e21
fix: minor improvements
cpl121 Mar 21, 2024
edd3be2
Merge branches 'feat/add-countdown-logic-for-mana-generation' and 'fe…
cpl121 Mar 21, 2024
706700d
Merge branches 'feat/add-countdown-logic-for-mana-generation' and 'de…
cpl121 Mar 21, 2024
9581836
Merge branch 'develop-iota2.0' into feat/add-countdown-logic-for-mana…
evavirseda Mar 22, 2024
48265fc
Merge branch 'develop-iota2.0' into feat/add-countdown-logic-for-mana…
cpl121 Mar 22, 2024
e0441fb
fix: add missing declaration
begonaalvarezd Mar 25, 2024
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
78 changes: 78 additions & 0 deletions packages/desktop/components/ManaBox.svelte
Original file line number Diff line number Diff line change
@@ -0,0 +1,78 @@
<script lang="ts">
import { localize } from '@core/i18n'
import { DEFAULT_SECONDS_PER_SLOT, getExtraMana, getManaBalance } from '@core/network'
import { activeProfile } from '@core/profile'
import { MILLISECONDS_PER_SECOND } from '@core/utils'
import { selectedWallet, formatTokenAmountBestMatch, selectedWalletAssets } from '@core/wallet'
import { PreparedTransaction } from '@iota/sdk/out/types'
import { KeyValueBox, Text, TextType } from '@ui'
import { onMount, onDestroy } from 'svelte'

export let preparedTransaction: PreparedTransaction | undefined
export let hasEnoughMana: boolean
export let showCountdown: boolean = true

const NUMBER_OF_EXTRA_SLOTS_MANA = 3

let allotmentManaCost: number = 0
let countdownInterval: NodeJS.Timeout
let extraMana: number = getExtraMana(NUMBER_OF_EXTRA_SLOTS_MANA)
let secondsToRefreshExtraMana = NUMBER_OF_EXTRA_SLOTS_MANA * DEFAULT_SECONDS_PER_SLOT

$: preparedTransaction && calculateAndSetManaCost() // updates mana values when preparedTransaction changes
$: mana = ($selectedWalletAssets?.[$activeProfile?.network?.id] ?? {}).mana
$: availableMana = getManaBalance($selectedWallet?.balances?.mana?.available)
$: hasEnoughMana = availableMana >= requiredMana
$: requiredMana = allotmentManaCost + extraMana

function calculateAndSetManaCost(): void {
allotmentManaCost =
preparedTransaction?._preparedData?.transaction?.allotments?.reduce(
(acc, { mana }) => acc + Number(mana),
0
) || 0
extraMana = getExtraMana(NUMBER_OF_EXTRA_SLOTS_MANA)
}

onMount(() => {
calculateAndSetManaCost()
countdownInterval = setInterval(() => {
secondsToRefreshExtraMana -= 1
if (secondsToRefreshExtraMana <= 0) {
calculateAndSetManaCost()
secondsToRefreshExtraMana = NUMBER_OF_EXTRA_SLOTS_MANA * DEFAULT_SECONDS_PER_SLOT
}
}, MILLISECONDS_PER_SECOND)
})

onDestroy(() => {
clearInterval(countdownInterval)
})
</script>

<div class="flex flex-col space-y-2">
<KeyValueBox
keyText={localize('general.manaCost')}
valueText={formatTokenAmountBestMatch(requiredMana, mana.metadata)}
/>

<!-- TODO: Update with mana generation -->
{#if !hasEnoughMana}
<Text type={TextType.p} error classes="text-center">
{localize('general.insufficientMana', {
values: {
availableMana,
},
})}
</Text>
{/if}
{#if showCountdown}
<Text type={TextType.p} classes="text-center">
{localize('general.secondsToRefreshManaCost', {
values: {
seconds: secondsToRefreshExtraMana,
},
})}
</Text>
{/if}
</div>
1 change: 1 addition & 0 deletions packages/desktop/components/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -23,3 +23,4 @@ export { default as VotingPower } from './VotingPower.svelte'
export { default as VestingSchedule } from './VestingSchedule.svelte'
export { default as AccountManagementDetails } from './AccountManagementDetails.svelte'
export { default as AccountManagementList } from './AccountManagementList.svelte'
export { default as ManaBox } from './ManaBox.svelte'
52 changes: 34 additions & 18 deletions packages/desktop/components/popups/ActivityDetailsPopup.svelte
Original file line number Diff line number Diff line change
Expand Up @@ -12,8 +12,10 @@
ActivityType,
claimActivity,
rejectActivity,
selectedWallet,
selectedWalletActivities,
} from '@core/wallet'
import { PreparedTransaction } from '@iota/sdk/out/types'
import {
ActivityInformation,
AccountActivityDetails,
Expand All @@ -29,12 +31,16 @@
} from '@ui'
import { TextHintVariant } from '@ui/enums'
import { onMount } from 'svelte'
import { ManaBox } from '@components'

export let activityId: string
export let _onMount: (..._: any[]) => Promise<void> = async () => {}

const explorerUrl = getOfficialExplorerUrl($activeProfile?.network?.id)

let preparedTransaction: PreparedTransaction
let hasEnoughMana = false

$: activity = $selectedWalletActivities?.find((_activity) => _activity.id === activityId)
$: isTimelocked = activity?.asyncData?.asyncStatus === ActivityAsyncStatus.Timelocked
$: isActivityIncomingAndUnclaimed =
Expand Down Expand Up @@ -69,6 +75,10 @@
await checkActiveProfileAuth(claim, { stronghold: true, ledger: false })
}

async function prepareClaimOutput(): Promise<void> {
preparedTransaction = await $selectedWallet?.prepareClaimOutputs([activity.outputId])
}

function onRejectClick(): void {
openPopup({
id: PopupId.Confirmation,
Expand All @@ -94,6 +104,9 @@
onMount(async () => {
try {
await _onMount()
if (!isTimelocked && isActivityIncomingAndUnclaimed) {
await prepareClaimOutput()
}
} catch (err) {
console.error(err)
}
Expand Down Expand Up @@ -139,24 +152,27 @@
<ActivityInformation {activity} />
</activity-details>
{#if !isTimelocked && isActivityIncomingAndUnclaimed}
<popup-buttons class="flex flex-row flex-nowrap w-full space-x-4">
<Button
outline
classes="w-full"
disabled={activity.asyncData?.isClaiming || activity.asyncData?.isRejected}
onClick={onRejectClick}
>
{localize('actions.reject')}
</Button>
<Button
classes="w-full"
disabled={activity.asyncData?.isClaiming}
onClick={onClaimClick}
isBusy={activity.asyncData?.isClaiming}
>
{localize('actions.claim')}
</Button>
</popup-buttons>
<div class="flex flex-col space-y-4">
<ManaBox {preparedTransaction} bind:hasEnoughMana />
<popup-buttons class="flex flex-row flex-nowrap w-full space-x-4">
<Button
outline
classes="w-full"
disabled={activity.asyncData?.isClaiming || activity.asyncData?.isRejected}
onClick={onRejectClick}
>
{localize('actions.reject')}
</Button>
<Button
classes="w-full"
disabled={activity.asyncData?.isClaiming || !hasEnoughMana}
onClick={onClaimClick}
isBusy={activity.asyncData?.isClaiming}
>
{localize('actions.claim')}
</Button>
</popup-buttons>
</div>
{/if}
</activity-details-popup>
{/if}
Original file line number Diff line number Diff line change
Expand Up @@ -2,17 +2,22 @@
import { Button, Text, TextHint, FontWeight, TextType, ButtonVariant, KeyValueBox } from '@ui'
import { localize } from '@core/i18n'
import { closePopup, openPopup, PopupId } from '@auxiliary/popup'
import { burnAsset, formatTokenAmountBestMatch, IAsset } from '@core/wallet'
import { burnAsset, formatTokenAmountBestMatch, getDefaultTransactionOptions, IAsset } from '@core/wallet'
import { checkActiveProfileAuth } from '@core/profile'
import { handleError } from '@core/error/handlers'
import { onMount } from 'svelte'
import { selectedWallet } from '@core/wallet'
import { TextHintVariant } from '@ui/enums'
import { PreparedTransaction } from '@iota/sdk/out/types'
import { ManaBox } from '@components'

export let asset: IAsset
export let rawAmount: string
export let _onMount: (..._: any[]) => Promise<void> = async () => {}

let preparedTransaction: PreparedTransaction
let hasEnoughMana = false

$: formattedAmount = formatTokenAmountBestMatch(Number(rawAmount), asset?.metadata)

function onBackClick(): void {
Expand All @@ -36,9 +41,20 @@
}
}

async function prepareBurnFoundryTransaction(): Promise<void> {
if (asset && $selectedWallet && rawAmount) {
preparedTransaction = await $selectedWallet.prepareBurnNativeToken(
asset.id,
BigInt(rawAmount),
getDefaultTransactionOptions()
)
}
}

onMount(async () => {
try {
await _onMount()
await prepareBurnFoundryTransaction()
} catch (err) {
handleError(err)
}
Expand All @@ -57,14 +73,15 @@
<KeyValueBox keyText={localize('popups.nativeToken.property.assetId')} valueText={asset.id} isCopyable />
<KeyValueBox keyText={localize('general.amount')} valueText={formattedAmount} />
<TextHint variant={TextHintVariant.Warning} text={localize('actions.confirmTokenBurn.hint')} />
<ManaBox {preparedTransaction} bind:hasEnoughMana />
</div>
<popup-buttons class="flex flex-row flex-nowrap w-full space-x-4">
<Button classes="w-full" outline onClick={onBackClick}>{localize('actions.back')}</Button>
<Button
classes="w-full"
variant={ButtonVariant.Warning}
isBusy={$selectedWallet?.isTransferring}
disabled={$selectedWallet?.isTransferring}
disabled={$selectedWallet?.isTransferring || !hasEnoughMana}
onClick={onBurnTokenClick}
>
{localize('actions.burnToken')}
Expand Down
19 changes: 17 additions & 2 deletions packages/desktop/components/popups/CreateDelegationPopup.svelte
Original file line number Diff line number Diff line change
Expand Up @@ -11,8 +11,9 @@
selectedWalletId,
visibleSelectedWalletAssets,
} from '@core/wallet'
import { AccountAddress, CreateDelegationParams } from '@iota/sdk/out/types'
import { AccountAddress, CreateDelegationParams, PreparedTransaction } from '@iota/sdk/out/types'
import { Text, TextType, AssetAmountInput, TextInput, Button, HTMLButtonType } from '@ui'
import { ManaBox } from '@components'
import { onMount } from 'svelte'

export let _onMount: (..._: any[]) => Promise<void> = async () => {}
Expand All @@ -23,6 +24,9 @@
let amount: string
let confirmDisabled = false

let preparedTransaction: PreparedTransaction
let hasEnoughMana = false

$: asset = $visibleSelectedWalletAssets[$activeProfile?.network?.id].baseCoin
$: hasTransactionInProgress =
$selectedWallet?.hasConsolidatingOutputsTransactionInProgress ||
Expand All @@ -36,7 +40,7 @@
return
}
const convertedSliderAmount = convertToRawAmount(amount, asset?.metadata)?.toString()
confirmDisabled = convertedSliderAmount === rawAmount || hasTransactionInProgress
confirmDisabled = convertedSliderAmount === rawAmount || hasTransactionInProgress || !hasEnoughMana
}

async function onSubmit(): Promise<void> {
Expand Down Expand Up @@ -67,13 +71,23 @@
}
}

async function prepareDelegationOutput(): Promise<void> {
const params: CreateDelegationParams = {
address: AddressConverter.addressToBech32(new AccountAddress($selectedWallet?.mainAccountId)),
delegatedAmount: rawAmount,
validatorAddress: new AccountAddress(AddressConverter.parseBech32Address(accountAddress)),
}
preparedTransaction = await $selectedWallet?.prepareCreateDelegation(params, getDefaultTransactionOptions())
}

function onCancelClick(): void {
closePopup()
}

onMount(async () => {
try {
await _onMount()
await prepareDelegationOutput()
} catch (err) {
handleError(err.error)
}
Expand All @@ -99,6 +113,7 @@
placeholder={localize('popups.createDelegation.account.title')}
label={localize('popups.createDelegation.account.description')}
/>
<ManaBox {preparedTransaction} bind:hasEnoughMana />
</div>
<div class="flex flex-row flex-nowrap w-full space-x-4">
<Button outline disabled={hasTransactionInProgress} classes="w-full" onClick={onCancelClick}>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -15,12 +15,17 @@
import { onMount } from 'svelte'
import { selectedWallet } from '@core/wallet'
import { handleError } from '@core/error/handlers/handleError'
import { getClient } from '@core/wallet/actions'
import { getClient, prepareCreateNativeToken } from '@core/wallet/actions'
import { PreparedTransaction } from '@iota/sdk/out/types'
import { ManaBox } from '@components'

export let _onMount: (..._: any[]) => Promise<void> = async () => {}

let storageDeposit = '0'

let preparedTransaction: PreparedTransaction
let hasEnoughMana = false

let metadata: IIrc30Metadata | undefined
$: metadata = getMetadata($mintTokenDetails)
$: isTransferring = $selectedWallet?.isTransferring
Expand All @@ -37,6 +42,11 @@
const client = await getClient()
const preparedOutput = await client.buildFoundryOutput(outputData)
storageDeposit = formatTokenAmountPrecise(Number(preparedOutput.amount) ?? 0, getBaseToken())
preparedTransaction = await prepareCreateNativeToken(
Number($mintTokenDetails.totalSupply),
Number($mintTokenDetails.circulatingSupply),
metadata
)
}
}

Expand Down Expand Up @@ -151,14 +161,20 @@
isCopyable={value.isCopyable}
/>
{/each}
<ManaBox {preparedTransaction} bind:hasEnoughMana />
</details-list>
{/if}
</div>
<div class="flex flex-row flex-nowrap w-full space-x-4">
<Button outline classes="w-full" disabled={isTransferring} onClick={onBackClick}>
{localize('actions.back')}
</Button>
<Button classes="w-full" disabled={isTransferring} onClick={onConfirmClick} isBusy={isTransferring}>
<Button
classes="w-full"
disabled={isTransferring || !hasEnoughMana}
onClick={onConfirmClick}
isBusy={isTransferring}
>
{localize('actions.confirm')}
</Button>
</div>
Expand Down
Loading
Loading