diff --git a/packages/backend/src/accounting/psql/service.ts b/packages/backend/src/accounting/psql/service.ts index 81d4709cb0..a0e04e6c1d 100644 --- a/packages/backend/src/accounting/psql/service.ts +++ b/packages/backend/src/accounting/psql/service.ts @@ -13,7 +13,8 @@ import { Transaction, TransferOptions, TransferToCreate, - Withdrawal + Withdrawal, + GetLedgerTransfersResult } from '../service' import { getAccountBalances } from './balance' import { @@ -30,10 +31,10 @@ import { createTransfers, CreateTransfersResult, postTransfers, - voidTransfers + voidTransfers, + getAccountTransfers } from './ledger-transfer' import { LedgerTransfer, LedgerTransferType } from './ledger-transfer/model' -import { AccountId, AccountUserData128 } from '../tigerbeetle/utils' export interface ServiceDependencies extends BaseService { knex: TransactionOrKnex @@ -71,10 +72,28 @@ export function createAccountingService( createDeposit: (transfer, trx) => createAccountDeposit(deps, transfer, trx), createWithdrawal: (transfer) => createAccountWithdrawal(deps, transfer), postWithdrawal: (withdrawalRef) => postTransfers(deps, [withdrawalRef]), - voidWithdrawal: (withdrawalRef) => voidTransfers(deps, [withdrawalRef]) + voidWithdrawal: (withdrawalRef) => voidTransfers(deps, [withdrawalRef]), + getAccountTransfers: (id, trx) => getAccountTransfersAndMap(deps, id, trx) } } +async function getAccountTransfersAndMap( + deps: ServiceDependencies, + id: string, + trx?: TransactionOrKnex +): Promise { + const accountTransfers = await getAccountTransfers(deps, id, trx) + const returnVal = { credits: [], debits: [] } + if ( + !accountTransfers || + (accountTransfers.credits.length === 0 && + accountTransfers.debits.length === 0) + ) + return returnVal + + return returnVal +} + export async function createLiquidityAccount( deps: ServiceDependencies, account: LiquidityAccount, @@ -96,7 +115,7 @@ export async function createLiquidityAccount( export async function createSettlementAccount( deps: ServiceDependencies, ledger: number, - accountId: AccountUserData128, + accountId: string | number, trx?: TransactionOrKnex ): Promise { const asset = await Asset.query(trx || deps.knex).findOne({ ledger }) diff --git a/packages/backend/src/accounting/service.ts b/packages/backend/src/accounting/service.ts index 5725807661..3fbbaf88b4 100644 --- a/packages/backend/src/accounting/service.ts +++ b/packages/backend/src/accounting/service.ts @@ -1,7 +1,6 @@ import { TransactionOrKnex } from 'objection' import { BaseService } from '../shared/baseService' import { TransferError, isTransferError } from './errors' -import { AccountUserData128 } from './tigerbeetle/utils' export enum LiquidityAccountType { ASSET = 'ASSET', @@ -68,6 +67,19 @@ export interface Transaction { void: () => Promise } +export interface GetLedgerTransfersResult { + debits: LedgerTransfer[] + credits: LedgerTransfer[] +} + +export interface LedgerTransfer extends BaseTransfer { + debitAccount: string + creditAccount: string + amount: bigint + timeout: number + timestamp: bigint +} + export interface AccountingService { createLiquidityAccount( account: LiquidityAccount, @@ -76,7 +88,7 @@ export interface AccountingService { ): Promise createSettlementAccount( ledger: number, - accountId: AccountUserData128, + accountId: string | number, trx?: TransactionOrKnex ): Promise createLiquidityAndLinkedSettlementAccount( @@ -98,6 +110,10 @@ export interface AccountingService { createWithdrawal(withdrawal: Withdrawal): Promise postWithdrawal(id: string): Promise voidWithdrawal(id: string): Promise + getAccountTransfers( + id: string, + trx?: TransactionOrKnex + ): Promise } export interface TransferToCreate { diff --git a/packages/backend/src/accounting/tigerbeetle/service.ts b/packages/backend/src/accounting/tigerbeetle/service.ts index 2f65510209..1d72937ef8 100644 --- a/packages/backend/src/accounting/tigerbeetle/service.ts +++ b/packages/backend/src/accounting/tigerbeetle/service.ts @@ -26,8 +26,12 @@ import { TigerbeetleUnknownAccountError, areAllAccountExistsErrors } from './errors' -import { NewTransferOptions, createTransfers } from './transfers' -import { AccountUserData128, toTigerBeetleId, hexTextToBigInt } from './utils' +import { + NewTransferOptions, + createTransfers, + getAccountTransfers +} from './transfers' +import { toTigerBeetleId, hexTextToBigInt } from './utils' export enum TigerBeetleAccountCode { LIQUIDITY_WEB_MONETIZATION = 1, @@ -105,7 +109,8 @@ export function createAccountingService( createDeposit: (transfer) => createAccountDeposit(deps, transfer), createWithdrawal: (transfer) => createAccountWithdrawal(deps, transfer), postWithdrawal: (options) => postAccountWithdrawal(deps, options), - voidWithdrawal: (options) => voidAccountWithdrawal(deps, options) + voidWithdrawal: (options) => voidAccountWithdrawal(deps, options), + getAccountTransfers: (id) => getAccountTransfers(deps, id) } } @@ -141,7 +146,7 @@ export async function createLiquidityAccount( export async function createSettlementAccount( deps: ServiceDependencies, ledger: number, - accountId: AccountUserData128 + accountId: string | number ): Promise { try { await createAccounts(deps, [ diff --git a/packages/backend/src/accounting/tigerbeetle/transfers.ts b/packages/backend/src/accounting/tigerbeetle/transfers.ts index 2a23a9f040..15ea95621b 100644 --- a/packages/backend/src/accounting/tigerbeetle/transfers.ts +++ b/packages/backend/src/accounting/tigerbeetle/transfers.ts @@ -1,14 +1,17 @@ import { CreateTransferError as CreateTransferErrorCode, Transfer as TbTransfer, - TransferFlags + TransferFlags, + AccountFilter, + AccountFilterFlags } from 'tigerbeetle-node' import { v4 as uuid } from 'uuid' import { TransferError } from '../errors' import { TigerbeetleCreateTransferError } from './errors' import { ServiceDependencies, TigerBeetleTransferCode } from './service' -import { AccountId, toTigerBeetleId } from './utils' +import { AccountId, toTigerBeetleId, tbTransferToLedgerTransfer } from './utils' +import { GetLedgerTransfersResult } from '../service' type TransfersError = { index: number @@ -163,3 +166,25 @@ export async function createTransfers( } } } + +export async function getAccountTransfers( + deps: ServiceDependencies, + id: string +): Promise { + const tbAccId = toTigerBeetleId(id) + const filter: AccountFilter = { + account_id: tbAccId, + timestamp_min: 0n, + timestamp_max: 0n, + limit: 100_000, + flags: AccountFilterFlags.credits | AccountFilterFlags.debits + } + const tbAccountTransfers = await deps.tigerBeetle.getAccountTransfers(filter) + const returnVal = { credits: [], debits: [] } as GetLedgerTransfersResult + tbAccountTransfers.forEach((item) => { + const converted = tbTransferToLedgerTransfer(item) + if (item.debit_account_id === tbAccId) returnVal.debits.push(converted) + else returnVal.credits.push(converted) + }) + return returnVal +} diff --git a/packages/backend/src/accounting/tigerbeetle/utils.ts b/packages/backend/src/accounting/tigerbeetle/utils.ts index 25fccd2b8c..180445a980 100644 --- a/packages/backend/src/accounting/tigerbeetle/utils.ts +++ b/packages/backend/src/accounting/tigerbeetle/utils.ts @@ -1,4 +1,6 @@ import { validateId } from '../../shared/utils' +import { Transfer as TbTransfer } from 'tigerbeetle-node/dist/bindings' +import { LedgerTransfer } from '../service' export type AccountId = string | number | bigint export type AccountUserData128 = AccountId @@ -17,3 +19,34 @@ export function uuidToBigInt(id: string): bigint { export function hexTextToBigInt(hex: string): bigint { return BigInt(`0x${hex}`) } + +export function fromTigerBeetleId(bi: bigint): string { + let str = bi.toString(16) + while (str.length < 32) str = '0' + str + + if (str.length === 32) + str = + str.substring(0, 8) + + '-' + + str.substring(8, 12) + + '-' + + str.substring(12, 16) + + '-' + + str.substring(16, 20) + + '-' + + str.substring(20) + return str +} + +export function tbTransferToLedgerTransfer( + tbTransfer: TbTransfer +): LedgerTransfer { + return { + amount: tbTransfer.amount, + creditAccount: fromTigerBeetleId(tbTransfer.credit_account_id), + debitAccount: fromTigerBeetleId(tbTransfer.debit_account_id), + timeout: tbTransfer.timeout, + timestamp: tbTransfer.timestamp + //TODO need to convert the rest... + } +} diff --git a/packages/backend/src/payment-method/ilp/connector/core/test/mocks/accounting-service.ts b/packages/backend/src/payment-method/ilp/connector/core/test/mocks/accounting-service.ts index 35f9a9b4bb..103a4d6371 100644 --- a/packages/backend/src/payment-method/ilp/connector/core/test/mocks/accounting-service.ts +++ b/packages/backend/src/payment-method/ilp/connector/core/test/mocks/accounting-service.ts @@ -4,7 +4,8 @@ import { Transaction, AccountingService, Deposit, - Withdrawal + Withdrawal, + GetLedgerTransfersResult } from '../../../../../../accounting/service' import { CreateAccountError, @@ -12,7 +13,6 @@ import { } from '../../../../../../accounting/errors' import { CreateAccountError as CreateAccountErrorCode } from 'tigerbeetle-node' import { TransactionOrKnex } from 'objection' -import { AccountUserData128 } from '../../../../../../accounting/tigerbeetle/utils' interface MockAccount { id: string @@ -150,7 +150,7 @@ export class MockAccountingService implements AccountingService { // eslint-disable-next-line @typescript-eslint/no-unused-vars ledger: number, // eslint-disable-next-line @typescript-eslint/no-unused-vars - accountId: AccountUserData128, + accountId: string | number, // eslint-disable-next-line @typescript-eslint/no-unused-vars trx?: TransactionOrKnex ): Promise { @@ -220,4 +220,11 @@ export class MockAccountingService implements AccountingService { ): Promise { throw new Error('Not implemented!') } + + getAccountTransfers( + // eslint-disable-next-line @typescript-eslint/no-unused-vars + id: string + ): Promise { + throw new Error('Not implemented!') + } }