Skip to content

Commit

Permalink
feat: add pending tx queries
Browse files Browse the repository at this point in the history
  • Loading branch information
UncleSamtoshi committed Nov 2, 2023
1 parent 96dfbfa commit a1e0317
Show file tree
Hide file tree
Showing 17 changed files with 541 additions and 2 deletions.
31 changes: 31 additions & 0 deletions core/api/dev/apollo-federation/supergraph.graphql
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,7 @@ interface Account
level: AccountLevel!
limits: AccountLimits!
notificationSettings: NotificationSettings!
pendingTransactions(walletIds: [WalletId]): [Transaction!]!
realtimePrice: RealtimePrice!
transactions(
"""Returns the items in the list that come after the specified cursor."""
Expand Down Expand Up @@ -183,6 +184,11 @@ type BTCWallet implements Wallet

"""An unconfirmed incoming onchain balance."""
pendingIncomingBalance: SignedAmount!
pendingTransactions: [Transaction!]!
pendingTransactionsByAddress(
"""Returns the items that include this address."""
address: OnChainAddress!
): [Transaction!]!
transactionById(transactionId: ID!): Transaction!

"""A list of BTC transactions associated with this wallet."""
Expand Down Expand Up @@ -306,6 +312,7 @@ type ConsumerAccount implements Account
level: AccountLevel!
limits: AccountLimits!
notificationSettings: NotificationSettings!
pendingTransactions(walletIds: [WalletId]): [Transaction!]!

"""List the quiz questions of the consumer account"""
quiz: [Quiz!]!
Expand Down Expand Up @@ -1617,6 +1624,11 @@ type UsdWallet implements Wallet

"""An unconfirmed incoming onchain balance."""
pendingIncomingBalance: SignedAmount!
pendingTransactions: [Transaction!]!
pendingTransactionsByAddress(
"""Returns the items that include this address."""
address: OnChainAddress!
): [Transaction!]!
transactionById(transactionId: ID!): Transaction!
transactions(
"""Returns the items in the list that come after the specified cursor."""
Expand Down Expand Up @@ -1922,6 +1934,25 @@ interface Wallet
paymentHash: PaymentHash!
): Invoice!
pendingIncomingBalance: SignedAmount!

"""
Pending OnChain transactions. When transactions
are confirmed they will receive a new id and be found in the transactions
list. Transactions are ordered anti-chronologically,
ie: the newest transaction will be first
"""
pendingTransactions: [Transaction!]!

"""
Pending OnChain transactions. When transactions
are confirmed they will receive a new id and be found in the transactions
list. Transactions are ordered anti-chronologically,
ie: the newest transaction will be first
"""
pendingTransactionsByAddress(
"""Returns the items that include this address."""
address: OnChainAddress!
): [Transaction!]!
transactionById(transactionId: ID!): Transaction!

"""
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
import { getPendingOnChainTransactionsForWallets } from "../wallets/get-pending-onchain-transactions-for-wallets"

import { AccountValidator } from "@/domain/accounts"
import { RepositoryError } from "@/domain/errors"
import { WalletsRepository } from "@/services/mongoose"
import { checkedToWalletId } from "@/domain/wallets"

export const getPendingOnChainTransactionsForAccountByWalletIds = async ({
account,
walletIds,
}: {
account: Account
walletIds: string[]
}): Promise<WalletOnChainSettledTransaction[] | ApplicationError> => {
const walletsRepo = WalletsRepository()

const wallets: Wallet[] = []
for (const uncheckedWalletId of walletIds) {
const walletId = checkedToWalletId(uncheckedWalletId)
if (walletId instanceof Error) return walletId
const wallet = await walletsRepo.findById(walletId)
if (wallet instanceof RepositoryError) return wallet

const accountValidator = AccountValidator(account)
if (accountValidator instanceof Error) return accountValidator
const validateWallet = accountValidator.validateWalletForAccount(wallet)
if (validateWallet instanceof Error) return validateWallet

wallets.push(wallet)
}

return getPendingOnChainTransactionsForWallets({ wallets })
}
1 change: 1 addition & 0 deletions core/api/src/app/accounts/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,7 @@ export * from "./disable-notification-category"
export * from "./enable-notification-category"
export * from "./enable-notification-channel"
export * from "./disable-notification-channel"
export * from "./get-pending-onchain-transactions-for-account"

const accounts = AccountsRepository()

Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
import { CouldNotFindError } from "@/domain/errors"

import { WalletOnChainPendingReceiveRepository } from "@/services/mongoose"

export const getPendingOnChainTransactionsForWallets = async ({
wallets,
}: {
wallets: Wallet[]
}): Promise<WalletOnChainSettledTransaction[] | ApplicationError> => {
const walletIds = wallets.map((wallet) => wallet.id)

const pendingHistory = await WalletOnChainPendingReceiveRepository().listByWalletIds({
walletIds,
})

if (pendingHistory instanceof CouldNotFindError) {
return []
}

return pendingHistory
}
25 changes: 25 additions & 0 deletions core/api/src/app/wallets/get-pending-transactions-by-addresses.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
import { CouldNotFindError } from "@/domain/errors"

import { WalletOnChainPendingReceiveRepository } from "@/services/mongoose"

export const getPendingTransactionsForWalletsByAddresses = async ({
wallets,
addresses,
}: {
wallets: Wallet[]
addresses: OnChainAddress[]
}): Promise<WalletOnChainSettledTransaction[] | ApplicationError> => {
const walletIds = wallets.map((wallet) => wallet.id)

const pendingHistory =
await WalletOnChainPendingReceiveRepository().listByWalletIdsAndAddresses({
walletIds,
addresses,
})

if (pendingHistory instanceof CouldNotFindError) {
return []
}

return pendingHistory
}
2 changes: 2 additions & 0 deletions core/api/src/app/wallets/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,8 @@ export * from "./update-legacy-on-chain-receipt"
export * from "./update-pending-invoices"
export * from "./validate"
export * from "./get-invoice-for-wallet-by-hash"
export * from "./get-pending-onchain-transactions-for-wallets"
export * from "./get-pending-transactions-by-addresses"

import { WalletsRepository } from "@/services/mongoose"

Expand Down
29 changes: 29 additions & 0 deletions core/api/src/graphql/admin/schema.graphql
Original file line number Diff line number Diff line change
Expand Up @@ -85,6 +85,11 @@ type BTCWallet implements Wallet {

"""An unconfirmed incoming onchain balance."""
pendingIncomingBalance: SignedAmount!
pendingTransactions: [Transaction!]!
pendingTransactionsByAddress(
"""Returns the items that include this address."""
address: OnChainAddress!
): [Transaction!]!
transactionById(transactionId: ID!): Transaction!

"""A list of BTC transactions associated with this wallet."""
Expand Down Expand Up @@ -424,6 +429,11 @@ type UsdWallet implements Wallet {

"""An unconfirmed incoming onchain balance."""
pendingIncomingBalance: SignedAmount!
pendingTransactions: [Transaction!]!
pendingTransactionsByAddress(
"""Returns the items that include this address."""
address: OnChainAddress!
): [Transaction!]!
transactionById(transactionId: ID!): Transaction!
transactions(
"""Returns the items in the list that come after the specified cursor."""
Expand Down Expand Up @@ -480,6 +490,25 @@ interface Wallet {
paymentHash: PaymentHash!
): Invoice!
pendingIncomingBalance: SignedAmount!

"""
Pending OnChain transactions. When transactions
are confirmed they will receive a new id and be found in the transactions
list. Transactions are ordered anti-chronologically,
ie: the newest transaction will be first
"""
pendingTransactions: [Transaction!]!

"""
Pending OnChain transactions. When transactions
are confirmed they will receive a new id and be found in the transactions
list. Transactions are ordered anti-chronologically,
ie: the newest transaction will be first
"""
pendingTransactionsByAddress(
"""Returns the items that include this address."""
address: OnChainAddress!
): [Transaction!]!
transactionById(transactionId: ID!): Transaction!

"""
Expand Down
31 changes: 31 additions & 0 deletions core/api/src/graphql/public/schema.graphql
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ interface Account {
level: AccountLevel!
limits: AccountLimits!
notificationSettings: NotificationSettings!
pendingTransactions(walletIds: [WalletId]): [Transaction!]!
realtimePrice: RealtimePrice!
transactions(
"""Returns the items in the list that come after the specified cursor."""
Expand Down Expand Up @@ -126,6 +127,11 @@ type BTCWallet implements Wallet {

"""An unconfirmed incoming onchain balance."""
pendingIncomingBalance: SignedAmount!
pendingTransactions: [Transaction!]!
pendingTransactionsByAddress(
"""Returns the items that include this address."""
address: OnChainAddress!
): [Transaction!]!
transactionById(transactionId: ID!): Transaction!

"""A list of BTC transactions associated with this wallet."""
Expand Down Expand Up @@ -227,6 +233,7 @@ type ConsumerAccount implements Account {
level: AccountLevel!
limits: AccountLimits!
notificationSettings: NotificationSettings!
pendingTransactions(walletIds: [WalletId]): [Transaction!]!

"""List the quiz questions of the consumer account"""
quiz: [Quiz!]!
Expand Down Expand Up @@ -1269,6 +1276,11 @@ type UsdWallet implements Wallet {

"""An unconfirmed incoming onchain balance."""
pendingIncomingBalance: SignedAmount!
pendingTransactions: [Transaction!]!
pendingTransactionsByAddress(
"""Returns the items that include this address."""
address: OnChainAddress!
): [Transaction!]!
transactionById(transactionId: ID!): Transaction!
transactions(
"""Returns the items in the list that come after the specified cursor."""
Expand Down Expand Up @@ -1510,6 +1522,25 @@ interface Wallet {
paymentHash: PaymentHash!
): Invoice!
pendingIncomingBalance: SignedAmount!

"""
Pending OnChain transactions. When transactions
are confirmed they will receive a new id and be found in the transactions
list. Transactions are ordered anti-chronologically,
ie: the newest transaction will be first
"""
pendingTransactions: [Transaction!]!

"""
Pending OnChain transactions. When transactions
are confirmed they will receive a new id and be found in the transactions
list. Transactions are ordered anti-chronologically,
ie: the newest transaction will be first
"""
pendingTransactionsByAddress(
"""Returns the items that include this address."""
address: OnChainAddress!
): [Transaction!]!
transactionById(transactionId: ID!): Transaction!

"""
Expand Down
12 changes: 11 additions & 1 deletion core/api/src/graphql/public/types/abstract/account.ts
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,9 @@ import WalletId from "@/graphql/shared/types/scalar/wallet-id"
import AccountLimits from "@/graphql/public/types/object/account-limits"
import RealtimePrice from "@/graphql/public/types/object/realtime-price"
import DisplayCurrency from "@/graphql/shared/types/scalar/display-currency"
import { TransactionConnection } from "@/graphql/shared/types/object/transaction"
import Transaction, {
TransactionConnection,
} from "@/graphql/shared/types/object/transaction"

const IAccount = GT.Interface({
name: "Account",
Expand Down Expand Up @@ -59,6 +61,14 @@ const IAccount = GT.Interface({
},
},
},
pendingTransactions: {
type: GT.NonNullList(Transaction),
args: {
walletIds: {
type: GT.List(WalletId),
},
},
},
notificationSettings: {
type: GT.NonNull(NotificationSettings),
},
Expand Down
33 changes: 32 additions & 1 deletion core/api/src/graphql/public/types/object/consumer-account.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,8 @@
import AccountLevel from "../../../shared/types/scalar/account-level"

import { TransactionConnection } from "../../../shared/types/object/transaction"
import Transaction, {
TransactionConnection,
} from "../../../shared/types/object/transaction"

import AccountLimits from "./account-limits"

Expand Down Expand Up @@ -206,6 +208,35 @@ const ConsumerAccount = GT.Object<Account, GraphQLPublicContextAuth>({
)
},
},
pendingTransactions: {
type: GT.NonNullList(Transaction),
args: {
walletIds: {
type: GT.List(WalletId),
},
},
resolve: async (source, args) => {
let { walletIds } = args

if (!walletIds) {
const wallets = await WalletsRepository().listByAccountId(source.id)
if (wallets instanceof Error) {
throw mapError(wallets)
}
walletIds = wallets.map((wallet) => wallet.id)
}

const transactions =
await Accounts.getPendingOnChainTransactionsForAccountByWalletIds({
account: source,
walletIds,
})
if (transactions instanceof Error) {
throw mapError(transactions)
}
return transactions
},
},

notificationSettings: {
type: GT.NonNull(NotificationSettings),
Expand Down
20 changes: 20 additions & 0 deletions core/api/src/graphql/shared/types/abstract/wallet.ts
Original file line number Diff line number Diff line change
Expand Up @@ -48,6 +48,26 @@ const IWallet = GT.Interface({
},
},
},
pendingTransactionsByAddress: {
description: dedent`Pending OnChain transactions. When transactions
are confirmed they will receive a new id and be found in the transactions
list. Transactions are ordered anti-chronologically,
ie: the newest transaction will be first`,
type: GT.NonNullList(Transaction),
args: {
address: {
type: GT.NonNull(OnChainAddress),
description: "Returns the items that include this address.",
},
},
},
pendingTransactions: {
description: dedent`Pending OnChain transactions. When transactions
are confirmed they will receive a new id and be found in the transactions
list. Transactions are ordered anti-chronologically,
ie: the newest transaction will be first`,
type: GT.NonNullList(Transaction),
},
invoiceByPaymentHash: {
type: GT.NonNull(IInvoice),
args: {
Expand Down
Loading

0 comments on commit a1e0317

Please sign in to comment.