From 8bb29cca5b685de605a8a8abd05e85753ca0521a Mon Sep 17 00:00:00 2001 From: Conner Ow Date: Tue, 9 Jan 2024 14:38:48 -0600 Subject: [PATCH] Mutinynet Quick Actions --- src/client/pages/index.tsx | 32 ++-- src/client/src/api/FaucetApi.ts | 91 ++++++++++ src/client/src/components/logo/GhostIcon.tsx | 21 +++ .../home/faucetActions/FaucetActions.tsx | 132 ++++++++++++++ .../src/views/home/faucetActions/onchain.tsx | 55 ++++++ .../views/home/faucetActions/pay-invoice.tsx | 46 +++++ .../home/faucetActions/refund-faucet.tsx | 56 ++++++ .../home/faucetActions/request-channel.tsx | 133 ++++++++++++++ .../home/quickActions/MainnetQuickActions.tsx | 146 ---------------- .../quickActions/MutinynetQuickActions.tsx | 144 ---------------- .../views/home/quickActions/QuickActions.tsx | 163 +++++++++++++++--- .../home/quickActions/RegtestQuickActions.tsx | 126 -------------- .../quickActions/ghost/GhostQuickAction.tsx | 57 ++++++ .../home/quickActions/lnmarkets/index.tsx | 2 +- .../home/quickActions/openChannel/index.tsx | 7 +- 15 files changed, 759 insertions(+), 452 deletions(-) create mode 100644 src/client/src/api/FaucetApi.ts create mode 100644 src/client/src/components/logo/GhostIcon.tsx create mode 100644 src/client/src/views/home/faucetActions/FaucetActions.tsx create mode 100644 src/client/src/views/home/faucetActions/onchain.tsx create mode 100644 src/client/src/views/home/faucetActions/pay-invoice.tsx create mode 100644 src/client/src/views/home/faucetActions/refund-faucet.tsx create mode 100644 src/client/src/views/home/faucetActions/request-channel.tsx delete mode 100644 src/client/src/views/home/quickActions/MainnetQuickActions.tsx delete mode 100644 src/client/src/views/home/quickActions/MutinynetQuickActions.tsx delete mode 100644 src/client/src/views/home/quickActions/RegtestQuickActions.tsx create mode 100644 src/client/src/views/home/quickActions/ghost/GhostQuickAction.tsx diff --git a/src/client/pages/index.tsx b/src/client/pages/index.tsx index 7e9bdb5b8..a2e88998c 100644 --- a/src/client/pages/index.tsx +++ b/src/client/pages/index.tsx @@ -10,19 +10,27 @@ import { AccountInfo } from '../src/views/home/account/AccountInfo'; import { ForwardBox } from '../src/views/home/reports/forwardReport'; import { ConnectCard } from '../src/views/home/connect/Connect'; import { QuickActions } from '../src/views/home/quickActions/QuickActions'; +import { useGatewayState } from '../src/context/GatewayContext'; +import { Network } from '../src/api/types'; +import { FaucetActions } from '../src/views/home/faucetActions/FaucetActions'; -const HomeView = () => ( - <> - - - - - - - - - -); +const HomeView = () => { + const { gatewayInfo } = useGatewayState(); + + return ( + <> + + + + + + {gatewayInfo?.network === Network.Signet ? : null} + + + + + ); +}; const Wrapped = () => ( diff --git a/src/client/src/api/FaucetApi.ts b/src/client/src/api/FaucetApi.ts new file mode 100644 index 000000000..6ac94be65 --- /dev/null +++ b/src/client/src/api/FaucetApi.ts @@ -0,0 +1,91 @@ +// GatewayApi is an implementation of the ApiInterface +class FaucetApi { + private baseUrl: string | undefined = 'https://faucet.mutinynet.com/api'; + + private post = async (api: string, body: unknown): Promise => { + return fetch(`${this.baseUrl}/${api}`, { + method: 'POST', + headers: { + 'Content-Type': 'application/json', + }, + body: JSON.stringify(body), + }); + }; + + onchain = async (body: { address: string; sats: number }) => { + try { + if (body.sats < 10000 || body.sats > 200000) + throw new Error('Amount must be between 10000 and 200000'); + + const res = await this.post('onchain', body); + + if (res.ok) { + const result = await res.json(); + return Promise.resolve(result); + } + + throw responseToError(res); + } catch (error) { + return Promise.reject({ + message: (error as Error).message, + error, + }); + } + }; + + payInvoice = async (body: { bolt11: string }) => { + try { + const res = await this.post('lightning', body); + + if (res.ok) { + const result = await res.json(); + return Promise.resolve(result); + } + + throw responseToError(res); + } catch (error) { + return Promise.reject({ message: (error as Error).message, error }); + } + }; + + refundFaucet = async (body: { amount_sats: number }) => { + try { + const res = await this.post('bolt11', body); + + if (res.ok) { + const result = await res.text(); + return Promise.resolve(result); + } + + throw responseToError(res); + } catch (error) { + return Promise.reject({ message: (error as Error).message, error }); + } + }; + + requestChannel = async (body: { + capacity: number; + push_amount: number; + pubkey: string; + host: string; + }) => { + try { + const res = await this.post('channel', body); + + if (res.ok) { + const result = await res.json(); + return Promise.resolve(result); + } + + throw responseToError(res); + } catch (error) { + return Promise.reject({ message: (error as Error).message, error }); + } + }; +} + +const responseToError = (res: Response): Error => { + return new Error(`Status : ${res.status} \nReason : ${res.statusText}\n`); +}; + +export const faucetApi = new FaucetApi(); diff --git a/src/client/src/components/logo/GhostIcon.tsx b/src/client/src/components/logo/GhostIcon.tsx new file mode 100644 index 000000000..20abaa4ae --- /dev/null +++ b/src/client/src/components/logo/GhostIcon.tsx @@ -0,0 +1,21 @@ +import { forwardRef } from 'react'; + +export const GhostLogo = forwardRef( + ({ color = 'currentColor', size = 100, children, ...rest }, ref) => { + return ( + + {children} + + + ); + } +); + +GhostLogo.displayName = 'GhostLogo'; diff --git a/src/client/src/views/home/faucetActions/FaucetActions.tsx b/src/client/src/views/home/faucetActions/FaucetActions.tsx new file mode 100644 index 000000000..27401d24d --- /dev/null +++ b/src/client/src/views/home/faucetActions/FaucetActions.tsx @@ -0,0 +1,132 @@ +import React, { useState } from 'react'; +import styled from 'styled-components'; +import { + X, + Link, + CloudLightning, + FastForward, + GitPullRequest, +} from 'react-feather'; +import { + CardWithTitle, + SubTitle, + CardTitle, + SmallButton, +} from '../../../components/generic/Styled'; +import { + unSelectedNavButton, + cardColor, + cardBorderColor, + mediaWidths, +} from '../../../styles/Themes'; +import { Onchain } from './onchain'; +import { RequestChannel } from './request-channel'; +import { RefundFaucet } from './refund-faucet'; +import { PayInvoice } from './pay-invoice'; + +export const QuickCard = styled.div` + background: ${cardColor}; + box-shadow: 0 8px 16px -8px rgba(0, 0, 0, 0.1); + border-radius: 4px; + border: 1px solid ${cardBorderColor}; + height: 100px; + width: 100px; + display: flex; + flex-direction: column; + justify-content: center; + align-items: center; + padding: 10px; + cursor: pointer; + color: #69c0ff; + + @media (${mediaWidths.mobile}) { + padding: 4px; + height: 80px; + width: 80px; + } + + &:hover { + border: 1px solid #69c0ff; + } +`; + +export const QuickTitle = styled.div` + font-size: 12px; + color: ${unSelectedNavButton}; + margin-top: 10px; + text-align: center; +`; + +const QuickRow = styled.div` + display: flex; + flex-wrap: wrap; + gap: 8px; + margin: 16px 0 32px; +`; + +export const FaucetActions = () => { + const [openCard, setOpenCard] = useState('none'); + + const getTitle = () => { + switch (openCard) { + case 'refund_faucet': + return 'Send your unused sats back to the Faucet'; + case 'pay_invoice': + return 'Pay an invoice with the Faucet'; + case 'request_channel': + return 'Request a channel from the Faucet'; + case 'onchain': + return 'Receive onchain sats from the Faucet'; + default: + return 'Mutinynet Faucet Actions'; + } + }; + + const renderContent = () => { + switch (openCard) { + case 'refund_faucet': + return ; + case 'request_channel': + return ; + case 'onchain': + return ; + case 'pay_invoice': + return ; + default: + return ( + + setOpenCard('onchain')}> + + Onchain + + setOpenCard('pay_invoice')}> + + Pay Invoice + + setOpenCard('refund_faucet')}> + + Refund Faucet + + setOpenCard('request_channel')}> + + Request Channel + + + ); + } + }; + + return ( + + + {getTitle()} + {openCard !== 'none' && ( + setOpenCard('none')}> + + + )} + + {renderContent()} + + ); +}; diff --git a/src/client/src/views/home/faucetActions/onchain.tsx b/src/client/src/views/home/faucetActions/onchain.tsx new file mode 100644 index 000000000..7b3dad34f --- /dev/null +++ b/src/client/src/views/home/faucetActions/onchain.tsx @@ -0,0 +1,55 @@ +import { useState } from 'react'; +import { toast } from 'react-toastify'; +import { Card } from '../../../components/generic/Styled'; +import { InputWithDeco } from '../../../components/input/InputWithDeco'; +import { ColorButton } from '../../../components/buttons/colorButton/ColorButton'; +import { faucetApi } from '../../../api/FaucetApi'; + +export const Onchain = () => { + const [loading, setLoading] = useState(false); + const [amount, setAmount] = useState(50000); + const [address, setAddress] = useState(''); + + const handleOnchain = async () => { + setLoading(true); + + try { + await faucetApi.onchain({ sats: amount, address }); + toast.success('Successfully Paid to Onchain Address'); + } catch (err) { + toast.error((err as Error).message); + } + setLoading(false); + }; + + return ( + <> + + setAmount(Number(value))} + onEnter={() => handleOnchain()} + placeholder="Amount in sats" + title="Amount (sats)" + inputType="number" + /> + setAddress(value)} + onEnter={() => handleOnchain()} + /> + handleOnchain()} + > + Make it Rain + + + + ); +}; diff --git a/src/client/src/views/home/faucetActions/pay-invoice.tsx b/src/client/src/views/home/faucetActions/pay-invoice.tsx new file mode 100644 index 000000000..3bd0d2580 --- /dev/null +++ b/src/client/src/views/home/faucetActions/pay-invoice.tsx @@ -0,0 +1,46 @@ +import { useState } from 'react'; +import { toast } from 'react-toastify'; +import { Card } from '../../../components/generic/Styled'; +import { InputWithDeco } from '../../../components/input/InputWithDeco'; +import { ColorButton } from '../../../components/buttons/colorButton/ColorButton'; +import { faucetApi } from '../../../api/FaucetApi'; + +export const PayInvoice = () => { + const [loading, setLoading] = useState(false); + const [bolt11, setBolt11] = useState(''); + + const handlePayInvoice = async () => { + setLoading(true); + + try { + await faucetApi.payInvoice({ bolt11 }); + toast.success('Successfully Paid to Onchain Address'); + } catch (err) { + toast.error((err as Error).message); + } + setLoading(false); + }; + + return ( + <> + + setBolt11(value)} + onEnter={() => handlePayInvoice()} + placeholder="lnbt..." + title="Bolt11 Invoice" + /> + handlePayInvoice()} + > + Strike me now + + + + ); +}; diff --git a/src/client/src/views/home/faucetActions/refund-faucet.tsx b/src/client/src/views/home/faucetActions/refund-faucet.tsx new file mode 100644 index 000000000..2f3ec968d --- /dev/null +++ b/src/client/src/views/home/faucetActions/refund-faucet.tsx @@ -0,0 +1,56 @@ +import { useState } from 'react'; +import { toast } from 'react-toastify'; +import { Card } from '../../../components/generic/Styled'; +import { InputWithDeco } from '../../../components/input/InputWithDeco'; +import { ColorButton } from '../../../components/buttons/colorButton/ColorButton'; +import { faucetApi } from '../../../api/FaucetApi'; +import { usePayMutation } from '../../../graphql/mutations/__generated__/pay.generated'; + +export const RefundFaucet = () => { + const [loading, setLoading] = useState(false); + const [amount_sats, setAmount] = useState(50000); + + const [pay] = usePayMutation(); + + const handleRefundFaucet = async () => { + setLoading(true); + + try { + const request = await faucetApi.refundFaucet({ amount_sats }); + await pay({ + variables: { + request, + max_fee: 1000, + max_paths: 10, + }, + }); + } catch (err) { + toast.error((err as Error).message); + } + setLoading(false); + }; + + return ( + <> + + setAmount(Number(value))} + onEnter={() => handleRefundFaucet()} + placeholder="Amount in sats" + title="Amount (sats)" + inputType="number" + /> + handleRefundFaucet()} + > + Make it Rain + + + + ); +}; diff --git a/src/client/src/views/home/faucetActions/request-channel.tsx b/src/client/src/views/home/faucetActions/request-channel.tsx new file mode 100644 index 000000000..6bf81b0d7 --- /dev/null +++ b/src/client/src/views/home/faucetActions/request-channel.tsx @@ -0,0 +1,133 @@ +import { useEffect, useState } from 'react'; +import { toast } from 'react-toastify'; +import { Card } from '../../../components/generic/Styled'; +import { InputWithDeco } from '../../../components/input/InputWithDeco'; +import { ColorButton } from '../../../components/buttons/colorButton/ColorButton'; +import { faucetApi } from '../../../api/FaucetApi'; +import { useGetNodeInfoQuery } from '../../../graphql/queries/__generated__/getNodeInfo.generated'; +import { Container, IconStyle, Item } from '../quickActions/openChannel'; +import { Hexagon } from 'react-feather'; + +const signetNodes = [ + { + name: '025698cc9ac623f5d1ba', + pubkey: + '025698cc9ac623f5d1baf56310f2f1b62dfffee43ffcdb2c20ccb541f70497d540', + host: '54.158.203.78', + connectionString: + '025698cc9ac623f5d1baf56310f2f1b62dfffee43ffcdb2c20ccb541f70497d540@54.158.203.78:9739', + }, + { + name: 'mutiny-net-lnd', + pubkey: + '02465ed5be53d04fde66c9418ff14a5f2267723810176c9212b722e542dc1afb1b', + host: '45.79.52.207', + connectionString: + '02465ed5be53d04fde66c9418ff14a5f2267723810176c9212b722e542dc1afb1b@45.79.52.207:9735', + }, + { + name: 'GREENFELONY', + pubkey: + '0366abc8eb4da61e31a8d2c4520d31cabdf58cc5250f855657397f3dd62493938a', + host: '45.33.17.66', + connectionString: + '0366abc8eb4da61e31a8d2c4520d31cabdf58cc5250f855657397f3dd62493938a@45.33.17.66:39735', + }, +]; + +export const RequestChannel = () => { + const [loading, setLoading] = useState(false); + + const [capacity, setCapacity] = useState(50000); + const [push_amount, setPushAmount] = useState(25000); + const [pubkey, setPubkey] = useState(''); + const [host, setHost] = useState(''); + const [port, setPort] = useState(9735); + + const { data } = useGetNodeInfoQuery(); + + const handleRequestChannel = async () => { + setLoading(true); + + try { + await faucetApi.requestChannel({ + capacity, + push_amount, + pubkey, + host: host + ':' + port, + }); + toast.success('Channel Opened'); + } catch (err) { + toast.error((err as Error).message); + } + setLoading(false); + }; + + useEffect(() => { + if ( + data?.getNodeInfo?.public_key && + typeof data.getNodeInfo.public_key === 'string' && + pubkey.length === 0 + ) { + setPubkey(data.getNodeInfo.public_key); + } + }, [data, pubkey]); + + return ( + <> + + + {signetNodes.map((item, index) => ( + { + const [pubkey, host, port] = item.connectionString.split(/@|:/); + setPubkey(pubkey); + setHost(host); + setPort(Number(port)); + }} + > + + + + {item.name} + + ))} + + setCapacity(Number(value))} + onEnter={() => handleRequestChannel()} + placeholder="50000" + title="Capacity (sats)" + inputType="number" + /> + setPushAmount(Number(value))} + onEnter={() => handleRequestChannel()} + placeholder="25000" + title="Push Amount (Sats)" + inputType="number" + /> + setHost(value)} + onEnter={() => handleRequestChannel()} + placeholder="127.0.0.1" + title="Host" + /> + + handleRequestChannel()} + > + Gimme a lightning channel + + + + ); +}; diff --git a/src/client/src/views/home/quickActions/MainnetQuickActions.tsx b/src/client/src/views/home/quickActions/MainnetQuickActions.tsx deleted file mode 100644 index c29577fe9..000000000 --- a/src/client/src/views/home/quickActions/MainnetQuickActions.tsx +++ /dev/null @@ -1,146 +0,0 @@ -import React, { useState } from 'react'; -import styled from 'styled-components'; -import { X, Layers, GitBranch, Command, Zap } from 'react-feather'; -import { - CardWithTitle, - SubTitle, - CardTitle, - SmallButton, - Card, -} from '../../../components/generic/Styled'; -import { - unSelectedNavButton, - cardColor, - cardBorderColor, - mediaWidths, -} from '../../../styles/Themes'; -import { DecodeCard } from './decode/Decode'; -import { SupportCard } from './donate/DonateCard'; -import { SupportBar } from './donate/DonateContent'; -import { OpenChannel } from './openChannel'; -import { LnUrlCard } from './lnurl'; -import { LnMarketsCard } from './lnmarkets'; -import { AmbossCard } from './amboss/AmbossCard'; -import { LightningAddressCard } from './lightningAddress/LightningAddress'; - -export const QuickCard = styled.div` - background: ${cardColor}; - box-shadow: 0 8px 16px -8px rgba(0, 0, 0, 0.1); - border-radius: 4px; - border: 1px solid ${cardBorderColor}; - height: 100px; - flex-grow: 1; - flex: 1 0 auto; - display: flex; - flex-direction: column; - justify-content: center; - align-items: center; - margin-bottom: 25px; - padding: 10px; - margin-right: 10px; - cursor: pointer; - color: #69c0ff; - - @media (${mediaWidths.mobile}) { - padding: 4px; - height: 80px; - width: 80px; - } - - &:hover { - border: 1px solid #69c0ff; - } -`; - -export const QuickTitle = styled.div` - font-size: 12px; - color: ${unSelectedNavButton}; - margin-top: 10px; - text-align: center; -`; - -const QuickRow = styled.div` - display: flex; - flex-wrap: wrap; - justify-content: space-between; -`; - -export const MainnetQuickActions = () => { - const [openCard, setOpenCard] = useState('none'); - - const getTitle = () => { - switch (openCard) { - case 'decode': - return 'Decode a Lightning Request'; - case 'open_channel': - return 'Open a Channel'; - case 'ln_url': - return 'Use lnurl'; - case 'lightning_address': - return 'Pay to a Lightning Address'; - default: - return 'Mainnet Quick Actions'; - } - }; - - const renderContent = () => { - switch (openCard) { - case 'support': - return ( - - - - ); - case 'decode': - return ; - case 'ln_url': - return ; - case 'lightning_address': - return ; - case 'open_channel': - return ( - - - - ); - default: - return ( - - setOpenCard('support')} /> - - setOpenCard('lightning_address')}> - - Address - - setOpenCard('open_channel')}> - - Open - - setOpenCard('decode')}> - - Decode - - setOpenCard('ln_url')}> - - LNURL - - - - ); - } - }; - - return ( - - - {getTitle()} - {openCard !== 'none' && ( - setOpenCard('none')}> - - - )} - - {renderContent()} - - ); -}; diff --git a/src/client/src/views/home/quickActions/MutinynetQuickActions.tsx b/src/client/src/views/home/quickActions/MutinynetQuickActions.tsx deleted file mode 100644 index 5bbacbf4f..000000000 --- a/src/client/src/views/home/quickActions/MutinynetQuickActions.tsx +++ /dev/null @@ -1,144 +0,0 @@ -import React, { useState } from 'react'; -import styled from 'styled-components'; -import { X, Layers, GitBranch, Command, Zap } from 'react-feather'; -import { - CardWithTitle, - SubTitle, - CardTitle, - SmallButton, - Card, -} from '../../../components/generic/Styled'; -import { - unSelectedNavButton, - cardColor, - cardBorderColor, - mediaWidths, -} from '../../../styles/Themes'; -import { DecodeCard } from './decode/Decode'; -import { SupportCard } from './donate/DonateCard'; -import { SupportBar } from './donate/DonateContent'; -import { OpenChannel } from './openChannel'; -import { LnUrlCard } from './lnurl'; -import { LightningAddressCard } from './lightningAddress/LightningAddress'; - -export const QuickCard = styled.div` - background: ${cardColor}; - box-shadow: 0 8px 16px -8px rgba(0, 0, 0, 0.1); - border-radius: 4px; - border: 1px solid ${cardBorderColor}; - height: 100px; - flex-grow: 1; - flex: 1 0 auto; - display: flex; - flex-direction: column; - justify-content: center; - align-items: center; - margin-bottom: 25px; - padding: 10px; - margin-right: 10px; - cursor: pointer; - color: #69c0ff; - - @media (${mediaWidths.mobile}) { - padding: 4px; - height: 80px; - width: 80px; - } - - &:hover { - border: 1px solid #69c0ff; - } -`; - -export const QuickTitle = styled.div` - font-size: 12px; - color: ${unSelectedNavButton}; - margin-top: 10px; - text-align: center; -`; - -const QuickRow = styled.div` - display: flex; - flex-wrap: wrap; - justify-content: space-between; -`; - -export const MutinynetQuickActions = () => { - const [openCard, setOpenCard] = useState('none'); - - const getTitle = () => { - switch (openCard) { - case 'decode': - return 'Decode a Lightning Request'; - case 'open_channel': - return 'Open Outbound Channel'; - case 'request_channel': - return 'Request Inbound Channel'; - case 'ln_url': - return 'Use lnurl'; - case 'lightning_address': - return 'Pay to a Lightning Address'; - default: - return 'Mutinynet Quick Actions'; - } - }; - - const renderContent = () => { - switch (openCard) { - case 'support': - return ( - - - - ); - case 'decode': - return ; - case 'ln_url': - return ; - case 'lightning_address': - return ; - case 'open_channel': - return ( - - - - ); - default: - return ( - - setOpenCard('support')} /> - setOpenCard('lightning_address')}> - - Address - - setOpenCard('open_channel')}> - - Open - - setOpenCard('decode')}> - - Decode - - setOpenCard('ln_url')}> - - LNURL - - - ); - } - }; - - return ( - - - {getTitle()} - {openCard !== 'none' && ( - setOpenCard('none')}> - - - )} - - {renderContent()} - - ); -}; diff --git a/src/client/src/views/home/quickActions/QuickActions.tsx b/src/client/src/views/home/quickActions/QuickActions.tsx index 4ddf0c3d7..7138cd0ba 100644 --- a/src/client/src/views/home/quickActions/QuickActions.tsx +++ b/src/client/src/views/home/quickActions/QuickActions.tsx @@ -1,23 +1,146 @@ -import React from 'react'; -import { useGatewayState } from '../../../context/GatewayContext'; -import { MutinynetQuickActions } from './MutinynetQuickActions'; -import { MainnetQuickActions } from './MainnetQuickActions'; -import { RegtestQuickActions } from './RegtestQuickActions'; -import { Network } from '../../../api/types'; +import React, { useState } from 'react'; +import styled from 'styled-components'; +import { X, Layers, GitBranch, Command, Zap } from 'react-feather'; +import { + CardWithTitle, + SubTitle, + CardTitle, + SmallButton, + Card, +} from '../../../components/generic/Styled'; +import { + unSelectedNavButton, + cardColor, + cardBorderColor, + mediaWidths, +} from '../../../styles/Themes'; +import { DecodeCard } from './decode/Decode'; +import { SupportCard } from './donate/DonateCard'; +import { SupportBar } from './donate/DonateContent'; +import { OpenChannel } from './openChannel'; +import { LnUrlCard } from './lnurl'; +import { LnMarketsCard } from './lnmarkets'; +import { AmbossCard } from './amboss/AmbossCard'; +import { LightningAddressCard } from './lightningAddress/LightningAddress'; +import { GhostCard } from './ghost/GhostQuickAction'; -export const QuickActions = () => { - const { gatewayInfo } = useGatewayState(); - - switch (gatewayInfo?.network) { - case Network.Signet: - return ; - case Network.Bitcoin: - return ; - case Network.Regtest: - return ; - // case Network.Testnet: - // return ; - default: - return null; +export const QuickCard = styled.div` + background: ${cardColor}; + box-shadow: 0 8px 16px -8px rgba(0, 0, 0, 0.1); + border-radius: 4px; + border: 1px solid ${cardBorderColor}; + height: 100px; + width: 100px; + display: flex; + flex-direction: column; + justify-content: center; + align-items: center; + padding: 10px; + cursor: pointer; + color: #69c0ff; + + @media (${mediaWidths.mobile}) { + padding: 4px; + height: 80px; + width: 80px; + } + + &:hover { + border: 1px solid #69c0ff; } +`; + +export const QuickTitle = styled.div` + font-size: 12px; + color: ${unSelectedNavButton}; + margin-top: 10px; + text-align: center; +`; + +const QuickRow = styled.div` + display: flex; + flex-wrap: wrap; + gap: 8px; + margin: 16px 0 32px; +`; + +export const QuickActions = () => { + const [openCard, setOpenCard] = useState('none'); + + const getTitle = () => { + switch (openCard) { + case 'decode': + return 'Decode a Lightning Request'; + case 'open_channel': + return 'Open a Channel'; + case 'ln_url': + return 'Use lnurl'; + case 'lightning_address': + return 'Pay to a Lightning Address'; + default: + return 'Quick Actions'; + } + }; + + const renderContent = () => { + switch (openCard) { + case 'support': + return ( + + + + ); + case 'decode': + return ; + case 'ln_url': + return ; + case 'lightning_address': + return ; + case 'open_channel': + return ( + + + + ); + default: + return ( + + + setOpenCard('support')} /> + + setOpenCard('lightning_address')}> + + Address + + setOpenCard('open_channel')}> + + Open + + setOpenCard('decode')}> + + Decode + + setOpenCard('ln_url')}> + + LNURL + + + + ); + } + }; + + return ( + + + {getTitle()} + {openCard !== 'none' && ( + setOpenCard('none')}> + + + )} + + {renderContent()} + + ); }; diff --git a/src/client/src/views/home/quickActions/RegtestQuickActions.tsx b/src/client/src/views/home/quickActions/RegtestQuickActions.tsx deleted file mode 100644 index 2958e4b64..000000000 --- a/src/client/src/views/home/quickActions/RegtestQuickActions.tsx +++ /dev/null @@ -1,126 +0,0 @@ -import React, { useState } from 'react'; -import styled from 'styled-components'; -import { X } from 'react-feather'; -import { - CardWithTitle, - SubTitle, - CardTitle, - SmallButton, - Card, -} from '../../../components/generic/Styled'; -import { - unSelectedNavButton, - cardColor, - cardBorderColor, - mediaWidths, -} from '../../../styles/Themes'; -import { DecodeCard } from './decode/Decode'; -import { SupportCard } from './donate/DonateCard'; -import { SupportBar } from './donate/DonateContent'; -import { OpenChannel } from './openChannel'; -import { LnUrlCard } from './lnurl'; -import { LightningAddressCard } from './lightningAddress/LightningAddress'; - -export const QuickCard = styled.div` - background: ${cardColor}; - box-shadow: 0 8px 16px -8px rgba(0, 0, 0, 0.1); - border-radius: 4px; - border: 1px solid ${cardBorderColor}; - height: 100px; - flex-grow: 1; - flex: 1 0 auto; - display: flex; - flex-direction: column; - justify-content: center; - align-items: center; - margin-bottom: 25px; - padding: 10px; - margin-right: 10px; - cursor: pointer; - color: #69c0ff; - - @media (${mediaWidths.mobile}) { - padding: 4px; - height: 80px; - width: 80px; - } - - &:hover { - border: 1px solid #69c0ff; - } -`; - -export const QuickTitle = styled.div` - font-size: 12px; - color: ${unSelectedNavButton}; - margin-top: 10px; - text-align: center; -`; - -const QuickRow = styled.div` - display: flex; - flex-wrap: wrap; - justify-content: space-between; -`; - -export const RegtestQuickActions = () => { - const [openCard, setOpenCard] = useState('none'); - - const getTitle = () => { - switch (openCard) { - case 'decode': - return 'Decode a Lightning Request'; - case 'open_channel': - return 'Open Outbound Channel'; - case 'ln_url': - return 'Use lnurl'; - case 'lightning_address': - return 'Pay to a Lightning Address'; - default: - return 'Regtest Quick Actions'; - } - }; - - const renderContent = () => { - switch (openCard) { - case 'support': - return ( - - - - ); - case 'decode': - return ; - case 'ln_url': - return ; - case 'lightning_address': - return ; - case 'open_channel': - return ( - - - - ); - default: - return ( - - setOpenCard('support')} /> - - ); - } - }; - - return ( - - - {getTitle()} - {openCard !== 'none' && ( - setOpenCard('none')}> - - - )} - - {renderContent()} - - ); -}; diff --git a/src/client/src/views/home/quickActions/ghost/GhostQuickAction.tsx b/src/client/src/views/home/quickActions/ghost/GhostQuickAction.tsx new file mode 100644 index 000000000..dd8ac457b --- /dev/null +++ b/src/client/src/views/home/quickActions/ghost/GhostQuickAction.tsx @@ -0,0 +1,57 @@ +import styled from 'styled-components'; +import { + cardBorderColor, + cardColor, + mediaWidths, + unSelectedNavButton, +} from '../../../../styles/Themes'; +import { GhostLogo } from '../../../../components/logo/GhostIcon'; +import { useRouter } from 'next/router'; + +const QuickTitle = styled.div` + font-size: 12px; + color: ${unSelectedNavButton}; + margin-top: 10px; +`; + +const QuickCard = styled.div` + background: ${cardColor}; + box-shadow: 0 8px 16px -8px rgba(0, 0, 0, 0.1); + border-radius: 4px; + border: 1px solid ${cardBorderColor}; + height: 100px; + width: 100px; + display: flex; + flex-direction: column; + justify-content: center; + align-items: center; + padding: 10px; + cursor: pointer; + color: #69c0ff; + + @media (${mediaWidths.mobile}) { + padding: 4px; + height: 80px; + width: 80px; + } + + &:hover { + background-color: black; + color: white; + + & ${QuickTitle} { + color: white; + } + } +`; + +export const GhostCard = () => { + const { push } = useRouter(); + + return ( + push('/amboss')}> + + Ghost + + ); +}; diff --git a/src/client/src/views/home/quickActions/lnmarkets/index.tsx b/src/client/src/views/home/quickActions/lnmarkets/index.tsx index 049cb544f..298694785 100644 --- a/src/client/src/views/home/quickActions/lnmarkets/index.tsx +++ b/src/client/src/views/home/quickActions/lnmarkets/index.tsx @@ -11,7 +11,7 @@ import { useLnMarketsLoginMutation } from '../../../../graphql/mutations/__gener import { useGetLnMarketsStatusQuery } from '../../../../graphql/queries/__generated__/getLnMarketsStatus.generated'; import { getErrorContent } from '../../../../utils/error'; import getConfig from 'next/config'; -import { QuickCard, QuickTitle } from '../MainnetQuickActions'; +import { QuickCard, QuickTitle } from '../QuickActions'; const { publicRuntimeConfig } = getConfig(); const { disableLnMarkets } = publicRuntimeConfig; diff --git a/src/client/src/views/home/quickActions/openChannel/index.tsx b/src/client/src/views/home/quickActions/openChannel/index.tsx index 3f39e6836..65cced865 100644 --- a/src/client/src/views/home/quickActions/openChannel/index.tsx +++ b/src/client/src/views/home/quickActions/openChannel/index.tsx @@ -31,12 +31,12 @@ import { BaseNode } from '../../../../graphql/types'; import { OpenChannelCard } from './OpenChannel'; import { OpenRecommended } from './OpenRecommended'; -const IconStyle = styled.div` +export const IconStyle = styled.div` margin-bottom: 8px; color: ${themeColors.blue2}; `; -const Item = styled.div` +export const Item = styled.div` font-size: 14px; display: flex; flex-direction: column; @@ -67,7 +67,7 @@ const Item = styled.div` } `; -const Container = styled.div` +export const Container = styled.div` display: flex; justify-content: center; flex-wrap: wrap; @@ -88,6 +88,7 @@ export const OpenChannel = ({ setOpenCard }: OpenChannelProps) => { if (!loading && data && data.getBaseNodes) { if (data.getBaseNodes.length > 0) { set(true); + console.log(data.getBaseNodes); } } }, [loading, data]);