Skip to content

Commit

Permalink
feat: expose walletById and invoiceByHash
Browse files Browse the repository at this point in the history
  • Loading branch information
UncleSamtoshi committed Oct 6, 2023
1 parent 8f39707 commit b92c394
Show file tree
Hide file tree
Showing 10 changed files with 136 additions and 11 deletions.
5 changes: 5 additions & 0 deletions core/api/dev/apollo-federation/supergraph.graphql
Original file line number Diff line number Diff line change
Expand Up @@ -47,6 +47,7 @@ interface Account
last: Int
walletIds: [WalletId]
): TransactionConnection
walletById(walletId: WalletId!): Wallet!
wallets: [Wallet!]!
}

Expand Down Expand Up @@ -178,6 +179,7 @@ type BTCWallet implements Wallet
"""A balance stored in BTC."""
balance: SignedAmount!
id: ID!
invoiceByHash(paymentHash: PaymentHash!): LnInvoice!

"""An unconfirmed incoming onchain balance."""
pendingIncomingBalance: SignedAmount!
Expand Down Expand Up @@ -324,6 +326,7 @@ type ConsumerAccount implements Account
last: Int
walletIds: [WalletId]
): TransactionConnection
walletById(walletId: WalletId!): Wallet!
wallets: [Wallet!]!
}

Expand Down Expand Up @@ -1582,6 +1585,7 @@ type UsdWallet implements Wallet
accountId: ID!
balance: SignedAmount!
id: ID!
invoiceByHash(paymentHash: PaymentHash!): LnInvoice!

"""An unconfirmed incoming onchain balance."""
pendingIncomingBalance: SignedAmount!
Expand Down Expand Up @@ -1894,6 +1898,7 @@ interface Wallet
accountId: ID!
balance: SignedAmount!
id: ID!
invoiceByHash(paymentHash: PaymentHash!): LnInvoice!
pendingIncomingBalance: SignedAmount!

"""
Expand Down
15 changes: 5 additions & 10 deletions core/api/src/app/wallets/get-invoice-for-wallet-by-hash.ts
Original file line number Diff line number Diff line change
@@ -1,24 +1,19 @@
import { CouldNotFindWalletInvoiceError } from "@domain/errors"
import { checkedToWalletId } from "@domain/wallets"
import { WalletInvoicesRepository } from "@services/mongoose"
import { CouldNotFindWalletInvoiceError } from "@/domain/errors"
import { WalletInvoicesRepository } from "@/services/mongoose"

export const getInvoiceForWalletByHash = async ({
walletId: uncheckedWalletId,
walletId,
paymentHash,
}: {
walletId: string
walletId: WalletId
paymentHash: PaymentHash
}) => {
const walletId = checkedToWalletId(uncheckedWalletId)
if (walletId instanceof Error) return walletId

}): Promise<WalletInvoice | ApplicationError> => {
const walletInvoicesRepository = WalletInvoicesRepository()

const walletInvoice = await walletInvoicesRepository.findByPaymentHash(paymentHash)

if (walletInvoice instanceof Error) return walletInvoice

// QUESTION: Should we make the walletId part of the repository method or do this check here?
if (walletInvoice.recipientWalletDescriptor.id !== walletId) {
return new CouldNotFindWalletInvoiceError()
}
Expand Down
21 changes: 21 additions & 0 deletions core/api/src/app/wallets/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -16,14 +16,35 @@ export * from "./settle-payout-txn"
export * from "./update-legacy-on-chain-receipt"
export * from "./update-pending-invoices"
export * from "./validate"
export * from "./get-invoice-for-wallet-by-hash"

import { CouldNotFindWalletFromIdError } from "@/domain/errors"
import { WalletsRepository } from "@/services/mongoose"

export const getWallet = async (walletId: WalletId) => {
const wallets = WalletsRepository()
return wallets.findById(walletId)
}

export const getWalletForAccountById = async ({
accountId,
walletId,
}: {
accountId: AccountId
walletId: WalletId
}): Promise<Wallet | ApplicationError> => {
const wallets = WalletsRepository()
const wallet = await wallets.findById(walletId)

if (wallet instanceof Error) return wallet

if (wallet.accountId !== accountId) {
return new CouldNotFindWalletFromIdError()
}

return wallet
}

export const listWalletsByAccountId = async (
accountId: AccountId,
): Promise<Wallet[] | RepositoryError> => {
Expand Down
10 changes: 10 additions & 0 deletions core/api/src/graphql/admin/schema.graphql
Original file line number Diff line number Diff line change
Expand Up @@ -88,6 +88,7 @@ type BTCWallet implements Wallet {
"""A balance stored in BTC."""
balance: SignedAmount!
id: ID!
invoiceByHash(paymentHash: PaymentHash!): LnInvoice!

"""An unconfirmed incoming onchain balance."""
pendingIncomingBalance: SignedAmount!
Expand Down Expand Up @@ -223,6 +224,13 @@ type LightningPayment {
status: LnPaymentStatus
}

type LnInvoice {
paymentHash: PaymentHash!
paymentRequest: LnPaymentRequest!
paymentSecret: LnPaymentSecret!
satoshis: SatAmount
}

scalar LnPaymentPreImage

"""BOLT11 lightning invoice payment request with the amount included"""
Expand Down Expand Up @@ -436,6 +444,7 @@ type UsdWallet implements Wallet {
accountId: ID!
balance: SignedAmount!
id: ID!
invoiceByHash(paymentHash: PaymentHash!): LnInvoice!

"""An unconfirmed incoming onchain balance."""
pendingIncomingBalance: SignedAmount!
Expand Down Expand Up @@ -491,6 +500,7 @@ interface Wallet {
accountId: ID!
balance: SignedAmount!
id: ID!
invoiceByHash(paymentHash: PaymentHash!): LnInvoice!
pendingIncomingBalance: SignedAmount!

"""
Expand Down
5 changes: 5 additions & 0 deletions core/api/src/graphql/public/schema.graphql
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@ interface Account {
last: Int
walletIds: [WalletId]
): TransactionConnection
walletById(walletId: WalletId!): Wallet!
wallets: [Wallet!]!
}

Expand Down Expand Up @@ -121,6 +122,7 @@ type BTCWallet implements Wallet {
"""A balance stored in BTC."""
balance: SignedAmount!
id: ID!
invoiceByHash(paymentHash: PaymentHash!): LnInvoice!

"""An unconfirmed incoming onchain balance."""
pendingIncomingBalance: SignedAmount!
Expand Down Expand Up @@ -245,6 +247,7 @@ type ConsumerAccount implements Account {
last: Int
walletIds: [WalletId]
): TransactionConnection
walletById(walletId: WalletId!): Wallet!
wallets: [Wallet!]!
}

Expand Down Expand Up @@ -1243,6 +1246,7 @@ type UsdWallet implements Wallet {
accountId: ID!
balance: SignedAmount!
id: ID!
invoiceByHash(paymentHash: PaymentHash!): LnInvoice!

"""An unconfirmed incoming onchain balance."""
pendingIncomingBalance: SignedAmount!
Expand Down Expand Up @@ -1487,6 +1491,7 @@ interface Wallet {
accountId: ID!
balance: SignedAmount!
id: ID!
invoiceByHash(paymentHash: PaymentHash!): LnInvoice!
pendingIncomingBalance: SignedAmount!

"""
Expand Down
9 changes: 8 additions & 1 deletion core/api/src/graphql/public/types/abstract/account.ts
Original file line number Diff line number Diff line change
Expand Up @@ -62,7 +62,14 @@ const IAccount = GT.Interface({
notificationSettings: {
type: GT.NonNull(NotificationSettings),
},

walletById: {
type: GT.NonNull(Wallet),
args: {
walletId: {
type: GT.NonNull(WalletId),
},
},
},
// FUTURE-PLAN: Support a `users: [User!]!` field here
}),
})
Expand Down
20 changes: 20 additions & 0 deletions core/api/src/graphql/public/types/object/consumer-account.ts
Original file line number Diff line number Diff line change
Expand Up @@ -62,6 +62,26 @@ const ConsumerAccount = GT.Object<Account, GraphQLPublicContextAuth>({
},
},

walletById: {
type: GT.NonNull(Wallet),
args: {
walletId: {
type: GT.NonNull(WalletId),
},
},
resolve: async (source, args) => {
const { walletId } = args
const wallet = await Wallets.getWalletForAccountById({
walletId,
accountId: source.id,
})
if (wallet instanceof Error) {
throw mapError(wallet)
}
return wallet
},
},

defaultWalletId: {
type: GT.NonNull(WalletId),
resolve: (source) => source.defaultWalletId,
Expand Down
10 changes: 10 additions & 0 deletions core/api/src/graphql/shared/types/abstract/wallet.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,9 +4,11 @@ import { TransactionConnection } from "../object/transaction"
import WalletCurrency from "../scalar/wallet-currency"
import SignedAmount from "../scalar/signed-amount"
import OnChainAddress from "../scalar/on-chain-address"
import PaymentHash from "../scalar/payment-hash"

import { connectionArgs } from "@/graphql/connections"
import { GT } from "@/graphql/index"
import LnInvoice from "@/graphql/public/types/object/ln-invoice"

const IWallet = GT.Interface({
name: "Wallet",
Expand Down Expand Up @@ -45,6 +47,14 @@ const IWallet = GT.Interface({
},
},
},
invoiceByHash: {
type: GT.NonNull(LnInvoice),
args: {
paymentHash: {
type: GT.NonNull(PaymentHash),
},
},
},
}),
})

Expand Down
26 changes: 26 additions & 0 deletions core/api/src/graphql/shared/types/object/btc-wallet.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,8 @@ import WalletCurrency from "../scalar/wallet-currency"

import OnChainAddress from "../scalar/on-chain-address"

import PaymentHash from "../scalar/payment-hash"

import { TransactionConnection } from "./transaction"

import { GT } from "@/graphql/index"
Expand All @@ -20,6 +22,7 @@ import { mapError } from "@/graphql/error-map"
import { Wallets } from "@/app"

import { WalletCurrency as WalletCurrencyDomain } from "@/domain/shared"
import LnInvoice from "@/graphql/public/types/object/ln-invoice"

const BtcWallet = GT.Object<Wallet>({
name: "BTCWallet",
Expand Down Expand Up @@ -125,6 +128,29 @@ const BtcWallet = GT.Object<Wallet>({
)
},
},
invoiceByHash: {
type: GT.NonNull(LnInvoice),
args: {
paymentHash: {
type: GT.NonNull(PaymentHash),
},
},
resolve: async (source, args) => {
const { paymentHash } = args
if (paymentHash instanceof Error) throw paymentHash

const invoice = await Wallets.getInvoiceForWalletByHash({
walletId: source.id,
paymentHash,
})

if (invoice instanceof Error) {
throw mapError(invoice)
}

return invoice
},
},
}),
})

Expand Down
26 changes: 26 additions & 0 deletions core/api/src/graphql/shared/types/object/usd-wallet.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,8 @@ import SignedAmount from "../scalar/signed-amount"

import OnChainAddress from "../scalar/on-chain-address"

import PaymentHash from "../scalar/payment-hash"

import { TransactionConnection } from "./transaction"

import { GT } from "@/graphql/index"
Expand All @@ -20,6 +22,7 @@ import { mapError } from "@/graphql/error-map"
import { Wallets } from "@/app"

import { WalletCurrency as WalletCurrencyDomain } from "@/domain/shared"
import LnInvoice from "@/graphql/public/types/object/ln-invoice"

const UsdWallet = GT.Object<Wallet>({
name: "UsdWallet",
Expand Down Expand Up @@ -123,6 +126,29 @@ const UsdWallet = GT.Object<Wallet>({
)
},
},
invoiceByHash: {
type: GT.NonNull(LnInvoice),
args: {
paymentHash: {
type: GT.NonNull(PaymentHash),
},
},
resolve: async (source, args) => {
const { paymentHash } = args
if (paymentHash instanceof Error) throw paymentHash

const invoice = await Wallets.getInvoiceForWalletByHash({
walletId: source.id,
paymentHash,
})

if (invoice instanceof Error) {
throw mapError(invoice)
}

return invoice
},
},
}),
})

Expand Down

0 comments on commit b92c394

Please sign in to comment.