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/swap UI #211

Open
wants to merge 12 commits into
base: dev
Choose a base branch
from
7 changes: 5 additions & 2 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,9 @@
"@fontsource/onest": "^5.0.3",
"@fontsource/poppins": "^5.0.8",
"@gemwallet/api": "^3.8.0",
"@gardenfi/core": "0.3.0-beta.14",
"@gardenfi/orderbook": "0.2.0-beta.41",
"@gardenfi/react-hooks": "0.0.1-beta.135",
"@ledgerhq/hw-app-xrp": "^6.29.4",
"@ledgerhq/hw-transport-webusb": "^6.28.6",
"@netlify/functions": "^2.8.1",
Expand All @@ -48,7 +51,7 @@
"decimal.js": "^10.4.3",
"dlc-btc-lib": "2.5.1",
"dotenv": "^16.3.1",
"ethers": "5.7.2",
"ethers": "6.8.0",
"formik": "^2.4.5",
"framer-motion": "^11.2.10",
"ledger-bitcoin": "^0.2.3",
Expand All @@ -64,7 +67,7 @@
"redux": "^4.2.1",
"redux-persist": "^6.0.0",
"redux-persist-expire": "^1.1.1",
"viem": "2.x",
"viem": "^2.20.1",
"vite-plugin-toml": "^0.7.0",
"wagmi": "^2.12.2",
"xrpl": "^4.0.0"
Expand Down
4 changes: 4 additions & 0 deletions public/images/gear-icon.svg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
3 changes: 3 additions & 0 deletions public/images/swap-arrow.svg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
79 changes: 46 additions & 33 deletions src/app/app.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,9 @@ import { Route } from 'react-router-dom';

import { AppLayout } from '@components/app.layout';
import { MerchantDetails } from '@components/proof-of-reserve/components/merchant-details/merchant-details';
import { SwapPage } from '@components/swap/pages/swap-page';
import { getWagmiConfiguration } from '@functions/configuration.functions';
import { GardenProvider, environment } from '@gardenfi/react-hooks';
import { AttestorDetailsPage } from '@pages/attestor-details/attestor-details-page';
import { AttestorDetailsSelectPage } from '@pages/attestor-details/attestor-details-select-page';
import { MyVaults } from '@pages/my-vaults/my-vaults';
Expand Down Expand Up @@ -31,39 +33,50 @@ export function App(): React.JSX.Element {
return (
<WagmiProvider config={wagmiConfiguration}>
<QueryClientProvider client={queryClient}>
<NetworkConfigurationContextProvider>
<RippleNetworkConfigurationContextProvider>
<EthereumNetworkConfigurationContextProvider>
<XRPWalletContextProvider>
<BitcoinWalletContextProvider>
<NetworkConnectionContextProvider>
<VaultContextProvider>
<BitcoinTransactionConfirmationsProvider>
<BalanceContextProvider>
<ProofOfReserveContextProvider>
<AppLayout>
<Route path="/" element={<PointsPage />} />
<Route path="/my-vaults" element={<MyVaults />} />
{/* <Route path="/how-it-works" element={<About />} /> */}
<Route path="/proof-of-reserve" element={<ProofOfReservePage />} />
<Route path="/attestor-details" element={<AttestorDetailsPage />} />
<Route
path="/attestor-details-select"
element={<AttestorDetailsSelectPage />}
/>
<Route path="/merchant-details/:name" element={<MerchantDetails />} />
<Route path="/mint-withdraw" element={<Dashboard />} />
</AppLayout>
</ProofOfReserveContextProvider>
</BalanceContextProvider>
</BitcoinTransactionConfirmationsProvider>
</VaultContextProvider>
</NetworkConnectionContextProvider>
</BitcoinWalletContextProvider>
</XRPWalletContextProvider>
</EthereumNetworkConfigurationContextProvider>
</RippleNetworkConfigurationContextProvider>
</NetworkConfigurationContextProvider>
<GardenProvider
config={{
store: localStorage,
environment: environment.testnet,
}}
>
<NetworkConfigurationContextProvider>
<RippleNetworkConfigurationContextProvider>
<EthereumNetworkConfigurationContextProvider>
<XRPWalletContextProvider>
<BitcoinWalletContextProvider>
<NetworkConnectionContextProvider>
<VaultContextProvider>
<BitcoinTransactionConfirmationsProvider>
<BalanceContextProvider>
<ProofOfReserveContextProvider>
<AppLayout>
<Route path="/" element={<PointsPage />} />
<Route path="/my-vaults" element={<MyVaults />} />
{/* <Route path="/how-it-works" element={<About />} /> */}
<Route path="/proof-of-reserve" element={<ProofOfReservePage />} />
<Route path="/attestor-details" element={<AttestorDetailsPage />} />
<Route
path="/attestor-details-select"
element={<AttestorDetailsSelectPage />}
/>
<Route
path="/merchant-details/:name"
element={<MerchantDetails />}
/>
<Route path="/mint-withdraw" element={<Dashboard />} />
<Route path="/swap" element={<SwapPage />} />
</AppLayout>
</ProofOfReserveContextProvider>
</BalanceContextProvider>
</BitcoinTransactionConfirmationsProvider>
</VaultContextProvider>
</NetworkConnectionContextProvider>
</BitcoinWalletContextProvider>
</XRPWalletContextProvider>
</EthereumNetworkConfigurationContextProvider>
</RippleNetworkConfigurationContextProvider>
</NetworkConfigurationContextProvider>
</GardenProvider>
</QueryClientProvider>
</WagmiProvider>
);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -42,7 +42,7 @@

const { ethereumNetworkConfiguration } = useContext(EthereumNetworkConfigurationContext);

const signer = useEthersSigner();
const { getEthersSigner } = useEthersSigner();

const { unmintStep } = useSelector((state: RootState) => state.mintunmint);
const [isSubmitting, setIsSubmitting] = useState(false);
Expand All @@ -60,8 +60,11 @@
if (currentRisk === 'High') throw new Error('Risk Level is too high');
const formattedWithdrawAmount = BigInt(shiftValue(withdrawAmount));

const signer = await getEthersSigner();
if (!signer) throw new Error('No signer available');

await withdraw(
ethereumNetworkConfiguration.dlcManagerContract.connect(signer!),
ethereumNetworkConfiguration.dlcManagerContract.connect(signer),

Check failure on line 67 in src/app/components/mint-unmint/components/burn-transaction-screen/burn-transaction-screen.tsx

View workflow job for this annotation

GitHub Actions / typecheck

Argument of type 'BaseContract' is not assignable to parameter of type 'Contract'.
currentVault.uuid,
formattedWithdrawAmount
);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,7 @@
const { ethereumNetworkConfiguration } = useContext(EthereumNetworkConfigurationContext);
const { rippleNetworkConfiguration } = useContext(RippleNetworkConfigurationContext);

const signer = useEthersSigner();
const { getEthersSigner } = useEthersSigner();

Check warning on line 27 in src/app/components/mint-unmint/components/setup-vault-screen/setup-vault-screen.tsx

View workflow job for this annotation

GitHub Actions / lint-eslint

'getEthersSigner' is assigned a value but never used

Check failure on line 27 in src/app/components/mint-unmint/components/setup-vault-screen/setup-vault-screen.tsx

View workflow job for this annotation

GitHub Actions / typecheck

'getEthersSigner' is declared but its value is never read.

const [isSubmitting, setIsSubmitting] = useState(false);

Expand All @@ -40,7 +40,7 @@
);
break;
case NetworkType.EVM:
await setupVault(ethereumNetworkConfiguration.dlcManagerContract.connect(signer!));
await setupVault(ethereumNetworkConfiguration.dlcManagerContract.connect());

Check failure on line 43 in src/app/components/mint-unmint/components/setup-vault-screen/setup-vault-screen.tsx

View workflow job for this annotation

GitHub Actions / typecheck

Argument of type 'BaseContract' is not assignable to parameter of type 'Contract'.

Check failure on line 43 in src/app/components/mint-unmint/components/setup-vault-screen/setup-vault-screen.tsx

View workflow job for this annotation

GitHub Actions / typecheck

Expected 1 arguments, but got 0.
break;
default:
throw new Error('Unsupported Network Type');
Expand Down
91 changes: 91 additions & 0 deletions src/app/components/swap/components/swap-amount-card.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,91 @@
import { HStack, Text, VStack } from '@chakra-ui/react';
import { Asset } from '@gardenfi/orderbook';

import { SwapTokenButton } from './swap-token-button';
import { SwapTokenLabel } from './swap-token-label';

interface SwapAmountCardProps {
direction: string;
asset: Asset;
amount: number;
amountInUSD?: string;
balance?: number;
transactionGasFee?: number;
}

const assetDetails = {
iBTC: {
assetColor: 'purple.01',
assetSymbol: 'iBTC',
assetLogo: '/images/logos/ibtc-logo.svg',
},
BTC: {
assetColor: 'orange.01',
assetSymbol: 'BTC',
assetLogo: '/images/logos/bitcoin-logo.svg',
},
};

export function SwapAmountCard({
direction,
amount,
asset,
amountInUSD,

Check warning on line 33 in src/app/components/swap/components/swap-amount-card.tsx

View workflow job for this annotation

GitHub Actions / lint-eslint

'amountInUSD' is defined but never used

Check failure on line 33 in src/app/components/swap/components/swap-amount-card.tsx

View workflow job for this annotation

GitHub Actions / typecheck

'amountInUSD' is declared but its value is never read.
balance,
}: SwapAmountCardProps): React.JSX.Element | null {
const isBTC = asset.symbol === 'btc';
const { assetColor, assetSymbol, assetLogo } = assetDetails[isBTC ? 'BTC' : 'iBTC'];

return (
<VStack
p={'15px'}
w={'100%'}
bg={'background.container.02'}
borderRadius={'md'}
border={'1px solid'}
spacing={'15px'}
borderColor={assetColor}
alignItems={'flex-start'}
boxShadow={'2px 2px 4px rgba(0, 0, 0, 0.5)'}
>
<Text color={'white'} fontWeight={'600'}>
{direction}
</Text>
<VStack
p={'15px'}
w={'100%'}
bg={'background.content.02'}
borderRadius={'md'}
border={'1px solid'}
spacing={'15px'}
borderColor={'white.03'}
alignItems={'flex-start'}
boxShadow={'2px 2px 4px rgba(0, 0, 0, 0.5)'}
>
<HStack w={'100%'} justifyContent={'space-between'}>
<Text
color={'white'}
fontWeight={'800'}
fontSize={'x-large'}
textShadow={'2px 2px 4px rgba(0, 0, 0, 0.5)'}
>
{amount}
</Text>
{isBTC ? (
<SwapTokenButton tokenImage={assetLogo} tokenDisplay={assetSymbol} onClick={() => {}} />
) : (
<SwapTokenLabel tokenImage={assetLogo} tokenDisplay={assetSymbol} />
)}
</HStack>
<HStack justifyContent={'space-between'} width={'100%'}>
<Text color={'white.03'} fontSize={'sm'}>
{amount}
</Text>
<Text color={'white.03'} fontSize={'sm'}>
Bal. {balance}
</Text>
</HStack>
</VStack>
</VStack>
);
}
15 changes: 15 additions & 0 deletions src/app/components/swap/components/swap-button.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
import React from 'react';

import { Button } from '@chakra-ui/react';

interface SwapButtonProps {
onClick: () => void;
}

export function SwapButton({ onClick }: SwapButtonProps): React.JSX.Element {
return (
<Button onClick={onClick} w={'100%'} boxShadow={'2px 2px 4px rgba(0, 0, 0, 0.5)'}>
Swap
</Button>
);
}
45 changes: 45 additions & 0 deletions src/app/components/swap/components/swap-extra-details-card.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,45 @@
import { HStack, Text, VStack } from '@chakra-ui/react';

interface SwapExtraDetailsCardProps {
gasFee: number;
}

export function SwapExtraDetailsCard({ gasFee }: SwapExtraDetailsCardProps): React.JSX.Element {
return (
<VStack
p={'15px'}
w={'100%'}
bg={'background.container.02'}
borderRadius={'md'}
border={'1px dashed'}
spacing={'15px'}
borderColor={'white.02'}
alignItems={'flex-start'}
>
<HStack w={'100%'} justifyContent={'space-between'}>
<Text color={'white.02'} fontSize={'sm'}>
Gas Fee
</Text>
<Text color={'white.02'} fontSize={'sm'} fontWeight={600}>
{gasFee}
</Text>
</HStack>
<HStack w={'100%'} justifyContent={'space-between'}>
<Text color={'white.02'} fontSize={'sm'}>
Rate
</Text>
<Text color={'white.02'} fontSize={'sm'} fontWeight={600}>
1 BTC = 1 dlcBTC
</Text>
</HStack>
<HStack w={'100%'} justifyContent={'space-between'}>
<Text color={'white.02'} fontSize={'sm'}>
Slippage Tolerance
</Text>
<Text color={'white.02'} fontSize={'sm'} fontWeight={600}>
Auto
</Text>
</HStack>
</VStack>
);
}
18 changes: 18 additions & 0 deletions src/app/components/swap/components/swap-header.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
import { HStack, Text } from '@chakra-ui/react';

import { SwapNetworksMenu } from './swap-networks-menu';
import { SwapSettingsMenu } from './swap-settings-menu';

export function SwapHeader(): React.JSX.Element {
return (
<HStack w={'100%'} justifyContent={'space-between'}>
<Text color={'white'} fontSize={'xx-large'} fontWeight={'600'}>
Swap
</Text>
<HStack>
<SwapNetworksMenu isMenuOpen={false} setIsMenuOpen={() => {}} />
<SwapSettingsMenu isMenuOpen={false} setIsMenuOpen={() => {}} />
</HStack>
</HStack>
);
}
Loading
Loading