diff --git a/apps/frontend/package.json b/apps/frontend/package.json index e73ae359d..b0608c7ec 100644 --- a/apps/frontend/package.json +++ b/apps/frontend/package.json @@ -6,6 +6,8 @@ "dependencies": { "@apollo/client": "3.7.1", "@apollo/react-hooks": "4.0.0", + "@gobob/bob-sdk": "^3.1.0", + "@gobob/sats-wagmi": "^0.3.17", "@loadable/component": "5.15.2", "@sovryn-zero/lib-base": "0.2.1", "@sovryn-zero/lib-ethers": "0.2.5", @@ -26,6 +28,7 @@ "@sovryn/tailwindcss-config": "*", "@sovryn/ui": "*", "@sovryn/utils": "0.0.2", + "@tanstack/react-query": "^5.59.0", "@uniswap/permit2-sdk": "1.2.0", "bitcoin-address-validation": "2.2.1", "chart.js": "4.1.1", diff --git a/apps/frontend/src/app/5_pages/BobGateway/BobGateway.tsx b/apps/frontend/src/app/5_pages/BobGateway/BobGateway.tsx new file mode 100644 index 000000000..d2f9790d2 --- /dev/null +++ b/apps/frontend/src/app/5_pages/BobGateway/BobGateway.tsx @@ -0,0 +1,50 @@ +import { Network, SatsWagmiConfig } from '@gobob/sats-wagmi'; +import { QueryClientProvider } from '@tanstack/react-query'; + +import React, { FC } from 'react'; + +import { t } from 'i18next'; +import { Helmet } from 'react-helmet-async'; + +import { Heading, Paragraph, ParagraphSize } from '@sovryn/ui'; + +import { translations } from '../../../locales/i18n'; +import { Promotions } from '../MarketMakingPage/components/Promotions/Promotions'; +import { queryClient } from './BobGateway.utils'; +import { BitcoinWallet } from './components/BitcoinWallet/BitcoinWallet'; +import { BobGatewayForm } from './components/BobGatewayForm/BobGatewayForm'; + +const BobGateway: FC = () => { + return ( + <> + + {t(translations.bobGatewayPage.meta.title)} + +
+ + {t(translations.bobGatewayPage.meta.title)} + + + + {t(translations.bobGatewayPage.description)} + + + + +
+
+ +
+ {}} onClick={() => {}} /> + +
+
+
+
+ + ); +}; +export default BobGateway; diff --git a/apps/frontend/src/app/5_pages/BobGateway/BobGateway.utils.ts b/apps/frontend/src/app/5_pages/BobGateway/BobGateway.utils.ts new file mode 100644 index 000000000..1f6473898 --- /dev/null +++ b/apps/frontend/src/app/5_pages/BobGateway/BobGateway.utils.ts @@ -0,0 +1,19 @@ +import { GatewayQuoteParams, GatewaySDK } from '@gobob/bob-sdk'; +import { QueryClient } from '@tanstack/react-query'; + +export const bobGateway = new GatewaySDK('bob'); + +export const strategies: GatewayQuoteParams[] = [ + { + fromToken: 'BTC', + fromChain: 'Bitcoin', + fromUserAddress: 'bc1qafk4yhqvj4wep57m62dgrmutldusqde8adh20d', + toChain: 'BOB', + toUserAddress: '0x2D2E86236a5bC1c8a5e5499C517E17Fb88Dbc18c', + toToken: 'tBTC', // or e.g. "SolvBTC" + amount: 10000000, // 0.1 BTC + gasRefill: 10000, // 0.0001 BTC. The amount of BTC to swap for ETH for tx fees. + }, +]; + +export const queryClient = new QueryClient(); diff --git a/apps/frontend/src/app/5_pages/BobGateway/components/BitcoinWallet/BitcoinWallet.tsx b/apps/frontend/src/app/5_pages/BobGateway/components/BitcoinWallet/BitcoinWallet.tsx new file mode 100644 index 000000000..fd52e6685 --- /dev/null +++ b/apps/frontend/src/app/5_pages/BobGateway/components/BitcoinWallet/BitcoinWallet.tsx @@ -0,0 +1,82 @@ +import { useAccount, useConnect, useDisconnect } from '@gobob/sats-wagmi'; + +import React, { FC, useCallback, useEffect, useState } from 'react'; + +import { t } from 'i18next'; +import { nanoid } from 'nanoid'; + +import { + Button, + Dialog, + DialogBody, + DialogHeader, + NotificationType, + WalletIdentity, +} from '@sovryn/ui'; + +import { useNotificationContext } from '../../../../../contexts/NotificationContext'; +import { translations } from '../../../../../locales/i18n'; + +export const BitcoinWallet: FC = () => { + const { addNotification } = useNotificationContext(); + const { connectors, connect } = useConnect(); + const { address: btcAddress } = useAccount(); + const { disconnect } = useDisconnect(); + const [isOpen, setIsOpen] = useState(false); + + const onCopyAddress = useCallback(() => { + addNotification({ + type: NotificationType.success, + title: t(translations.copyAddress), + content: '', + dismissible: true, + id: nanoid(), + }); + }, [addNotification]); + + useEffect(() => { + if (btcAddress && isOpen) { + setIsOpen(false); + } + }, [btcAddress, isOpen]); + + if (!btcAddress) { + return ( + <> +