Skip to content

feat: add account info logic #8032

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

Merged
merged 49 commits into from
Feb 16, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
49 commits
Select commit Hold shift + click to select a range
40512e3
feat: add account management router
evavirseda Feb 6, 2024
b6a15f2
feat: update icon
evavirseda Feb 6, 2024
b6ceba1
feat: add account list
evavirseda Feb 6, 2024
094f722
Merge branch 'develop-iota2.0' into feat/add-account-management-router
evavirseda Feb 6, 2024
45e6f80
Merge branch 'develop-iota2.0' into feat/add-acount-management-list-ui
evavirseda Feb 7, 2024
97969ac
Merge branch 'develop-iota2.0' into feat/add-account-management-router
evavirseda Feb 7, 2024
00136ce
Merge branch 'feat/add-account-management-router' into feat/add-acoun…
evavirseda Feb 7, 2024
96d9438
fix: display as isBusy if hasImplicitAccountCreationTransactionInProg…
evavirseda Feb 7, 2024
ebd0372
feat: format and truncate address
evavirseda Feb 7, 2024
b7a6c67
feat: cleanup code
evavirseda Feb 8, 2024
222e941
feat: add features flag
evavirseda Feb 8, 2024
c92a0cb
feat: add account management details ui
evavirseda Feb 8, 2024
a241985
feat: add locales
evavirseda Feb 9, 2024
2772f39
feat: enable features
evavirseda Feb 9, 2024
4fa8d55
feat: update accountManagement
evavirseda Feb 9, 2024
3fba6a5
Merge branch 'develop-iota2.0' into feat/add-acount-management-list-ui
evavirseda Feb 9, 2024
7741032
Merge branch 'feat/add-acount-management-list-ui' into feat/add-accou…
evavirseda Feb 12, 2024
01d151e
feat: use real data
evavirseda Feb 12, 2024
b922eec
feat: fix wrong merge
evavirseda Feb 12, 2024
6c40111
Merge branch 'develop-iota2.0' into feat/add-acount-management-list-ui
evavirseda Feb 12, 2024
c01b709
feat: add isImplicitAccountAccountOutput function
evavirseda Feb 12, 2024
2b55cb6
Merge branch 'feat/add-acount-management-list-ui' into feat/add-accou…
evavirseda Feb 12, 2024
d73eb3d
fix import
evavirseda Feb 12, 2024
2d5e4d9
Merge branch 'feat/add-acount-management-list-ui' into feat/add-accou…
evavirseda Feb 12, 2024
1e6710d
fix: improve function
evavirseda Feb 13, 2024
c74de66
Merge branch 'feat/add-acount-management-list-ui' into feat/add-accou…
evavirseda Feb 13, 2024
826ac45
feat: cleanup
evavirseda Feb 13, 2024
152171e
feat: cleanup
evavirseda Feb 13, 2024
d7f94ed
feat: cleanup
evavirseda Feb 13, 2024
687d022
Merge branch 'feat/add-account-info' into feat/add-account-info-logic
evavirseda Feb 13, 2024
9f40d56
minor fix
evavirseda Feb 13, 2024
c5b76e9
feat: show address
evavirseda Feb 13, 2024
65d8b5d
fix type
evavirseda Feb 13, 2024
015446c
Merge branch 'feat/add-acount-management-list-ui' into feat/add-accou…
evavirseda Feb 13, 2024
67fdb22
Merge branch 'develop-iota2.0' into feat/add-account-info
evavirseda Feb 13, 2024
26b74db
Merge branch 'feat/add-account-info' into feat/add-account-info-logic
evavirseda Feb 13, 2024
910f6ba
Merge branch 'develop-iota2.0' into feat/add-account-info-logic
evavirseda Feb 13, 2024
f47602c
feat: cleanup
evavirseda Feb 13, 2024
f137ff8
feat: hide implicitAccount address, clenaup and display transition bu…
evavirseda Feb 14, 2024
ce39114
feat: update main account id and persist
evavirseda Feb 14, 2024
75fdc17
feat: cleanup
evavirseda Feb 14, 2024
91f7195
feat: add locales and menuItem
evavirseda Feb 14, 2024
77bebe2
feat: update details and cleanup
evavirseda Feb 14, 2024
4746c51
fix warnings
evavirseda Feb 14, 2024
d490304
Merge branches 'feat/add-account-info-logic' and 'develop-iota2.0' of…
Feb 16, 2024
0e5e5a9
Merge branches 'feat/add-account-info-logic' and 'develop-iota2.0' of…
Feb 16, 2024
88cc985
fix: format
Feb 16, 2024
12ca588
Merge branches 'feat/add-account-info-logic' and 'develop-iota2.0' of…
Feb 16, 2024
244f3df
fix: minor improvements
Feb 16, 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
172 changes: 102 additions & 70 deletions packages/desktop/components/AccountManagementDetails.svelte
Original file line number Diff line number Diff line change
Expand Up @@ -12,95 +12,127 @@
CopyableBox,
Icon,
Pill,
Button,
ButtonSize,
} from '@ui'
import { Icon as IconEnum } from '@auxiliary/icon'
import { AccountManagementMenu } from './modals'
import {
formatTokenAmountBestMatch,
getBech32AddressFromAddressTypes,
isAccountOutput,
isImplicitAccountOutput,
} from '@core/wallet'
import { AccountAddress, AccountOutput, CommonOutput, OutputData } from '@iota/sdk/out/types'
import { openUrlInBrowser } from '@core/app'
import { ExplorerEndpoint, getOfficialExplorerUrl } from '@core/network'
import { activeProfile, getBaseToken } from '@core/profile'

export let selectedOutput: OutputData
export let index: number

let modal: Modal
let address: string = ''

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

$: isImplicitAccount = isImplicitAccountOutput(selectedOutput.output as CommonOutput)
$: accountId = isAccountOutput(selectedOutput) ? (selectedOutput?.output as AccountOutput)?.accountId : null
$: address = accountId ? getBech32AddressFromAddressTypes(new AccountAddress(accountId)) : null

const DUMMY_ACCOUNT_DATA = {
id: '1',
tiles: [
{
title: localize('views.accountManagement.details.balance'),
amount: '12 Gi',
},
{
title: localize('views.accountManagement.details.staked'),
amount: '0i',
},
],
address: {
title: localize('views.accountManagement.details.address'),
value: '0xba6a556cfdb7c6a66a45ee520e529c2ea6c526dd27f364865bc0d1167f41c819',
},
info: [
{
title: localize('views.accountManagement.details.mana'),
value: '120000',
},
{
title: localize('views.accountManagement.details.key'),
value: '7f364865bc0d1167f41c819',
},
],
function onExplorerClick(): void {
const url = `${explorerUrl}/${ExplorerEndpoint.Output}/${selectedOutput.outputId.toString()}`
openUrlInBrowser(url)
}
</script>

<right-pane class="w-full h-full min-h-96 flex-1 space-y-4 flex flex-col">
<Pane height={Height.Full}>
<right-pane-container class="flex flex-col space-y-10 h-full">
<title-container class="flex justify-between w-full">
<title-wrapper class="flex items-center space-x-2">
<Text type={TextType.h2}>{localize('views.accountManagement.list.tile.title')}</Text>
<Pill backgroundColor="blue-200" textColor="blue-600"
>{localize('views.accountManagement.list.tile.pill.main')}
</Pill>
</title-wrapper>
<wallet-actions-button class="block relative">
<MeatballMenuButton onClick={modal?.toggle} />
<AccountManagementMenu bind:modal position={{ right: '0' }} classes="mt-1.5" />
</wallet-actions-button>
</title-container>
<div class="flex flex-row space-x-2 w-1/2">
{#each DUMMY_ACCOUNT_DATA.tiles as tile}
<Tile>
<div class="flex flex-col space-y-2 items-center justify-center w-full">
<Text type={TextType.h3}>{tile.amount}</Text>
<Text color="gray-600" fontWeight={FontWeight.medium} fontSize="12" type={TextType.p}
>{tile.title}</Text
<right-pane-container class="flex flex-col space-y-8 h-full">
<right-pane-title class="flex flex-col space-y-1">
<title-container class="flex justify-between w-full items-center">
<title-wrapper class="flex items-center space-x-2 py-1">
<Text type={TextType.h2}>{localize('views.accountManagement.list.tile.title')} {index}</Text>
{#if isImplicitAccount}
<Pill backgroundColor="yellow-200" textColor="yellow-900"
>{localize('views.accountManagement.list.tile.pill.pending')}</Pill
>
</div>
</Tile>
{/each}
</div>
<div class="flex flex-col space-y-2 w-1/2">
<Text color="gray-600" fontWeight={FontWeight.medium} fontSize="12" type={TextType.p}
>{DUMMY_ACCOUNT_DATA.address.title}</Text
>
<CopyableBox
clearBackground
clearBoxPadding
isCopyable
value={DUMMY_ACCOUNT_DATA.address.value}
classes="flex space-x-2 items-center"
{:else}
<Pill backgroundColor="blue-200" textColor="blue-600"
>{localize('views.accountManagement.list.tile.pill.main')}
</Pill>
{/if}
</title-wrapper>

{#if accountId}
<wallet-actions-button class="block relative">
<MeatballMenuButton onClick={modal?.toggle} />
<AccountManagementMenu bind:modal position={{ right: '0' }} classes="mt-1.5" {accountId} />
</wallet-actions-button>
{/if}
{#if isImplicitAccount}
<Button size={ButtonSize.Small}
>{localize('views.implicit-account-creation.steps.step2.view.action')}</Button
>
{/if}
</title-container>
<button
class="action w-max flex justify-start text-center font-medium text-14 text-blue-500"
on:click={onExplorerClick}
>
<Text type={TextType.pre} fontSize="13" lineHeight="leading-120" classes="text-start w-[260px]"
>{DUMMY_ACCOUNT_DATA.address.value}</Text
>
<Icon icon={IconEnum.Copy} classes="text-blue-500" width={24} height={24} />
</CopyableBox>
{localize('general.viewOnExplorer')}
</button>
</right-pane-title>
<div class="flex flex-row space-x-2 w-1/2">
<Tile>
<div class="flex flex-col space-y-2 items-center justify-center w-full">
<!-- TODO: Replace this with the actual balance for accountOutputs-->
<Text type={TextType.h3}
>{isImplicitAccount
? formatTokenAmountBestMatch(Number(selectedOutput.output.amount), getBaseToken())
: 0 + ' Gi'}</Text
>
<Text color="gray-600" fontWeight={FontWeight.medium} fontSize="12" type={TextType.p}
>{localize('views.accountManagement.details.balance')}</Text
>
</div>
</Tile>

<Tile>
<div class="flex flex-col space-y-2 items-center justify-center w-full">
<!-- TODO: Replace this with the actual staked amount -->
<Text type={TextType.h3}>0i</Text>
<Text color="gray-600" fontWeight={FontWeight.medium} fontSize="12" type={TextType.p}
>{localize('views.accountManagement.details.staked')}</Text
>
</div>
</Tile>
</div>
{#each DUMMY_ACCOUNT_DATA.info as info}
{#if accountId}
<div class="flex flex-col space-y-2 w-1/2">
<Text color="gray-600" fontWeight={FontWeight.medium} fontSize="12" type={TextType.p}
>{info.title}</Text
<Text color="gray-600" fontWeight={FontWeight.medium} fontSize="12" type={TextType.p}>Address</Text>
<CopyableBox
clearBackground
clearBoxPadding
isCopyable
value={address}
classes="flex space-x-2 items-center"
>
<Text type={TextType.pre} fontSize="13" lineHeight="leading-120" classes="text-start w-[260px]"
>{address}</Text
>
<Icon icon={IconEnum.Copy} classes="text-blue-500" width={24} height={24} />
</CopyableBox>
</div>
{/if}
{#if isImplicitAccount}
<div class="flex flex-col space-y-2 w-1/2">
<Text color="gray-600" fontWeight={FontWeight.medium} fontSize="12" type={TextType.p}>Mana</Text>
<Text type={TextType.pre} fontSize="13" lineHeight="leading-120" classes="text-start w-[260px]"
>{info.value}</Text
>{selectedOutput?.output?.mana}</Text
>
</div>
{/each}
{/if}
</right-pane-container>
</Pane>
</right-pane>
42 changes: 15 additions & 27 deletions packages/desktop/components/AccountManagementList.svelte
Original file line number Diff line number Diff line change
@@ -1,43 +1,29 @@
<script lang="ts">
import { truncateString } from '@core/utils'
import { AccountAddress, AccountOutput, ImplicitAccountCreationAddress, OutputData } from '@iota/sdk/out/types'
import { AccountAddress, OutputData } from '@iota/sdk/out/types'
import { Height, Pane, TextType, Text, ClickableTile, FontWeight, Pill } from '@ui'
import { localize } from '@core/i18n'
import { getBech32AddressFromAddressTypes, isImplicitAccountOutput } from '@core/wallet/utils'
import { getBech32AddressFromAddressTypes, isAccountOutput, isImplicitAccountOutput } from '@core/wallet/utils'
import { selectedWallet } from '@core/wallet'

const allAccounts: OutputData[] = [...$selectedWallet.accountOutputs, ...$selectedWallet.implicitAccountOutputs]
export let onAccountClick: (account: OutputData) => void

function isAnAccount(output: OutputData): OutputData {
return $selectedWallet?.accountOutputs.find((account) => account.outputId === output.outputId)
}
const allOutputs: OutputData[] = [...$selectedWallet.accountOutputs, ...$selectedWallet.implicitAccountOutputs]

function formatAndTruncateAccount(output): string {
function formatAndTruncateAccount(account): string {
let address: string = ''
if (isImplicitAccountOutput(output)) {
address = getBech32AddressFromAddressTypes(
new ImplicitAccountCreationAddress(output.unlockConditions[0].address.pubKeyHash).address()
)
} else {
const accountId = (output as AccountOutput).accountId
if (accountId) {
address = getBech32AddressFromAddressTypes(new AccountAddress(accountId))
}
}
address = getBech32AddressFromAddressTypes(new AccountAddress(account.output.accountId))
return truncateString(address, 7, 5)
}
function handleAccountClick(): void {
// TODO: Implement account details
}
</script>

<left-pane class="flex flex-col w-1/3">
<Pane height={Height.Full}>
<left-pane-container class="flex flex-col space-y-10 h-full">
<Text type={TextType.h2}>{localize('views.accountManagement.list.title')}</Text>
<list-wrapper class="flex flex-col space-y-2">
{#each allAccounts as account, index}
<ClickableTile onClick={handleAccountClick}>
{#each allOutputs as output, index}
<ClickableTile onClick={() => onAccountClick(output)}>
<div class="flex flex-col space-y-1">
<div class="flex space-x-2">
<Text
Expand All @@ -49,20 +35,22 @@
{localize('views.accountManagement.list.tile.title')}
{index + 1}
</Text>
{#if isAnAccount(account)}
{#if isAccountOutput(output)}
<Pill backgroundColor="blue-200" textColor="blue-600"
>{localize('views.accountManagement.list.tile.pill.main')}</Pill
>
{/if}
{#if isImplicitAccountOutput(account.output)}
{#if isImplicitAccountOutput(output.output)}
<Pill backgroundColor="yellow-200" textColor="yellow-900"
>{localize('views.accountManagement.list.tile.pill.pending')}</Pill
>
{/if}
</div>
<Text type={TextType.p} fontSize="12" lineHeight="leading-140" color="gray-600"
>{formatAndTruncateAccount(account.output)}</Text
>
{#if isAccountOutput(output)}
<Text type={TextType.p} fontSize="12" lineHeight="leading-140" color="gray-600"
>{formatAndTruncateAccount(output)}</Text
>
{/if}
</div>
</ClickableTile>
{/each}
Expand Down
17 changes: 16 additions & 1 deletion packages/desktop/components/modals/AccountManagementMenu.svelte
Original file line number Diff line number Diff line change
Expand Up @@ -2,17 +2,32 @@
import { MenuItem, Modal } from '@ui'
import { localize } from '@core/i18n'
import { Icon } from '@auxiliary/icon/enums'
import { updateActiveWalletPersistedData } from '@core/profile'
import { selectedWalletId } from '@core/wallet'

export let modal: Modal = undefined
export let accountId: string

function setAsMainAccount(): void {
// TODO: Add logic to set the account as the main account
updateActiveWalletPersistedData($selectedWalletId, {
mainAccountId: accountId,
})
modal?.close()
}

function manageKeys(): void {
// TODO: Implement manage keys
modal?.close()
}
</script>

<Modal bind:this={modal} {...$$restProps}>
<account-management-menu class="flex flex-col">
<MenuItem
icon={Icon.Key}
title={localize('views.accountManagement.details.modal.manageKeys')}
onClick={manageKeys}
/>
<MenuItem
icon={Icon.Star}
title={localize('views.accountManagement.details.modal.setMainAccount')}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,22 @@
import { selectedWallet } from '@core/wallet/stores'
import features from '@features/features'
import { AccountManagementDetails, AccountManagementList } from '@components'
import { OutputData } from '@iota/sdk/out/types'

const allAccountOutputs: OutputData[] = [
...$selectedWallet.accountOutputs,
...$selectedWallet.implicitAccountOutputs,
]

let selectedOutput: OutputData = allAccountOutputs[0]

function handleAccountClick(account: OutputData): void {
selectedOutput = account
}

function setAccountOutputIndex(account: OutputData): number {
return allAccountOutputs.indexOf(account) + 1
}
</script>

{#if $selectedWallet}
Expand All @@ -11,10 +27,10 @@
<div class="flex space-x-4 max-w-7xl justify-center w-full">
{#key $selectedWallet?.id}
{#if features.accountManagement.accountList.enabled}
<AccountManagementList />
<AccountManagementList onAccountClick={handleAccountClick} />
{/if}
{#if features.accountManagement.accountDetails.enabled}
<AccountManagementDetails />
<AccountManagementDetails {selectedOutput} index={setAccountOutputIndex(selectedOutput)} />
{/if}
{/key}
</div>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ import {
getBech32AddressFromAddressTypes,
getOrRequestAssetFromPersistedAssets,
hasBlockIssuerFeature,
isAccountOutput,
isImplicitAccountOutput,
preprocessGroupedOutputs,
syncBalance,
Expand Down Expand Up @@ -43,12 +44,11 @@ export async function handleNewOutputEventInternal(walletId: string, payload: Ne
if (!wallet || !outputData) return

const output = outputData.output
const isAccountOutput = output.type === OutputType.Account
const isNftOutput = output.type === OutputType.Nft

const address = outputData.address ? getBech32AddressFromAddressTypes(outputData.address) : undefined

if ((address && wallet?.depositAddress === address && !outputData?.remainder) || isAccountOutput) {
if ((address && wallet?.depositAddress === address && !outputData?.remainder) || isAccountOutput(outputData)) {
await syncBalance(wallet.id)
const walletOutputs = await wallet.outputs()
const accountOutputs = await wallet.accounts()
Expand All @@ -72,7 +72,7 @@ export async function handleNewOutputEventInternal(walletId: string, payload: Ne
const implicitAccountOutputs = await wallet.implicitAccounts()
updateActiveWallet(wallet.id, { implicitAccountOutputs })
}
if (isAccountOutput) {
if (isAccountOutput(outputData)) {
const accountOutput = output as AccountOutput
// TODO: move to packages/shared/lib/core/wallet/actions/events-handlers/handleTransactionInclusionEvent.ts
// when https://github.com/iotaledger/firefly/pull/7926 is merged and we can have ActivityType.Account
Expand Down
1 change: 1 addition & 0 deletions packages/shared/lib/core/wallet/utils/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@ export * from './getSenderAddressFromUnlockCondition'
export * from './getSubjectFromAddress'
export * from './getTokenFromSelectedWallet'
export * from './getUnitFromTokenMetadata'
export * from './isAccountOutput'
export * from './isImplicitAccountOutput'
export * from './isReservedTagKeyword'
export * from './isSubjectInternal'
Expand Down
5 changes: 5 additions & 0 deletions packages/shared/lib/core/wallet/utils/isAccountOutput.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
import { OutputData, OutputType } from '@iota/sdk/out/types'

export function isAccountOutput(output: OutputData): boolean {
return output.output.type === OutputType.Account
}
Loading