diff --git a/schema.gql b/schema.gql index 45e954cd..48a2416c 100644 --- a/schema.gql +++ b/schema.gql @@ -867,6 +867,7 @@ type Query { getConfigState: ConfigState! getForwards(days: Float!): GetForwards! getHello: String! + getInvoice(id: String!): InvoiceType! getInvoiceStatusChange(id: String!): String! getInvoices(token: String): GetInvoicesType! getLatestVersion: String! @@ -877,6 +878,7 @@ type Query { getNodeBalances: Balances! getNodeInfo: NodeInfo! getNodeSocialInfo(pubkey: String!): LightningNodeSocialInfo! + getPayment(id: String!): PaymentType! getPayments(token: String): GetPaymentsType! getPeers: [Peer!]! getPendingChannels: [PendingChannel!]! diff --git a/src/client/src/graphql/queries/__generated__/getInvoice.generated.tsx b/src/client/src/graphql/queries/__generated__/getInvoice.generated.tsx new file mode 100644 index 00000000..f20fc4f4 --- /dev/null +++ b/src/client/src/graphql/queries/__generated__/getInvoice.generated.tsx @@ -0,0 +1,180 @@ +import * as Types from '../../types'; + +import { gql } from '@apollo/client'; +import * as Apollo from '@apollo/client'; +const defaultOptions = {} as const; +export type GetInvoiceQueryVariables = Types.Exact<{ + id: Types.Scalars['String']['input']; +}>; + +export type GetInvoiceQuery = { + __typename?: 'Query'; + getInvoice: { + __typename?: 'InvoiceType'; + chain_address?: string | null; + confirmed_at?: string | null; + created_at: string; + description: string; + description_hash?: string | null; + expires_at: string; + id: string; + is_canceled?: boolean | null; + is_confirmed: boolean; + is_held?: boolean | null; + is_private: boolean; + is_push?: boolean | null; + received: number; + received_mtokens: string; + request?: string | null; + secret: string; + tokens: string; + type: string; + date: string; + payments: Array<{ + __typename?: 'InvoicePayment'; + canceled_at?: string | null; + confirmed_at?: string | null; + created_at: string; + created_height: number; + is_canceled: boolean; + is_confirmed: boolean; + is_held: boolean; + mtokens: string; + pending_index?: number | null; + timeout: number; + tokens: number; + total_mtokens?: string | null; + in_channel: string; + messages?: { __typename?: 'MessageType'; message?: string | null } | null; + }>; + }; +}; + +export const GetInvoiceDocument = gql` + query GetInvoice($id: String!) { + getInvoice(id: $id) { + chain_address + confirmed_at + created_at + description + description_hash + expires_at + id + is_canceled + is_confirmed + is_held + is_private + is_push + received + received_mtokens + request + secret + tokens + type + date + payments { + canceled_at + confirmed_at + created_at + created_height + is_canceled + is_confirmed + is_held + mtokens + pending_index + timeout + tokens + total_mtokens + in_channel + messages { + message + } + } + } + } +`; + +/** + * __useGetInvoiceQuery__ + * + * To run a query within a React component, call `useGetInvoiceQuery` and pass it any options that fit your needs. + * When your component renders, `useGetInvoiceQuery` returns an object from Apollo Client that contains loading, error, and data properties + * you can use to render your UI. + * + * @param baseOptions options that will be passed into the query, supported options are listed on: https://www.apollographql.com/docs/react/api/react-hooks/#options; + * + * @example + * const { data, loading, error } = useGetInvoiceQuery({ + * variables: { + * id: // value for 'id' + * }, + * }); + */ +export function useGetInvoiceQuery( + baseOptions: Apollo.QueryHookOptions< + GetInvoiceQuery, + GetInvoiceQueryVariables + > & + ( + | { variables: GetInvoiceQueryVariables; skip?: boolean } + | { skip: boolean } + ) +) { + const options = { ...defaultOptions, ...baseOptions }; + return Apollo.useQuery( + GetInvoiceDocument, + options + ); +} +export function useGetInvoiceLazyQuery( + baseOptions?: Apollo.LazyQueryHookOptions< + GetInvoiceQuery, + GetInvoiceQueryVariables + > +) { + const options = { ...defaultOptions, ...baseOptions }; + return Apollo.useLazyQuery( + GetInvoiceDocument, + options + ); +} +// @ts-ignore +export function useGetInvoiceSuspenseQuery( + baseOptions?: Apollo.SuspenseQueryHookOptions< + GetInvoiceQuery, + GetInvoiceQueryVariables + > +): Apollo.UseSuspenseQueryResult; +export function useGetInvoiceSuspenseQuery( + baseOptions?: + | Apollo.SkipToken + | Apollo.SuspenseQueryHookOptions +): Apollo.UseSuspenseQueryResult< + GetInvoiceQuery | undefined, + GetInvoiceQueryVariables +>; +export function useGetInvoiceSuspenseQuery( + baseOptions?: + | Apollo.SkipToken + | Apollo.SuspenseQueryHookOptions +) { + const options = + baseOptions === Apollo.skipToken + ? baseOptions + : { ...defaultOptions, ...baseOptions }; + return Apollo.useSuspenseQuery( + GetInvoiceDocument, + options + ); +} +export type GetInvoiceQueryHookResult = ReturnType; +export type GetInvoiceLazyQueryHookResult = ReturnType< + typeof useGetInvoiceLazyQuery +>; +export type GetInvoiceSuspenseQueryHookResult = ReturnType< + typeof useGetInvoiceSuspenseQuery +>; +export type GetInvoiceQueryResult = Apollo.QueryResult< + GetInvoiceQuery, + GetInvoiceQueryVariables +>; diff --git a/src/client/src/graphql/queries/__generated__/getOfferReadiness.generated.tsx b/src/client/src/graphql/queries/__generated__/getOfferReadiness.generated.tsx index a63aae65..7dbcd441 100644 --- a/src/client/src/graphql/queries/__generated__/getOfferReadiness.generated.tsx +++ b/src/client/src/graphql/queries/__generated__/getOfferReadiness.generated.tsx @@ -17,6 +17,7 @@ export type GetOfferReadinessQuery = { is_peer_connected: boolean; has_pending_order: boolean; pending_order_id?: string | null; + pending_order_status?: string | null; onchain_balance_sats: string; onchain_asset_balance: string; btc_channels: { @@ -47,6 +48,7 @@ export const GetOfferReadinessDocument = gql` is_peer_connected has_pending_order pending_order_id + pending_order_status onchain_balance_sats onchain_asset_balance btc_channels { diff --git a/src/client/src/graphql/queries/__generated__/getPayment.generated.tsx b/src/client/src/graphql/queries/__generated__/getPayment.generated.tsx new file mode 100644 index 00000000..386baaca --- /dev/null +++ b/src/client/src/graphql/queries/__generated__/getPayment.generated.tsx @@ -0,0 +1,165 @@ +import * as Types from '../../types'; + +import { gql } from '@apollo/client'; +import * as Apollo from '@apollo/client'; +const defaultOptions = {} as const; +export type GetPaymentQueryVariables = Types.Exact<{ + id: Types.Scalars['String']['input']; +}>; + +export type GetPaymentQuery = { + __typename?: 'Query'; + getPayment: { + __typename?: 'PaymentType'; + created_at: string; + destination: string; + fee: number; + fee_mtokens: string; + id: string; + is_confirmed: boolean; + is_outgoing: boolean; + mtokens: string; + request?: string | null; + safe_fee: number; + safe_tokens?: number | null; + secret: string; + tokens: string; + type: string; + date: string; + destination_node: { + __typename?: 'Node'; + node?: { + __typename?: 'NodeType'; + alias: string; + public_key: string; + } | null; + }; + hops: Array<{ + __typename?: 'Node'; + node?: { + __typename?: 'NodeType'; + alias: string; + public_key: string; + } | null; + }>; + }; +}; + +export const GetPaymentDocument = gql` + query GetPayment($id: String!) { + getPayment(id: $id) { + created_at + destination + destination_node { + node { + alias + public_key + } + } + fee + fee_mtokens + hops { + node { + alias + public_key + } + } + id + is_confirmed + is_outgoing + mtokens + request + safe_fee + safe_tokens + secret + tokens + type + date + } + } +`; + +/** + * __useGetPaymentQuery__ + * + * To run a query within a React component, call `useGetPaymentQuery` and pass it any options that fit your needs. + * When your component renders, `useGetPaymentQuery` returns an object from Apollo Client that contains loading, error, and data properties + * you can use to render your UI. + * + * @param baseOptions options that will be passed into the query, supported options are listed on: https://www.apollographql.com/docs/react/api/react-hooks/#options; + * + * @example + * const { data, loading, error } = useGetPaymentQuery({ + * variables: { + * id: // value for 'id' + * }, + * }); + */ +export function useGetPaymentQuery( + baseOptions: Apollo.QueryHookOptions< + GetPaymentQuery, + GetPaymentQueryVariables + > & + ( + | { variables: GetPaymentQueryVariables; skip?: boolean } + | { skip: boolean } + ) +) { + const options = { ...defaultOptions, ...baseOptions }; + return Apollo.useQuery( + GetPaymentDocument, + options + ); +} +export function useGetPaymentLazyQuery( + baseOptions?: Apollo.LazyQueryHookOptions< + GetPaymentQuery, + GetPaymentQueryVariables + > +) { + const options = { ...defaultOptions, ...baseOptions }; + return Apollo.useLazyQuery( + GetPaymentDocument, + options + ); +} +// @ts-ignore +export function useGetPaymentSuspenseQuery( + baseOptions?: Apollo.SuspenseQueryHookOptions< + GetPaymentQuery, + GetPaymentQueryVariables + > +): Apollo.UseSuspenseQueryResult; +export function useGetPaymentSuspenseQuery( + baseOptions?: + | Apollo.SkipToken + | Apollo.SuspenseQueryHookOptions +): Apollo.UseSuspenseQueryResult< + GetPaymentQuery | undefined, + GetPaymentQueryVariables +>; +export function useGetPaymentSuspenseQuery( + baseOptions?: + | Apollo.SkipToken + | Apollo.SuspenseQueryHookOptions +) { + const options = + baseOptions === Apollo.skipToken + ? baseOptions + : { ...defaultOptions, ...baseOptions }; + return Apollo.useSuspenseQuery( + GetPaymentDocument, + options + ); +} +export type GetPaymentQueryHookResult = ReturnType; +export type GetPaymentLazyQueryHookResult = ReturnType< + typeof useGetPaymentLazyQuery +>; +export type GetPaymentSuspenseQueryHookResult = ReturnType< + typeof useGetPaymentSuspenseQuery +>; +export type GetPaymentQueryResult = Apollo.QueryResult< + GetPaymentQuery, + GetPaymentQueryVariables +>; diff --git a/src/client/src/graphql/queries/getInvoice.ts b/src/client/src/graphql/queries/getInvoice.ts new file mode 100644 index 00000000..72fc3c5f --- /dev/null +++ b/src/client/src/graphql/queries/getInvoice.ts @@ -0,0 +1,45 @@ +import { gql } from '@apollo/client'; + +export const GET_INVOICE = gql` + query GetInvoice($id: String!) { + getInvoice(id: $id) { + chain_address + confirmed_at + created_at + description + description_hash + expires_at + id + is_canceled + is_confirmed + is_held + is_private + is_push + received + received_mtokens + request + secret + tokens + type + date + payments { + canceled_at + confirmed_at + created_at + created_height + is_canceled + is_confirmed + is_held + mtokens + pending_index + timeout + tokens + total_mtokens + in_channel + messages { + message + } + } + } + } +`; diff --git a/src/client/src/graphql/queries/getPayment.ts b/src/client/src/graphql/queries/getPayment.ts new file mode 100644 index 00000000..a94b9e46 --- /dev/null +++ b/src/client/src/graphql/queries/getPayment.ts @@ -0,0 +1,35 @@ +import { gql } from '@apollo/client'; + +export const GET_PAYMENT = gql` + query GetPayment($id: String!) { + getPayment(id: $id) { + created_at + destination + destination_node { + node { + alias + public_key + } + } + fee + fee_mtokens + hops { + node { + alias + public_key + } + } + id + is_confirmed + is_outgoing + mtokens + request + safe_fee + safe_tokens + secret + tokens + type + date + } + } +`; diff --git a/src/client/src/graphql/types.ts b/src/client/src/graphql/types.ts index 2093c777..f5068bad 100644 --- a/src/client/src/graphql/types.ts +++ b/src/client/src/graphql/types.ts @@ -948,6 +948,7 @@ export type OfferReadinessResult = { onchain_asset_balance: Scalars['String']['output']; onchain_balance_sats: Scalars['String']['output']; pending_order_id?: Maybe; + pending_order_status?: Maybe; }; export type OnChainBalance = { @@ -1157,6 +1158,7 @@ export type Query = { getConfigState: ConfigState; getForwards: GetForwards; getHello: Scalars['String']['output']; + getInvoice: InvoiceType; getInvoiceStatusChange: Scalars['String']['output']; getInvoices: GetInvoicesType; getLatestVersion: Scalars['String']['output']; @@ -1167,6 +1169,7 @@ export type Query = { getNodeBalances: Balances; getNodeInfo: NodeInfo; getNodeSocialInfo: LightningNodeSocialInfo; + getPayment: PaymentType; getPayments: GetPaymentsType; getPeers: Array; getPendingChannels: Array; @@ -1206,6 +1209,10 @@ export type QueryGetForwardsArgs = { days: Scalars['Float']['input']; }; +export type QueryGetInvoiceArgs = { + id: Scalars['String']['input']; +}; + export type QueryGetInvoiceStatusChangeArgs = { id: Scalars['String']['input']; }; @@ -1227,6 +1234,10 @@ export type QueryGetNodeSocialInfoArgs = { pubkey: Scalars['String']['input']; }; +export type QueryGetPaymentArgs = { + id: Scalars['String']['input']; +}; + export type QueryGetPaymentsArgs = { token?: InputMaybe; }; diff --git a/src/client/src/pages/TransactionsPage.tsx b/src/client/src/pages/TransactionsPage.tsx index 04df0028..3177115c 100644 --- a/src/client/src/pages/TransactionsPage.tsx +++ b/src/client/src/pages/TransactionsPage.tsx @@ -1,8 +1,8 @@ -import { useState, useMemo, useCallback } from 'react'; +import { useState, useMemo, useCallback, FormEvent } from 'react'; import toast from 'react-hot-toast'; import { InvoiceCard } from '../views/transactions/InvoiceCard'; import { GridWrapper } from '../components/gridWrapper/GridWrapper'; -import { Settings, Loader2 } from 'lucide-react'; +import { Settings, Loader2, Search, X } from 'lucide-react'; import { useLocalStorage } from '../hooks/UseLocalStorage'; import { useNodeInfo } from '../hooks/UseNodeInfo'; import { @@ -13,6 +13,7 @@ import { format } from 'date-fns'; import { getErrorContent } from '../utils/error'; import { PaymentsCard } from '../views/transactions/PaymentsCards'; import { Button } from '@/components/ui/button'; +import { Input } from '@/components/ui/input'; import { FlowBox } from '../views/home/reports/flow'; import { GetInvoicesQuery, @@ -22,6 +23,8 @@ import { GetPaymentsQuery, useGetPaymentsQuery, } from '../graphql/queries/__generated__/getPayments.generated'; +import { useGetInvoiceLazyQuery } from '../graphql/queries/__generated__/getInvoice.generated'; +import { useGetPaymentLazyQuery } from '../graphql/queries/__generated__/getPayment.generated'; import { Card, CardContent, CardFooter } from '@/components/ui/card'; import { ToggleGroup, ToggleGroupItem } from '@/components/ui/toggle-group'; import { TradeDisplayMode } from '../views/transactions/tradeMemo'; @@ -32,6 +35,41 @@ const TransactionsView = () => { const [settingsOpen, setSettingsOpen] = useState(false); const [graphShow, setGraphShow] = useState('invoices'); const [graphType, setGraphType] = useState('count'); + const [lookupValue, setLookupValue] = useState(''); + const [lookupOpen, setLookupOpen] = useState(1); + + const [lookupInvoice, invoiceLookup] = useGetInvoiceLazyQuery({ + onError: error => toast.error(getErrorContent(error)), + }); + const [lookupPayment, paymentLookup] = useGetPaymentLazyQuery({ + onError: error => toast.error(getErrorContent(error)), + }); + + const activeLookup = activeTab === 'invoices' ? invoiceLookup : paymentLookup; + + const handleLookupSubmit = (e: FormEvent) => { + e.preventDefault(); + const id = lookupValue.trim(); + if (!id) return; + setLookupOpen(1); + if (activeTab === 'invoices') { + lookupInvoice({ variables: { id } }); + } else { + lookupPayment({ variables: { id } }); + } + }; + + const handleLookupClear = () => { + setLookupValue(''); + invoiceLookup.reset(); + paymentLookup.reset(); + }; + + const handleTabChange = (v: string) => { + if (!v) return; + setActiveTab(v); + handleLookupClear(); + }; const { publicKey } = useNodeInfo(); @@ -250,7 +288,7 @@ const TransactionsView = () => { variant="outline" size="sm" value={activeTab} - onValueChange={v => v && setActiveTab(v)} + onValueChange={handleTabChange} > Invoices Payments @@ -264,6 +302,81 @@ const TransactionsView = () => { + + +
+
+ + setLookupValue(e.target.value)} + placeholder={ + activeTab === 'invoices' + ? 'Lookup invoice by r-hash (payment hash)' + : 'Lookup payment by payment hash' + } + className="pl-8 pr-8 font-mono text-xs" + spellCheck={false} + /> + {lookupValue && ( + + )} +
+ +
+ {activeLookup.called && !activeLookup.loading && ( +
+ {activeTab === 'invoices' && invoiceLookup.data?.getInvoice ? ( + + ) : activeTab === 'payments' && paymentLookup.data?.getPayment ? ( + + ) : activeLookup.error ? ( +
+ {activeTab === 'invoices' + ? 'No invoice found for that hash.' + : 'No payment found for that hash.'} +
+ ) : null} +
+ )} +
+
+ {settingsOpen && ( diff --git a/src/client/src/views/transactions/InvoiceCard.tsx b/src/client/src/views/transactions/InvoiceCard.tsx index f9c1fcbc..a7f05a65 100644 --- a/src/client/src/views/transactions/InvoiceCard.tsx +++ b/src/client/src/views/transactions/InvoiceCard.tsx @@ -27,7 +27,7 @@ interface InvoiceCardProps { indexOpen: number; } -const ChannelAlias: FC<{ id: string }> = ({ id }) => { +const ChannelPeer: FC<{ id: string }> = ({ id }) => { const { data, loading, error } = useGetChannelQuery({ variables: { id }, }); @@ -35,10 +35,20 @@ const ChannelAlias: FC<{ id: string }> = ({ id }) => { if (loading) return ; if (error) return Unknown; - const alias = - data?.getChannel.partner_node_policies?.node?.node?.alias || 'Unknown'; + const peer = data?.getChannel.partner_node_policies?.node?.node; + const alias = peer?.alias || 'Unknown'; + const pubkey = peer?.public_key; - return {alias}; + return ( +
+ {alias} + {pubkey && ( + + {pubkey} + + )} +
+ ); }; const StatusBadge = ({ @@ -166,46 +176,6 @@ export const InvoiceCard = ({ {isOpen && (
- {payments.length > 0 && ( -
-
- Payments -
- {payments.map((p, idx) => { - const message = getTradeMemoText( - p.messages?.message, - tradeDisplayMode - ); - const messageDisplay = getTradeMemoDisplay(p.messages?.message); - return ( -
- - - - - {p.in_channel} - - - - {messageDisplay?.isTradeMemo && ( - -
- {messageDisplay.computed} - -
-
- )} - {message && ( - - {messageDisplay?.raw ?? message} - - )} -
-
- ); - })} -
- )} {descriptionDisplay?.isTradeMemo && ( @@ -244,6 +214,76 @@ export const InvoiceCard = ({ {secret && {secret}} {request && {request}} + {payments.length > 0 && ( +
+
+ HTLCs +
+ {payments.map((p, idx) => { + const message = getTradeMemoText( + p.messages?.message, + tradeDisplayMode + ); + const messageDisplay = getTradeMemoDisplay(p.messages?.message); + return ( +
+ + + + + {p.pending_index != null && ( + + {p.pending_index} + + )} + + + + {p.mtokens} + {p.total_mtokens && ( + + {p.total_mtokens} + + )} + {p.in_channel} + + + + + {`${getDateDif(p.created_at)} ago (${getFormatDate(p.created_at)})`} + + + {p.created_height} + + {p.is_confirmed && p.confirmed_at && ( + + {`${getDateDif(p.confirmed_at)} ago (${getFormatDate(p.confirmed_at)})`} + + )} + {p.timeout} + {p.is_held && Yes} + {messageDisplay?.isTradeMemo && ( + +
+ {messageDisplay.computed} + +
+
+ )} + {message && ( + + {messageDisplay?.raw ?? message} + + )} +
+
+ ); + })} +
+ )}
)} diff --git a/src/server/modules/api/transactions/transactions.resolver.ts b/src/server/modules/api/transactions/transactions.resolver.ts index b238d4ee..731e9cc2 100644 --- a/src/server/modules/api/transactions/transactions.resolver.ts +++ b/src/server/modules/api/transactions/transactions.resolver.ts @@ -3,12 +3,32 @@ import { decodeMessages } from 'src/server/utils/customRecords'; import { NodeService } from '../../node/node.service'; import { CurrentUser } from '../../security/security.decorators'; import { UserId } from '../../security/security.types'; -import { GetInvoicesType, GetPaymentsType } from './transactions.types'; +import { + GetInvoicesType, + GetPaymentsType, + InvoiceType, + PaymentType, +} from './transactions.types'; @Resolver() export class TransactionsResolver { constructor(private nodeService: NodeService) {} + @Query(() => InvoiceType) + async getInvoice(@CurrentUser() user: UserId, @Args('id') id: string) { + const invoice = await this.nodeService.getInvoice(user.id, { id }); + + return { + ...invoice, + type: 'invoice', + date: invoice.confirmed_at || invoice.created_at, + payments: invoice.payments.map(p => ({ + ...p, + messages: decodeMessages(p.messages), + })), + }; + } + @Query(() => GetInvoicesType) async getInvoices( @CurrentUser() user: UserId, @@ -31,6 +51,30 @@ export class TransactionsResolver { return { next, invoices: mapped }; } + @Query(() => PaymentType) + async getPayment(@CurrentUser() user: UserId, @Args('id') id: string) { + const result = await this.nodeService.getPayment(user.id, { id }); + const payment = result?.payment; + + if (!payment) { + throw new Error('Payment not found'); + } + + return { + ...payment, + type: 'payment', + date: payment.created_at, + is_confirmed: result.is_confirmed ?? false, + is_outgoing: true, + safe_fee: payment.fee, + safe_tokens: payment.tokens, + destination_node: { publicKey: payment.destination }, + hops: payment.hops.map((hop: { public_key: string }) => ({ + publicKey: hop.public_key, + })), + }; + } + @Query(() => GetPaymentsType) async getPayments( @CurrentUser() user: UserId, diff --git a/src/server/modules/node/lightning.types.ts b/src/server/modules/node/lightning.types.ts index b28d4089..1d648116 100644 --- a/src/server/modules/node/lightning.types.ts +++ b/src/server/modules/node/lightning.types.ts @@ -294,10 +294,12 @@ export interface LightningProvider { options: GetRouteToDestinationOptions ): Promise; decodePaymentRequest(connection: any, request: string): Promise; + getPayment(connection: any, options: { id: string }): Promise; getPayments(connection: any, options: GetPaymentsOptions): Promise; // ── Invoices ── createInvoice(connection: any, options: CreateInvoiceOptions): Promise; + getInvoice(connection: any, options: { id: string }): Promise; getInvoices(connection: any, options: GetInvoicesOptions): Promise; subscribeToInvoice(connection: any, id: string): EventEmitter; diff --git a/src/server/modules/node/litd/litd.service.ts b/src/server/modules/node/litd/litd.service.ts index 1c807de6..c8119c00 100644 --- a/src/server/modules/node/litd/litd.service.ts +++ b/src/server/modules/node/litd/litd.service.ts @@ -210,6 +210,10 @@ export class LitdService implements LightningProvider, TaprootAssetsProvider { ); } + async getPayment(connection: LitdConnection, options: { id: string }) { + return this.lndService.getPayment(this.getLnd(connection), options); + } + async getPayments(connection: LitdConnection, options: GetPaymentsOptions) { return this.lndService.getPayments(this.getLnd(connection), options); } @@ -223,6 +227,10 @@ export class LitdService implements LightningProvider, TaprootAssetsProvider { return this.lndService.createInvoice(this.getLnd(connection), options); } + async getInvoice(connection: LitdConnection, options: { id: string }) { + return this.lndService.getInvoice(this.getLnd(connection), options); + } + async getInvoices(connection: LitdConnection, options: GetInvoicesOptions) { return this.lndService.getInvoices(this.getLnd(connection), options); } diff --git a/src/server/modules/node/lnd/lnd.service.ts b/src/server/modules/node/lnd/lnd.service.ts index dc9787ed..46a7aea0 100644 --- a/src/server/modules/node/lnd/lnd.service.ts +++ b/src/server/modules/node/lnd/lnd.service.ts @@ -32,11 +32,13 @@ import { payViaRoutes, getRouteToDestination, createInvoice, + getInvoice, getChannel, closeChannel, openChannel, updateRoutingFees, getForwards, + getPayment, getPayments, getInvoices, subscribeToInvoice, @@ -304,10 +306,18 @@ export class LndService implements LightningProvider { return to(getForwards({ lnd, ...options } as any)); } + async getPayment(lnd: AuthenticatedLnd, options: { id: string }) { + return to(getPayment({ lnd, ...options } as any)); + } + async getPayments(lnd: AuthenticatedLnd, options: GetPaymentsOptions) { return to(getPayments({ lnd, ...options } as any)); } + async getInvoice(lnd: AuthenticatedLnd, options: { id: string }) { + return to(getInvoice({ lnd, ...options } as any)); + } + async getInvoices(lnd: AuthenticatedLnd, options: GetInvoicesOptions) { return to(getInvoices({ lnd, ...options } as any)); } diff --git a/src/server/modules/node/node.service.ts b/src/server/modules/node/node.service.ts index 82ccd211..d4b69513 100644 --- a/src/server/modules/node/node.service.ts +++ b/src/server/modules/node/node.service.ts @@ -253,11 +253,21 @@ export class NodeService { return provider.getForwards(account.connection, options); } + async getPayment(id: string, options: { id: string }) { + const { account, provider } = this.getAccountAndProvider(id); + return provider.getPayment(account.connection, options); + } + async getPayments(id: string, options: GetPaymentsOptions) { const { account, provider } = this.getAccountAndProvider(id); return provider.getPayments(account.connection, options); } + async getInvoice(id: string, options: { id: string }) { + const { account, provider } = this.getAccountAndProvider(id); + return provider.getInvoice(account.connection, options); + } + async getInvoices(id: string, options: GetInvoicesOptions) { const { account, provider } = this.getAccountAndProvider(id); return provider.getInvoices(account.connection, options);