wallet-core: allow inclusion of refreshes in transactions list
This commit is contained in:
parent
97fac057c2
commit
55f868d5e8
@ -68,6 +68,11 @@ export interface TransactionsRequest {
|
||||
* if present, results will be limited to transactions related to the given search string
|
||||
*/
|
||||
search?: string;
|
||||
|
||||
/**
|
||||
* If true, include all refreshes in the transactions list.
|
||||
*/
|
||||
includeRefreshes?: boolean;
|
||||
}
|
||||
|
||||
export interface TransactionsResponse {
|
||||
@ -514,11 +519,6 @@ export interface TransactionTip extends TransactionCommon {
|
||||
export interface TransactionRefresh extends TransactionCommon {
|
||||
type: TransactionType.Refresh;
|
||||
|
||||
/**
|
||||
* Exchange that the coins are refreshed with
|
||||
*/
|
||||
exchangeBaseUrl: string;
|
||||
|
||||
refreshReason: RefreshReason;
|
||||
|
||||
/**
|
||||
|
@ -381,7 +381,8 @@ walletCli
|
||||
const transactionsCli = walletCli
|
||||
.subcommand("transactions", "transactions", { help: "Manage transactions." })
|
||||
.maybeOption("currency", ["--currency"], clk.STRING)
|
||||
.maybeOption("search", ["--search"], clk.STRING);
|
||||
.maybeOption("search", ["--search"], clk.STRING)
|
||||
.flag("includeRefreshes", ["--include-refreshes"]);
|
||||
|
||||
// Default action
|
||||
transactionsCli.action(async (args) => {
|
||||
@ -391,6 +392,7 @@ transactionsCli.action(async (args) => {
|
||||
{
|
||||
currency: args.transactions.currency,
|
||||
search: args.transactions.search,
|
||||
includeRefreshes: args.transactions.includeRefreshes,
|
||||
},
|
||||
);
|
||||
console.log(JSON.stringify(pending, undefined, 2));
|
||||
|
@ -56,6 +56,8 @@ import {
|
||||
PeerPullPaymentIncomingStatus,
|
||||
TransactionStatus,
|
||||
WithdrawalGroupStatus,
|
||||
RefreshGroupRecord,
|
||||
RefreshOperationStatus,
|
||||
} from "../db.js";
|
||||
import { InternalWalletState } from "../internal-wallet-state.js";
|
||||
import { checkDbInvariant } from "../util/invariants.js";
|
||||
@ -580,6 +582,45 @@ function buildTransactionForManualWithdraw(
|
||||
};
|
||||
}
|
||||
|
||||
function buildTransactionForRefresh(
|
||||
refreshGroupRecord: RefreshGroupRecord,
|
||||
ort?: OperationRetryRecord,
|
||||
): Transaction {
|
||||
let extendedStatus: ExtendedStatus;
|
||||
switch (refreshGroupRecord.operationStatus) {
|
||||
case RefreshOperationStatus.Finished:
|
||||
case RefreshOperationStatus.FinishedWithError:
|
||||
extendedStatus = ExtendedStatus.Done;
|
||||
break;
|
||||
default:
|
||||
extendedStatus = ExtendedStatus.Pending;
|
||||
}
|
||||
return {
|
||||
type: TransactionType.Refresh,
|
||||
refreshReason: refreshGroupRecord.reason,
|
||||
amountEffective: Amounts.stringify(
|
||||
Amounts.zeroOfCurrency(refreshGroupRecord.currency),
|
||||
),
|
||||
amountRaw: Amounts.stringify(
|
||||
Amounts.zeroOfCurrency(refreshGroupRecord.currency),
|
||||
),
|
||||
extendedStatus:
|
||||
refreshGroupRecord.operationStatus === RefreshOperationStatus.Finished ||
|
||||
refreshGroupRecord.operationStatus ===
|
||||
RefreshOperationStatus.FinishedWithError
|
||||
? ExtendedStatus.Done
|
||||
: ExtendedStatus.Pending,
|
||||
pending: extendedStatus == ExtendedStatus.Pending,
|
||||
timestamp: refreshGroupRecord.timestampCreated,
|
||||
transactionId: makeTransactionId(
|
||||
TransactionType.Refresh,
|
||||
refreshGroupRecord.refreshGroupId,
|
||||
),
|
||||
frozen: false,
|
||||
...(ort?.lastError ? { error: ort.lastError } : {}),
|
||||
};
|
||||
}
|
||||
|
||||
function buildTransactionForDeposit(
|
||||
dg: DepositGroupRecord,
|
||||
ort?: OperationRetryRecord,
|
||||
@ -880,6 +921,7 @@ export async function getTransactions(
|
||||
x.tips,
|
||||
x.tombstones,
|
||||
x.withdrawalGroups,
|
||||
x.refreshGroups,
|
||||
])
|
||||
.runReadOnly(async (tx) => {
|
||||
tx.peerPushPaymentInitiations.iter().forEachAsync(async (pi) => {
|
||||
@ -916,6 +958,17 @@ export async function getTransactions(
|
||||
transactions.push(buildTransactionForPullPaymentDebit(pi));
|
||||
});
|
||||
|
||||
if (transactionsRequest?.includeRefreshes) {
|
||||
tx.refreshGroups.iter().forEachAsync(async (rg) => {
|
||||
if (shouldSkipCurrency(transactionsRequest, rg.currency)) {
|
||||
return;
|
||||
}
|
||||
const opId = RetryTags.forRefresh(rg);
|
||||
const ort = await tx.operationRetries.get(opId);
|
||||
transactions.push(buildTransactionForRefresh(rg, ort));
|
||||
});
|
||||
}
|
||||
|
||||
tx.withdrawalGroups.iter().forEachAsync(async (wsr) => {
|
||||
if (
|
||||
shouldSkipCurrency(
|
||||
|
@ -110,7 +110,7 @@ export function TransactionItem(props: { tx: Transaction }): VNode {
|
||||
id={tx.transactionId}
|
||||
amount={tx.amountEffective}
|
||||
debitCreditIndicator={"credit"}
|
||||
title={new URL(tx.exchangeBaseUrl).hostname}
|
||||
title={"Refresh"}
|
||||
timestamp={AbsoluteTime.fromTimestamp(tx.timestamp)}
|
||||
iconPath={"R"}
|
||||
// pending={tx.pending}
|
||||
|
@ -21,6 +21,7 @@
|
||||
|
||||
import {
|
||||
PaymentStatus,
|
||||
RefreshReason,
|
||||
ScopeType,
|
||||
TalerProtocolTimestamp,
|
||||
TransactionCommon,
|
||||
@ -90,6 +91,7 @@ const exampleData = {
|
||||
totalRefundRaw: "USD:0",
|
||||
proposalId: "1EMJJH8EP1NX3XF7733NCYS2DBEJW4Q2KA5KEB37MCQJQ8Q5HMC0",
|
||||
status: PaymentStatus.Accepted,
|
||||
refundQueryActive: false,
|
||||
} as TransactionPayment,
|
||||
deposit: {
|
||||
...commonTransaction(),
|
||||
@ -101,6 +103,7 @@ const exampleData = {
|
||||
...commonTransaction(),
|
||||
type: TransactionType.Refresh,
|
||||
exchangeBaseUrl: "http://exchange.taler",
|
||||
refreshReason: RefreshReason.PayMerchant,
|
||||
} as TransactionRefresh,
|
||||
tip: {
|
||||
...commonTransaction(),
|
||||
|
@ -23,6 +23,7 @@ import {
|
||||
AbsoluteTime,
|
||||
ExtendedStatus,
|
||||
PaymentStatus,
|
||||
RefreshReason,
|
||||
TalerProtocolTimestamp,
|
||||
TransactionCommon,
|
||||
TransactionDeposit,
|
||||
@ -111,6 +112,7 @@ const exampleData = {
|
||||
totalRefundRaw: "KUDOS:0",
|
||||
proposalId: "1EMJJH8EP1NX3XF7733NCYS2DBEJW4Q2KA5KEB37MCQJQ8Q5HMC0",
|
||||
status: PaymentStatus.Accepted,
|
||||
refundQueryActive: false,
|
||||
} as TransactionPayment,
|
||||
deposit: {
|
||||
...commonTransaction,
|
||||
@ -125,6 +127,7 @@ const exampleData = {
|
||||
...commonTransaction,
|
||||
type: TransactionType.Refresh,
|
||||
exchangeBaseUrl: "http://exchange.taler",
|
||||
refreshReason: RefreshReason.Manual,
|
||||
} as TransactionRefresh,
|
||||
tip: {
|
||||
...commonTransaction,
|
||||
|
@ -729,7 +729,7 @@ export function TransactionView({
|
||||
total={effective}
|
||||
kind="negative"
|
||||
>
|
||||
{transaction.exchangeBaseUrl}
|
||||
{"Refresh"}
|
||||
</Header>
|
||||
<Part
|
||||
title={i18n.str`Details`}
|
||||
|
Loading…
Reference in New Issue
Block a user