diff --git a/packages/desktop/components/popups/AddressHistoryPopup.svelte b/packages/desktop/components/popups/AddressHistoryPopup.svelte index 1bd948281ff..eeecfcb3de0 100644 --- a/packages/desktop/components/popups/AddressHistoryPopup.svelte +++ b/packages/desktop/components/popups/AddressHistoryPopup.svelte @@ -6,11 +6,18 @@ import { fetchWithTimeout } from '@core/nfts' import { checkActiveProfileAuth, getActiveProfile, updateAccountPersistedDataOnActiveProfile } from '@core/profile' import { getProfileManager } from '@core/profile-manager/stores' - import { setClipboard, truncateString } from '@core/utils' + import { + setClipboard, + truncateString, + isValidBech32AddressAndPrefix, + BECH32_DEFAULT_HRP, + convertBech32ToHex, + } from '@core/utils' import { AccountAddress } from '@iota/sdk/out/types' import VirtualList from '@sveltejs/svelte-virtual-list' - import { Button, FontWeight, KeyValueBox, Spinner, Text, TextType } from 'shared/components' + import { Button, ButtonSize, FontWeight, KeyValueBox, Spinner, Text, TextType } from 'shared/components' import { onMount } from 'svelte' + import { HexAddressBox } from '@ui' interface AddressHistory { address: string @@ -42,6 +49,13 @@ setClipboard(addresses) } + function onCopyAllHexAdressesClick(): void { + const hexList = knownAddresses + .map((address) => convertBech32ToHex(address.address, BECH32_DEFAULT_HRP)) + .join(',') + setClipboard(hexList) + } + onMount(() => { knownAddresses = $selectedAccount?.knownAddresses if (!knownAddresses?.length) { @@ -146,7 +160,7 @@ {#if knownAddresses.length > 0}
-
+
+ + {#if isValidBech32AddressAndPrefix(item.address, BECH32_DEFAULT_HRP)} + +
+ {/if}
@@ -174,13 +193,18 @@ {/if}
-
- +
+
+ + +
@@ -199,4 +223,7 @@ .virtual-list-wrapper :global(svelte-virtual-list-contents) { margin-right: -1rem !important; } + .virtual-list-wrapper :global(svelte-virtual-list-row:last-of-type hr) { + display: none !important; + } diff --git a/packages/desktop/components/popups/ReceiveAddressPopup.svelte b/packages/desktop/components/popups/ReceiveAddressPopup.svelte index 526e9c2309d..e517ab28c22 100644 --- a/packages/desktop/components/popups/ReceiveAddressPopup.svelte +++ b/packages/desktop/components/popups/ReceiveAddressPopup.svelte @@ -1,11 +1,17 @@ @@ -13,5 +19,10 @@
+ {#if hasHexAddressToShow} +
+ +
+ {/if}
diff --git a/packages/desktop/views/dashboard/wallet/Wallet.svelte b/packages/desktop/views/dashboard/wallet/Wallet.svelte index 0a371662431..4e8f0f7afa4 100644 --- a/packages/desktop/views/dashboard/wallet/Wallet.svelte +++ b/packages/desktop/views/dashboard/wallet/Wallet.svelte @@ -1,9 +1,16 @@ {#if $selectedAccount} @@ -20,10 +27,15 @@ {/if} -
+
{#if features?.wallet?.sendAndReceive?.enabled} - + {#if !hasHexAddressToShow} + + {/if} + {#if hasHexAddressToShow} + + {/if} {/if}
@@ -42,3 +54,36 @@ {/key} {/if} + + diff --git a/packages/shared/components/SubjectBox.svelte b/packages/shared/components/SubjectBox.svelte index c3b11b7a635..92686c475a3 100644 --- a/packages/shared/components/SubjectBox.svelte +++ b/packages/shared/components/SubjectBox.svelte @@ -1,9 +1,16 @@ {#if subject?.type === SubjectType.Account} @@ -12,6 +19,11 @@ {:else if subject?.type === SubjectType.Address} + {#if hasHexAddressToShow} +
+ +
+ {/if} {:else} diff --git a/packages/shared/components/boxes/AddressBox.svelte b/packages/shared/components/boxes/AddressBox.svelte index 25726827742..bd697ec281c 100644 --- a/packages/shared/components/boxes/AddressBox.svelte +++ b/packages/shared/components/boxes/AddressBox.svelte @@ -1,12 +1,9 @@ + +{#if hexAddress.length > 0} + + +
+
+ + {hexAddress} + +
+ + {#if hexAddress.length > 0} + + + + {/if} + + {#if showInfoTooltip} + + + Equivalent hex address in the new IOTA Wallet extension + + + {/if} +
+
+
+{/if} diff --git a/packages/shared/components/boxes/index.js b/packages/shared/components/boxes/index.js index d2a0aceeeed..8b27902b104 100644 --- a/packages/shared/components/boxes/index.js +++ b/packages/shared/components/boxes/index.js @@ -2,3 +2,4 @@ export { default as Box } from './Box.svelte' export { default as KeyValueBox } from './KeyValueBox.svelte' export { default as AddressBox } from './AddressBox.svelte' export { default as CopyableBox } from './CopyableBox.svelte' +export { default as HexAddressBox } from './HexAddressBox.svelte' diff --git a/packages/shared/components/buttons/ReceiveAddressButton.svelte b/packages/shared/components/buttons/ReceiveAddressButton.svelte index 70cf87b922d..787454d093a 100644 --- a/packages/shared/components/buttons/ReceiveAddressButton.svelte +++ b/packages/shared/components/buttons/ReceiveAddressButton.svelte @@ -3,12 +3,9 @@ import { appSettings } from '@core/app' import { localize } from '@core/i18n' import { QR, Text, FontWeight, AddressBox } from 'shared/components' - let addressBoxElement: AddressBox - $: receiveAddress = $selectedAccount.depositAddress $: darkModeEnabled = $appSettings.darkMode - function onReceiveClick(): void { addressBoxElement.copyAddress() } @@ -39,7 +36,6 @@ @apply border; @apply border-solid; @apply border-gray-300; - &:hover { @apply bg-blue-50; @apply border-gray-500; diff --git a/packages/shared/lib/core/utils/constants/bech32-hrp.constant.ts b/packages/shared/lib/core/utils/constants/bech32-hrp.constant.ts new file mode 100644 index 00000000000..18663d4d15a --- /dev/null +++ b/packages/shared/lib/core/utils/constants/bech32-hrp.constant.ts @@ -0,0 +1 @@ +export const BECH32_DEFAULT_HRP = 'iota' diff --git a/packages/shared/lib/core/utils/constants/index.ts b/packages/shared/lib/core/utils/constants/index.ts index 42caf588888..1a7d0b50897 100644 --- a/packages/shared/lib/core/utils/constants/index.ts +++ b/packages/shared/lib/core/utils/constants/index.ts @@ -7,3 +7,4 @@ export * from './max-bytes.constant' export * from './max-number-of-iotas.constant' export * from './pin-length.constant' export * from './time.constants' +export * from './bech32-hrp.constant' diff --git a/packages/shared/lib/core/utils/convert.ts b/packages/shared/lib/core/utils/convert.ts index 03bcf5bdbc5..57326cb6b5b 100644 --- a/packages/shared/lib/core/utils/convert.ts +++ b/packages/shared/lib/core/utils/convert.ts @@ -4,6 +4,15 @@ import { HEXADECIMAL_PREFIX, MILLISECONDS_PER_SECOND } from './constants' import { isValidDate } from './date' import { Base64 } from './encode' import { clamp } from './math' +import { Bech32Helper } from './crypto' + +/** + * Converts a Bech32 address to a hexadecimal string. + */ +export function convertBech32ToHex(bech32Address: string, hrp: string): string { + const { addressBytes } = Bech32Helper.fromBech32(bech32Address, hrp) + return convertBytesToHexString(Array.from(addressBytes), true) +} /** * Returns a UNIX timestamp from a given Date object.