From aa5a12dfeaa4fc16996e14f5cd8dba6f8ae53230 Mon Sep 17 00:00:00 2001 From: Alex Lewin Date: Tue, 22 Oct 2024 13:35:57 +0100 Subject: [PATCH] feat: add useSendLightning() hook --- packages/react/lib/hooks/index.ts | 9 +++- packages/react/lib/hooks/useSendLightning.ts | 49 +++++++++++++++++++ packages/react/src/components/HooksDemo.tsx | 50 +++++++++++++++++++- 3 files changed, 105 insertions(+), 3 deletions(-) create mode 100644 packages/react/lib/hooks/useSendLightning.ts diff --git a/packages/react/lib/hooks/index.ts b/packages/react/lib/hooks/index.ts index daf1ad4..4145cc6 100644 --- a/packages/react/lib/hooks/index.ts +++ b/packages/react/lib/hooks/index.ts @@ -2,5 +2,12 @@ import { useBalance } from './useBalance' import { useOpenWallet } from './useOpenWallet' import { useFedimintWallet } from './useFedimintWallet' import { useReceiveLightning } from './useReceiveLightning' +import { useSendLightning } from './useSendLightning' -export { useBalance, useOpenWallet, useFedimintWallet, useReceiveLightning } +export { + useBalance, + useOpenWallet, + useFedimintWallet, + useReceiveLightning, + useSendLightning, +} diff --git a/packages/react/lib/hooks/useSendLightning.ts b/packages/react/lib/hooks/useSendLightning.ts new file mode 100644 index 0000000..9229d4f --- /dev/null +++ b/packages/react/lib/hooks/useSendLightning.ts @@ -0,0 +1,49 @@ +import { useCallback, useEffect, useState } from 'react' +import { useFedimintWallet, useOpenWallet } from '.' +import { + type LnPayState, + type OutgoingLightningPayment, +} from '@fedimint/core-web' + +export const useSendLightning = () => { + const wallet = useFedimintWallet() + const { walletStatus } = useOpenWallet() + const [payment, setPayment] = useState() + const [paymentState, setPaymentState] = useState() + const [error, setError] = useState() + + const payInvoice = useCallback( + async (bolt11: string) => { + if (walletStatus !== 'open') throw new Error('Wallet is not open') + const response = await wallet.lightning.payInvoice(bolt11) + setPayment(response) + return response + }, + [wallet, walletStatus], + ) + + useEffect(() => { + if (walletStatus !== 'open' || !payment) return + const unsubscribe = wallet.lightning.subscribeLnPay( + // @ts-ignore + payment.payment_type.lightning, + (state) => { + setPaymentState(state) + }, + (error) => { + setError(error) + }, + ) + + return () => { + unsubscribe() + } + }, [walletStatus, payment]) + + return { + payInvoice, + payment, + paymentStatus: paymentState, + paymentError: error, + } +} diff --git a/packages/react/src/components/HooksDemo.tsx b/packages/react/src/components/HooksDemo.tsx index 4326a36..d23ddca 100644 --- a/packages/react/src/components/HooksDemo.tsx +++ b/packages/react/src/components/HooksDemo.tsx @@ -1,5 +1,10 @@ -import React from 'react' -import { useBalance, useReceiveLightning, useOpenWallet } from '../../lib' +import React, { useState } from 'react' +import { + useBalance, + useReceiveLightning, + useOpenWallet, + useSendLightning, +} from '../../lib' const TEST_FEDERATION_INVITE = 'fed11qgqzc2nhwden5te0vejkg6tdd9h8gepwvejkg6tdd9h8garhduhx6at5d9h8jmn9wshxxmmd9uqqzgxg6s3evnr6m9zdxr6hxkdkukexpcs3mn7mj3g5pc5dfh63l4tj6g9zk4er' @@ -7,9 +12,12 @@ const TEST_FEDERATION_INVITE = function HooksDemo() { const balance = useBalance() const { walletStatus, openWallet, joinFederation } = useOpenWallet() + const [bolt11Input, setBolt11Input] = useState() const isOpen = walletStatus === 'open' const { generateInvoice, bolt11, invoiceStatus, error } = useReceiveLightning() + const { payInvoice, payment, paymentStatus, paymentError } = + useSendLightning() return ( <> @@ -75,6 +83,44 @@ function HooksDemo() { error:

{error}

+
+ useSendLightning() +
+ bolt11: + setBolt11Input(e.target.value)} + /> +
+
+ payInvoice(bolt11) + +
+
+ payment: +

{payment ? JSON.stringify(payment) : 'no payment'}

+
+
+ paymentStatus: +

+ {typeof paymentStatus === 'string' + ? paymentStatus + : typeof paymentStatus === 'object' + ? Object.keys(paymentStatus)[0] + : 'no payment status'} +

+
+
+ paymentError: +

{paymentError}

+
+
)