wallet-core: compute full peer push payment fees
This commit is contained in:
parent
8309f803ab
commit
a3f9e86805
@ -70,6 +70,7 @@ import {
|
||||
} from "@gnu-taler/taler-util";
|
||||
import { SpendCoinDetails } from "../crypto/cryptoImplementation.js";
|
||||
import {
|
||||
DenominationRecord,
|
||||
OperationStatus,
|
||||
PeerPullPaymentIncomingStatus,
|
||||
PeerPushPaymentCoinSelection,
|
||||
@ -97,6 +98,7 @@ import {
|
||||
} from "../util/retries.js";
|
||||
import { getPeerPaymentBalanceDetailsInTx } from "./balance.js";
|
||||
import { updateExchangeFromUrl } from "./exchanges.js";
|
||||
import { getTotalRefreshCost } from "./refresh.js";
|
||||
import { internalCreateWithdrawalGroup } from "./withdraw.js";
|
||||
|
||||
const logger = new Logger("operations/peer-to-peer.ts");
|
||||
@ -329,13 +331,83 @@ export async function selectPeerCoins(
|
||||
return { type: "failure", insufficientBalanceDetails: errDetails };
|
||||
}
|
||||
|
||||
export async function getTotalPeerPaymentCost(
|
||||
ws: InternalWalletState,
|
||||
pcs: PeerCoinSelectionDetails,
|
||||
): Promise<AmountJson> {
|
||||
return ws.db
|
||||
.mktx((x) => [x.coins, x.denominations])
|
||||
.runReadOnly(async (tx) => {
|
||||
const costs: AmountJson[] = [];
|
||||
for (let i = 0; i < pcs.coins.length; i++) {
|
||||
const coin = await tx.coins.get(pcs.coins[i].coinPub);
|
||||
if (!coin) {
|
||||
throw Error("can't calculate payment cost, coin not found");
|
||||
}
|
||||
const denom = await tx.denominations.get([
|
||||
coin.exchangeBaseUrl,
|
||||
coin.denomPubHash,
|
||||
]);
|
||||
if (!denom) {
|
||||
throw Error(
|
||||
"can't calculate payment cost, denomination for coin not found",
|
||||
);
|
||||
}
|
||||
const allDenoms = await tx.denominations.indexes.byExchangeBaseUrl
|
||||
.iter(coin.exchangeBaseUrl)
|
||||
.filter((x) =>
|
||||
Amounts.isSameCurrency(
|
||||
DenominationRecord.getValue(x),
|
||||
pcs.coins[i].contribution,
|
||||
),
|
||||
);
|
||||
const amountLeft = Amounts.sub(
|
||||
DenominationRecord.getValue(denom),
|
||||
pcs.coins[i].contribution,
|
||||
).amount;
|
||||
const refreshCost = getTotalRefreshCost(
|
||||
allDenoms,
|
||||
DenominationRecord.toDenomInfo(denom),
|
||||
amountLeft,
|
||||
);
|
||||
costs.push(Amounts.parseOrThrow(pcs.coins[i].contribution));
|
||||
costs.push(refreshCost);
|
||||
}
|
||||
const zero = Amounts.zeroOfAmount(pcs.coins[0].contribution);
|
||||
return Amounts.sum([zero, ...costs]).amount;
|
||||
});
|
||||
}
|
||||
|
||||
export async function preparePeerPushPayment(
|
||||
ws: InternalWalletState,
|
||||
req: PreparePeerPushPaymentRequest,
|
||||
): Promise<PreparePeerPushPaymentResponse> {
|
||||
// FIXME: look up for the exchange and calculate fee
|
||||
const instructedAmount = Amounts.parseOrThrow(req.amount);
|
||||
const coinSelRes: SelectPeerCoinsResult = await ws.db
|
||||
.mktx((x) => [
|
||||
x.exchanges,
|
||||
x.contractTerms,
|
||||
x.coins,
|
||||
x.coinAvailability,
|
||||
x.denominations,
|
||||
x.refreshGroups,
|
||||
x.peerPushPaymentInitiations,
|
||||
])
|
||||
.runReadWrite(async (tx) => {
|
||||
const selRes = await selectPeerCoins(ws, tx, instructedAmount);
|
||||
return selRes;
|
||||
});
|
||||
if (coinSelRes.type === "failure") {
|
||||
throw TalerError.fromDetail(
|
||||
TalerErrorCode.WALLET_PEER_PUSH_PAYMENT_INSUFFICIENT_BALANCE,
|
||||
{
|
||||
insufficientBalanceDetails: coinSelRes.insufficientBalanceDetails,
|
||||
},
|
||||
);
|
||||
}
|
||||
const totalAmount = await getTotalPeerPaymentCost(ws, coinSelRes.result);
|
||||
return {
|
||||
amountEffective: req.amount,
|
||||
amountEffective: Amounts.stringify(totalAmount),
|
||||
amountRaw: req.amount,
|
||||
};
|
||||
}
|
||||
@ -954,7 +1026,7 @@ export async function processPeerPullInitiation(
|
||||
return {
|
||||
type: OperationAttemptResultType.Finished,
|
||||
result: undefined,
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
const mergeReserve = await ws.db
|
||||
|
Loading…
Reference in New Issue
Block a user