|
1 | 1 | <script lang="ts">
|
2 |
| - import { onMount } from 'svelte' |
3 |
| - import { getProfileManager } from '@core/profile-manager/stores' |
4 |
| - import { checkActiveProfileAuth, getActiveProfile, updateAccountPersistedDataOnActiveProfile } from '@core/profile' |
5 |
| - import { fetchWithTimeout } from '@core/nfts' |
6 |
| - import { CHRONICLE_URLS, CHRONICLE_ADDRESS_HISTORY_ROUTE } from '@core/network/constants/chronicle-urls.constant' |
7 |
| - import { getSelectedAccount } from '@core/account' |
8 |
| - import { Button, Error, FontWeight, KeyValueBox, Text, TextType, Spinner } from 'shared/components' |
9 |
| - import VirtualList from '@sveltejs/svelte-virtual-list' |
10 |
| - import { AccountAddress } from '@iota/sdk/out/types' |
11 |
| - import { closePopup } from '@auxiliary/popup/actions/closePopup' |
| 2 | + import { getSelectedAccount, selectedAccount } from '@core/account' |
| 3 | + import { handleError } from '@core/error/handlers/handleError' |
12 | 4 | import { localize } from '@core/i18n'
|
| 5 | + import { CHRONICLE_ADDRESS_HISTORY_ROUTE, CHRONICLE_URLS } from '@core/network/constants/chronicle-urls.constant' |
| 6 | + import { fetchWithTimeout } from '@core/nfts' |
| 7 | + import { checkActiveProfileAuth, getActiveProfile, updateAccountPersistedDataOnActiveProfile } from '@core/profile' |
| 8 | + import { getProfileManager } from '@core/profile-manager/stores' |
13 | 9 | import { truncateString } from '@core/utils'
|
| 10 | + import { AccountAddress } from '@iota/sdk/out/types' |
| 11 | + import VirtualList from '@sveltejs/svelte-virtual-list' |
| 12 | + import { Button, FontWeight, KeyValueBox, Spinner, Text, TextType } from 'shared/components' |
| 13 | + import { onMount } from 'svelte' |
14 | 14 |
|
15 | 15 | interface AddressHistory {
|
16 | 16 | address: string
|
|
24 | 24 | ]
|
25 | 25 | }
|
26 | 26 |
|
27 |
| - const account = getSelectedAccount() |
28 |
| - const accountIndex = account.index |
29 |
| - const network = getActiveProfile().network.id |
| 27 | + const activeProfile = getActiveProfile() |
30 | 28 | const ADDRESS_GAP_LIMIT = 20
|
31 | 29 |
|
32 |
| - let error: string = '' |
| 30 | + $: accountIndex = $selectedAccount?.index |
| 31 | + $: network = activeProfile?.network?.id |
| 32 | + $: knownAddresses = $selectedAccount?.knownAddresses |
| 33 | +
|
33 | 34 | let searchURL: string
|
34 |
| - let knownAddresses: AccountAddress[] | undefined = undefined |
35 | 35 | let searchAddressStartIndex = 0
|
36 | 36 | let currentSearchGap = 0
|
37 | 37 | let isBusy = false
|
38 | 38 |
|
39 | 39 | onMount(() => {
|
40 | 40 | knownAddresses = getSelectedAccount().knownAddresses
|
41 |
| - if (knownAddresses === undefined) { |
42 |
| - getSelectedAccount() |
43 |
| - ?.addresses() |
44 |
| - .then((_addressList) => { |
45 |
| - knownAddresses = _addressList ?? [] |
46 |
| - updateAccountPersistedDataOnActiveProfile(accountIndex, { knownAddresses }) |
47 |
| - }) |
48 |
| - .catch((err) => { |
49 |
| - console.error(err) |
50 |
| - }) |
51 |
| - } |
52 | 41 |
|
53 | 42 | if (CHRONICLE_URLS[network] && CHRONICLE_URLS[network].length > 0) {
|
54 | 43 | const chronicleRoot = CHRONICLE_URLS[network][0]
|
55 | 44 | searchURL = `${chronicleRoot}${CHRONICLE_ADDRESS_HISTORY_ROUTE}`
|
56 | 45 | } else {
|
57 |
| - error = localize('popups.addressHistory.errorNoChronicle') |
| 46 | + throw new Error(localize('popups.addressHistory.errorNoChronicle')) |
58 | 47 | }
|
59 | 48 | })
|
60 | 49 |
|
|
64 | 53 | const addressHistory: AddressHistory = await response.json()
|
65 | 54 | return addressHistory?.items?.length > 0
|
66 | 55 | } catch (err) {
|
67 |
| - console.error(err) |
68 |
| - error = localize('popups.addressHistory.errorFailedFetch') |
| 56 | + throw new Error(localize('popups.addressHistory.errorFailedFetch')) |
69 | 57 | }
|
70 | 58 | }
|
71 | 59 |
|
72 | 60 | async function generateNextUnknownAddress(): Promise<[string, number]> {
|
73 | 61 | let nextUnknownAddress: string
|
74 |
| -
|
75 | 62 | try {
|
76 | 63 | do {
|
77 | 64 | nextUnknownAddress = await getProfileManager().generateEd25519Address(
|
|
82 | 69 | searchAddressStartIndex++
|
83 | 70 | } while (knownAddresses.map((accountAddress) => accountAddress.address).includes(nextUnknownAddress))
|
84 | 71 | } catch (err) {
|
85 |
| - console.error(err) |
86 |
| - error = localize('popups.addressHistory.errorFailedGenerate') |
| 72 | + throw new Error(localize('popups.addressHistory.errorFailedGenerate')) |
87 | 73 | }
|
88 | 74 |
|
89 | 75 | return [nextUnknownAddress, searchAddressStartIndex - 1]
|
90 | 76 | }
|
91 | 77 |
|
92 | 78 | async function search(): Promise<void> {
|
93 | 79 | currentSearchGap = 0
|
94 |
| - const isUnlocked = await unlock |
95 |
| -
|
96 |
| - if (isUnlocked && !error) { |
97 |
| - isBusy = true |
98 |
| - while (currentSearchGap < ADDRESS_GAP_LIMIT) { |
99 |
| - const [nextAddressToCheck, addressIndex] = await generateNextUnknownAddress() |
100 |
| - if (!nextAddressToCheck) { |
101 |
| - isBusy = false |
102 |
| - break |
103 |
| - } |
| 80 | + while (currentSearchGap < ADDRESS_GAP_LIMIT) { |
| 81 | + const [nextAddressToCheck, addressIndex] = await generateNextUnknownAddress() |
| 82 | + if (!nextAddressToCheck) { |
| 83 | + isBusy = false |
| 84 | + break |
| 85 | + } |
104 | 86 |
|
105 |
| - const hasHistory = await isAddressWithHistory(nextAddressToCheck) |
106 |
| - if (error) { |
107 |
| - isBusy = false |
108 |
| - break |
| 87 | + const hasHistory = await isAddressWithHistory(nextAddressToCheck) |
| 88 | + if (hasHistory) { |
| 89 | + const accountAddress: AccountAddress = { |
| 90 | + address: nextAddressToCheck, |
| 91 | + keyIndex: addressIndex, |
| 92 | + internal: false, |
| 93 | + used: true, |
109 | 94 | }
|
110 | 95 |
|
111 |
| - if (hasHistory) { |
112 |
| - const accountAddress: AccountAddress = { |
113 |
| - address: nextAddressToCheck, |
114 |
| - keyIndex: addressIndex, |
115 |
| - internal: false, |
116 |
| - used: true, |
117 |
| - } |
118 |
| -
|
119 |
| - knownAddresses.push(accountAddress) |
120 |
| - } else { |
121 |
| - currentSearchGap++ |
122 |
| - } |
| 96 | + knownAddresses.push(accountAddress) |
| 97 | + } else { |
| 98 | + currentSearchGap++ |
123 | 99 | }
|
124 |
| -
|
125 |
| - updateAccountPersistedDataOnActiveProfile(accountIndex, { knownAddresses }) |
126 |
| - isBusy = false |
127 | 100 | }
|
| 101 | + updateAccountPersistedDataOnActiveProfile(accountIndex, { knownAddresses }) |
128 | 102 | }
|
129 | 103 |
|
130 |
| - const unlock = new Promise<boolean>((resolve) => { |
131 |
| - const onSuccess: () => Promise<void> = () => { |
132 |
| - resolve(true) |
133 |
| - return Promise.resolve() |
| 104 | + async function handleSearchClick(): Promise<void> { |
| 105 | + isBusy = true |
| 106 | + try { |
| 107 | + await checkActiveProfileAuth(search, { stronghold: true, ledger: true }) |
| 108 | + } catch (err) { |
| 109 | + handleError(err) |
| 110 | + } finally { |
| 111 | + isBusy = false |
134 | 112 | }
|
135 |
| - const onCancel: () => void = () => resolve(false) |
136 |
| - const config = { stronghold: true, ledger: true } |
137 |
| - checkActiveProfileAuth(onSuccess, config, onCancel) |
138 |
| - }) |
139 |
| -
|
140 |
| - function onCancelClick(): void { |
141 |
| - closePopup() |
142 | 113 | }
|
143 | 114 | </script>
|
144 | 115 |
|
|
177 | 148 | <Spinner />
|
178 | 149 | </div>
|
179 | 150 | {/if}
|
180 |
| - {#if error} |
181 |
| - <Error {error} /> |
182 |
| - {/if} |
183 | 151 | </div>
|
184 | 152 | <div class="flex flex-row flex-nowrap w-full space-x-4 mt-6">
|
185 |
| - <Button classes="w-full" outline onClick={onCancelClick} disabled={isBusy}> |
186 |
| - {localize('actions.cancel')} |
187 |
| - </Button> |
188 | 153 | <Button
|
189 | 154 | classes="w-full"
|
190 |
| - onClick={search} |
191 |
| - disabled={isBusy || !!error} |
| 155 | + onClick={handleSearchClick} |
| 156 | + disabled={isBusy} |
192 | 157 | {isBusy}
|
193 | 158 | busyMessage={localize('actions.searching')}
|
194 | 159 | >
|
|
0 commit comments