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: adds multichain support in Buy/Sell view #2725

Merged
Show file tree
Hide file tree
Changes from all commits
Commits
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
2 changes: 2 additions & 0 deletions packages/desktop/components/popup/Popup.svelte
Original file line number Diff line number Diff line change
Expand Up @@ -64,6 +64,7 @@
import SyncAccountsPopup from './popups/SyncAccountsPopup.svelte'
import TestDeepLinkFormPopup from './popups/TestDeepLinkFormPopup.svelte'
import TokenInformationPopup from './popups/TokenInformationPopup.svelte'
import TransakSelectTokenPopup from './popups/TransakSelectTokenPopup.svelte'
import VoteForProposal from './popups/VoteForProposalPopup.svelte'
import VotingPowerToZeroPopup from './popups/VotingPowerToZeroPopup.svelte'
import { localize } from '@core/i18n'
Expand Down Expand Up @@ -146,6 +147,7 @@
[PopupId.SyncAccounts]: SyncAccountsPopup,
[PopupId.TestDeepLinkForm]: TestDeepLinkFormPopup,
[PopupId.TokenInformation]: TokenInformationPopup,
[PopupId.TransakSelectToken]: TransakSelectTokenPopup,
[PopupId.VoteForProposal]: VoteForProposal,
[PopupId.VotingPowerToZero]: VotingPowerToZeroPopup,
}
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,106 @@
<script lang="ts">
import { selectedExchangeCryptoCurrency, transakCryptoCurrencies, TransakCryptoCurrency } from '@auxiliary/transak'
import { IOption, SelectInput } from '@bloomwalletio/ui'
import { PopupTemplate } from '@components'
import { handleError } from '@core/error/handlers'
import { localize } from '@core/i18n'
import { networks } from '@core/network'
import { closePopup } from '@desktop/auxiliary/popup'
import { SearchInput } from '@ui'
import { TransakCryptoCurrencyTile } from '@views/dashboard/buy-sell/components'

let searchValue: string = ''

const options = [
{ value: 'all', label: localize('popups.transaction.allNetworks') },
...($networks?.reduce((acc, network) => {
if (!acc.find((option) => option.value === network.id)) {
acc.push({
value: network.id,
label: network.name,
})
}
return acc
}, [] as IOption[]) ?? []),
]
let selectedOption = options[0]

let filteredCryptoCurrencies = $transakCryptoCurrencies
function setFilteredfilteredCryptoCurrencies(): void {
if (selectedOption.value === 'all') {
filteredCryptoCurrencies = $transakCryptoCurrencies?.filter((cryptoCurrency) => {
const _searchValue = searchValue.toLowerCase()
return (
cryptoCurrency.name.toLowerCase().includes(_searchValue) ||
cryptoCurrency.symbol.toLowerCase().includes(_searchValue)
)
})
} else {
filteredCryptoCurrencies = $transakCryptoCurrencies?.filter((cryptoCurrency) => {
// TODO: map key to transak network name or compare chain id if possible?
const isInNetwork = cryptoCurrency.network.id === selectedOption.value

const _searchValue = searchValue.toLowerCase()
const isSearched =
cryptoCurrency.name.toLowerCase().includes(_searchValue) ||
cryptoCurrency.symbol.toLowerCase().includes(_searchValue)

return isInNetwork && isSearched
})
}
}
$: $transakCryptoCurrencies, searchValue, selectedOption, setFilteredfilteredCryptoCurrencies()

function onCryptoCurrencyClick(cryptoCurrency: TransakCryptoCurrency): void {
try {
if (cryptoCurrency === $selectedExchangeCryptoCurrency) {
onContinueClick()
} else {
$selectedExchangeCryptoCurrency = cryptoCurrency
}
} catch (err) {
handleError(err)
}
}

function onCancelClick(): void {
closePopup()
}

function onContinueClick(): void {
closePopup()
}
</script>

<PopupTemplate
title={localize('popups.transaction.selectToken')}
backButton={{ text: localize('actions.cancel'), onClick: onCancelClick }}
continueButton={{
text: localize('actions.continue'),
onClick: onContinueClick,
disabled: !$selectedExchangeCryptoCurrency,
}}
>
<div class="flex-1 h-0 flex flex-col gap-4">
<div class="flex-none flex flex-col gap-4">
{#if $networks.length > 1}
<SelectInput bind:selected={selectedOption} {options} hideValue />
{/if}
<SearchInput bind:value={searchValue} />
</div>
<div class="-mr-3 overflow-y-scroll">
<token-list class="flex flex-col p-0.5 pr-1.5 gap-2">
{#each filteredCryptoCurrencies ?? [] as cryptoCurrency}
{@const selected =
$selectedExchangeCryptoCurrency?.name === cryptoCurrency.name &&
$selectedExchangeCryptoCurrency?.network.id === cryptoCurrency?.network.id}
<TransakCryptoCurrencyTile
{cryptoCurrency}
onClick={() => onCryptoCurrencyClick(cryptoCurrency)}
{selected}
/>
{/each}
</token-list>
</div>
</div>
</PopupTemplate>
Original file line number Diff line number Diff line change
Expand Up @@ -48,6 +48,7 @@ export enum PopupId {
SyncAccounts = 'syncAccounts',
TestDeepLinkForm = 'testDeepLinkForm',
TokenInformation = 'tokenInformation',
TransakSelectToken = 'transakSelectToken',
VoteForProposal = 'voteForProposal',
VotingPowerToZero = 'votingPowerToZero',
}
6 changes: 3 additions & 3 deletions packages/desktop/lib/electron/managers/transak.manager.ts
Original file line number Diff line number Diff line change
Expand Up @@ -219,7 +219,7 @@ export default class TransakManager implements ITransakManager {
}

private getUrl(data: ITransakWindowData): string {
const { address, currency, service, amount, paymentMethod } = data
const { address, currency, service, amount, paymentMethod, networkName, cryptoCurrencySymbol } = data
const apiKey = process.env.TRANSAK_API_KEY

if (typeof apiKey !== 'string') {
Expand Down Expand Up @@ -248,8 +248,8 @@ export default class TransakManager implements ITransakManager {
walletAddress: address,
paymentMethod: paymentMethod,
productsAvailed: service,
cryptoCurrencyCode: 'IOTA',
network: 'miota',
cryptoCurrencyCode: cryptoCurrencySymbol,
network: networkName,
themeColor: '7C41C9',
hideMenu: true,
disableWalletAddressForm: true,
Expand Down
3 changes: 2 additions & 1 deletion packages/desktop/views/dashboard/buy-sell/BuySell.svelte
Original file line number Diff line number Diff line change
Expand Up @@ -4,14 +4,15 @@
import { BuySellMainView } from './views'
import { dashboardRoute, DashboardRoute } from '@core/router'
import { onMount } from 'svelte'
import { updateTransakFiatCurrencies } from '@auxiliary/transak'
import { updateTransakCryptoCurrencies, updateTransakFiatCurrencies } from '@auxiliary/transak'

$: if (features.analytics.dashboardRoute.buySell.enabled && $dashboardRoute === DashboardRoute.BuySell) {
Platform.trackEvent('buy-sell-route', { route: $dashboardRoute })
}

onMount(() => {
void updateTransakFiatCurrencies()
void updateTransakCryptoCurrencies()
})
</script>

Expand Down

This file was deleted.

Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
<script lang="ts">
import { TransakCryptoCurrency } from '@auxiliary/transak'
import { Avatar } from '@bloomwalletio/ui'
import { CoinGeckoCoinImage } from '@core/market/interfaces'
import { NetworkBadge } from '@ui/badges'

export let cryptoCurrency: TransakCryptoCurrency
export let size: 'xxs' | 'xs' | 'sm' | 'base' | 'md' | 'lg' = 'md'
export let hideNetworkBadge: boolean = false

const IMAGE_SIZES: Record<typeof size, keyof CoinGeckoCoinImage> = {
xxs: 'thumb',
xs: 'thumb',
sm: 'thumb',
base: 'small',
md: 'small',
lg: 'small',
}

let imageLoadError = false

$: image = cryptoCurrency?.image[IMAGE_SIZES[size]]
</script>

<div class="avatar">
<Avatar {size} backgroundColor="brand/10">
{#if image && !imageLoadError}
<img
src={image}
alt={cryptoCurrency.name}
class="w-full h-full object-cover"
on:error={() => (imageLoadError = true)}
/>
{/if}
</Avatar>
{#if (size === 'base' || size === 'md' || size === 'lg') && !hideNetworkBadge}
<span class="relative flex justify-center items-center bottom-0 right-0">
<NetworkBadge size="xs" networkId={cryptoCurrency.network.id} />
</span>
{/if}
</div>
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
<script lang="ts">
import { Tile, Text, Pill } from '@bloomwalletio/ui'
import { TransakCryptoCurrency } from '@auxiliary/transak/stores'
import TransakCryptoCurrencyAvatar from './TransakCryptoCurrencyAvatar.svelte'

export let cryptoCurrency: TransakCryptoCurrency
export let onClick: (() => unknown) | undefined = undefined
export let selected = false
</script>

<Tile {onClick} {selected} surface={1} width="full">
<div class="w-full flex items-center gap-2">
<TransakCryptoCurrencyAvatar {cryptoCurrency} hideNetworkBadge />
<div class="flex w-full justify-between items-center">
<div class="flex flex-col">
<Text>{cryptoCurrency.symbol}</Text>
<Text fontWeight="medium">{cryptoCurrency.name}</Text>
</div>
<Pill color="brand" compact>
<Text type="xs" textColor="brand" transform="uppercase">{cryptoCurrency.network.name}</Text>
</Pill>
</div>
</div>
</Tile>
Original file line number Diff line number Diff line change
Expand Up @@ -11,12 +11,19 @@
import { isDashboardSideBarExpanded } from '@core/ui'
import { drawerState } from '@desktop/auxiliary/drawer/stores'
import { DrawerState } from '@desktop/auxiliary/drawer/types'
import { IPopupState, IProfileAuthPopupState, popupState, profileAuthPopup } from '@desktop/auxiliary/popup'
import {
IPopupState,
IProfileAuthPopupState,
openPopup,
PopupId,
popupState,
profileAuthPopup,
} from '@desktop/auxiliary/popup'
import { isFeatureEnabled } from '@lib/features/utils'
import { Pane } from '@ui'
import { onDestroy, tick } from 'svelte'
import { TokenTile, TransakAmountInput } from './'
import { transakFiatCurrencies } from '@auxiliary/transak'
import { TransakCryptoCurrencyTile, TransakAmountInput } from './'
import { selectedExchangeCryptoCurrency, transakCryptoCurrencies, transakFiatCurrencies } from '@auxiliary/transak'

const CURRENCY_OPTIONS: IOption[] = Object.keys(FiatCurrency).map((currency) => ({
value: currency,
Expand Down Expand Up @@ -65,7 +72,7 @@
state: IPopupState,
profilePopupState: IProfileAuthPopupState,
settingsState: ISettingsState,
drawerState: DrawerState
drawerState: DrawerState | undefined
): Promise<void> {
if (state.active || profilePopupState.active || settingsState.open || drawerState?.id) {
await Platform.hideTransak()
Expand Down Expand Up @@ -132,6 +139,10 @@
service: selectedTab.key as 'BUY' | 'SELL',
amount: Number(fiatValue),
paymentMethod: selectedPaymentOption.value ?? '',
networkName:
$selectedExchangeCryptoCurrency?.networkName ?? $transakCryptoCurrencies?.[0]?.networkName ?? 'miota',
cryptoCurrencySymbol:
$selectedExchangeCryptoCurrency?.symbol ?? $transakCryptoCurrencies?.[0]?.symbol ?? 'IOTA',
})
isTransakOpen = true
await updateTransakBounds()
Expand All @@ -142,6 +153,10 @@
isTransakOpen = false
}

function onTokenTileClick(): void {
openPopup({ id: PopupId.TransakSelectToken })
}

onDestroy(() => {
void Platform.closeTransak()
isTransakOpen = false
Expand Down Expand Up @@ -181,7 +196,12 @@
/>
</div>
<TransakAmountInput currency={selectedCurrency} bind:value={fiatValue} />
<TokenTile {fiatValue} currency={FiatCurrency[selectedCurrency]} />
{#if $transakCryptoCurrencies && $transakCryptoCurrencies.length > 0}
<TransakCryptoCurrencyTile
cryptoCurrency={$selectedExchangeCryptoCurrency ?? $transakCryptoCurrencies[0]}
onClick={onTokenTileClick}
/>
{/if}
<div class="w-full">
<SelectInput
label="Payment method"
Expand Down
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
export { default as TokenTile } from './TokenTile.svelte'
export { default as TransakCryptoCurrencyTile } from './TransakCryptoCurrencyTile.svelte'
export { default as TransakAmountInput } from './TransakAmountInput.svelte'
export { default as TransakConnectionPanel } from './TransakConnectionPanel.svelte'
export { default as TransakExchangePanel } from './TransakExchangePanel.svelte'
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,6 @@
import { ProfileActionsMenu, SidebarTab } from '@components'
import { APP_STAGE, AppStage } from '@core/app'
import { localize } from '@core/i18n'
import { SupportedStardustNetworkId } from '@core/network'
import { activeProfile, isSoftwareProfile } from '@core/profile/stores'
import {
DashboardRoute,
Expand All @@ -16,12 +15,12 @@
} from '@core/router'
import { isDashboardSideBarExpanded } from '@core/ui'
import { IDashboardSidebarTab } from '@desktop/routers'
import { isFeatureEnabled, isFeatureNotGeoFenced } from '@lib/features/utils'
import { Logo } from '@ui'
import { campaignsRouter } from '../campaigns'
import LedgerStatusTile from './LedgerStatusTile.svelte'
import StrongholdStatusTile from './StrongholdStatusTile.svelte'
import { BackupToast, VersionToast } from './toasts'
import { isFeatureEnabled, isFeatureNotGeoFenced } from '@lib/features/utils'

let expanded = true
function toggleExpand(): void {
Expand Down Expand Up @@ -77,11 +76,6 @@
label: localize('tabs.buySell'),
route: DashboardRoute.BuySell,
onClick: openBuySell,
disabled: $activeProfile?.network?.id !== SupportedStardustNetworkId.Iota,
tooltip:
$activeProfile?.network?.id !== SupportedStardustNetworkId.Iota
? localize('tabs.tooltips.buySell')
: '',
},
]
: []),
Expand Down
Loading
Loading