wallet-core: put taler:// URIs in transactions list
This commit is contained in:
parent
a11ac57535
commit
f3231ccdf9
@ -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;
|
||||
|
||||
|
@ -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.
|
||||
@ -1301,12 +1334,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).
|
||||
|
@ -534,7 +534,9 @@ export async function acceptPeerPushPayment(
|
||||
|
||||
await internalCreateWithdrawalGroup(ws, {
|
||||
amount,
|
||||
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),
|
||||
wgInfo: {
|
||||
withdrawalType: WithdrawalRecordType.PeerPullCredit,
|
||||
contractPriv: econtractResp.contractPriv,
|
||||
},
|
||||
exchangeBaseUrl: req.exchangeBaseUrl,
|
||||
reserveStatus: ReserveRecordStatus.QueryingStatus,
|
||||
reserveKeyPair: {
|
||||
|
@ -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(
|
||||
|
@ -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,
|
||||
wgInfo: {
|
||||
withdrawalType: WithdrawalRecordType.BankIntegrated,
|
||||
forcedDenomSel: req.forcedDenomSel,
|
||||
reserveStatus: ReserveRecordStatus.RegisteringBank,
|
||||
bankInfo: {
|
||||
exchangePaytoUri,
|
||||
talerWithdrawUri: req.talerWithdrawUri,
|
||||
confirmUrl: withdrawInfo.confirmTransferUrl,
|
||||
},
|
||||
},
|
||||
forcedDenomSel: req.forcedDenomSel,
|
||||
reserveStatus: ReserveRecordStatus.RegisteringBank,
|
||||
});
|
||||
|
||||
const withdrawalGroupId = withdrawalGroup.withdrawalGroupId;
|
||||
@ -1881,7 +1899,9 @@ export async function createManualWithdrawal(
|
||||
): Promise<AcceptManualWithdrawalResult> {
|
||||
const withdrawalGroup = await internalCreateWithdrawalGroup(ws, {
|
||||
amount: Amounts.jsonifyAmount(req.amount),
|
||||
wgInfo: {
|
||||
withdrawalType: WithdrawalRecordType.BankManual,
|
||||
},
|
||||
exchangeBaseUrl: req.exchangeBaseUrl,
|
||||
bankInfo: undefined,
|
||||
forcedDenomSel: req.forcedDenomSel,
|
||||
|
Loading…
Reference in New Issue
Block a user