Skip to content

Commit

Permalink
feat(frontend): implement Swap component and use it in Actions (#4174)
Browse files Browse the repository at this point in the history
# Motivation

This is the last step of the Swap feature - Swap component + its usage.
  • Loading branch information
DenysKarmazynDFINITY authored Jan 14, 2025
1 parent 2109a8a commit 3cebd36
Show file tree
Hide file tree
Showing 3 changed files with 110 additions and 2 deletions.
9 changes: 9 additions & 0 deletions src/frontend/src/lib/components/hero/Actions.svelte
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@
import { page } from '$app/stores';
import ConvertToCkBTC from '$btc/components/convert/ConvertToCkBTC.svelte';
import BtcReceive from '$btc/components/receive/BtcReceive.svelte';
import { SWAP_ACTION_ENABLED } from '$env/actions.env';
import { BTC_TO_CKBTC_EXCHANGE_ENABLED } from '$env/networks/networks.btc.env';
import EthReceive from '$eth/components/receive/EthReceive.svelte';
import ConvertToCkERC20 from '$eth/components/send/ConvertToCkERC20.svelte';
Expand All @@ -15,6 +16,7 @@
import Buy from '$lib/components/buy/Buy.svelte';
import Receive from '$lib/components/receive/Receive.svelte';
import Send from '$lib/components/send/Send.svelte';
import Swap from '$lib/components/swap/Swap.svelte';
import HeroButtonGroup from '$lib/components/ui/HeroButtonGroup.svelte';
import { allBalancesZero } from '$lib/derived/balances.derived';
import {
Expand Down Expand Up @@ -45,6 +47,9 @@
let isTransactionsPage = false;
$: isTransactionsPage = isRouteTransactions($page);
let swapAction = false;
$: swapAction = SWAP_ACTION_ENABLED && !isTransactionsPage;
let sendAction = true;
$: sendAction = !$allBalancesZero || isTransactionsPage;
</script>
Expand All @@ -67,6 +72,10 @@
<Send {isTransactionsPage} />
{/if}

{#if swapAction}
<Swap />
{/if}

{#if isTransactionsPage}
{#if convertEth}
{#if $networkICP}
Expand Down
99 changes: 99 additions & 0 deletions src/frontend/src/lib/components/swap/Swap.svelte
Original file line number Diff line number Diff line change
@@ -0,0 +1,99 @@
<script lang="ts">
import { isNullish, nonNullish } from '@dfinity/utils';
import { BigNumber } from '@ethersproject/bignumber';
import { setContext } from 'svelte';
import { ICRC_CK_TOKENS_LEDGER_CANISTER_IDS } from '$env/networks/networks.icrc.env';
import type { Erc20ContractAddress, Erc20Token } from '$eth/types/erc20';
import { balance } from '$icp/api/icrc-ledger.api';
import type { LedgerCanisterIdText } from '$icp/types/canister';
import type { IcCkToken } from '$icp/types/ic-token';
import SwapButtonWithModal from '$lib/components/swap/SwapButtonWithModal.svelte';
import SwapModal from '$lib/components/swap/SwapModal.svelte';
import { allDisabledIcrcTokens } from '$lib/derived/all-tokens.derived';
import { authIdentity } from '$lib/derived/auth.derived';
import { modalSwap } from '$lib/derived/modal.derived';
import { nullishSignOut } from '$lib/services/auth.services';
import { exchangeRateERC20ToUsd, exchangeRateICRCToUsd } from '$lib/services/exchange.services';
import { balancesStore } from '$lib/stores/balances.store';
import { exchangeStore } from '$lib/stores/exchange.store';
import { modalStore } from '$lib/stores/modal.store';
import {
initSwapAmountsStore,
SWAP_AMOUNTS_CONTEXT_KEY,
type SwapAmountsContext
} from '$lib/stores/swap-amounts.store';
setContext<SwapAmountsContext>(SWAP_AMOUNTS_CONTEXT_KEY, {
store: initSwapAmountsStore()
});
const onOpenSwap = async (tokenId: symbol) => {
if (isNullish($authIdentity)) {
await nullishSignOut();
return;
}
modalStore.openSwap(tokenId);
const loadDisabledIcrcTokensBalances = (): Promise<void[]> =>
Promise.all(
$allDisabledIcrcTokens.map(async ({ ledgerCanisterId, id }) => {
const icrcTokenBalance = await balance({
identity: $authIdentity,
owner: $authIdentity.getPrincipal(),
ledgerCanisterId
});
balancesStore.set({
tokenId: id,
data: {
data: BigNumber.from(icrcTokenBalance),
certified: true
}
});
})
);
const loadDisabledIcrcTokensExchanges = async (): Promise<void> => {
const [currentErc20Prices, currentIcrcPrices] = await Promise.all([
exchangeRateERC20ToUsd(
$allDisabledIcrcTokens.reduce<Erc20ContractAddress[]>((acc, token) => {
const twinTokenAddress = (
(token as Partial<IcCkToken>).twinToken as Erc20Token | undefined
)?.address;
return nonNullish(twinTokenAddress)
? [
...acc,
{
address: twinTokenAddress
}
]
: acc;
}, [])
),
exchangeRateICRCToUsd(
$allDisabledIcrcTokens.reduce<LedgerCanisterIdText[]>(
(acc, { ledgerCanisterId }) =>
!ICRC_CK_TOKENS_LEDGER_CANISTER_IDS.includes(ledgerCanisterId)
? [...acc, ledgerCanisterId]
: acc,
[]
)
)
]);
exchangeStore.set([
...(nonNullish(currentErc20Prices) ? [currentErc20Prices] : []),
...(nonNullish(currentIcrcPrices) ? [currentIcrcPrices] : [])
]);
};
await loadDisabledIcrcTokensBalances();
await loadDisabledIcrcTokensExchanges();
};
</script>

<SwapButtonWithModal open={onOpenSwap} isOpen={$modalSwap}>
<SwapModal on:nnsClose />
</SwapButtonWithModal>
4 changes: 2 additions & 2 deletions src/frontend/src/lib/derived/exchange.derived.ts
Original file line number Diff line number Diff line change
Expand Up @@ -14,8 +14,8 @@ import {
} from '$env/tokens/tokens.sol.env';
import { enabledErc20Tokens } from '$eth/derived/erc20.derived';
import type { Erc20Token } from '$eth/types/erc20';
import { enabledIcrcTokens } from '$icp/derived/icrc.derived';
import type { IcCkToken } from '$icp/types/ic-token';
import { allIcrcTokens } from '$lib/derived/all-tokens.derived';
import { exchangeStore } from '$lib/stores/exchange.store';
import type { ExchangesData } from '$lib/types/exchange';
import { enabledSplTokens } from '$sol/derived/spl.derived';
Expand All @@ -29,7 +29,7 @@ export const exchangeInitialized: Readable<boolean> = derived(

// TODO: create tests for store
export const exchanges: Readable<ExchangesData> = derived(
[exchangeStore, enabledErc20Tokens, enabledIcrcTokens, enabledSplTokens],
[exchangeStore, enabledErc20Tokens, allIcrcTokens, enabledSplTokens],
([$exchangeStore, $erc20Tokens, $icrcTokens, $splTokens]) => {
const ethPrice = $exchangeStore?.ethereum;
const btcPrice = $exchangeStore?.bitcoin;
Expand Down

0 comments on commit 3cebd36

Please sign in to comment.