From 4c19543c0d0a2e0239d333c2e769a307426205e5 Mon Sep 17 00:00:00 2001 From: Sam Peters Date: Fri, 20 Oct 2023 16:38:44 -0500 Subject: [PATCH] chore: address pr feedback --- .../wallets/get-invoice-for-wallet-by-hash.ts | 16 ++----- .../src/app/wallets/get-transaction-by-id.ts | 25 ++++++---- .../app/wallets/get-transactions-by-hash.ts | 20 ++++---- .../app/wallets/get-wallet-invoice-status.ts | 0 core/api/src/app/wallets/index.ts | 15 ++---- .../domain/bitcoin/lightning/index.types.d.ts | 2 +- core/api/src/domain/ledger/index.types.d.ts | 10 ++++ .../domain/wallet-invoices/index.types.d.ts | 9 ++++ core/api/src/domain/wallets/index.types.d.ts | 4 ++ .../graphql/shared/types/object/ln-invoice.ts | 4 +- .../types/object/ln-noamount-invoice.ts | 4 +- core/api/src/services/ledger/index.ts | 47 +++++++++++++++++++ .../src/services/mongoose/wallet-invoices.ts | 18 +++++++ core/api/src/services/mongoose/wallets.ts | 22 +++++++++ 14 files changed, 151 insertions(+), 45 deletions(-) delete mode 100644 core/api/src/app/wallets/get-wallet-invoice-status.ts diff --git a/core/api/src/app/wallets/get-invoice-for-wallet-by-hash.ts b/core/api/src/app/wallets/get-invoice-for-wallet-by-hash.ts index 86808caa01..3f1ad39c8b 100644 --- a/core/api/src/app/wallets/get-invoice-for-wallet-by-hash.ts +++ b/core/api/src/app/wallets/get-invoice-for-wallet-by-hash.ts @@ -1,7 +1,6 @@ -import { CouldNotFindWalletInvoiceError } from "@/domain/errors" import { WalletInvoicesRepository } from "@/services/mongoose" -export const getInvoiceForWalletByPaymentHash = async ({ +export const getInvoiceForWalletByPaymentHash = ({ walletId, paymentHash, }: { @@ -10,13 +9,8 @@ export const getInvoiceForWalletByPaymentHash = async ({ }): Promise => { const walletInvoicesRepository = WalletInvoicesRepository() - const walletInvoice = await walletInvoicesRepository.findByPaymentHash(paymentHash) - - if (walletInvoice instanceof Error) return walletInvoice - - if (walletInvoice.recipientWalletDescriptor.id !== walletId) { - return new CouldNotFindWalletInvoiceError() - } - - return walletInvoice + return walletInvoicesRepository.findForWalletByPaymentHash({ + walletId, + paymentHash, + }) } diff --git a/core/api/src/app/wallets/get-transaction-by-id.ts b/core/api/src/app/wallets/get-transaction-by-id.ts index f6eb4c3806..897ec33a55 100644 --- a/core/api/src/app/wallets/get-transaction-by-id.ts +++ b/core/api/src/app/wallets/get-transaction-by-id.ts @@ -1,9 +1,6 @@ import { memoSharingConfig } from "@/config" import { WalletTransactionHistory } from "@/domain/wallets" -import { - checkedToLedgerTransactionId, - CouldNotFindTransactionError, -} from "@/domain/ledger" +import { checkedToLedgerTransactionId } from "@/domain/ledger" import { getNonEndUserWalletIds, LedgerService } from "@/services/ledger" @@ -14,10 +11,22 @@ export const getTransactionForWalletById = async ({ walletId: WalletId transactionId: string }): Promise => { - const transaction = await getTransactionById(uncheckedTransactionId) - if (transaction instanceof Error) return transaction - if (transaction.walletId !== walletId) return new CouldNotFindTransactionError() - return transaction + const ledger = LedgerService() + + const ledgerTransactionId = checkedToLedgerTransactionId(uncheckedTransactionId) + if (ledgerTransactionId instanceof Error) return ledgerTransactionId + + const ledgerTransaction = await ledger.getTransactionForWalletById({ + walletId, + transactionId: ledgerTransactionId, + }) + if (ledgerTransaction instanceof Error) return ledgerTransaction + + return WalletTransactionHistory.fromLedger({ + ledgerTransactions: [ledgerTransaction], + nonEndUserWalletIds: Object.values(await getNonEndUserWalletIds()), + memoSharingConfig, + }).transactions[0] } export const getTransactionById = async ( diff --git a/core/api/src/app/wallets/get-transactions-by-hash.ts b/core/api/src/app/wallets/get-transactions-by-hash.ts index c1ff25274e..cb4bd69406 100644 --- a/core/api/src/app/wallets/get-transactions-by-hash.ts +++ b/core/api/src/app/wallets/get-transactions-by-hash.ts @@ -11,20 +11,18 @@ export const getTransactionForWalletByPaymentHash = async ({ paymentHash: PaymentHash }): Promise => { const ledger = LedgerService() - const ledgerTransactions = await ledger.getTransactionsByHash(paymentHash) - if (ledgerTransactions instanceof Error) return ledgerTransactions + const ledgerTransaction = await ledger.getTransactionForWalletByPaymentHash({ + walletId, + paymentHash, + }) - const transactions = WalletTransactionHistory.fromLedger({ - ledgerTransactions, + if (ledgerTransaction instanceof Error) return ledgerTransaction + + return WalletTransactionHistory.fromLedger({ + ledgerTransactions: [ledgerTransaction], nonEndUserWalletIds: Object.values(await getNonEndUserWalletIds()), memoSharingConfig, - }).transactions - - const transaction = transactions.find( - (transaction) => transaction.walletId === walletId, - ) - - return transaction + }).transactions[0] } export const getTransactionsByHash = async ( diff --git a/core/api/src/app/wallets/get-wallet-invoice-status.ts b/core/api/src/app/wallets/get-wallet-invoice-status.ts deleted file mode 100644 index e69de29bb2..0000000000 diff --git a/core/api/src/app/wallets/index.ts b/core/api/src/app/wallets/index.ts index 4c8dda24f7..f39e97348f 100644 --- a/core/api/src/app/wallets/index.ts +++ b/core/api/src/app/wallets/index.ts @@ -18,7 +18,6 @@ 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) => { @@ -26,7 +25,7 @@ export const getWallet = async (walletId: WalletId) => { return wallets.findById(walletId) } -export const getWalletForAccountById = async ({ +export const getWalletForAccountById = ({ accountId, walletId, }: { @@ -34,15 +33,11 @@ export const getWalletForAccountById = async ({ walletId: WalletId }): Promise => { const wallets = WalletsRepository() - const wallet = await wallets.findById(walletId) - if (wallet instanceof Error) return wallet - - if (wallet.accountId !== accountId) { - return new CouldNotFindWalletFromIdError() - } - - return wallet + return wallets.findForAccountById({ + accountId, + walletId, + }) } export const listWalletsByAccountId = async ( diff --git a/core/api/src/domain/bitcoin/lightning/index.types.d.ts b/core/api/src/domain/bitcoin/lightning/index.types.d.ts index d69cbba748..13a27e9dd8 100644 --- a/core/api/src/domain/bitcoin/lightning/index.types.d.ts +++ b/core/api/src/domain/bitcoin/lightning/index.types.d.ts @@ -110,7 +110,7 @@ type LnInvoice = { readonly paymentSecret: PaymentIdentifyingSecret | null readonly features: LnInvoiceFeature[] readonly expiresAt: Date - readonly isExpired: boolean // Should we remove this because it can become stale? + readonly isExpired: boolean } type RegisterInvoiceArgs = { diff --git a/core/api/src/domain/ledger/index.types.d.ts b/core/api/src/domain/ledger/index.types.d.ts index 61adf58e1e..7f2f9faf3a 100644 --- a/core/api/src/domain/ledger/index.types.d.ts +++ b/core/api/src/domain/ledger/index.types.d.ts @@ -236,10 +236,20 @@ interface ILedgerService { id: LedgerTransactionId, ): Promise | LedgerServiceError> + getTransactionForWalletById(args: { + walletId: WalletId + transactionId: LedgerTransactionId + }): Promise | LedgerServiceError> + getTransactionsByHash( paymentHash: PaymentHash | OnChainTxHash, ): Promise[] | LedgerServiceError> + getTransactionForWalletByPaymentHash(args: { + walletId: WalletId + paymentHash: PaymentHash + }): Promise | LedgerServiceError> + getTransactionsByWalletId( walletId: WalletId, ): Promise[] | LedgerServiceError> diff --git a/core/api/src/domain/wallet-invoices/index.types.d.ts b/core/api/src/domain/wallet-invoices/index.types.d.ts index 2f1e2399cd..460db0bd22 100644 --- a/core/api/src/domain/wallet-invoices/index.types.d.ts +++ b/core/api/src/domain/wallet-invoices/index.types.d.ts @@ -165,6 +165,11 @@ type WalletAddressReceiverArgs = { type WalletInvoicesPersistNewArgs = Omit +type WalletInvoiceFindForWalletByPaymentHashArgs = { + walletId: WalletId + paymentHash: PaymentHash +} + interface IWalletInvoicesRepository { persistNew: ( invoice: WalletInvoicesPersistNewArgs, @@ -178,6 +183,10 @@ interface IWalletInvoicesRepository { paymentHash: PaymentHash, ) => Promise + findForWalletByPaymentHash: ( + args: WalletInvoiceFindForWalletByPaymentHashArgs, + ) => Promise + yieldPending: () => AsyncGenerator | RepositoryError deleteByPaymentHash: (paymentHash: PaymentHash) => Promise diff --git a/core/api/src/domain/wallets/index.types.d.ts b/core/api/src/domain/wallets/index.types.d.ts index 3e754bfd91..398d9265d3 100644 --- a/core/api/src/domain/wallets/index.types.d.ts +++ b/core/api/src/domain/wallets/index.types.d.ts @@ -178,6 +178,10 @@ interface IWalletsRepository { currency, }: NewWalletInfo): Promise findById(walletId: WalletId): Promise + findForAccountById(args: { + accountId: AccountId + walletId: WalletId + }): Promise listByAccountId(accountId: AccountId): Promise findAccountWalletsByAccountId( accountId: AccountId, diff --git a/core/api/src/graphql/shared/types/object/ln-invoice.ts b/core/api/src/graphql/shared/types/object/ln-invoice.ts index d2009011f5..0e4defab7c 100644 --- a/core/api/src/graphql/shared/types/object/ln-invoice.ts +++ b/core/api/src/graphql/shared/types/object/ln-invoice.ts @@ -34,8 +34,8 @@ const LnInvoice = GT.Object({ paymentStatus: { type: GT.NonNull(InvoicePaymentStatus), resolve: (source) => { - const statusCheker = WalletInvoiceStatusChecker(source) - const status = statusCheker.status(new Date()) + const statusChecker = WalletInvoiceStatusChecker(source) + const status = statusChecker.status(new Date()) return status }, }, diff --git a/core/api/src/graphql/shared/types/object/ln-noamount-invoice.ts b/core/api/src/graphql/shared/types/object/ln-noamount-invoice.ts index 2661946a08..9c3772efac 100644 --- a/core/api/src/graphql/shared/types/object/ln-noamount-invoice.ts +++ b/core/api/src/graphql/shared/types/object/ln-noamount-invoice.ts @@ -28,8 +28,8 @@ const LnNoAmountInvoice = GT.Object({ paymentStatus: { type: GT.NonNull(InvoicePaymentStatus), resolve: (source) => { - const statusCheker = WalletInvoiceStatusChecker(source) - const status = statusCheker.status(new Date()) + const statusChecker = WalletInvoiceStatusChecker(source) + const status = statusChecker.status(new Date()) return status }, }, diff --git a/core/api/src/services/ledger/index.ts b/core/api/src/services/ledger/index.ts index 91010a61b9..44853f2ddc 100644 --- a/core/api/src/services/ledger/index.ts +++ b/core/api/src/services/ledger/index.ts @@ -88,6 +88,29 @@ export const LedgerService = (): ILedgerService => { } } + const getTransactionForWalletById = async ({ + walletId, + transactionId, + }: { + walletId: WalletId + transactionId: LedgerTransactionId + }): Promise | LedgerServiceError> => { + const liabilitiesWalletId = toLiabilitiesWalletId(walletId) + try { + const _id = toObjectId(transactionId) + const { results } = await MainBook.ledger({ + account: liabilitiesWalletId, + _id, + }) + if (results.length === 1) { + return translateToLedgerTx(results[0]) + } + return new CouldNotFindTransactionError() + } catch (err) { + return new UnknownLedgerError(err) + } + } + const getTransactionsByHash = async ( hash: PaymentHash | OnChainTxHash, ): Promise[] | LedgerServiceError> => { @@ -104,6 +127,28 @@ export const LedgerService = (): ILedgerService => { } } + const getTransactionForWalletByPaymentHash = async ({ + walletId, + paymentHash, + }: { + walletId: WalletId + paymentHash: PaymentHash + }): Promise | LedgerError> => { + const liabilitiesWalletId = toLiabilitiesWalletId(walletId) + try { + const { results } = await MainBook.ledger({ + account: liabilitiesWalletId, + hash: paymentHash, + }) + if (results.length === 1) { + return translateToLedgerTx(results[0]) + } + return new CouldNotFindTransactionError() + } catch (err) { + return new UnknownLedgerError(err) + } + } + const getTransactionsByWalletId = async ( walletId: WalletId, ): Promise[] | LedgerError> => { @@ -414,7 +459,9 @@ export const LedgerService = (): ILedgerService => { fns: { updateMetadataByHash, getTransactionById, + getTransactionForWalletById, getTransactionsByHash, + getTransactionForWalletByPaymentHash, getTransactionsByWalletId, getTransactionsByWalletIds, getTransactionsByWalletIdAndContactUsername, diff --git a/core/api/src/services/mongoose/wallet-invoices.ts b/core/api/src/services/mongoose/wallet-invoices.ts index 4e29b92196..e31ee037f4 100644 --- a/core/api/src/services/mongoose/wallet-invoices.ts +++ b/core/api/src/services/mongoose/wallet-invoices.ts @@ -75,6 +75,23 @@ export const WalletInvoicesRepository = (): IWalletInvoicesRepository => { } } + const findForWalletByPaymentHash = async ({ + walletId, + paymentHash, + }: WalletInvoiceFindForWalletByPaymentHashArgs): Promise< + WalletInvoice | RepositoryError + > => { + try { + const walletInvoice = await WalletInvoice.findOne({ _id: paymentHash, walletId }) + if (!walletInvoice) { + return new CouldNotFindWalletInvoiceError(paymentHash) + } + return ensureWalletInvoiceHasLnInvoice(walletInvoiceFromRaw(walletInvoice)) + } catch (err) { + return parseRepositoryError(err) + } + } + async function* yieldPending(): | AsyncGenerator | RepositoryError { @@ -124,6 +141,7 @@ export const WalletInvoicesRepository = (): IWalletInvoicesRepository => { persistNew, markAsPaid, findByPaymentHash, + findForWalletByPaymentHash, yieldPending, deleteByPaymentHash, deleteUnpaidOlderThan, diff --git a/core/api/src/services/mongoose/wallets.ts b/core/api/src/services/mongoose/wallets.ts index 29fdce80a6..1cd9a05900 100644 --- a/core/api/src/services/mongoose/wallets.ts +++ b/core/api/src/services/mongoose/wallets.ts @@ -51,6 +51,27 @@ export const WalletsRepository = (): IWalletsRepository => { } } + const findForAccountById = async ({ + accountId, + walletId, + }: { + accountId: AccountId + walletId: WalletId + }): Promise => { + try { + const result: WalletRecord | null = await Wallet.findOne({ + id: walletId, + accountId, + }) + if (!result) { + return new CouldNotFindWalletFromIdError() + } + return resultToWallet(result) + } catch (err) { + return parseRepositoryError(err) + } + } + const listByAccountId = async ( accountId: AccountId, ): Promise => { @@ -146,6 +167,7 @@ export const WalletsRepository = (): IWalletsRepository => { return { findById, + findForAccountById, listByAccountId, findAccountWalletsByAccountId, findByAddress,