Skip to content

Commit

Permalink
feat(pay): sats currency (#4085)
Browse files Browse the repository at this point in the history
rebase
  • Loading branch information
siddhart1o1 authored Mar 2, 2024
1 parent c6577a5 commit e7c8306
Show file tree
Hide file tree
Showing 6 changed files with 88 additions and 35 deletions.
10 changes: 10 additions & 0 deletions apps/pay/app/sats-currency-metadata.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
import { Currency } from "@/lib/graphql/generated"

export const satCurrencyMetadata: Currency = {
__typename: "Currency",
id: "SAT",
flag: "₿",
name: "Bitcoin sats",
symbol: "sats",
fractionDigits: 0,
}
34 changes: 22 additions & 12 deletions apps/pay/components/currency/currency-dropdown.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,9 @@ import { useSearchParams } from "next/navigation"

import { useCurrencyListQuery } from "../../lib/graphql/generated"

import { useInvoiceContext } from "@/context/invoice-context"
import { satCurrencyMetadata } from "@/app/sats-currency-metadata"

type OptionType = {
value: string
label: string
Expand All @@ -29,16 +32,21 @@ const CurrencyDropdown: React.FC<CurrencyDropdownProps> = ({
}) => {
const searchParams = useSearchParams()
const display = searchParams?.get("display")

const { state } = useInvoiceContext()
const { data: currencyData } = useCurrencyListQuery()

const [selectedOption, setSelectedOption] = useState<OptionType | null>(null)

useEffect(() => {
const defaultDisplay = display || localStorage.getItem("display") || "USD"
const initialCurrency = currencyData?.currencyList?.find(
({ id }) => id === defaultDisplay,
)
let currencies = currencyData?.currencyList || []

// add sats currency metadata if the wallet currency is not USD
if (state.walletCurrency !== "USD") {
currencies = [...currencies, satCurrencyMetadata]
}

const initialCurrency = currencies.find(({ id }) => id === defaultDisplay)
setSelectedOption(
initialCurrency
? {
Expand All @@ -47,7 +55,7 @@ const CurrencyDropdown: React.FC<CurrencyDropdownProps> = ({
}
: null,
)
}, [display, currencyData?.currencyList])
}, [display, currencyData?.currencyList, state.walletCurrency]) // Ensure walletCurrency is a dependency

const handleOnChange = (option: SingleValue<OptionType>) => {
const newDisplayCurrency = option ? option.value : "USD"
Expand All @@ -58,13 +66,15 @@ const CurrencyDropdown: React.FC<CurrencyDropdownProps> = ({
}

const options: OptionType[] =
currencyData?.currencyList?.map((currency) => ({
value: currency.id,
label:
showOnlyFlag && currency.flag
? `${currency.flag}`
: `${currency.id} - ${currency.name} ${currency.flag}`,
})) || []
(currencyData?.currencyList || [])
.concat(state.walletCurrency !== "USD" ? [satCurrencyMetadata] : [])
.map((currency) => ({
value: currency.id,
label:
showOnlyFlag && currency.flag
? `${currency.flag}`
: `${currency.id} - ${currency.name} ${currency.flag}`,
})) || []

const customStyles: StylesConfig<OptionType, false> = {
container: (base: CSSObjectWithLabel) => {
Expand Down
29 changes: 26 additions & 3 deletions apps/pay/components/parse-pos-payment/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,8 @@ import styles from "./parse-payment.module.css"
import ReceiveInvoice from "./receive-invoice"
import NFCComponent from "./nfc"

import { satCurrencyMetadata } from "@/app/sats-currency-metadata"

interface Props {
defaultWalletCurrency: string
walletId: string
Expand Down Expand Up @@ -107,12 +109,33 @@ function ParsePayment({

// Update CurrencyMetadata
React.useEffect(() => {
const latestCurrencyMetadata = currencyList?.find((c) => c.id === display)
if (latestCurrencyMetadata) {
if (display === "SAT" && state.walletCurrency === "USD") {
// update param if display is "SAT" and wallet currency is "USD"
const params = new URLSearchParams({
amount: "0",
memo: memo ?? "",
display: "USD",
})
const newUrl = new URL(window.location.toString())
newUrl.pathname = `/${username}`
newUrl.search = params.toString()
router.replace(newUrl.toString(), {
scroll: true,
})
// "currencyList?.length > 0" is to prevent unnecessary renders
} else if (display === "SAT" && currencyList?.length > 0) {
dispatch({
type: ACTIONS.UPDATE_DISPLAY_CURRENCY_METADATA,
payload: latestCurrencyMetadata,
payload: satCurrencyMetadata,
})
} else {
const latestCurrencyMetadata = currencyList?.find((c) => c.id === display)
if (latestCurrencyMetadata) {
dispatch({
type: ACTIONS.UPDATE_DISPLAY_CURRENCY_METADATA,
payload: latestCurrencyMetadata,
})
}
}
}, [display, currencyList])

Expand Down
25 changes: 15 additions & 10 deletions apps/pay/components/parse-pos-payment/receive-invoice.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -112,11 +112,13 @@ function ReceiveInvoice({ recipientWalletCurrency, walletId, state, dispatch }:

const paymentAmount = React.useMemo(() => {
let amountInSats = state.currentAmount
;({ convertedCurrencyAmount: amountInSats } = currencyToSats(
Number(state.currentAmount),
state.displayCurrencyMetaData.id,
state.displayCurrencyMetaData.fractionDigits,
))
if (state.displayCurrencyMetaData.id !== "SAT") {
;({ convertedCurrencyAmount: amountInSats } = currencyToSats(
Number(state.currentAmount),
state.displayCurrencyMetaData.id,
state.displayCurrencyMetaData.fractionDigits,
))
}

let amt = safeAmount(amountInSats)
if (recipientWalletCurrency === "USD") {
Expand All @@ -138,11 +140,14 @@ function ReceiveInvoice({ recipientWalletCurrency, walletId, state, dispatch }:

React.useEffect(() => {
let amountInSats = state.currentAmount
;({ convertedCurrencyAmount: amountInSats } = currencyToSats(
Number(state.currentAmount),
state.displayCurrencyMetaData.id,
state.displayCurrencyMetaData.fractionDigits,
))

if (state.displayCurrencyMetaData.id !== "SAT") {
;({ convertedCurrencyAmount: amountInSats } = currencyToSats(
Number(state.currentAmount),
state.displayCurrencyMetaData.id,
state.displayCurrencyMetaData.fractionDigits,
))
}

if (!walletId || !Number(paymentAmount)) return

Expand Down
7 changes: 5 additions & 2 deletions apps/pay/components/payment-outcome/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@ import styles from "./payment-outcome.module.css"
import Receipt from "./receipt"

import { extractSearchParams } from "@/utils/utils"
import { useInvoiceContext } from "@/context/invoice-context"

interface Props {
paymentRequest: string
Expand All @@ -40,7 +41,8 @@ function PaymentOutcome({ paymentRequest, paymentAmount, dispatch, satoshis }: P
const searchParams = useSearchParams()
const { username } = useParams()
const { amount, memo } = extractSearchParams(searchParams)

const { state } = useInvoiceContext()
const isCurrencySats = state.displayCurrencyMetaData.id === "SAT"
const componentRef = useRef<HTMLDivElement | null>(null)

const printReceipt = useReactToPrint({
Expand Down Expand Up @@ -93,7 +95,7 @@ function PaymentOutcome({ paymentRequest, paymentAmount, dispatch, satoshis }: P
/>
<p className={styles.text}>
{`The invoice of ${localStorage.getItem("formattedFiatValue")}
(~${satoshis} sats)
${!isCurrencySats ? `(~${satoshis} sats)` : ""}
has been paid`}
</p>

Expand All @@ -107,6 +109,7 @@ function PaymentOutcome({ paymentRequest, paymentAmount, dispatch, satoshis }: P
paymentRequest={paymentRequest}
paymentAmount={paymentAmount}
memo={memo}
isCurrencySats={isCurrencySats}
/>
</div>
</div>
Expand Down
18 changes: 10 additions & 8 deletions apps/pay/components/payment-outcome/receipt.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@ interface Props {
paymentRequest: string
memo: string | string[] | undefined
paymentAmount: string | string[] | undefined
isCurrencySats: boolean
}

function receipt(props: Props) {
Expand All @@ -25,14 +26,15 @@ function receipt(props: Props) {

<div className="text-center">
<span>Transaction Amount</span>

<h1
style={{
fontSize: "2.5rem",
}}
>
{props.sats} sats
</h1>
{!props.isCurrencySats && (
<h1
style={{
fontSize: "2.5rem",
}}
>
{props.sats} sats
</h1>
)}
<span> ~ {localStorage.getItem("formattedFiatValue")}</span>

<div className="d-flex justify-content-center">
Expand Down

0 comments on commit e7c8306

Please sign in to comment.