diff --git a/packages/desktop/components/ConfirmationDialog.svelte b/packages/desktop/components/ConfirmationDialog.svelte index 12ade47f5c..606b5f75f9 100644 --- a/packages/desktop/components/ConfirmationDialog.svelte +++ b/packages/desktop/components/ConfirmationDialog.svelte @@ -12,6 +12,7 @@ export let backText: string = localize('actions.cancel') export let confirmText: string = localize('actions.confirm') export let onConfirm: () => void + export let onClose: () => void export function openDialog(): void { visible = true @@ -19,6 +20,7 @@ function closeDialog(): void { visible = false + onClose() } function onConfirmClick(): void { diff --git a/packages/desktop/components/popup/Popup.svelte b/packages/desktop/components/popup/Popup.svelte index 9d54771aba..5cb335338d 100644 --- a/packages/desktop/components/popup/Popup.svelte +++ b/packages/desktop/components/popup/Popup.svelte @@ -64,6 +64,8 @@ import SyncAccountsPopup from './popups/SyncAccountsPopup.svelte' import TestDeepLinkFormPopup from './popups/TestDeepLinkFormPopup.svelte' import TokenInformationPopup from './popups/TokenInformationPopup.svelte' + import TransakFramePopup from './popups/TransakFramePopup.svelte' + import TransakSelectTokenPopup from './popups/TransakSelectTokenPopup.svelte' import VoteForProposal from './popups/VoteForProposalPopup.svelte' import VotingPowerToZeroPopup from './popups/VotingPowerToZeroPopup.svelte' import { localize } from '@core/i18n' @@ -146,6 +148,8 @@ [PopupId.SyncAccounts]: SyncAccountsPopup, [PopupId.TestDeepLinkForm]: TestDeepLinkFormPopup, [PopupId.TokenInformation]: TokenInformationPopup, + [PopupId.TransakFrame]: TransakFramePopup, + [PopupId.TransakSelectToken]: TransakSelectTokenPopup, [PopupId.VoteForProposal]: VoteForProposal, [PopupId.VotingPowerToZero]: VotingPowerToZeroPopup, } @@ -169,6 +173,7 @@ if (!preventClose) { if (confirmClickOutside) { confirmationDialog?.openDialog() + modifyPopupState({ confirmClickOutsideActive: true }) } else { closePopup({ callOnCancel: true }) } @@ -241,9 +246,12 @@ { - modifyPopupState({ confirmClickOutside: false }) + modifyPopupState({ confirmClickOutside: false, confirmClickOutsideActive: false }) closePopup() }} + onClose={() => { + modifyPopupState({ confirmClickOutsideActive: false }) + }} confirmText={localize('actions.close')} title="Close popup" variant="danger" diff --git a/packages/desktop/components/popup/popups/TransakFramePopup.svelte b/packages/desktop/components/popup/popups/TransakFramePopup.svelte new file mode 100644 index 0000000000..37c553c0a9 --- /dev/null +++ b/packages/desktop/components/popup/popups/TransakFramePopup.svelte @@ -0,0 +1,137 @@ + + + + +
+
+ +
+
+ {#if error} +
+ + {localize('views.buySell.error.title')} + {localize('views.buySell.error.description')} +
+ {:else if isTransakLoading} +
+ +
+ {/if} +
+
+ + diff --git a/packages/desktop/components/popup/popups/TransakSelectTokenPopup.svelte b/packages/desktop/components/popup/popups/TransakSelectTokenPopup.svelte new file mode 100644 index 0000000000..c55342ed65 --- /dev/null +++ b/packages/desktop/components/popup/popups/TransakSelectTokenPopup.svelte @@ -0,0 +1,108 @@ + + + + + diff --git a/packages/desktop/features/buy-sell.features.ts b/packages/desktop/features/buy-sell.features.ts index 07735ed62c..8d2e1c259f 100644 --- a/packages/desktop/features/buy-sell.features.ts +++ b/packages/desktop/features/buy-sell.features.ts @@ -2,6 +2,9 @@ import { IFeatureFlag } from '@lib/features/interfaces' const buySellFeatures: IFeatureFlag = { enabled: true, + sell: { + enabled: false, + }, } export default buySellFeatures diff --git a/packages/desktop/lib/auxiliary/popup/enums/popup-id.enum.ts b/packages/desktop/lib/auxiliary/popup/enums/popup-id.enum.ts index 429921049d..9efdc19e56 100644 --- a/packages/desktop/lib/auxiliary/popup/enums/popup-id.enum.ts +++ b/packages/desktop/lib/auxiliary/popup/enums/popup-id.enum.ts @@ -48,6 +48,8 @@ export enum PopupId { SyncAccounts = 'syncAccounts', TestDeepLinkForm = 'testDeepLinkForm', TokenInformation = 'tokenInformation', + TransakFrame = 'transakFrame', + TransakSelectToken = 'transakSelectToken', VoteForProposal = 'voteForProposal', VotingPowerToZero = 'votingPowerToZero', } diff --git a/packages/desktop/lib/auxiliary/popup/interfaces/popup-state.interface.ts b/packages/desktop/lib/auxiliary/popup/interfaces/popup-state.interface.ts index 1dc7bdac79..db2d3aa370 100644 --- a/packages/desktop/lib/auxiliary/popup/interfaces/popup-state.interface.ts +++ b/packages/desktop/lib/auxiliary/popup/interfaces/popup-state.interface.ts @@ -12,4 +12,5 @@ export interface IPopupState { relative?: boolean autofocusContent?: boolean confirmClickOutside?: boolean + confirmClickOutsideActive?: boolean } diff --git a/packages/desktop/lib/electron/managers/transak.manager.ts b/packages/desktop/lib/electron/managers/transak.manager.ts index 8bd5498e19..b5f5bc94a7 100644 --- a/packages/desktop/lib/electron/managers/transak.manager.ts +++ b/packages/desktop/lib/electron/managers/transak.manager.ts @@ -3,7 +3,7 @@ import { windows } from '../constants/windows.constant' import features from '@features/features' import { ITransakManager, ITransakWindowData } from '@core/app' import path from 'path' -import { TRANSAK_WIDGET_URL } from '@auxiliary/transak/constants' +import { TRANSAK_PRODUCTION_WIDGET_URL, TRANSAK_STAGING_WIDGET_URL } from '@auxiliary/transak/constants' import { buildUrl } from '@core/utils/url' import { FiatCurrency } from '@core/market/enums/fiat-currency.enum' import fs from 'fs' @@ -144,13 +144,16 @@ export default class TransakManager implements ITransakManager { }) windows.transak.webContents.addListener('did-navigate-in-page', (_, url) => { - const googlePayUrl = TRANSAK_WIDGET_URL + '/googlepay' + const widgetUrl = + data.environment === 'PRODUCTION' ? TRANSAK_PRODUCTION_WIDGET_URL : TRANSAK_STAGING_WIDGET_URL + + const googlePayUrl = widgetUrl + '/googlepay' if (url.startsWith(googlePayUrl)) { windows.main?.webContents?.send?.('try-open-url-in-browser', url) void windows.transak?.loadURL?.(initialUrl) } - const kycUrl = TRANSAK_WIDGET_URL + '/user/kyc-forms/idProof' + const kycUrl = widgetUrl + '/user/kyc-forms/idProof' if (process.platform === 'darwin' && url.startsWith(kycUrl)) { void systemPreferences.askForMediaAccess('camera') } @@ -219,14 +222,15 @@ export default class TransakManager implements ITransakManager { } private getUrl(data: ITransakWindowData): string { - const { address, currency, service, amount } = data + const { address, currency, service, amount, paymentMethod, networkName, cryptoCurrencySymbol, environment } = + data const apiKey = process.env.TRANSAK_API_KEY if (typeof apiKey !== 'string') { throw new Error('Undefined Transak API key') } - if (!Object.values(FiatCurrency).includes(currency as FiatCurrency)) { + if (!Object.keys(FiatCurrency).includes(currency)) { throw new Error('Invalid Transak currency') } @@ -243,22 +247,34 @@ export default class TransakManager implements ITransakManager { const queryParams: QueryParameters = { apiKey, - defaultFiatCurrency: currency, - defaultFiatAmount: amount, - walletAddress: address, - productsAvailed: service, - cryptoCurrencyCode: 'IOTA', - network: 'miota', + + // Styling + colorMode, themeColor: '7C41C9', - hideMenu: true, - disableWalletAddressForm: true, + + // Service Feature Flags + productsAvailed: service, + hideMenu: false, isFeeCalculationHidden: true, disablePaymentMethods: ['apple_pay', 'google_pay'], excludeFiatCurrencies: 'USD', - colorMode, + + // Quotations Fields + fiatCurrency: currency, + fiatAmount: amount, + network: networkName, + cryptoCurrencyCode: cryptoCurrencySymbol, + walletAddress: address, + paymentMethod: paymentMethod, + + // Flags for skippable forms + hideExchangeScreen: true, + disableWalletAddressForm: true, } - const urlObject = buildUrl({ base: TRANSAK_WIDGET_URL, query: queryParams }) + const widgetUrl = environment === 'PRODUCTION' ? TRANSAK_PRODUCTION_WIDGET_URL : TRANSAK_STAGING_WIDGET_URL + + const urlObject = buildUrl({ base: widgetUrl, query: queryParams }) return urlObject?.href ?? '' } diff --git a/packages/desktop/lib/electron/preloads/transak.preload.ts b/packages/desktop/lib/electron/preloads/transak.preload.ts index 7fc46aa60c..2ff174de2a 100644 --- a/packages/desktop/lib/electron/preloads/transak.preload.ts +++ b/packages/desktop/lib/electron/preloads/transak.preload.ts @@ -32,7 +32,9 @@ window.addEventListener('DOMContentLoaded', () => { const appRoot = window.document.getElementById('appRoot') if (appRoot) { - appRoot.style.borderRadius = '16px' + appRoot.style.borderBottomLeftRadius = '32px' + appRoot.style.borderBottomRightRadius = '32px' appRoot.style.overflow = 'hidden' } + window.document.documentElement.style.backgroundColor = 'transparent' }) diff --git a/packages/desktop/views/dashboard/buy-sell/BuySell.svelte b/packages/desktop/views/dashboard/buy-sell/BuySell.svelte index d3185a10b6..c45f460266 100644 --- a/packages/desktop/views/dashboard/buy-sell/BuySell.svelte +++ b/packages/desktop/views/dashboard/buy-sell/BuySell.svelte @@ -3,12 +3,22 @@ import features from '@features/features' import { BuySellMainView } from './views' import { dashboardRoute, DashboardRoute } from '@core/router' + import { onMount } from 'svelte' + import { updateTransakCryptoCurrencies, updateTransakFiatCurrencies } from '@auxiliary/transak' + import { Text } from '@bloomwalletio/ui' + import { localize } from '@core/i18n' $: if (features.analytics.dashboardRoute.buySell.enabled && $dashboardRoute === DashboardRoute.BuySell) { Platform.trackEvent('buy-sell-route', { route: $dashboardRoute }) } + + onMount(() => { + void updateTransakFiatCurrencies() + void updateTransakCryptoCurrencies() + }) -
+
+ {localize('views.buySell.title')}
diff --git a/packages/desktop/views/dashboard/buy-sell/components/TransakAccountPanel.svelte b/packages/desktop/views/dashboard/buy-sell/components/TransakAccountPanel.svelte deleted file mode 100644 index e4a16a29cb..0000000000 --- a/packages/desktop/views/dashboard/buy-sell/components/TransakAccountPanel.svelte +++ /dev/null @@ -1,49 +0,0 @@ - - - -
-
- - - - IOTA -
- -
-
- - {fiatBalance} -
- -
- - {$selectedAccount?.depositAddress} - -
-
-
diff --git a/packages/desktop/views/dashboard/buy-sell/components/TransakAmountInput.svelte b/packages/desktop/views/dashboard/buy-sell/components/TransakAmountInput.svelte new file mode 100644 index 0000000000..ae83db0be7 --- /dev/null +++ b/packages/desktop/views/dashboard/buy-sell/components/TransakAmountInput.svelte @@ -0,0 +1,43 @@ + + +
+
+ + {currency} +
+ +
diff --git a/packages/desktop/views/dashboard/buy-sell/components/TransakConnectionPanel.svelte b/packages/desktop/views/dashboard/buy-sell/components/TransakConnectionBanner.svelte similarity index 66% rename from packages/desktop/views/dashboard/buy-sell/components/TransakConnectionPanel.svelte rename to packages/desktop/views/dashboard/buy-sell/components/TransakConnectionBanner.svelte index 1b0b830af1..2b1023efee 100644 --- a/packages/desktop/views/dashboard/buy-sell/components/TransakConnectionPanel.svelte +++ b/packages/desktop/views/dashboard/buy-sell/components/TransakConnectionBanner.svelte @@ -1,14 +1,16 @@ - -
- Transak -
- {#if connectionStatus === TransakConnectionStatus.Connected} - {localize('general.connected')} - {:else if connectionStatus === TransakConnectionStatus.Redirected} - {localize('general.redirected')} - {:else} - {localize('general.disconnected')} - {/if} -
-
-
+
+ Transak +
+ Transak
{#if connectionStatus === TransakConnectionStatus.Connected} + {:else if connectionStatus === TransakConnectionStatus.Waiting} + {:else} {/if}
- {url ?? TRANSAK_WIDGET_URL} + {url ?? transakWidgetUrl}
{#if showTextTooltip} - + {/if}
+
+
- +
- +
diff --git a/packages/desktop/views/dashboard/buy-sell/components/TransakCryptoCurrencyAvatar.svelte b/packages/desktop/views/dashboard/buy-sell/components/TransakCryptoCurrencyAvatar.svelte new file mode 100644 index 0000000000..459470f629 --- /dev/null +++ b/packages/desktop/views/dashboard/buy-sell/components/TransakCryptoCurrencyAvatar.svelte @@ -0,0 +1,41 @@ + + +
+ + {#if image && !imageLoadError} + {cryptoCurrency?.name (imageLoadError = true)} + /> + {/if} + + {#if (size === 'base' || size === 'md' || size === 'lg') && !hideNetworkBadge} + + + + {/if} +
diff --git a/packages/desktop/views/dashboard/buy-sell/components/TransakCryptoCurrencyTile.svelte b/packages/desktop/views/dashboard/buy-sell/components/TransakCryptoCurrencyTile.svelte new file mode 100644 index 0000000000..d26daed79e --- /dev/null +++ b/packages/desktop/views/dashboard/buy-sell/components/TransakCryptoCurrencyTile.svelte @@ -0,0 +1,42 @@ + + + +
+ + {#if variant === 'item'} +
+
+ {cryptoCurrency?.symbol ?? '​'} + {cryptoCurrency?.name ?? '​'} +
+ +
+ {:else} +
+
+ {cryptoCurrency?.symbol ?? '​'} + +
+ +
+ {/if} +
+
diff --git a/packages/desktop/views/dashboard/buy-sell/components/TransakExchangePanel.svelte b/packages/desktop/views/dashboard/buy-sell/components/TransakExchangePanel.svelte new file mode 100644 index 0000000000..2bd8b6107b --- /dev/null +++ b/packages/desktop/views/dashboard/buy-sell/components/TransakExchangePanel.svelte @@ -0,0 +1,350 @@ + + + + {@const hasCryptoCurrencies = $transakCryptoCurrencies && $transakCryptoCurrencies.length > 0} +
+
+ {#if isFeatureEnabled('buySell.sell')} +
+ +
+ {/if} +
+
+
+ +
+ {#key paymentOptions} + + {/key} +
+ +
+ + +
+
+
+
+
+
+
+ + {localize('views.buySell.quotations.title')} + + {#if loading} + + {localize('views.buySell.quotations.description')} + + + {displayedQuotationTime + ? localize('views.buySell.quotations.pill.newQuotes', { time: displayedQuotationTime }) + : localize('views.buySell.quotations.pill.fetchingQuotes')} + + {:else if quotes.length === 0} +
+ +
+ {:else} + + {localize('views.buySell.quotations.description')} + + {/if} +
+ {#if loading} + + + + {:else if quotes.length > 0} + {#each quotes as quote, i} + (selectedQuoteId = i)} + selected={selectedQuoteId === i} + /> + {/each} + {/if} +
+
+
diff --git a/packages/desktop/views/dashboard/buy-sell/components/TransakInfoPanel.svelte b/packages/desktop/views/dashboard/buy-sell/components/TransakInfoPanel.svelte deleted file mode 100644 index 53baa91be1..0000000000 --- a/packages/desktop/views/dashboard/buy-sell/components/TransakInfoPanel.svelte +++ /dev/null @@ -1,12 +0,0 @@ - - - - {localize('general.info')} - {localize('views.buySell.info.receive')} - {localize('views.buySell.info.multipleAccounts')} - {localize('views.buySell.info.changingAccounts')} - diff --git a/packages/desktop/views/dashboard/buy-sell/components/TransakQuotationTile.svelte b/packages/desktop/views/dashboard/buy-sell/components/TransakQuotationTile.svelte new file mode 100644 index 0000000000..57ada5c1c7 --- /dev/null +++ b/packages/desktop/views/dashboard/buy-sell/components/TransakQuotationTile.svelte @@ -0,0 +1,43 @@ + + + +
+ {#if isLoading} +
+
+
+
+
+ {:else} + Transak +
+ + {fiatAmount && fiatSymbol ? formatCurrency(String(fiatAmount), fiatSymbol) : '​'} + + + {cryptoAmount ? `≈ ${formatCurrency(String(cryptoAmount), cryptoCurrency?.symbol)}` : '​'} + +
+ {/if} +
+
diff --git a/packages/desktop/views/dashboard/buy-sell/components/TransakWindowPlaceholder.svelte b/packages/desktop/views/dashboard/buy-sell/components/TransakWindowPlaceholder.svelte deleted file mode 100644 index 1abbf927dd..0000000000 --- a/packages/desktop/views/dashboard/buy-sell/components/TransakWindowPlaceholder.svelte +++ /dev/null @@ -1,30 +0,0 @@ - - - - {#if error} - - {localize('views.buySell.error.title')} - {localize('views.buySell.error.description')} -