summaryrefslogtreecommitdiff
path: root/packages/taler-wallet-core/src/util
diff options
context:
space:
mode:
authorFlorian Dold <florian@dold.me>2020-12-16 17:59:04 +0100
committerFlorian Dold <florian@dold.me>2020-12-16 17:59:04 +0100
commitbafb52edff4d56bcb9e3c3d0a260f507c517b08c (patch)
tree09b484a8cedc9893f5ea7593a98fadde075eafa3 /packages/taler-wallet-core/src/util
parentc09c5bbe625566fc61c811160d2ccdab263327fa (diff)
downloadwallet-core-bafb52edff4d56bcb9e3c3d0a260f507c517b08c.tar.gz
wallet-core-bafb52edff4d56bcb9e3c3d0a260f507c517b08c.tar.bz2
wallet-core-bafb52edff4d56bcb9e3c3d0a260f507c517b08c.zip
don't store reserve history anymore, adjust withdrawal implementation accordingly
Diffstat (limited to 'packages/taler-wallet-core/src/util')
-rw-r--r--packages/taler-wallet-core/src/util/query.ts2
-rw-r--r--packages/taler-wallet-core/src/util/reserveHistoryUtil-test.ts285
-rw-r--r--packages/taler-wallet-core/src/util/reserveHistoryUtil.ts363
3 files changed, 1 insertions, 649 deletions
diff --git a/packages/taler-wallet-core/src/util/query.ts b/packages/taler-wallet-core/src/util/query.ts
index e1a23b168..35aab81e9 100644
--- a/packages/taler-wallet-core/src/util/query.ts
+++ b/packages/taler-wallet-core/src/util/query.ts
@@ -583,7 +583,7 @@ export class Database {
}
async getIndexed<Ind extends Index<string, string, any, any>>(
- index: InferIndex<Ind>,
+ index: Ind,
key: IDBValidKey,
): Promise<IndexRecord<Ind> | undefined> {
const tx = this.db.transaction([index.storeName], "readonly");
diff --git a/packages/taler-wallet-core/src/util/reserveHistoryUtil-test.ts b/packages/taler-wallet-core/src/util/reserveHistoryUtil-test.ts
deleted file mode 100644
index 79022de77..000000000
--- a/packages/taler-wallet-core/src/util/reserveHistoryUtil-test.ts
+++ /dev/null
@@ -1,285 +0,0 @@
-/*
- This file is part of GNU Taler
- (C) 2020 Taler Systems S.A.
-
- GNU Taler is free software; you can redistribute it and/or modify it under the
- terms of the GNU General Public License as published by the Free Software
- Foundation; either version 3, or (at your option) any later version.
-
- GNU Taler is distributed in the hope that it will be useful, but WITHOUT ANY
- WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
- A PARTICULAR PURPOSE. See the GNU General Public License for more details.
-
- You should have received a copy of the GNU General Public License along with
- GNU Taler; see the file COPYING. If not, see <http://www.gnu.org/licenses/>
- */
-
-/**
- * Imports.
- */
-import test from "ava";
-import {
- reconcileReserveHistory,
- summarizeReserveHistory,
-} from "./reserveHistoryUtil";
-import {
- WalletReserveHistoryItem,
- WalletReserveHistoryItemType,
-} from "../types/dbTypes";
-import {
- ReserveTransaction,
- ReserveTransactionType,
-} from "../types/ReserveTransaction";
-import { Amounts } from "./amounts";
-
-test("basics", (t) => {
- const r = reconcileReserveHistory([], []);
- t.deepEqual(r.updatedLocalHistory, []);
-});
-
-test("unmatched credit", (t) => {
- const localHistory: WalletReserveHistoryItem[] = [];
- const remoteHistory: ReserveTransaction[] = [
- {
- type: ReserveTransactionType.Credit,
- amount: "TESTKUDOS:100",
- sender_account_url: "payto://void/",
- timestamp: { t_ms: 42 },
- wire_reference: "ABC01",
- },
- ];
- const r = reconcileReserveHistory(localHistory, remoteHistory);
- const s = summarizeReserveHistory(r.updatedLocalHistory, "TESTKUDOS");
- t.deepEqual(r.updatedLocalHistory.length, 1);
- t.deepEqual(Amounts.stringify(s.computedReserveBalance), "TESTKUDOS:100");
- t.deepEqual(Amounts.stringify(s.awaitedReserveAmount), "TESTKUDOS:0");
- t.deepEqual(Amounts.stringify(s.unclaimedReserveAmount), "TESTKUDOS:100");
-});
-
-test("unmatched credit #2", (t) => {
- const localHistory: WalletReserveHistoryItem[] = [];
- const remoteHistory: ReserveTransaction[] = [
- {
- type: ReserveTransactionType.Credit,
- amount: "TESTKUDOS:100",
- sender_account_url: "payto://void/",
- timestamp: { t_ms: 42 },
- wire_reference: "ABC01",
- },
- {
- type: ReserveTransactionType.Credit,
- amount: "TESTKUDOS:50",
- sender_account_url: "payto://void/",
- timestamp: { t_ms: 42 },
- wire_reference: "ABC02",
- },
- ];
- const r = reconcileReserveHistory(localHistory, remoteHistory);
- const s = summarizeReserveHistory(r.updatedLocalHistory, "TESTKUDOS");
- t.deepEqual(r.updatedLocalHistory.length, 2);
- t.deepEqual(Amounts.stringify(s.computedReserveBalance), "TESTKUDOS:150");
- t.deepEqual(Amounts.stringify(s.awaitedReserveAmount), "TESTKUDOS:0");
- t.deepEqual(Amounts.stringify(s.unclaimedReserveAmount), "TESTKUDOS:150");
-});
-
-test("matched credit", (t) => {
- const localHistory: WalletReserveHistoryItem[] = [
- {
- type: WalletReserveHistoryItemType.Credit,
- expectedAmount: Amounts.parseOrThrow("TESTKUDOS:100"),
- matchedExchangeTransaction: {
- type: ReserveTransactionType.Credit,
- amount: "TESTKUDOS:100",
- sender_account_url: "payto://void/",
- timestamp: { t_ms: 42 },
- wire_reference: "ABC01",
- },
- },
- ];
- const remoteHistory: ReserveTransaction[] = [
- {
- type: ReserveTransactionType.Credit,
- amount: "TESTKUDOS:100",
- sender_account_url: "payto://void/",
- timestamp: { t_ms: 42 },
- wire_reference: "ABC01",
- },
- {
- type: ReserveTransactionType.Credit,
- amount: "TESTKUDOS:50",
- sender_account_url: "payto://void/",
- timestamp: { t_ms: 42 },
- wire_reference: "ABC02",
- },
- ];
- const r = reconcileReserveHistory(localHistory, remoteHistory);
- const s = summarizeReserveHistory(r.updatedLocalHistory, "TESTKUDOS");
- t.deepEqual(r.updatedLocalHistory.length, 2);
- t.deepEqual(Amounts.stringify(s.computedReserveBalance), "TESTKUDOS:150");
- t.deepEqual(Amounts.stringify(s.awaitedReserveAmount), "TESTKUDOS:0");
- t.deepEqual(Amounts.stringify(s.unclaimedReserveAmount), "TESTKUDOS:150");
-});
-
-test("fulfilling credit", (t) => {
- const localHistory: WalletReserveHistoryItem[] = [
- {
- type: WalletReserveHistoryItemType.Credit,
- expectedAmount: Amounts.parseOrThrow("TESTKUDOS:100"),
- },
- ];
- const remoteHistory: ReserveTransaction[] = [
- {
- type: ReserveTransactionType.Credit,
- amount: "TESTKUDOS:100",
- sender_account_url: "payto://void/",
- timestamp: { t_ms: 42 },
- wire_reference: "ABC01",
- },
- {
- type: ReserveTransactionType.Credit,
- amount: "TESTKUDOS:50",
- sender_account_url: "payto://void/",
- timestamp: { t_ms: 42 },
- wire_reference: "ABC02",
- },
- ];
- const r = reconcileReserveHistory(localHistory, remoteHistory);
- const s = summarizeReserveHistory(r.updatedLocalHistory, "TESTKUDOS");
- t.deepEqual(r.updatedLocalHistory.length, 2);
- t.deepEqual(Amounts.stringify(s.computedReserveBalance), "TESTKUDOS:150");
-});
-
-test("unfulfilled credit", (t) => {
- const localHistory: WalletReserveHistoryItem[] = [
- {
- type: WalletReserveHistoryItemType.Credit,
- expectedAmount: Amounts.parseOrThrow("TESTKUDOS:100"),
- },
- ];
- const remoteHistory: ReserveTransaction[] = [
- {
- type: ReserveTransactionType.Credit,
- amount: "TESTKUDOS:100",
- sender_account_url: "payto://void/",
- timestamp: { t_ms: 42 },
- wire_reference: "ABC01",
- },
- {
- type: ReserveTransactionType.Credit,
- amount: "TESTKUDOS:50",
- sender_account_url: "payto://void/",
- timestamp: { t_ms: 42 },
- wire_reference: "ABC02",
- },
- ];
- const r = reconcileReserveHistory(localHistory, remoteHistory);
- const s = summarizeReserveHistory(r.updatedLocalHistory, "TESTKUDOS");
- t.deepEqual(r.updatedLocalHistory.length, 2);
- t.deepEqual(Amounts.stringify(s.computedReserveBalance), "TESTKUDOS:150");
-});
-
-test("awaited credit", (t) => {
- const localHistory: WalletReserveHistoryItem[] = [
- {
- type: WalletReserveHistoryItemType.Credit,
- expectedAmount: Amounts.parseOrThrow("TESTKUDOS:50"),
- },
- {
- type: WalletReserveHistoryItemType.Credit,
- expectedAmount: Amounts.parseOrThrow("TESTKUDOS:100"),
- },
- ];
- const remoteHistory: ReserveTransaction[] = [
- {
- type: ReserveTransactionType.Credit,
- amount: "TESTKUDOS:100",
- sender_account_url: "payto://void/",
- timestamp: { t_ms: 42 },
- wire_reference: "ABC01",
- },
- ];
- const r = reconcileReserveHistory(localHistory, remoteHistory);
- const s = summarizeReserveHistory(r.updatedLocalHistory, "TESTKUDOS");
- t.deepEqual(r.updatedLocalHistory.length, 2);
- t.deepEqual(Amounts.stringify(s.computedReserveBalance), "TESTKUDOS:100");
- t.deepEqual(Amounts.stringify(s.awaitedReserveAmount), "TESTKUDOS:50");
- t.deepEqual(Amounts.stringify(s.unclaimedReserveAmount), "TESTKUDOS:100");
-});
-
-test("withdrawal new match", (t) => {
- const localHistory: WalletReserveHistoryItem[] = [
- {
- type: WalletReserveHistoryItemType.Credit,
- expectedAmount: Amounts.parseOrThrow("TESTKUDOS:100"),
- matchedExchangeTransaction: {
- type: ReserveTransactionType.Credit,
- amount: "TESTKUDOS:100",
- sender_account_url: "payto://void/",
- timestamp: { t_ms: 42 },
- wire_reference: "ABC01",
- },
- },
- {
- type: WalletReserveHistoryItemType.Withdraw,
- expectedAmount: Amounts.parseOrThrow("TESTKUDOS:5"),
- },
- ];
- const remoteHistory: ReserveTransaction[] = [
- {
- type: ReserveTransactionType.Credit,
- amount: "TESTKUDOS:100",
- sender_account_url: "payto://void/",
- timestamp: { t_ms: 42 },
- wire_reference: "ABC01",
- },
- {
- type: ReserveTransactionType.Withdraw,
- amount: "TESTKUDOS:5",
- h_coin_envelope: "foobar",
- h_denom_pub: "foobar",
- reserve_sig: "foobar",
- withdraw_fee: "TESTKUDOS:0.1",
- },
- ];
- const r = reconcileReserveHistory(localHistory, remoteHistory);
- const s = summarizeReserveHistory(r.updatedLocalHistory, "TESTKUDOS");
- t.deepEqual(r.updatedLocalHistory.length, 2);
- t.deepEqual(Amounts.stringify(s.computedReserveBalance), "TESTKUDOS:95");
- t.deepEqual(Amounts.stringify(s.awaitedReserveAmount), "TESTKUDOS:0");
- t.deepEqual(Amounts.stringify(s.unclaimedReserveAmount), "TESTKUDOS:95");
-});
-
-test("claimed but now arrived", (t) => {
- const localHistory: WalletReserveHistoryItem[] = [
- {
- type: WalletReserveHistoryItemType.Credit,
- expectedAmount: Amounts.parseOrThrow("TESTKUDOS:100"),
- matchedExchangeTransaction: {
- type: ReserveTransactionType.Credit,
- amount: "TESTKUDOS:100",
- sender_account_url: "payto://void/",
- timestamp: { t_ms: 42 },
- wire_reference: "ABC01",
- },
- },
- {
- type: WalletReserveHistoryItemType.Withdraw,
- expectedAmount: Amounts.parseOrThrow("TESTKUDOS:5"),
- },
- ];
- const remoteHistory: ReserveTransaction[] = [
- {
- type: ReserveTransactionType.Credit,
- amount: "TESTKUDOS:100",
- sender_account_url: "payto://void/",
- timestamp: { t_ms: 42 },
- wire_reference: "ABC01",
- },
- ];
- const r = reconcileReserveHistory(localHistory, remoteHistory);
- const s = summarizeReserveHistory(r.updatedLocalHistory, "TESTKUDOS");
- t.deepEqual(r.updatedLocalHistory.length, 2);
- t.deepEqual(Amounts.stringify(s.computedReserveBalance), "TESTKUDOS:100");
- t.deepEqual(Amounts.stringify(s.awaitedReserveAmount), "TESTKUDOS:0");
- t.deepEqual(Amounts.stringify(s.unclaimedReserveAmount), "TESTKUDOS:95");
-});
diff --git a/packages/taler-wallet-core/src/util/reserveHistoryUtil.ts b/packages/taler-wallet-core/src/util/reserveHistoryUtil.ts
deleted file mode 100644
index 60823e1e0..000000000
--- a/packages/taler-wallet-core/src/util/reserveHistoryUtil.ts
+++ /dev/null
@@ -1,363 +0,0 @@
-/*
- This file is part of GNU Taler
- (C) 2020 Taler Systems S.A.
-
- GNU Taler is free software; you can redistribute it and/or modify it under the
- terms of the GNU General Public License as published by the Free Software
- Foundation; either version 3, or (at your option) any later version.
-
- GNU Taler is distributed in the hope that it will be useful, but WITHOUT ANY
- WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
- A PARTICULAR PURPOSE. See the GNU General Public License for more details.
-
- You should have received a copy of the GNU General Public License along with
- GNU Taler; see the file COPYING. If not, see <http://www.gnu.org/licenses/>
- */
-
-/**
- * Helpers for dealing with reserve histories.
- *
- * @author Florian Dold <dold@taler.net>
- */
-
-/**
- * Imports.
- */
-import {
- WalletReserveHistoryItem,
- WalletReserveHistoryItemType,
-} from "../types/dbTypes";
-import {
- ReserveTransaction,
- ReserveTransactionType,
-} from "../types/ReserveTransaction";
-import * as Amounts from "../util/amounts";
-import { timestampCmp } from "./time";
-import { deepCopy } from "./helpers";
-import { AmountJson } from "../util/amounts";
-
-/**
- * Result of a reserve reconciliation.
- */
-export interface ReserveReconciliationResult {
- /**
- * The wallet's local history reconciled with the exchange's reserve history.
- */
- updatedLocalHistory: WalletReserveHistoryItem[];
-
- /**
- * History items that were newly created, subset of the
- * updatedLocalHistory items.
- */
- newAddedItems: WalletReserveHistoryItem[];
-
- /**
- * History items that were newly matched, subset of the
- * updatedLocalHistory items.
- */
- newMatchedItems: WalletReserveHistoryItem[];
-}
-
-/**
- * Various totals computed from the wallet's view
- * on the reserve history.
- */
-export interface ReserveHistorySummary {
- /**
- * Balance computed by the wallet, should match the balance
- * computed by the reserve.
- */
- computedReserveBalance: Amounts.AmountJson;
-
- /**
- * Reserve balance that is still available for withdrawal.
- */
- unclaimedReserveAmount: Amounts.AmountJson;
-
- /**
- * Amount that we're still expecting to come into the reserve.
- */
- awaitedReserveAmount: Amounts.AmountJson;
-
- /**
- * Amount withdrawn from the reserve so far. Only counts
- * finished withdrawals, not withdrawals in progress.
- */
- withdrawnAmount: Amounts.AmountJson;
-}
-
-/**
- * Check if two reserve history items (exchange's version) match.
- */
-function isRemoteHistoryMatch(
- t1: ReserveTransaction,
- t2: ReserveTransaction,
-): boolean {
- switch (t1.type) {
- case ReserveTransactionType.Closing: {
- return t1.type === t2.type && t1.wtid == t2.wtid;
- }
- case ReserveTransactionType.Credit: {
- return t1.type === t2.type && t1.wire_reference === t2.wire_reference;
- }
- case ReserveTransactionType.Recoup: {
- return (
- t1.type === t2.type &&
- t1.coin_pub === t2.coin_pub &&
- timestampCmp(t1.timestamp, t2.timestamp) === 0
- );
- }
- case ReserveTransactionType.Withdraw: {
- return t1.type === t2.type && t1.h_coin_envelope === t2.h_coin_envelope;
- }
- }
-}
-
-/**
- * Check a local reserve history item and a remote history item are a match.
- */
-export function isLocalRemoteHistoryMatch(
- t1: WalletReserveHistoryItem,
- t2: ReserveTransaction,
-): boolean {
- switch (t1.type) {
- case WalletReserveHistoryItemType.Credit: {
- return (
- t2.type === ReserveTransactionType.Credit &&
- !!t1.expectedAmount &&
- Amounts.cmp(t1.expectedAmount, Amounts.parseOrThrow(t2.amount)) === 0
- );
- }
- case WalletReserveHistoryItemType.Withdraw:
- return (
- t2.type === ReserveTransactionType.Withdraw &&
- !!t1.expectedAmount &&
- Amounts.cmp(t1.expectedAmount, Amounts.parseOrThrow(t2.amount)) === 0
- );
- case WalletReserveHistoryItemType.Recoup: {
- return (
- t2.type === ReserveTransactionType.Recoup &&
- !!t1.expectedAmount &&
- Amounts.cmp(t1.expectedAmount, Amounts.parseOrThrow(t2.amount)) === 0
- );
- }
- }
- return false;
-}
-
-/**
- * Compute totals for the wallet's view of the reserve history.
- */
-export function summarizeReserveHistory(
- localHistory: WalletReserveHistoryItem[],
- currency: string,
-): ReserveHistorySummary {
- const posAmounts: AmountJson[] = [];
- const negAmounts: AmountJson[] = [];
- const expectedPosAmounts: AmountJson[] = [];
- const expectedNegAmounts: AmountJson[] = [];
- const withdrawnAmounts: AmountJson[] = [];
-
- for (const item of localHistory) {
- switch (item.type) {
- case WalletReserveHistoryItemType.Credit:
- if (item.matchedExchangeTransaction) {
- posAmounts.push(
- Amounts.parseOrThrow(item.matchedExchangeTransaction.amount),
- );
- } else if (item.expectedAmount) {
- expectedPosAmounts.push(item.expectedAmount);
- }
- break;
- case WalletReserveHistoryItemType.Recoup:
- if (item.matchedExchangeTransaction) {
- if (item.matchedExchangeTransaction) {
- posAmounts.push(
- Amounts.parseOrThrow(item.matchedExchangeTransaction.amount),
- );
- } else if (item.expectedAmount) {
- expectedPosAmounts.push(item.expectedAmount);
- } else {
- throw Error("invariant failed");
- }
- }
- break;
- case WalletReserveHistoryItemType.Closing:
- if (item.matchedExchangeTransaction) {
- negAmounts.push(
- Amounts.parseOrThrow(item.matchedExchangeTransaction.amount),
- );
- } else {
- throw Error("invariant failed");
- }
- break;
- case WalletReserveHistoryItemType.Withdraw:
- if (item.matchedExchangeTransaction) {
- negAmounts.push(
- Amounts.parseOrThrow(item.matchedExchangeTransaction.amount),
- );
- withdrawnAmounts.push(
- Amounts.parseOrThrow(item.matchedExchangeTransaction.amount),
- );
- } else if (item.expectedAmount) {
- expectedNegAmounts.push(item.expectedAmount);
- } else {
- throw Error("invariant failed");
- }
- break;
- }
- }
-
- const z = Amounts.getZero(currency);
-
- const computedBalance = Amounts.sub(
- Amounts.add(z, ...posAmounts).amount,
- ...negAmounts,
- ).amount;
-
- const unclaimedReserveAmount = Amounts.sub(
- Amounts.add(z, ...posAmounts).amount,
- ...negAmounts,
- ...expectedNegAmounts,
- ).amount;
-
- const awaitedReserveAmount = Amounts.sub(
- Amounts.add(z, ...expectedPosAmounts).amount,
- ...expectedNegAmounts,
- ).amount;
-
- const withdrawnAmount = Amounts.add(z, ...withdrawnAmounts).amount;
-
- return {
- computedReserveBalance: computedBalance,
- unclaimedReserveAmount: unclaimedReserveAmount,
- awaitedReserveAmount: awaitedReserveAmount,
- withdrawnAmount,
- };
-}
-
-/**
- * Reconcile the wallet's local model of the reserve history
- * with the reserve history of the exchange.
- */
-export function reconcileReserveHistory(
- localHistory: WalletReserveHistoryItem[],
- remoteHistory: ReserveTransaction[],
-): ReserveReconciliationResult {
- const updatedLocalHistory: WalletReserveHistoryItem[] = deepCopy(
- localHistory,
- );
- const newMatchedItems: WalletReserveHistoryItem[] = [];
- const newAddedItems: WalletReserveHistoryItem[] = [];
-
- const remoteMatched = remoteHistory.map(() => false);
- const localMatched = localHistory.map(() => false);
-
- // Take care of deposits
-
- // First, see which pairs are already a definite match.
- for (let remoteIndex = 0; remoteIndex < remoteHistory.length; remoteIndex++) {
- const rhi = remoteHistory[remoteIndex];
- for (let localIndex = 0; localIndex < localHistory.length; localIndex++) {
- if (localMatched[localIndex]) {
- continue;
- }
- const lhi = localHistory[localIndex];
- if (!lhi.matchedExchangeTransaction) {
- continue;
- }
- if (isRemoteHistoryMatch(rhi, lhi.matchedExchangeTransaction)) {
- localMatched[localIndex] = true;
- remoteMatched[remoteIndex] = true;
- break;
- }
- }
- }
-
- // Check that all previously matched items are still matched
- for (let localIndex = 0; localIndex < localHistory.length; localIndex++) {
- if (localMatched[localIndex]) {
- continue;
- }
- const lhi = localHistory[localIndex];
- if (lhi.matchedExchangeTransaction) {
- // Don't use for further matching
- localMatched[localIndex] = true;
- // FIXME: emit some error here!
- throw Error("previously matched reserve history item now unmatched");
- }
- }
-
- // Next, find out if there are any exact new matches between local and remote
- // history items
- for (let localIndex = 0; localIndex < localHistory.length; localIndex++) {
- if (localMatched[localIndex]) {
- continue;
- }
- const lhi = localHistory[localIndex];
- for (
- let remoteIndex = 0;
- remoteIndex < remoteHistory.length;
- remoteIndex++
- ) {
- const rhi = remoteHistory[remoteIndex];
- if (remoteMatched[remoteIndex]) {
- continue;
- }
- if (isLocalRemoteHistoryMatch(lhi, rhi)) {
- localMatched[localIndex] = true;
- remoteMatched[remoteIndex] = true;
- updatedLocalHistory[localIndex].matchedExchangeTransaction = rhi as any;
- newMatchedItems.push(lhi);
- break;
- }
- }
- }
-
- // Finally we add new history items
- for (let remoteIndex = 0; remoteIndex < remoteHistory.length; remoteIndex++) {
- if (remoteMatched[remoteIndex]) {
- continue;
- }
- const rhi = remoteHistory[remoteIndex];
- let newItem: WalletReserveHistoryItem;
- switch (rhi.type) {
- case ReserveTransactionType.Closing: {
- newItem = {
- type: WalletReserveHistoryItemType.Closing,
- matchedExchangeTransaction: rhi,
- };
- break;
- }
- case ReserveTransactionType.Credit: {
- newItem = {
- type: WalletReserveHistoryItemType.Credit,
- matchedExchangeTransaction: rhi,
- };
- break;
- }
- case ReserveTransactionType.Recoup: {
- newItem = {
- type: WalletReserveHistoryItemType.Recoup,
- matchedExchangeTransaction: rhi,
- };
- break;
- }
- case ReserveTransactionType.Withdraw: {
- newItem = {
- type: WalletReserveHistoryItemType.Withdraw,
- matchedExchangeTransaction: rhi,
- };
- break;
- }
- }
- updatedLocalHistory.push(newItem);
- newAddedItems.push(newItem);
- }
-
- return {
- updatedLocalHistory,
- newAddedItems,
- newMatchedItems,
- };
-}