Skip to content
This repository has been archived by the owner on Dec 7, 2023. It is now read-only.

Commit

Permalink
feat: support recieve to usd wallet (#174)
Browse files Browse the repository at this point in the history
  • Loading branch information
UncleSamtoshi authored Feb 25, 2022
1 parent 711c683 commit 88ada8d
Show file tree
Hide file tree
Showing 3 changed files with 69 additions and 19 deletions.
39 changes: 31 additions & 8 deletions components/generate-invoice.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -26,45 +26,68 @@ const LN_INVOICE_CREATE_ON_BEHALF_OF_RECIPIENT = gql`
}
`

const INVOICE_STALE_CHECK_INTERVAL = 5 * 60 * 1000
const LN_USD_INVOICE_CREATE_ON_BEHALF_OF_RECIPIENT = gql`
mutation lnUsdInvoiceCreateOnBehalfOfRecipient(
$walletId: WalletId!
$amount: CentAmount!
) {
mutationData: lnUsdInvoiceCreateOnBehalfOfRecipient(
input: { recipientWalletId: $walletId, amount: $amount }
) {
errors {
message
}
invoice {
paymentRequest
}
}
}
`

const INVOICE_STALE_CHECK_INTERVAL = 2 * 60 * 1000
const INVOICE_EXPIRE_INTERVAL = 60 * 60 * 1000

function GenerateInvoice({
recipientWalletId,
amountInSats,
recipientWalletCurrency,
amountInBase,
regenerate,
currency,
}: {
recipientWalletId: string
amountInSats: number
recipientWalletCurrency: string
amountInBase: number
regenerate: () => void
currency: string
}) {
const [invoiceStatus, setInvoiceStatus] = useState<
"loading" | "new" | "need-update" | "expired"
>("loading")

const INVOICE_CREATION_MUTATION =
recipientWalletCurrency === "USD"
? LN_USD_INVOICE_CREATE_ON_BEHALF_OF_RECIPIENT
: LN_INVOICE_CREATE_ON_BEHALF_OF_RECIPIENT
const timerIds = useRef<number[]>([])

const [createInvoice, { loading, error, data }] = useMutation<{
mutationData: {
errors: OperationError[]
invoice?: LnInvoiceObject
}
}>(LN_INVOICE_CREATE_ON_BEHALF_OF_RECIPIENT, {
}>(INVOICE_CREATION_MUTATION, {
onError: console.error,
onCompleted: () => setInvoiceStatus("new"),
})

const clearAllTimers = () => {
timerIds.current.forEach((timerId) => clearTimeout(timerId))
}

useEffect(() => {
createInvoice({
variables: { walletId: recipientWalletId, amount: amountInSats },
variables: { walletId: recipientWalletId, amount: amountInBase },
})
if (currency !== "SATS") {
if (currency !== "SATS" || recipientWalletCurrency === "USD") {
timerIds.current.push(
window.setTimeout(
() => setInvoiceStatus("need-update"),
Expand All @@ -76,7 +99,7 @@ function GenerateInvoice({
window.setTimeout(() => setInvoiceStatus("expired"), INVOICE_EXPIRE_INTERVAL),
)
return clearAllTimers
}, [recipientWalletId, amountInSats, currency, createInvoice])
}, [recipientWalletId, amountInBase, currency, createInvoice])

let errorString: string | null = error?.message || null
let invoice
Expand Down
34 changes: 27 additions & 7 deletions components/receive-amount.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -19,8 +19,10 @@ const satsFormatter = new Intl.NumberFormat("en-US", {

export default function ReceiveAmount({
recipientWalletId,
recipientWalletCurrency,
}: {
recipientWalletId: string
recipientWalletCurrency: string
}) {
const router = useRouter()
const { satsToUsd, usdToSats } = useSatPrice()
Expand All @@ -41,14 +43,23 @@ export default function ReceiveAmount({
const getSatsForInvoice = React.useCallback(() => {
return Math.round(currency === "SATS" ? amount : Math.round(usdToSats(amount)))
}, [amount, currency, usdToSats])
const [satsForInvoice, setSatsForInvoice] = useState(() => getSatsForInvoice())

const getCentsForInvoice = React.useCallback(() => {
return Math.round(currency === "USD" ? amount * 100 : satsToUsd(amount) * 100)
}, [amount, currency, satsToUsd])
const [centsForInvoice, setCentsForInvoice] = useState(() => getCentsForInvoice())

function triggerRegenerateUsdInvoice() {
setCentsForInvoice(0)
setTimeout(() => setCentsForInvoice(getCentsForInvoice()))
}

function triggerRegenerateInvoice() {
function triggerRegenerateBtcInvoice() {
setSatsForInvoice(0)
setTimeout(() => setSatsForInvoice(getSatsForInvoice()))
}

const [satsForInvoice, setSatsForInvoice] = useState(() => getSatsForInvoice())

const convertedValue =
currency === "SATS"
? usdFormatter.format(satsToUsd(amount))
Expand All @@ -57,8 +68,16 @@ export default function ReceiveAmount({
useEffect(() => {
const newSats = getSatsForInvoice()
if (newSats !== satsForInvoice) setSatsForInvoice(newSats)
}, [amount, currency, getSatsForInvoice, satsForInvoice, usdToSats])

const newCents = getCentsForInvoice()
if (newCents !== centsForInvoice) setCentsForInvoice(newCents)
}, [getSatsForInvoice, satsForInvoice, centsForInvoice, getCentsForInvoice])

const amountInBase =
recipientWalletCurrency === "USD" ? centsForInvoice : satsForInvoice
const triggerRegenerateInvoice =
recipientWalletCurrency === "USD"
? triggerRegenerateUsdInvoice
: triggerRegenerateBtcInvoice
return (
<>
<div className="amount-input">
Expand All @@ -76,10 +95,11 @@ export default function ReceiveAmount({
</div>
<div>&#8776; {convertedValue}</div>

{satsForInvoice > 0 && (
{amountInBase > 0 && (
<GenerateInvoice
recipientWalletId={recipientWalletId}
amountInSats={satsForInvoice}
recipientWalletCurrency={recipientWalletCurrency}
amountInBase={amountInBase}
regenerate={triggerRegenerateInvoice}
currency={currency}
/>
Expand Down
15 changes: 11 additions & 4 deletions pages/[username].tsx
Original file line number Diff line number Diff line change
Expand Up @@ -12,8 +12,11 @@ import ReceiveNoAmount from "../components/receive-no-amount"
import { getOS, playStoreLink, appStoreLink } from "../lib/download"

const RECIPIENT_WALLET_ID = gql`
query userDefaultWalletId($username: Username!) {
recipientWalletId: userDefaultWalletId(username: $username)
query accountDefaultWallet($username: Username!) {
accountDefaultWallet(username: $username) {
id
walletCurrency
}
}
`

Expand All @@ -33,7 +36,8 @@ export default function Receive() {
if (loading) return <div className="loading">Loading...</div>
if (!data) return null

const { recipientWalletId } = data
const { id: recipientWalletId, walletCurrency: recipientWalletCurrency } =
data.accountDefaultWallet

const isAmountInvoice = amount !== undefined

Expand All @@ -50,7 +54,10 @@ export default function Receive() {
<Card.Header>Pay {username}</Card.Header>

{isAmountInvoice ? (
<ReceiveAmount recipientWalletId={recipientWalletId} />
<ReceiveAmount
recipientWalletId={recipientWalletId}
recipientWalletCurrency={recipientWalletCurrency}
/>
) : (
<ReceiveNoAmount
recipientWalletId={recipientWalletId}
Expand Down

0 comments on commit 88ada8d

Please sign in to comment.