aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--packages/taler-util/src/transactionsTypes.ts22
-rw-r--r--packages/taler-wallet-core/src/db.ts41
-rw-r--r--packages/taler-wallet-core/src/operations/peer-to-peer.ts9
-rw-r--r--packages/taler-wallet-core/src/operations/transactions.ts26
-rw-r--r--packages/taler-wallet-core/src/operations/withdraw.ts74
5 files changed, 131 insertions, 41 deletions
diff --git a/packages/taler-util/src/transactionsTypes.ts b/packages/taler-util/src/transactionsTypes.ts
index c4bd3d464..79c62cbc8 100644
--- a/packages/taler-util/src/transactionsTypes.ts
+++ b/packages/taler-util/src/transactionsTypes.ts
@@ -187,6 +187,9 @@ export interface TransactionWithdrawal extends TransactionCommon {
withdrawalDetails: WithdrawalDetails;
}
+/**
+ * Credit because we were paid for a P2P invoice we created.
+ */
export interface TransactionPeerPullCredit extends TransactionCommon {
type: TransactionType.PeerPullCredit;
@@ -204,8 +207,16 @@ export interface TransactionPeerPullCredit extends TransactionCommon {
* Amount that actually was (or will be) added to the wallet's balance.
*/
amountEffective: AmountString;
+
+ /**
+ * URI to send to the other party.
+ */
+ talerUri: string;
}
+/**
+ * Debit because we paid someone's invoice.
+ */
export interface TransactionPeerPullDebit extends TransactionCommon {
type: TransactionType.PeerPullDebit;
@@ -219,6 +230,9 @@ export interface TransactionPeerPullDebit extends TransactionCommon {
amountEffective: AmountString;
}
+/**
+ * We sent money via a P2P payment.
+ */
export interface TransactionPeerPushDebit extends TransactionCommon {
type: TransactionType.PeerPushDebit;
@@ -236,8 +250,16 @@ export interface TransactionPeerPushDebit extends TransactionCommon {
* Amount that actually was (or will be) added to the wallet's balance.
*/
amountEffective: AmountString;
+
+ /**
+ * URI to accept the payment.
+ */
+ talerUri: string;
}
+/**
+ * We received money via a P2P payment.
+ */
export interface TransactionPeerPushCredit extends TransactionCommon {
type: TransactionType.PeerPushCredit;
diff --git a/packages/taler-wallet-core/src/db.ts b/packages/taler-wallet-core/src/db.ts
index e6b4854db..40f4ea2b5 100644
--- a/packages/taler-wallet-core/src/db.ts
+++ b/packages/taler-wallet-core/src/db.ts
@@ -1226,6 +1226,39 @@ export const enum WithdrawalRecordType {
PeerPushCredit = "peer-push-credit",
}
+export interface WgInfoBankIntegrated {
+ withdrawalType: WithdrawalRecordType.BankIntegrated;
+ /**
+ * Extra state for when this is a withdrawal involving
+ * a Taler-integrated bank.
+ */
+ bankInfo: ReserveBankInfo;
+}
+
+export interface WgInfoBankManual {
+ withdrawalType: WithdrawalRecordType.BankManual;
+}
+
+export interface WgInfoBankPeerPull {
+ withdrawalType: WithdrawalRecordType.PeerPullCredit;
+
+ /**
+ * Needed to quickly construct the taler:// URI for the counterparty
+ * without a join.
+ */
+ contractPriv: string;
+}
+
+export interface WgInfoBankPeerPush {
+ withdrawalType: WithdrawalRecordType.PeerPushCredit;
+}
+
+export type WgInfo =
+ | WgInfoBankIntegrated
+ | WgInfoBankManual
+ | WgInfoBankPeerPull
+ | WgInfoBankPeerPush;
+
/**
* Group of withdrawal operations that need to be executed.
* (Either for a normal withdrawal or from a tip.)
@@ -1239,7 +1272,7 @@ export interface WithdrawalGroupRecord {
*/
withdrawalGroupId: string;
- withdrawalType: WithdrawalRecordType;
+ wgInfo: WgInfo;
/**
* Secret seed used to derive planchets.
@@ -1302,12 +1335,6 @@ export interface WithdrawalGroupRecord {
restrictAge?: number;
/**
- * Extra state for when this is a withdrawal involving
- * a Taler-integrated bank.
- */
- bankInfo?: ReserveBankInfo;
-
- /**
* Amount including fees (i.e. the amount subtracted from the
* reserve to withdraw all coins in this withdrawal session).
*/
diff --git a/packages/taler-wallet-core/src/operations/peer-to-peer.ts b/packages/taler-wallet-core/src/operations/peer-to-peer.ts
index d6d71720c..19306845a 100644
--- a/packages/taler-wallet-core/src/operations/peer-to-peer.ts
+++ b/packages/taler-wallet-core/src/operations/peer-to-peer.ts
@@ -534,7 +534,9 @@ export async function acceptPeerPushPayment(
await internalCreateWithdrawalGroup(ws, {
amount,
- withdrawalType: WithdrawalRecordType.PeerPushCredit,
+ wgInfo: {
+ withdrawalType: WithdrawalRecordType.PeerPushCredit,
+ },
exchangeBaseUrl: peerInc.exchangeBaseUrl,
reserveStatus: ReserveRecordStatus.QueryingStatus,
reserveKeyPair: {
@@ -804,7 +806,10 @@ export async function initiatePeerRequestForPay(
await internalCreateWithdrawalGroup(ws, {
amount: Amounts.parseOrThrow(req.amount),
- withdrawalType: WithdrawalRecordType.PeerPullCredit,
+ wgInfo: {
+ withdrawalType: WithdrawalRecordType.PeerPullCredit,
+ contractPriv: econtractResp.contractPriv,
+ },
exchangeBaseUrl: req.exchangeBaseUrl,
reserveStatus: ReserveRecordStatus.QueryingStatus,
reserveKeyPair: {
diff --git a/packages/taler-wallet-core/src/operations/transactions.ts b/packages/taler-wallet-core/src/operations/transactions.ts
index 62df996c3..8eff945c5 100644
--- a/packages/taler-wallet-core/src/operations/transactions.ts
+++ b/packages/taler-wallet-core/src/operations/transactions.ts
@@ -21,6 +21,8 @@ import {
AbsoluteTime,
AmountJson,
Amounts,
+ constructPayPullUri,
+ constructPayPushUri,
Logger,
OrderShortInfo,
PaymentStatus,
@@ -156,6 +158,10 @@ export async function getTransactions(
frozen: false,
pending: !pi.purseCreated,
timestamp: pi.timestampCreated,
+ talerUri: constructPayPushUri({
+ exchangeBaseUrl: pi.exchangeBaseUrl,
+ contractPriv: pi.contractPriv,
+ }),
transactionId: makeEventId(
TransactionType.PeerPushDebit,
pi.pursePub,
@@ -203,7 +209,7 @@ export async function getTransactions(
return;
}
let withdrawalDetails: WithdrawalDetails;
- if (wsr.withdrawalType === WithdrawalRecordType.PeerPullCredit) {
+ if (wsr.wgInfo.withdrawalType === WithdrawalRecordType.PeerPullCredit) {
transactions.push({
type: TransactionType.PeerPullCredit,
amountEffective: Amounts.stringify(wsr.denomsSel.totalCoinValue),
@@ -211,6 +217,10 @@ export async function getTransactions(
exchangeBaseUrl: wsr.exchangeBaseUrl,
pending: !wsr.timestampFinish,
timestamp: wsr.timestampStart,
+ talerUri: constructPayPullUri({
+ exchangeBaseUrl: wsr.exchangeBaseUrl,
+ contractPriv: wsr.wgInfo.contractPriv,
+ }),
transactionId: makeEventId(
TransactionType.PeerPullCredit,
wsr.withdrawalGroupId,
@@ -219,7 +229,9 @@ export async function getTransactions(
...(wsr.lastError ? { error: wsr.lastError } : {}),
});
return;
- } else if (wsr.withdrawalType === WithdrawalRecordType.PeerPushCredit) {
+ } else if (
+ wsr.wgInfo.withdrawalType === WithdrawalRecordType.PeerPushCredit
+ ) {
transactions.push({
type: TransactionType.PeerPushCredit,
amountEffective: Amounts.stringify(wsr.denomsSel.totalCoinValue),
@@ -235,12 +247,16 @@ export async function getTransactions(
...(wsr.lastError ? { error: wsr.lastError } : {}),
});
return;
- } else if (wsr.bankInfo) {
+ } else if (
+ wsr.wgInfo.withdrawalType === WithdrawalRecordType.BankIntegrated
+ ) {
withdrawalDetails = {
type: WithdrawalType.TalerBankIntegrationApi,
- confirmed: wsr.bankInfo.timestampBankConfirmed ? true : false,
+ confirmed: wsr.wgInfo.bankInfo.timestampBankConfirmed
+ ? true
+ : false,
reservePub: wsr.reservePub,
- bankConfirmationUrl: wsr.bankInfo.confirmUrl,
+ bankConfirmationUrl: wsr.wgInfo.bankInfo.confirmUrl,
};
} else {
const exchangeDetails = await getExchangeDetails(
diff --git a/packages/taler-wallet-core/src/operations/withdraw.ts b/packages/taler-wallet-core/src/operations/withdraw.ts
index 4e350670d..a0a4b4bbd 100644
--- a/packages/taler-wallet-core/src/operations/withdraw.ts
+++ b/packages/taler-wallet-core/src/operations/withdraw.ts
@@ -73,6 +73,7 @@ import {
ReserveBankInfo,
ReserveRecordStatus,
WalletStoresV1,
+ WgInfo,
WithdrawalGroupRecord,
WithdrawalRecordType,
} from "../db.js";
@@ -1531,7 +1532,12 @@ async function registerReserveWithBank(
default:
return;
}
- const bankInfo = withdrawalGroup.bankInfo;
+ if (
+ withdrawalGroup.wgInfo.withdrawalType != WithdrawalRecordType.BankIntegrated
+ ) {
+ throw Error();
+ }
+ const bankInfo = withdrawalGroup.wgInfo.bankInfo;
if (!bankInfo) {
return;
}
@@ -1566,10 +1572,10 @@ async function registerReserveWithBank(
default:
return;
}
- if (!r.bankInfo) {
+ if (r.wgInfo.withdrawalType !== WithdrawalRecordType.BankIntegrated) {
throw Error("invariant failed");
}
- r.bankInfo.timestampReserveInfoPosted = AbsoluteTime.toTimestamp(
+ r.wgInfo.bankInfo.timestampReserveInfoPosted = AbsoluteTime.toTimestamp(
AbsoluteTime.now(),
);
r.reserveStatus = ReserveRecordStatus.WaitConfirmBank;
@@ -1595,12 +1601,18 @@ async function processReserveBankStatus(
default:
return;
}
- if (!withdrawalGroup.bankInfo) {
+
+ if (
+ withdrawalGroup.wgInfo.withdrawalType != WithdrawalRecordType.BankIntegrated
+ ) {
+ throw Error();
+ }
+ const bankInfo = withdrawalGroup.wgInfo.bankInfo;
+ if (!bankInfo) {
return;
}
- const bankStatusUrl = getBankStatusUrl(
- withdrawalGroup.bankInfo.talerWithdrawUri,
- );
+
+ const bankStatusUrl = getBankStatusUrl(bankInfo.talerWithdrawUri);
const statusResp = await ws.http.get(bankStatusUrl, {
timeout: getReserveRequestTimeout(withdrawalGroup),
@@ -1628,11 +1640,11 @@ async function processReserveBankStatus(
default:
return;
}
- if (!r.bankInfo) {
+ if (r.wgInfo.withdrawalType !== WithdrawalRecordType.BankIntegrated) {
throw Error("invariant failed");
}
const now = AbsoluteTime.toTimestamp(AbsoluteTime.now());
- r.bankInfo.timestampBankConfirmed = now;
+ r.wgInfo.bankInfo.timestampBankConfirmed = now;
r.reserveStatus = ReserveRecordStatus.BankAborted;
r.operationStatus = OperationStatus.Finished;
r.retryInfo = RetryInfo.reset();
@@ -1670,21 +1682,19 @@ async function processReserveBankStatus(
default:
return;
}
+ if (r.wgInfo.withdrawalType !== WithdrawalRecordType.BankIntegrated) {
+ throw Error("invariant failed");
+ }
if (status.transfer_done) {
logger.info("withdrawal: transfer confirmed by bank.");
const now = AbsoluteTime.toTimestamp(AbsoluteTime.now());
- if (!r.bankInfo) {
- throw Error("invariant failed");
- }
- r.bankInfo.timestampBankConfirmed = now;
+ r.wgInfo.bankInfo.timestampBankConfirmed = now;
r.reserveStatus = ReserveRecordStatus.QueryingStatus;
r.operationStatus = OperationStatus.Pending;
r.retryInfo = RetryInfo.reset();
} else {
logger.info("withdrawal: transfer not yet confirmed by bank");
- if (r.bankInfo) {
- r.bankInfo.confirmUrl = status.confirm_transfer_url;
- }
+ r.wgInfo.bankInfo.confirmUrl = status.confirm_transfer_url;
r.retryInfo = RetryInfo.increment(r.retryInfo);
}
await tx.withdrawalGroups.put(r);
@@ -1701,7 +1711,7 @@ export async function internalCreateWithdrawalGroup(
forcedDenomSel?: ForcedDenomSel;
reserveKeyPair?: EddsaKeypair;
restrictAge?: number;
- withdrawalType: WithdrawalRecordType;
+ wgInfo: WgInfo;
},
): Promise<WithdrawalGroupRecord> {
const reserveKeyPair =
@@ -1743,11 +1753,10 @@ export async function internalCreateWithdrawalGroup(
reserveStatus: args.reserveStatus,
retryInfo: RetryInfo.reset(),
withdrawalGroupId,
- bankInfo: args.bankInfo,
restrictAge: args.restrictAge,
senderWire: undefined,
timestampFinish: undefined,
- withdrawalType: args.withdrawalType,
+ wgInfo: args.wgInfo,
};
const exchangeInfo = await updateExchangeFromUrl(ws, canonExchange);
@@ -1802,9 +1811,16 @@ export async function acceptWithdrawalFromUri(
});
if (existingWithdrawalGroup) {
+ let url: string | undefined;
+ if (
+ existingWithdrawalGroup.wgInfo.withdrawalType ===
+ WithdrawalRecordType.BankIntegrated
+ ) {
+ url = existingWithdrawalGroup.wgInfo.bankInfo.confirmUrl;
+ }
return {
reservePub: existingWithdrawalGroup.reservePub,
- confirmTransferUrl: existingWithdrawalGroup.bankInfo?.confirmUrl,
+ confirmTransferUrl: url,
};
}
@@ -1822,14 +1838,16 @@ export async function acceptWithdrawalFromUri(
const withdrawalGroup = await internalCreateWithdrawalGroup(ws, {
amount: withdrawInfo.amount,
exchangeBaseUrl: req.selectedExchange,
- withdrawalType: WithdrawalRecordType.BankIntegrated,
+ wgInfo: {
+ withdrawalType: WithdrawalRecordType.BankIntegrated,
+ bankInfo: {
+ exchangePaytoUri,
+ talerWithdrawUri: req.talerWithdrawUri,
+ confirmUrl: withdrawInfo.confirmTransferUrl,
+ },
+ },
forcedDenomSel: req.forcedDenomSel,
reserveStatus: ReserveRecordStatus.RegisteringBank,
- bankInfo: {
- exchangePaytoUri,
- talerWithdrawUri: req.talerWithdrawUri,
- confirmUrl: withdrawInfo.confirmTransferUrl,
- },
});
const withdrawalGroupId = withdrawalGroup.withdrawalGroupId;
@@ -1881,7 +1899,9 @@ export async function createManualWithdrawal(
): Promise<AcceptManualWithdrawalResult> {
const withdrawalGroup = await internalCreateWithdrawalGroup(ws, {
amount: Amounts.jsonifyAmount(req.amount),
- withdrawalType: WithdrawalRecordType.BankManual,
+ wgInfo: {
+ withdrawalType: WithdrawalRecordType.BankManual,
+ },
exchangeBaseUrl: req.exchangeBaseUrl,
bankInfo: undefined,
forcedDenomSel: req.forcedDenomSel,