forked from apotdevin/thunderhub
-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
1 parent
93c559f
commit 8bb29cc
Showing
15 changed files
with
759 additions
and
452 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -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<Response> => { | ||
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(); |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,21 @@ | ||
import { forwardRef } from 'react'; | ||
|
||
export const GhostLogo = forwardRef<any, any>( | ||
({ color = 'currentColor', size = 100, children, ...rest }, ref) => { | ||
return ( | ||
<svg | ||
ref={ref} | ||
xmlns="http://www.w3.org/2000/svg" | ||
width={size} | ||
fill={color} | ||
viewBox="0 0 100 100" | ||
{...rest} | ||
> | ||
{children} | ||
<path d="M50 1C22.9 1 1 22.9 1 50v36.8C1 93.5 6.5 99 13.2 99s12.3-5.5 12.3-12.3C25.5 93.5 31 99 37.7 99 44.5 99 50 93.5 50 86.8 50 93.5 55.5 99 62.3 99c6.8 0 12.3-5.5 12.3-12.3C74.5 93.5 80 99 86.8 99 93.5 99 99 93.5 99 86.8V50C99 22.9 77.1 1 50 1z" /> | ||
</svg> | ||
); | ||
} | ||
); | ||
|
||
GhostLogo.displayName = 'GhostLogo'; |
132 changes: 132 additions & 0 deletions
132
src/client/src/views/home/faucetActions/FaucetActions.tsx
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -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 <RefundFaucet />; | ||
case 'request_channel': | ||
return <RequestChannel />; | ||
case 'onchain': | ||
return <Onchain />; | ||
case 'pay_invoice': | ||
return <PayInvoice />; | ||
default: | ||
return ( | ||
<QuickRow> | ||
<QuickCard onClick={() => setOpenCard('onchain')}> | ||
<Link size={24} /> | ||
<QuickTitle>Onchain</QuickTitle> | ||
</QuickCard> | ||
<QuickCard onClick={() => setOpenCard('pay_invoice')}> | ||
<CloudLightning size={24} /> | ||
<QuickTitle>Pay Invoice</QuickTitle> | ||
</QuickCard> | ||
<QuickCard onClick={() => setOpenCard('refund_faucet')}> | ||
<FastForward size={24} /> | ||
<QuickTitle>Refund Faucet</QuickTitle> | ||
</QuickCard> | ||
<QuickCard onClick={() => setOpenCard('request_channel')}> | ||
<GitPullRequest size={24} /> | ||
<QuickTitle>Request Channel</QuickTitle> | ||
</QuickCard> | ||
</QuickRow> | ||
); | ||
} | ||
}; | ||
|
||
return ( | ||
<CardWithTitle> | ||
<CardTitle> | ||
<SubTitle>{getTitle()}</SubTitle> | ||
{openCard !== 'none' && ( | ||
<SmallButton onClick={() => setOpenCard('none')}> | ||
<X size={18} /> | ||
</SmallButton> | ||
)} | ||
</CardTitle> | ||
{renderContent()} | ||
</CardWithTitle> | ||
); | ||
}; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -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<boolean>(false); | ||
const [amount, setAmount] = useState<number>(50000); | ||
const [address, setAddress] = useState<string>(''); | ||
|
||
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 ( | ||
<> | ||
<Card> | ||
<InputWithDeco | ||
value={amount} | ||
inputCallback={value => setAmount(Number(value))} | ||
onEnter={() => handleOnchain()} | ||
placeholder="Amount in sats" | ||
title="Amount (sats)" | ||
inputType="number" | ||
/> | ||
<InputWithDeco | ||
value={address} | ||
placeholder="bcrt1..." | ||
title="Address" | ||
inputCallback={value => setAddress(value)} | ||
onEnter={() => handleOnchain()} | ||
/> | ||
<ColorButton | ||
arrow={true} | ||
fullWidth={true} | ||
disabled={loading} | ||
withMargin={'16px 0 0'} | ||
onClick={() => handleOnchain()} | ||
> | ||
Make it Rain | ||
</ColorButton> | ||
</Card> | ||
</> | ||
); | ||
}; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -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<boolean>(false); | ||
const [bolt11, setBolt11] = useState<string>(''); | ||
|
||
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 ( | ||
<> | ||
<Card> | ||
<InputWithDeco | ||
value={bolt11} | ||
inputCallback={value => setBolt11(value)} | ||
onEnter={() => handlePayInvoice()} | ||
placeholder="lnbt..." | ||
title="Bolt11 Invoice" | ||
/> | ||
<ColorButton | ||
arrow={true} | ||
fullWidth={true} | ||
disabled={loading} | ||
withMargin={'16px 0 0'} | ||
onClick={() => handlePayInvoice()} | ||
> | ||
Strike me now | ||
</ColorButton> | ||
</Card> | ||
</> | ||
); | ||
}; |
Oops, something went wrong.