fix: 7740 check max on p2p push
This commit is contained in:
parent
ce3c3d7839
commit
28dce57f92
@ -367,6 +367,6 @@ test("taler withdraw exchange URI with amount (stringify)", (t) => {
|
|||||||
});
|
});
|
||||||
t.deepEqual(
|
t.deepEqual(
|
||||||
url,
|
url,
|
||||||
"taler://withdraw-exchange/exchange.demo.taler.net/GJKG23V4ZBHEH45YRK7TWQE8ZTY7JWTY5094TQJSRZN5DSDBX8E0?a=KUDOS%3A19",
|
"taler://withdraw-exchange/exchange.demo.taler.net/JFX1NE38C65A5XT8VSNQXX7R7BBG4GNZ63F5T7Y6859V4J8KBKF0?a=KUDOS%3A19",
|
||||||
);
|
);
|
||||||
});
|
});
|
||||||
|
@ -14,15 +14,21 @@
|
|||||||
GNU Taler; see the file COPYING. If not, see <http://www.gnu.org/licenses/>
|
GNU Taler; see the file COPYING. If not, see <http://www.gnu.org/licenses/>
|
||||||
*/
|
*/
|
||||||
|
|
||||||
import { Amounts, TalerProtocolTimestamp } from "@gnu-taler/taler-util";
|
import {
|
||||||
|
Amounts,
|
||||||
|
TalerError,
|
||||||
|
TalerErrorCode,
|
||||||
|
TalerProtocolTimestamp,
|
||||||
|
} from "@gnu-taler/taler-util";
|
||||||
import { WalletApiOperation } from "@gnu-taler/taler-wallet-core";
|
import { WalletApiOperation } from "@gnu-taler/taler-wallet-core";
|
||||||
import { isFuture, parse } from "date-fns";
|
import { isFuture, parse } from "date-fns";
|
||||||
import { useState } from "preact/hooks";
|
import { useEffect, useState } from "preact/hooks";
|
||||||
import { alertFromError, useAlertContext } from "../../context/alert.js";
|
import { alertFromError, useAlertContext } from "../../context/alert.js";
|
||||||
import { useBackendContext } from "../../context/backend.js";
|
import { useBackendContext } from "../../context/backend.js";
|
||||||
import { useTranslationContext } from "@gnu-taler/web-util/browser";
|
import { useTranslationContext } from "@gnu-taler/web-util/browser";
|
||||||
import { useAsyncAsHook } from "../../hooks/useAsyncAsHook.js";
|
import { useAsyncAsHook } from "../../hooks/useAsyncAsHook.js";
|
||||||
import { Props, State } from "./index.js";
|
import { Props, State } from "./index.js";
|
||||||
|
import { BackgroundError, WxApiType } from "../../wxApi.js";
|
||||||
|
|
||||||
export function useComponentState({
|
export function useComponentState({
|
||||||
amount: amountStr,
|
amount: amountStr,
|
||||||
@ -38,9 +44,7 @@ export function useComponentState({
|
|||||||
const [timestamp, setTimestamp] = useState<string | undefined>();
|
const [timestamp, setTimestamp] = useState<string | undefined>();
|
||||||
|
|
||||||
const hook = useAsyncAsHook(async () => {
|
const hook = useAsyncAsHook(async () => {
|
||||||
const resp = await api.wallet.call(WalletApiOperation.CheckPeerPushDebit, {
|
const resp = await checkPeerPushDebitAndCheckMax(api, amountStr);
|
||||||
amount: amountStr,
|
|
||||||
});
|
|
||||||
return resp;
|
return resp;
|
||||||
});
|
});
|
||||||
|
|
||||||
@ -59,12 +63,6 @@ export function useComponentState({
|
|||||||
),
|
),
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
// if (hook.hasError) {
|
|
||||||
// return {
|
|
||||||
// status: "loading-uri",
|
|
||||||
// error: hook,
|
|
||||||
// };
|
|
||||||
// }
|
|
||||||
|
|
||||||
const { amountEffective, amountRaw } = hook.response;
|
const { amountEffective, amountRaw } = hook.response;
|
||||||
const debitAmount = Amounts.parseOrThrow(amountEffective);
|
const debitAmount = Amounts.parseOrThrow(amountEffective);
|
||||||
@ -140,3 +138,40 @@ export function useComponentState({
|
|||||||
error: undefined,
|
error: undefined,
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
async function checkPeerPushDebitAndCheckMax(
|
||||||
|
api: WxApiType,
|
||||||
|
amountState: string,
|
||||||
|
) {
|
||||||
|
// FIXME : https://bugs.gnunet.org/view.php?id=7872
|
||||||
|
try {
|
||||||
|
return await api.wallet.call(WalletApiOperation.CheckPeerPushDebit, {
|
||||||
|
amount: amountState,
|
||||||
|
});
|
||||||
|
} catch (e) {
|
||||||
|
if (!(e instanceof BackgroundError)) {
|
||||||
|
throw e;
|
||||||
|
}
|
||||||
|
if (
|
||||||
|
!e.hasErrorCode(
|
||||||
|
TalerErrorCode.WALLET_PEER_PUSH_PAYMENT_INSUFFICIENT_BALANCE,
|
||||||
|
)
|
||||||
|
) {
|
||||||
|
throw e;
|
||||||
|
}
|
||||||
|
const material = Amounts.parseOrThrow(
|
||||||
|
e.errorDetail.insufficientBalanceDetails.balanceMaterial,
|
||||||
|
);
|
||||||
|
const gap = Amounts.parseOrThrow(
|
||||||
|
e.errorDetail.insufficientBalanceDetails.feeGapEstimate,
|
||||||
|
);
|
||||||
|
const newAmount = Amounts.sub(material, gap).amount;
|
||||||
|
const amount = Amounts.parseOrThrow(amountState);
|
||||||
|
if (Amounts.cmp(newAmount, amount) === 0) {
|
||||||
|
//insufficient balance and the exception didn't give
|
||||||
|
//a good response that allow us to try again
|
||||||
|
throw e;
|
||||||
|
}
|
||||||
|
return checkPeerPushDebitAndCheckMax(api, Amounts.stringify(newAmount));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
@ -1741,7 +1741,7 @@ function DepositDetails({ amount }: { amount: AmountWithFee }): VNode {
|
|||||||
</tr>
|
</tr>
|
||||||
<tr>
|
<tr>
|
||||||
<td>
|
<td>
|
||||||
<i18n.Translate>Total transfer</i18n.Translate>
|
<i18n.Translate>Total</i18n.Translate>
|
||||||
</td>
|
</td>
|
||||||
<td>
|
<td>
|
||||||
<Amount value={amount.total} maxFracSize={amount.maxFrac} />
|
<Amount value={amount.total} maxFracSize={amount.maxFrac} />
|
||||||
|
@ -24,9 +24,11 @@
|
|||||||
import {
|
import {
|
||||||
AbsoluteTime,
|
AbsoluteTime,
|
||||||
CoreApiResponse,
|
CoreApiResponse,
|
||||||
|
DetailsMap,
|
||||||
Logger,
|
Logger,
|
||||||
LogLevel,
|
LogLevel,
|
||||||
NotificationType,
|
NotificationType,
|
||||||
|
TalerError,
|
||||||
TalerErrorCode,
|
TalerErrorCode,
|
||||||
TalerErrorDetail,
|
TalerErrorDetail,
|
||||||
WalletDiagnostics,
|
WalletDiagnostics,
|
||||||
@ -92,13 +94,19 @@ export interface BackgroundApiClient {
|
|||||||
): Promise<BackgroundOperations[Op]["response"]>;
|
): Promise<BackgroundOperations[Op]["response"]>;
|
||||||
}
|
}
|
||||||
|
|
||||||
export class BackgroundError extends Error {
|
export class BackgroundError<T = any> extends Error {
|
||||||
public errorDetail: TalerErrorDetail;
|
public errorDetail: TalerErrorDetail & T;
|
||||||
|
|
||||||
constructor(title: string, e: TalerErrorDetail) {
|
constructor(title: string, e: TalerErrorDetail & T) {
|
||||||
super(title);
|
super(title);
|
||||||
this.errorDetail = e;
|
this.errorDetail = e;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
hasErrorCode<C extends keyof DetailsMap>(
|
||||||
|
code: C,
|
||||||
|
): this is BackgroundError<DetailsMap[C]> {
|
||||||
|
return this.errorDetail.code === code;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
Loading…
Reference in New Issue
Block a user