Skip to content

Commit

Permalink
refactor: deprecate current query/subscription
Browse files Browse the repository at this point in the history
  • Loading branch information
dolcalmi committed Feb 12, 2024
1 parent c1ce4b5 commit ab07d54
Show file tree
Hide file tree
Showing 13 changed files with 274 additions and 35 deletions.
20 changes: 18 additions & 2 deletions core/api/dev/apollo-federation/supergraph.graphql
Original file line number Diff line number Diff line change
Expand Up @@ -811,12 +811,26 @@ input LnInvoicePaymentInput
walletId: WalletId!
}

type LnInvoicePaymentStatus
@join__type(graph: PUBLIC)
{
paymentHash: PaymentHash
paymentRequest: LnPaymentRequest
status: InvoicePaymentStatus
}

input LnInvoicePaymentStatusByHashInput
@join__type(graph: PUBLIC)
{
paymentHash: PaymentHash!
}

input LnInvoicePaymentStatusByRequestInput
@join__type(graph: PUBLIC)
{
paymentRequest: LnPaymentRequest!
}

input LnInvoicePaymentStatusInput
@join__type(graph: PUBLIC)
{
Expand Down Expand Up @@ -1553,8 +1567,9 @@ type Query
businessMapMarkers: [MapMarker!]! @join__field(graph: PUBLIC)
currencyList: [Currency!]! @join__field(graph: PUBLIC)
globals: Globals @join__field(graph: PUBLIC)
lnInvoicePaymentStatus(input: LnInvoicePaymentStatusInput!): LnInvoicePaymentStatusPayload! @join__field(graph: PUBLIC)
lnInvoicePaymentStatusByHash(input: LnInvoicePaymentStatusByHashInput!): LnInvoicePaymentStatusPayload! @join__field(graph: PUBLIC)
lnInvoicePaymentStatus(input: LnInvoicePaymentStatusInput!): LnInvoicePaymentStatusPayload! @join__field(graph: PUBLIC) @deprecated(reason: "Deprecated in favor of lnInvoicePaymentStatusByRequest")
lnInvoicePaymentStatusByHash(input: LnInvoicePaymentStatusByHashInput!): LnInvoicePaymentStatus! @join__field(graph: PUBLIC)
lnInvoicePaymentStatusByRequest(input: LnInvoicePaymentStatusByRequestInput!): LnInvoicePaymentStatus! @join__field(graph: PUBLIC)
me: User @join__field(graph: PUBLIC)
mobileVersions: [MobileVersions] @join__field(graph: PUBLIC)
onChainTxFee(address: OnChainAddress!, amount: SatAmount!, speed: PayoutSpeed! = FAST, walletId: WalletId!): OnChainTxFee! @join__field(graph: PUBLIC)
Expand Down Expand Up @@ -1699,6 +1714,7 @@ type Subscription
{
lnInvoicePaymentStatus(input: LnInvoicePaymentStatusInput!): LnInvoicePaymentStatusPayload!
lnInvoicePaymentStatusByHash(input: LnInvoicePaymentStatusByHashInput!): LnInvoicePaymentStatusPayload!
lnInvoicePaymentStatusByRequest(input: LnInvoicePaymentStatusByRequestInput!): LnInvoicePaymentStatusPayload!
myUpdates: MyUpdatesPayload!
price(input: PriceInput!): PricePayload!

Expand Down
6 changes: 4 additions & 2 deletions core/api/src/graphql/public/queries.ts
Original file line number Diff line number Diff line change
Expand Up @@ -13,8 +13,9 @@ import UsernameAvailableQuery from "@/graphql/public/root/query/username-availab
import BusinessMapMarkersQuery from "@/graphql/public/root/query/business-map-markers"
import AccountDefaultWalletQuery from "@/graphql/public/root/query/account-default-wallet"
import AccountDefaultWalletIdQuery from "@/graphql/public/root/query/account-default-wallet-id"
import LnInvoicePaymentStatusByRequestQuery from "@/graphql/public/root/query/ln-invoice-payment-status-by-request"
import LnInvoicePaymentStatusQuery from "@/graphql/public/root/query/ln-invoice-payment-status"
import LnInvoicePaymentStatusByHashQuery from "@/graphql/public/root/query/ln-invoice-payment-status-by-hash"
import LnInvoicePaymentStatusByRequestQuery from "@/graphql/public/root/query/ln-invoice-payment-status-by-request"

export const queryFields = {
unauthed: {
Expand All @@ -27,8 +28,9 @@ export const queryFields = {
mobileVersions: MobileVersionsQuery,
realtimePrice: RealtimePriceQuery,
btcPriceList: BtcPriceListQuery,
lnInvoicePaymentStatus: LnInvoicePaymentStatusByRequestQuery,
lnInvoicePaymentStatus: LnInvoicePaymentStatusQuery,
lnInvoicePaymentStatusByHash: LnInvoicePaymentStatusByHashQuery,
lnInvoicePaymentStatusByRequest: LnInvoicePaymentStatusByRequestQuery,
},
authed: {
atAccountLevel: {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,40 +3,38 @@ import { WalletInvoiceStatus } from "@/domain/wallet-invoices"

import { GT } from "@/graphql/index"
import { mapAndParseErrorForGqlResponse } from "@/graphql/error-map"
import LnInvoicePaymentStatusPayload from "@/graphql/public/types/payload/ln-invoice-payment-status"
import LnInvoicePaymentStatus from "@/graphql/public/types/object/ln-invoice-payment-status"
import LnInvoicePaymentStatusByHashInput from "@/graphql/public/types/object/ln-invoice-payment-status-by-hash-input"

const LnInvoicePaymentStatusByHashQuery = GT.Field({
type: GT.NonNull(LnInvoicePaymentStatusPayload),
type: GT.NonNull(LnInvoicePaymentStatus),
args: {
input: { type: GT.NonNull(LnInvoicePaymentStatusByHashInput) },
},
resolve: async (_, args) => {
const { paymentHash } = args.input
if (paymentHash instanceof Error) {
return { errors: [{ message: paymentHash.message }] }
}
if (paymentHash instanceof Error) throw paymentHash

const paymentStatusChecker = await Lightning.PaymentStatusCheckerByHash({
paymentHash,
})
if (paymentStatusChecker instanceof Error) {
return { errors: [mapAndParseErrorForGqlResponse(paymentStatusChecker)] }
throw mapAndParseErrorForGqlResponse(paymentStatusChecker)
}

const paid = await paymentStatusChecker.invoiceIsPaid()
if (paid instanceof Error) {
return { errors: [mapAndParseErrorForGqlResponse(paid)] }
throw mapAndParseErrorForGqlResponse(paid)
}

const { paymentRequest, isExpired } = paymentStatusChecker

if (paid) {
return { errors: [], paymentHash, paymentRequest, status: WalletInvoiceStatus.Paid }
return { paymentHash, paymentRequest, status: WalletInvoiceStatus.Paid }
}

const status = isExpired ? WalletInvoiceStatus.Expired : WalletInvoiceStatus.Pending
return { errors: [], paymentHash, paymentRequest, status }
return { paymentHash, paymentRequest, status }
},
})

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,39 +3,37 @@ import { WalletInvoiceStatus } from "@/domain/wallet-invoices"

import { GT } from "@/graphql/index"
import { mapAndParseErrorForGqlResponse } from "@/graphql/error-map"
import LnInvoicePaymentStatusPayload from "@/graphql/public/types/payload/ln-invoice-payment-status"
import LnInvoicePaymentStatus from "@/graphql/public/types/object/ln-invoice-payment-status"
import LnInvoicePaymentStatusByRequestInput from "@/graphql/public/types/object/ln-invoice-payment-status-by-request-input"

const LnInvoicePaymentStatusQuery = GT.Field({
type: GT.NonNull(LnInvoicePaymentStatusPayload),
const LnInvoicePaymentStatusByRequestQuery = GT.Field({
type: GT.NonNull(LnInvoicePaymentStatus),
args: {
input: { type: GT.NonNull(LnInvoicePaymentStatusByRequestInput) },
},
resolve: async (_, args) => {
const { paymentRequest } = args.input
if (paymentRequest instanceof Error) {
return { errors: [{ message: paymentRequest.message }] }
}
if (paymentRequest instanceof Error) throw paymentRequest

const paymentStatusChecker = await Lightning.PaymentStatusChecker(paymentRequest)
if (paymentStatusChecker instanceof Error) {
return { errors: [mapAndParseErrorForGqlResponse(paymentStatusChecker)] }
throw mapAndParseErrorForGqlResponse(paymentStatusChecker)
}

const paid = await paymentStatusChecker.invoiceIsPaid()
if (paid instanceof Error) {
return { errors: [mapAndParseErrorForGqlResponse(paid)] }
throw mapAndParseErrorForGqlResponse(paid)
}

const { paymentHash, isExpired } = paymentStatusChecker

if (paid) {
return { errors: [], paymentHash, paymentRequest, status: WalletInvoiceStatus.Paid }
return { paymentHash, paymentRequest, status: WalletInvoiceStatus.Paid }
}

const status = isExpired ? WalletInvoiceStatus.Expired : WalletInvoiceStatus.Pending
return { errors: [], paymentHash, paymentRequest, status }
return { paymentHash, paymentRequest, status }
},
})

export default LnInvoicePaymentStatusQuery
export default LnInvoicePaymentStatusByRequestQuery
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
import { Lightning } from "@/app"
import { WalletInvoiceStatus } from "@/domain/wallet-invoices"

import { GT } from "@/graphql/index"
import { mapAndParseErrorForGqlResponse } from "@/graphql/error-map"
import LnInvoicePaymentStatusPayload from "@/graphql/public/types/payload/ln-invoice-payment-status"
import LnInvoicePaymentStatusInput from "@/graphql/public/types/object/ln-invoice-payment-status-input"

const LnInvoicePaymentStatusQuery = GT.Field({
type: GT.NonNull(LnInvoicePaymentStatusPayload),
deprecationReason: "Deprecated in favor of lnInvoicePaymentStatusByRequest",
args: {
input: { type: GT.NonNull(LnInvoicePaymentStatusInput) },
},
resolve: async (_, args) => {
const { paymentRequest } = args.input
if (paymentRequest instanceof Error) {
return { errors: [{ message: paymentRequest.message }] }
}

const paymentStatusChecker = await Lightning.PaymentStatusChecker(paymentRequest)
if (paymentStatusChecker instanceof Error) {
return { errors: [mapAndParseErrorForGqlResponse(paymentStatusChecker)] }
}

const paid = await paymentStatusChecker.invoiceIsPaid()
if (paid instanceof Error) {
return { errors: [mapAndParseErrorForGqlResponse(paid)] }
}

const { paymentHash, isExpired } = paymentStatusChecker

if (paid) {
return { errors: [], paymentHash, paymentRequest, status: WalletInvoiceStatus.Paid }
}

const status = isExpired ? WalletInvoiceStatus.Expired : WalletInvoiceStatus.Pending
return { errors: [], paymentHash, paymentRequest, status }
},
})

export default LnInvoicePaymentStatusQuery
Original file line number Diff line number Diff line change
Expand Up @@ -14,13 +14,13 @@ import { WalletInvoiceStatus } from "@/domain/wallet-invoices"

const pubsub = PubSubService()

type LnInvoicePaymentSubscribeArgs = {
type LnInvoicePaymentStatusByRequestSubscribeArgs = {
input: {
paymentRequest: EncodedPaymentRequest | Error
}
}

type LnInvoicePaymentResolveSource = {
type LnInvoicePaymentStatusByRequestResolveSource = {
errors?: IError[]
status?: string
paymentHash?: PaymentHash
Expand All @@ -32,7 +32,7 @@ const LnInvoicePaymentStatusByRequestSubscription = {
args: {
input: { type: GT.NonNull(LnInvoicePaymentStatusByRequestInput) },
},
resolve: async (source: LnInvoicePaymentResolveSource | undefined) => {
resolve: async (source: LnInvoicePaymentStatusByRequestResolveSource | undefined) => {
if (source === undefined) {
throw new UnknownClientError({
message:
Expand Down Expand Up @@ -60,7 +60,10 @@ const LnInvoicePaymentStatusByRequestSubscription = {
}
},

subscribe: async (_source: unknown, args: LnInvoicePaymentSubscribeArgs) => {
subscribe: async (
_source: unknown,
args: LnInvoicePaymentStatusByRequestSubscribeArgs,
) => {
const { paymentRequest } = args.input
if (paymentRequest instanceof Error) throw paymentRequest

Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,124 @@
import { Lightning } from "@/app"

import { customPubSubTrigger, PubSubDefaultTriggers } from "@/domain/pubsub"

import { PubSubService } from "@/services/pubsub"
import { baseLogger } from "@/services/logger"

import { GT } from "@/graphql/index"
import LnInvoicePaymentStatusPayload from "@/graphql/public/types/payload/ln-invoice-payment-status"
import LnInvoicePaymentStatusInput from "@/graphql/public/types/object/ln-invoice-payment-status-input"
import { UnknownClientError } from "@/graphql/error"
import { mapAndParseErrorForGqlResponse } from "@/graphql/error-map"
import { WalletInvoiceStatus } from "@/domain/wallet-invoices"

const pubsub = PubSubService()

type LnInvoicePaymentSubscribeArgs = {
input: {
paymentRequest: EncodedPaymentRequest | Error
}
}

type LnInvoicePaymentResolveSource = {
errors?: IError[]
status?: string
paymentHash?: PaymentHash
paymentRequest?: EncodedPaymentRequest
}

const LnInvoicePaymentStatusSubscription = {
type: GT.NonNull(LnInvoicePaymentStatusPayload),
deprecationReason: "Deprecated in favor of lnInvoicePaymentStatusByRequest",
args: {
input: { type: GT.NonNull(LnInvoicePaymentStatusInput) },
},
resolve: async (source: LnInvoicePaymentResolveSource | undefined) => {
if (source === undefined) {
throw new UnknownClientError({
message:
"Got 'undefined' payload. Check url used to ensure right websocket endpoint was used for subscription.",
logger: baseLogger,
})
}

if (source.errors) {
return { errors: source.errors }
}

let paymentRequest = source.paymentRequest
if (source.paymentHash && !source.paymentRequest) {
const invoice = await Lightning.getInvoiceRequestByHash({
paymentHash: source.paymentHash,
})
paymentRequest = invoice instanceof Error ? paymentRequest : invoice
}
return {
errors: [],
status: source.status,
paymentHash: source.paymentHash,
paymentRequest,
}
},

subscribe: async (_source: unknown, args: LnInvoicePaymentSubscribeArgs) => {
const { paymentRequest } = args.input
if (paymentRequest instanceof Error) throw paymentRequest

const paymentStatusChecker = await Lightning.PaymentStatusChecker(paymentRequest)

if (paymentStatusChecker instanceof Error) {
const lnPaymentStatusTrigger = customPubSubTrigger({
event: PubSubDefaultTriggers.LnPaymentStatus,
suffix: paymentRequest,
})
pubsub.publishDelayed({
trigger: lnPaymentStatusTrigger,
payload: { errors: [mapAndParseErrorForGqlResponse(paymentStatusChecker)] },
})

return pubsub.createAsyncIterator({ trigger: lnPaymentStatusTrigger })
}

const paymentHash = paymentStatusChecker.paymentHash
const trigger = customPubSubTrigger({
event: PubSubDefaultTriggers.LnPaymentStatus,
suffix: paymentHash,
})
const paid = await paymentStatusChecker.invoiceIsPaid()

if (paid instanceof Error) {
pubsub.publishDelayed({
trigger,
payload: { errors: [mapAndParseErrorForGqlResponse(paid)] },
})
}

if (paid) {
pubsub.publishDelayed({
trigger,
payload: { paymentHash, paymentRequest, status: WalletInvoiceStatus.Paid },
})
return pubsub.createAsyncIterator({ trigger })
}

const status = paymentStatusChecker.isExpired
? WalletInvoiceStatus.Expired
: WalletInvoiceStatus.Pending
pubsub.publishDelayed({ trigger, payload: { paymentHash, paymentRequest, status } })

if (!paymentStatusChecker.isExpired) {
const timeout = Math.max(paymentStatusChecker.expiresAt.getTime() - Date.now(), 0)
setTimeout(() => {
pubsub.publish({
trigger,
payload: { paymentHash, paymentRequest, status: WalletInvoiceStatus.Expired },
})
}, timeout + 1000)
}

return pubsub.createAsyncIterator({ trigger })
},
}

export default LnInvoicePaymentStatusSubscription
Loading

0 comments on commit ab07d54

Please sign in to comment.