[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
[taler-wallet-core] branch master updated (ca179ef3a -> 02ceacd75)
From: |
gnunet |
Subject: |
[taler-wallet-core] branch master updated (ca179ef3a -> 02ceacd75) |
Date: |
Tue, 28 May 2024 15:38:19 +0200 |
This is an automated email from the git hooks/post-receive script.
sebasjm pushed a change to branch master
in repository wallet-core.
from ca179ef3a bump versions to 0.11.1
new a5dbd8bd0 dd53: Inconsistent to aldready have the “add” and “send”
buttons on this page
new 678777210 dd53: Valid until” is likely confusing
new efcab636f dd 53: "amount" is a bad label, "brut amount" might be good,
then use "net deposit"
new 02ceacd75 fix #8828
The 4 revisions listed above as "new" are entirely new to this
repository and will be described in separate emails. The revisions
listed as "add" were already present in the repository and have only
been added to this reference.
Summary of changes:
packages/taler-util/src/invariants.ts | 2 +-
packages/taler-util/src/wallet-types.ts | 4 +-
packages/taler-wallet-core/src/backup/index.ts | 16 +++--
packages/taler-wallet-core/src/coinSelection.ts | 5 +-
packages/taler-wallet-core/src/common.ts | 51 ++++++++--------
packages/taler-wallet-core/src/db.ts | 4 +-
packages/taler-wallet-core/src/deposits.ts | 2 +-
packages/taler-wallet-core/src/exchanges.ts | 2 +-
.../src/instructedAmountConversion.ts | 22 +++++--
packages/taler-wallet-core/src/pay-merchant.ts | 8 +--
packages/taler-wallet-core/src/pay-peer-common.ts | 6 +-
.../taler-wallet-core/src/pay-peer-pull-credit.ts | 2 +-
.../taler-wallet-core/src/pay-peer-push-credit.ts | 2 +-
.../taler-wallet-core/src/pay-peer-push-debit.ts | 2 +-
packages/taler-wallet-core/src/recoup.ts | 4 +-
packages/taler-wallet-core/src/refresh.ts | 14 ++---
packages/taler-wallet-core/src/transactions.ts | 22 +++----
packages/taler-wallet-core/src/wallet.ts | 10 +---
packages/taler-wallet-core/src/withdraw.ts | 4 +-
.../src/cta/InvoicePay/views.tsx | 21 +++++--
.../src/cta/Payment/views.tsx | 32 ++++++----
.../src/cta/TransferPickup/views.tsx | 22 ++++---
.../src/popup/BalancePage.tsx | 2 +-
.../src/wallet/DepositPage/index.ts | 2 +-
.../src/wallet/DepositPage/state.ts | 68 +++++++++++++---------
.../src/wallet/DepositPage/stories.tsx | 15 ++++-
.../src/wallet/DepositPage/test.ts | 57 ++++++++----------
.../src/wallet/DepositPage/views.tsx | 13 ++---
.../src/wallet/DeveloperPage.tsx | 15 +----
.../src/wallet/ManageAccount/views.tsx | 1 -
30 files changed, 235 insertions(+), 195 deletions(-)
diff --git a/packages/taler-util/src/invariants.ts
b/packages/taler-util/src/invariants.ts
index c6e9b8113..113d697c3 100644
--- a/packages/taler-util/src/invariants.ts
+++ b/packages/taler-util/src/invariants.ts
@@ -33,7 +33,7 @@ export class InvariantViolatedError extends Error {
*
* A violation of this invariant means that the database is inconsistent.
*/
-export function checkDbInvariant(b: boolean, m?: string): asserts b {
+export function checkDbInvariant(b: boolean, m: string): asserts b {
if (!b) {
if (m) {
throw Error(`BUG: database invariant failed (${m})`);
diff --git a/packages/taler-util/src/wallet-types.ts
b/packages/taler-util/src/wallet-types.ts
index 9301a9723..24a48b415 100644
--- a/packages/taler-util/src/wallet-types.ts
+++ b/packages/taler-util/src/wallet-types.ts
@@ -54,7 +54,7 @@ import {
canonicalizeBaseUrl,
} from "./index.js";
import { VersionMatchResult } from "./libtool-version.js";
-import { PaytoUri } from "./payto.js";
+import { PaytoString, PaytoUri, codecForPaytoString } from "./payto.js";
import { AgeCommitmentProof } from "./taler-crypto.js";
import { TalerErrorCode } from "./taler-error-codes.js";
import {
@@ -229,11 +229,13 @@ interface GetPlanForWalletInitiatedOperation {
export interface ConvertAmountRequest {
amount: AmountString;
type: TransactionAmountMode;
+ depositPaytoUri: PaytoString;
}
export const codecForConvertAmountRequest =
buildCodecForObject<ConvertAmountRequest>()
.property("amount", codecForAmountString())
+ .property("depositPaytoUri", codecForPaytoString())
.property(
"type",
codecForEither(
diff --git a/packages/taler-wallet-core/src/backup/index.ts
b/packages/taler-wallet-core/src/backup/index.ts
index 15904b470..09d5ae75d 100644
--- a/packages/taler-wallet-core/src/backup/index.ts
+++ b/packages/taler-wallet-core/src/backup/index.ts
@@ -805,9 +805,10 @@ async function backupRecoveryTheirs(
let backupStateEntry: ConfigRecord | undefined = await tx.config.get(
ConfigRecordKey.WalletBackupState,
);
- checkDbInvariant(!!backupStateEntry);
+ checkDbInvariant(!!backupStateEntry, `no backup entry`);
checkDbInvariant(
backupStateEntry.key === ConfigRecordKey.WalletBackupState,
+ `backup entry inconsistent`,
);
backupStateEntry.value.lastBackupNonce = undefined;
backupStateEntry.value.lastBackupTimestamp = undefined;
@@ -913,7 +914,10 @@ export async function provideBackupState(
},
);
if (bs) {
- checkDbInvariant(bs.key === ConfigRecordKey.WalletBackupState);
+ checkDbInvariant(
+ bs.key === ConfigRecordKey.WalletBackupState,
+ `backup entry inconsistent`,
+ );
return bs.value;
}
// We need to generate the key outside of the transaction
@@ -941,6 +945,7 @@ export async function provideBackupState(
}
checkDbInvariant(
backupStateEntry.key === ConfigRecordKey.WalletBackupState,
+ `backup entry inconsistent`,
);
return backupStateEntry.value;
});
@@ -952,7 +957,10 @@ export async function getWalletBackupState(
): Promise<WalletBackupConfState> {
const bs = await tx.config.get(ConfigRecordKey.WalletBackupState);
checkDbInvariant(!!bs, "wallet backup state should be in DB");
- checkDbInvariant(bs.key === ConfigRecordKey.WalletBackupState);
+ checkDbInvariant(
+ bs.key === ConfigRecordKey.WalletBackupState,
+ `backup entry inconsistent`,
+ );
return bs.value;
}
@@ -962,7 +970,7 @@ export async function setWalletDeviceId(
): Promise<void> {
await provideBackupState(wex);
await wex.db.runReadWriteTx({ storeNames: ["config"] }, async (tx) => {
- let backupStateEntry: ConfigRecord | undefined = await tx.config.get(
+ const backupStateEntry: ConfigRecord | undefined = await tx.config.get(
ConfigRecordKey.WalletBackupState,
);
if (
diff --git a/packages/taler-wallet-core/src/coinSelection.ts
b/packages/taler-wallet-core/src/coinSelection.ts
index a60e41ecd..db6384c93 100644
--- a/packages/taler-wallet-core/src/coinSelection.ts
+++ b/packages/taler-wallet-core/src/coinSelection.ts
@@ -691,7 +691,7 @@ export function checkAccountRestriction(
switch (myRestriction.type) {
case "deny":
return { ok: false };
- case "regex":
+ case "regex": {
const regex = new RegExp(myRestriction.payto_regex);
if (!regex.test(paytoUri)) {
return {
@@ -700,6 +700,7 @@ export function checkAccountRestriction(
hintI18n: myRestriction.human_hint_i18n,
};
}
+ }
}
}
return {
@@ -909,7 +910,7 @@ async function selectPayCandidates(
coinAvail.exchangeBaseUrl,
coinAvail.denomPubHash,
]);
- checkDbInvariant(!!denom);
+ checkDbInvariant(!!denom, `denomination of a coin is missing hash:
${coinAvail.denomPubHash}`);
if (denom.isRevoked) {
logger.trace("denom is revoked");
continue;
diff --git a/packages/taler-wallet-core/src/common.ts
b/packages/taler-wallet-core/src/common.ts
index 755c46188..00d462d6f 100644
--- a/packages/taler-wallet-core/src/common.ts
+++ b/packages/taler-wallet-core/src/common.ts
@@ -121,7 +121,7 @@ export async function makeCoinAvailable(
coinRecord.exchangeBaseUrl,
coinRecord.denomPubHash,
]);
- checkDbInvariant(!!denom);
+ checkDbInvariant(!!denom, `denomination of a coin is missing hash:
${coinRecord.denomPubHash}`);
const ageRestriction = coinRecord.maxAge;
let car = await tx.coinAvailability.get([
coinRecord.exchangeBaseUrl,
@@ -175,13 +175,13 @@ export async function spendCoins(
coin.exchangeBaseUrl,
coin.denomPubHash,
);
- checkDbInvariant(!!denom);
+ checkDbInvariant(!!denom, `denomination of a coin is missing hash:
${coin.denomPubHash}`);
const coinAvailability = await tx.coinAvailability.get([
coin.exchangeBaseUrl,
coin.denomPubHash,
coin.maxAge,
]);
- checkDbInvariant(!!coinAvailability);
+ checkDbInvariant(!!coinAvailability, `age denom info is missing for
${coin.maxAge}`);
const contrib = csi.contributions[i];
if (coin.status !== CoinStatus.Fresh) {
const alloc = coin.spendAllocation;
@@ -213,7 +213,6 @@ export async function spendCoins(
amount: Amounts.stringify(remaining.amount),
coinPub: coin.coinPub,
});
- checkDbInvariant(!!coinAvailability);
if (coinAvailability.freshCoinCount === 0) {
throw Error(
`invalid coin count ${coinAvailability.freshCoinCount} in DB`,
@@ -557,6 +556,28 @@ export function getAutoRefreshExecuteThreshold(d: {
return AbsoluteTime.addDuration(expireWithdraw, deltaDiv);
}
+/**
+ * Type and schema definitions for pending tasks in the wallet.
+ *
+ * These are only used internally, and are not part of the stable public
+ * interface to the wallet.
+ */
+
+export enum PendingTaskType {
+ ExchangeUpdate = "exchange-update",
+ Purchase = "purchase",
+ Refresh = "refresh",
+ Recoup = "recoup",
+ RewardPickup = "reward-pickup",
+ Withdraw = "withdraw",
+ Deposit = "deposit",
+ Backup = "backup",
+ PeerPushDebit = "peer-push-debit",
+ PeerPullCredit = "peer-pull-credit",
+ PeerPushCredit = "peer-push-credit",
+ PeerPullDebit = "peer-pull-debit",
+}
+
/**
* Parsed representation of task identifiers.
*/
@@ -747,28 +768,6 @@ export interface TransactionContext {
deleteTransaction(): Promise<void>;
}
-/**
- * Type and schema definitions for pending tasks in the wallet.
- *
- * These are only used internally, and are not part of the stable public
- * interface to the wallet.
- */
-
-export enum PendingTaskType {
- ExchangeUpdate = "exchange-update",
- Purchase = "purchase",
- Refresh = "refresh",
- Recoup = "recoup",
- RewardPickup = "reward-pickup",
- Withdraw = "withdraw",
- Deposit = "deposit",
- Backup = "backup",
- PeerPushDebit = "peer-push-debit",
- PeerPullCredit = "peer-pull-credit",
- PeerPushCredit = "peer-push-credit",
- PeerPullDebit = "peer-pull-debit",
-}
-
declare const __taskIdStr: unique symbol;
export type TaskIdStr = string & { [__taskIdStr]: true };
diff --git a/packages/taler-wallet-core/src/db.ts
b/packages/taler-wallet-core/src/db.ts
index 640d94753..ad9b4f1cb 100644
--- a/packages/taler-wallet-core/src/db.ts
+++ b/packages/taler-wallet-core/src/db.ts
@@ -2941,6 +2941,8 @@ export interface DbDump {
};
}
+const logger = new Logger("db.ts");
+
export async function exportSingleDb(
idb: IDBFactory,
dbName: string,
@@ -3082,8 +3084,6 @@ export interface FixupDescription {
*/
export const walletDbFixups: FixupDescription[] = [];
-const logger = new Logger("db.ts");
-
export async function applyFixups(
db: DbAccess<typeof WalletStoresV1>,
): Promise<void> {
diff --git a/packages/taler-wallet-core/src/deposits.ts
b/packages/taler-wallet-core/src/deposits.ts
index c4cd98d73..32b22c1ef 100644
--- a/packages/taler-wallet-core/src/deposits.ts
+++ b/packages/taler-wallet-core/src/deposits.ts
@@ -441,7 +441,7 @@ async function refundDepositGroup(
{ storeNames: ["coins"] },
async (tx) => {
const coinRecord = await tx.coins.get(coinPub);
- checkDbInvariant(!!coinRecord);
+ checkDbInvariant(!!coinRecord, `coin ${coinPub} not found in DB`);
return coinRecord.exchangeBaseUrl;
},
);
diff --git a/packages/taler-wallet-core/src/exchanges.ts
b/packages/taler-wallet-core/src/exchanges.ts
index d8063d561..fa3146c38 100644
--- a/packages/taler-wallet-core/src/exchanges.ts
+++ b/packages/taler-wallet-core/src/exchanges.ts
@@ -1548,7 +1548,7 @@ export async function updateExchangeFromUrlHandler(
r.cachebreakNextUpdate = false;
await tx.exchanges.put(r);
const drRowId = await tx.exchangeDetails.put(newDetails);
- checkDbInvariant(typeof drRowId.key === "number");
+ checkDbInvariant(typeof drRowId.key === "number", "exchange details key
is not a number");
for (const sk of keysInfo.signingKeys) {
// FIXME: validate signing keys before inserting them
diff --git a/packages/taler-wallet-core/src/instructedAmountConversion.ts
b/packages/taler-wallet-core/src/instructedAmountConversion.ts
index 1f7d95959..5b399a0a7 100644
--- a/packages/taler-wallet-core/src/instructedAmountConversion.ts
+++ b/packages/taler-wallet-core/src/instructedAmountConversion.ts
@@ -283,7 +283,7 @@ async function getAvailableDenoms(
coinAvail.exchangeBaseUrl,
coinAvail.denomPubHash,
]);
- checkDbInvariant(!!denom);
+ checkDbInvariant(!!denom, `denomination of a coin is missing hash:
${coinAvail.denomPubHash}`);
if (denom.isRevoked || !denom.isOffered) {
continue;
}
@@ -472,7 +472,7 @@ export async function getMaxDepositAmount(
export function getMaxDepositAmountForAvailableCoins(
denoms: AvailableCoins,
currency: string,
-) {
+): AmountWithFee {
const zero = Amounts.zeroOfCurrency(currency);
if (!denoms.list.length) {
// no coins in the database
@@ -663,8 +663,13 @@ function rankDenominationForWithdrawals(
//different exchanges may have different wireFee
//ranking should take the relative contribution in the exchange
//which is (value - denomFee / fixedFee)
- const rate1 = Amounts.divmod(d1.value, d1.denomWithdraw).quotient;
- const rate2 = Amounts.divmod(d2.value, d2.denomWithdraw).quotient;
+
+ const rate1 = Amounts.isZero(d1.denomWithdraw)
+ ? Number.MIN_SAFE_INTEGER
+ : Amounts.divmod(d1.value, d1.denomWithdraw).quotient;
+ const rate2 = Amounts.isZero(d2.denomWithdraw)
+ ? Number.MIN_SAFE_INTEGER
+ : Amounts.divmod(d2.value, d2.denomWithdraw).quotient;
const contribCmp = rate1 === rate2 ? 0 : rate1 < rate2 ? 1 : -1;
return (
contribCmp ||
@@ -719,8 +724,13 @@ function rankDenominationForDeposit(
//different exchanges may have different wireFee
//ranking should take the relative contribution in the exchange
//which is (value - denomFee / fixedFee)
- const rate1 = Amounts.divmod(d1.value, d1.denomDeposit).quotient;
- const rate2 = Amounts.divmod(d2.value, d2.denomDeposit).quotient;
+ const rate1 = Amounts.isZero(d1.denomDeposit)
+ ? Number.MIN_SAFE_INTEGER
+ : Amounts.divmod(d1.value, d1.denomDeposit).quotient;
+ const rate2 = Amounts.isZero(d2.denomDeposit)
+ ? Number.MIN_SAFE_INTEGER
+ : Amounts.divmod(d2.value, d2.denomDeposit).quotient;
+
const contribCmp = rate1 === rate2 ? 0 : rate1 < rate2 ? 1 : -1;
return (
contribCmp ||
diff --git a/packages/taler-wallet-core/src/pay-merchant.ts
b/packages/taler-wallet-core/src/pay-merchant.ts
index 090a11cf0..aa4919285 100644
--- a/packages/taler-wallet-core/src/pay-merchant.ts
+++ b/packages/taler-wallet-core/src/pay-merchant.ts
@@ -1028,11 +1028,11 @@ async function storeFirstPaySuccess(
purchase.merchantPaySig = payResponse.sig;
purchase.posConfirmation = payResponse.pos_confirmation;
const dl = purchase.download;
- checkDbInvariant(!!dl);
+ checkDbInvariant(!!dl, `purchase ${purchase.orderId} without ct
downloaded`);
const contractTermsRecord = await tx.contractTerms.get(
dl.contractTermsHash,
);
- checkDbInvariant(!!contractTermsRecord);
+ checkDbInvariant(!!contractTermsRecord, `no contract terms found for
purchase ${purchase.orderId}`);
const contractData = extractContractData(
contractTermsRecord.contractTermsRaw,
dl.contractTermsHash,
@@ -2155,7 +2155,7 @@ async function processPurchasePay(
logger.trace(`paying with session ID ${sessionId}`);
const payInfo = purchase.payInfo;
- checkDbInvariant(!!payInfo, "payInfo");
+ checkDbInvariant(!!payInfo, `purchase ${purchase.orderId} without payInfo`);
const download = await expectProposalDownload(wex, purchase);
@@ -2997,7 +2997,7 @@ async function processPurchaseAbortingRefund(
for (let i = 0; i < payCoinSelection.coinPubs.length; i++) {
const coinPub = payCoinSelection.coinPubs[i];
const coin = await tx.coins.get(coinPub);
- checkDbInvariant(!!coin, "expected coin to be present");
+ checkDbInvariant(!!coin, `coin not found for ${coinPub}`);
abortingCoins.push({
coin_pub: coinPub,
contribution: Amounts.stringify(payCoinSelection.coinContributions[i]),
diff --git a/packages/taler-wallet-core/src/pay-peer-common.ts
b/packages/taler-wallet-core/src/pay-peer-common.ts
index bfd39b657..a1729ced7 100644
--- a/packages/taler-wallet-core/src/pay-peer-common.ts
+++ b/packages/taler-wallet-core/src/pay-peer-common.ts
@@ -140,10 +140,10 @@ export async function getMergeReserveInfo(
{ storeNames: ["exchanges", "reserves"] },
async (tx) => {
const ex = await tx.exchanges.get(req.exchangeBaseUrl);
- checkDbInvariant(!!ex);
+ checkDbInvariant(!!ex, `no exchange record for ${req.exchangeBaseUrl}`);
if (ex.currentMergeReserveRowId != null) {
const reserve = await tx.reserves.get(ex.currentMergeReserveRowId);
- checkDbInvariant(!!reserve);
+ checkDbInvariant(!!reserve, `reserver ${ex.currentMergeReserveRowId}
missing in db`);
return reserve;
}
const reserve: ReserveRecord = {
@@ -151,7 +151,7 @@ export async function getMergeReserveInfo(
reservePub: newReservePair.pub,
};
const insertResp = await tx.reserves.put(reserve);
- checkDbInvariant(typeof insertResp.key === "number");
+ checkDbInvariant(typeof insertResp.key === "number", `reserve key is not
a number`);
reserve.rowId = insertResp.key;
ex.currentMergeReserveRowId = reserve.rowId;
await tx.exchanges.put(ex);
diff --git a/packages/taler-wallet-core/src/pay-peer-pull-credit.ts
b/packages/taler-wallet-core/src/pay-peer-pull-credit.ts
index 840c244d0..14b3eeaf0 100644
--- a/packages/taler-wallet-core/src/pay-peer-pull-credit.ts
+++ b/packages/taler-wallet-core/src/pay-peer-pull-credit.ts
@@ -1039,7 +1039,7 @@ export async function initiatePeerPullPayment(
const withdrawalGroupId = encodeCrock(getRandomBytes(32));
const mergeReserveRowId = mergeReserveInfo.rowId;
- checkDbInvariant(!!mergeReserveRowId);
+ checkDbInvariant(!!mergeReserveRowId, `merge reserve for ${exchangeBaseUrl}
without rowid`);
const contractEncNonce = encodeCrock(getRandomBytes(24));
diff --git a/packages/taler-wallet-core/src/pay-peer-push-credit.ts
b/packages/taler-wallet-core/src/pay-peer-push-credit.ts
index 93f1a63a7..1476a0f4b 100644
--- a/packages/taler-wallet-core/src/pay-peer-push-credit.ts
+++ b/packages/taler-wallet-core/src/pay-peer-push-credit.ts
@@ -872,7 +872,7 @@ export async function processPeerPushCredit(
`processing peerPushCredit in state ${peerInc.status.toString(16)}`,
);
- checkDbInvariant(!!contractTerms);
+ checkDbInvariant(!!contractTerms, `not contract terms for peer push
${peerPushCreditId}`);
switch (peerInc.status) {
case PeerPushCreditStatus.PendingMergeKycRequired: {
diff --git a/packages/taler-wallet-core/src/pay-peer-push-debit.ts
b/packages/taler-wallet-core/src/pay-peer-push-debit.ts
index 6452407ff..3a936fb04 100644
--- a/packages/taler-wallet-core/src/pay-peer-push-debit.ts
+++ b/packages/taler-wallet-core/src/pay-peer-push-debit.ts
@@ -406,7 +406,7 @@ async function handlePurseCreationConflict(
const instructedAmount = Amounts.parseOrThrow(peerPushInitiation.amount);
const sel = peerPushInitiation.coinSel;
- checkDbInvariant(!!sel);
+ checkDbInvariant(!!sel, `no coin selected for peer push initiation
${peerPushInitiation.pursePub}`);
const repair: PreviousPayCoins = [];
diff --git a/packages/taler-wallet-core/src/recoup.ts
b/packages/taler-wallet-core/src/recoup.ts
index 6a09f9a0e..be5731b0b 100644
--- a/packages/taler-wallet-core/src/recoup.ts
+++ b/packages/taler-wallet-core/src/recoup.ts
@@ -199,8 +199,8 @@ async function recoupRefreshCoin(
revokedCoin.exchangeBaseUrl,
revokedCoin.denomPubHash,
);
- checkDbInvariant(!!oldCoinDenom);
- checkDbInvariant(!!revokedCoinDenom);
+ checkDbInvariant(!!oldCoinDenom, `no denom for coin, hash
${oldCoin.denomPubHash}`);
+ checkDbInvariant(!!revokedCoinDenom, `no revoked denom for coin, hash
${revokedCoin.denomPubHash}`);
revokedCoin.status = CoinStatus.Dormant;
if (!revokedCoin.spendAllocation) {
// We don't know what happened to this coin
diff --git a/packages/taler-wallet-core/src/refresh.ts
b/packages/taler-wallet-core/src/refresh.ts
index 38b8b097c..f160e0731 100644
--- a/packages/taler-wallet-core/src/refresh.ts
+++ b/packages/taler-wallet-core/src/refresh.ts
@@ -387,7 +387,6 @@ async function getCoinAvailabilityForDenom(
denom: DenominationInfo,
ageRestriction: number,
): Promise<CoinAvailabilityRecord> {
- checkDbInvariant(!!denom);
let car = await tx.coinAvailability.get([
denom.exchangeBaseUrl,
denom.denomPubHash,
@@ -538,7 +537,7 @@ async function destroyRefreshSession(
denom,
oldCoin.maxAge,
);
- checkDbInvariant(car.pendingRefreshOutputCount != null);
+ checkDbInvariant(car.pendingRefreshOutputCount != null, `no
pendingRefreshOutputCount for denom ${dph}`);
car.pendingRefreshOutputCount =
car.pendingRefreshOutputCount - refreshSession.newDenoms[i].count;
await tx.coinAvailability.put(car);
@@ -1251,7 +1250,7 @@ async function refreshReveal(
coin.exchangeBaseUrl,
coin.denomPubHash,
);
- checkDbInvariant(!!denomInfo);
+ checkDbInvariant(!!denomInfo, `no denom with hash
${coin.denomPubHash}`);
const car = await getCoinAvailabilityForDenom(
wex,
tx,
@@ -1261,6 +1260,7 @@ async function refreshReveal(
checkDbInvariant(
car.pendingRefreshOutputCount != null &&
car.pendingRefreshOutputCount > 0,
+ `no pendingRefreshOutputCount for denom ${coin.denomPubHash} age
${coin.maxAge}`
);
car.pendingRefreshOutputCount--;
car.freshCoinCount++;
@@ -1568,8 +1568,8 @@ async function applyRefreshToOldCoins(
coin.denomPubHash,
coin.maxAge,
]);
- checkDbInvariant(!!coinAv);
- checkDbInvariant(coinAv.freshCoinCount > 0);
+ checkDbInvariant(!!coinAv, `no denom info for ${coin.denomPubHash} age
${coin.maxAge}`);
+ checkDbInvariant(coinAv.freshCoinCount > 0, `no fresh coins for
${coin.denomPubHash}`);
coinAv.freshCoinCount--;
await tx.coinAvailability.put(coinAv);
break;
@@ -1779,7 +1779,7 @@ export async function forceRefresh(
],
},
async (tx) => {
- let coinPubs: CoinRefreshRequest[] = [];
+ const coinPubs: CoinRefreshRequest[] = [];
for (const c of req.refreshCoinSpecs) {
const coin = await tx.coins.get(c.coinPub);
if (!coin) {
@@ -1791,7 +1791,7 @@ export async function forceRefresh(
coin.exchangeBaseUrl,
coin.denomPubHash,
);
- checkDbInvariant(!!denom);
+ checkDbInvariant(!!denom, `no denom hash: ${coin.denomPubHash}`);
coinPubs.push({
coinPub: c.coinPub,
amount: c.amount ?? denom.value,
diff --git a/packages/taler-wallet-core/src/transactions.ts
b/packages/taler-wallet-core/src/transactions.ts
index 1adfa5425..72aff319a 100644
--- a/packages/taler-wallet-core/src/transactions.ts
+++ b/packages/taler-wallet-core/src/transactions.ts
@@ -404,7 +404,7 @@ export async function getTransactionById(
const debit = await tx.peerPushDebit.get(parsedTx.pursePub);
if (!debit) throw Error("not found");
const ct = await tx.contractTerms.get(debit.contractTermsHash);
- checkDbInvariant(!!ct);
+ checkDbInvariant(!!ct, `no contract terms for p2p push
${parsedTx.pursePub}`);
return buildTransactionForPushPaymentDebit(
debit,
ct.contractTermsRaw,
@@ -428,7 +428,7 @@ export async function getTransactionById(
const pushInc = await tx.peerPushCredit.get(peerPushCreditId);
if (!pushInc) throw Error("not found");
const ct = await tx.contractTerms.get(pushInc.contractTermsHash);
- checkDbInvariant(!!ct);
+ checkDbInvariant(!!ct, `no contract terms for p2p push
${peerPushCreditId}`);
let wg: WithdrawalGroupRecord | undefined = undefined;
let wgOrt: OperationRetryRecord | undefined = undefined;
@@ -440,7 +440,7 @@ export async function getTransactionById(
}
}
const pushIncOpId = TaskIdentifiers.forPeerPushCredit(pushInc);
- let pushIncOrt = await tx.operationRetries.get(pushIncOpId);
+ const pushIncOrt = await tx.operationRetries.get(pushIncOpId);
return buildTransactionForPeerPushCredit(
pushInc,
@@ -468,7 +468,7 @@ export async function getTransactionById(
const pushInc = await tx.peerPullCredit.get(pursePub);
if (!pushInc) throw Error("not found");
const ct = await tx.contractTerms.get(pushInc.contractTermsHash);
- checkDbInvariant(!!ct);
+ checkDbInvariant(!!ct, `no contract terms for p2p push ${pursePub}`);
let wg: WithdrawalGroupRecord | undefined = undefined;
let wgOrt: OperationRetryRecord | undefined = undefined;
@@ -1034,8 +1034,8 @@ function buildTransactionForPurchase(
}));
const timestamp = purchaseRecord.timestampAccept;
- checkDbInvariant(!!timestamp);
- checkDbInvariant(!!purchaseRecord.payInfo);
+ checkDbInvariant(!!timestamp, `purchase ${purchaseRecord.orderId} without
accepted time`);
+ checkDbInvariant(!!purchaseRecord.payInfo, `purchase
${purchaseRecord.orderId} without payinfo`);
const txState = computePayMerchantTransactionState(purchaseRecord);
return {
@@ -1175,7 +1175,7 @@ export async function getTransactions(
return;
}
const ct = await tx.contractTerms.get(pi.contractTermsHash);
- checkDbInvariant(!!ct);
+ checkDbInvariant(!!ct, `no contract terms for p2p push
${pi.pursePub}`);
transactions.push(
buildTransactionForPushPaymentDebit(pi, ct.contractTermsRaw),
);
@@ -1249,9 +1249,9 @@ export async function getTransactions(
}
}
const pushIncOpId = TaskIdentifiers.forPeerPushCredit(pi);
- let pushIncOrt = await tx.operationRetries.get(pushIncOpId);
+ const pushIncOrt = await tx.operationRetries.get(pushIncOpId);
- checkDbInvariant(!!ct);
+ checkDbInvariant(!!ct, `no contract terms for p2p push
${pi.pursePub}`);
transactions.push(
buildTransactionForPeerPushCredit(
pi,
@@ -1283,9 +1283,9 @@ export async function getTransactions(
}
}
const pushIncOpId = TaskIdentifiers.forPeerPullPaymentInitiation(pi);
- let pushIncOrt = await tx.operationRetries.get(pushIncOpId);
+ const pushIncOrt = await tx.operationRetries.get(pushIncOpId);
- checkDbInvariant(!!ct);
+ checkDbInvariant(!!ct, `no contract terms for p2p push
${pi.pursePub}`);
transactions.push(
buildTransactionForPeerPullCredit(
pi,
diff --git a/packages/taler-wallet-core/src/wallet.ts
b/packages/taler-wallet-core/src/wallet.ts
index 86ea7bb4c..d98106d1f 100644
--- a/packages/taler-wallet-core/src/wallet.ts
+++ b/packages/taler-wallet-core/src/wallet.ts
@@ -479,7 +479,7 @@ async function setCoinSuspended(
c.denomPubHash,
c.maxAge,
]);
- checkDbInvariant(!!coinAvailability);
+ checkDbInvariant(!!coinAvailability, `no denom info for
${c.denomPubHash} age ${c.maxAge}`);
if (suspended) {
if (c.status !== CoinStatus.Fresh) {
return;
@@ -1063,10 +1063,6 @@ async function dispatchRequestInternal(
const req = codecForPreparePayTemplateRequest().decode(payload);
return preparePayForTemplate(wex, req);
}
- case WalletApiOperation.CheckPayForTemplate: {
- const req = codecForCheckPayTemplateRequest().decode(payload);
- return checkPayForTemplate(wex, req);
- }
case WalletApiOperation.ConfirmPay: {
const req = codecForConfirmPayRequest().decode(payload);
let transactionId;
@@ -1403,7 +1399,7 @@ async function dispatchRequestInternal(
return;
}
wex.ws.exchangeCache.clear();
- checkDbInvariant(!!existingRec.id);
+ checkDbInvariant(!!existingRec.id, `no global exchange for
${j2s(key)}`);
await tx.globalCurrencyExchanges.delete(existingRec.id);
},
);
@@ -1452,7 +1448,7 @@ async function dispatchRequestInternal(
if (!existingRec) {
return;
}
- checkDbInvariant(!!existingRec.id);
+ checkDbInvariant(!!existingRec.id, `no global currency for
${j2s(key)}`);
await tx.globalCurrencyAuditors.delete(existingRec.id);
wex.ws.exchangeCache.clear();
},
diff --git a/packages/taler-wallet-core/src/withdraw.ts
b/packages/taler-wallet-core/src/withdraw.ts
index 1dc4e0999..b2cecea16 100644
--- a/packages/taler-wallet-core/src/withdraw.ts
+++ b/packages/taler-wallet-core/src/withdraw.ts
@@ -965,7 +965,7 @@ async function processPlanchetGenerate(
return getDenomInfo(wex, tx, exchangeBaseUrl, denomPubHash);
},
);
- checkDbInvariant(!!denom);
+ checkDbInvariant(!!denom, `no denom info for ${denomPubHash}`);
const r = await wex.cryptoApi.createPlanchet({
denomPub: denom.denomPub,
feeWithdraw: Amounts.parseOrThrow(denom.feeWithdraw),
@@ -2314,7 +2314,7 @@ export async function getFundingPaytoUris(
withdrawalGroupId: string,
): Promise<string[]> {
const withdrawalGroup = await tx.withdrawalGroups.get(withdrawalGroupId);
- checkDbInvariant(!!withdrawalGroup);
+ checkDbInvariant(!!withdrawalGroup, `no withdrawal for
${withdrawalGroupId}`);
checkDbInvariant(
withdrawalGroup.instructedAmount !== undefined,
"can't get funding uri from uninitialized wg",
diff --git a/packages/taler-wallet-webextension/src/cta/InvoicePay/views.tsx
b/packages/taler-wallet-webextension/src/cta/InvoicePay/views.tsx
index 547d5ac9a..0d8035136 100644
--- a/packages/taler-wallet-webextension/src/cta/InvoicePay/views.tsx
+++ b/packages/taler-wallet-webextension/src/cta/InvoicePay/views.tsx
@@ -24,12 +24,21 @@ import {
InvoicePaymentDetails,
} from "../../wallet/Transaction.js";
import { State } from "./index.js";
+import { AbsoluteTime, Duration } from "@gnu-taler/taler-util";
export function ReadyView(
state: State.Ready | State.NoBalanceForCurrency | State.NoEnoughBalance,
): VNode {
const { i18n } = useTranslationContext();
const { summary, effective, raw, expiration, uri, status, payStatus } =
state;
+
+ const inFiveMinutes = AbsoluteTime.addDuration(
+ AbsoluteTime.now(),
+ Duration.fromSpec({ minutes: 5 }),
+ );
+ const willExpireSoon =
+ expiration && AbsoluteTime.cmp(expiration, inFiveMinutes) === -1;
+
return (
<Fragment>
<section style={{ textAlign: "left" }}>
@@ -42,11 +51,13 @@ export function ReadyView(
/>
}
/>
- <Part
- title={i18n.str`Valid until`}
- text={<Time timestamp={expiration} format="dd MMMM yyyy, HH:mm" />}
- kind="neutral"
- />
+ {willExpireSoon && (
+ <Part
+ title={i18n.str`Expires at`}
+ text={<Time timestamp={expiration} format="HH:mm" />}
+ kind="neutral"
+ />
+ )}
</section>
<PaymentButtons
amount={effective}
diff --git a/packages/taler-wallet-webextension/src/cta/Payment/views.tsx
b/packages/taler-wallet-webextension/src/cta/Payment/views.tsx
index 68d161ab2..b1eee85ec 100644
--- a/packages/taler-wallet-webextension/src/cta/Payment/views.tsx
+++ b/packages/taler-wallet-webextension/src/cta/Payment/views.tsx
@@ -18,6 +18,7 @@ import {
AbsoluteTime,
Amounts,
MerchantContractTerms as ContractTerms,
+ Duration,
PreparePayResultType,
TranslatedString,
} from "@gnu-taler/taler-util";
@@ -54,6 +55,17 @@ export function BaseView(state: SupportedStates): VNode {
: Amounts.zeroOfCurrency(state.amount.currency)
: state.amount;
+ const expiration = !contractTerms.pay_deadline
+ ? undefined
+ : AbsoluteTime.fromProtocolTimestamp(contractTerms.pay_deadline);
+ const inFiveMinutes = AbsoluteTime.addDuration(
+ AbsoluteTime.now(),
+ Duration.fromSpec({ minutes: 5 }),
+ );
+ const willExpireSoon =
+ !expiration || expiration.t_ms === "never"
+ ? undefined
+ : AbsoluteTime.cmp(expiration, inFiveMinutes) === -1;
return (
<Fragment>
<ShowImportantMessage state={state} />
@@ -65,7 +77,12 @@ export function BaseView(state: SupportedStates): VNode {
<Fragment>
<i18n.Translate>Purchase</i18n.Translate>
- <AgeSign size={20} title={i18n.str`This purchase is age
restricted.`}>{contractTerms.minimum_age}+</AgeSign>
+ <AgeSign
+ size={20}
+ title={i18n.str`This purchase is age restricted.`}
+ >
+ {contractTerms.minimum_age}+
+ </AgeSign>
</Fragment>
) : (
<i18n.Translate>Purchase</i18n.Translate>
@@ -79,17 +96,10 @@ export function BaseView(state: SupportedStates): VNode {
text={<MerchantDetails merchant={contractTerms.merchant} />}
kind="neutral"
/>
- {contractTerms.pay_deadline && (
+ {willExpireSoon && (
<Part
- title={i18n.str`Valid until`}
- text={
- <Time
- timestamp={AbsoluteTime.fromProtocolTimestamp(
- contractTerms.pay_deadline,
- )}
- format="dd MMMM yyyy, HH:mm"
- />
- }
+ title={i18n.str`Expires at`}
+ text={<Time timestamp={expiration} format="HH:mm" />}
kind="neutral"
/>
)}
diff --git
a/packages/taler-wallet-webextension/src/cta/TransferPickup/views.tsx
b/packages/taler-wallet-webextension/src/cta/TransferPickup/views.tsx
index caa1b485a..e82c4fbd2 100644
--- a/packages/taler-wallet-webextension/src/cta/TransferPickup/views.tsx
+++ b/packages/taler-wallet-webextension/src/cta/TransferPickup/views.tsx
@@ -26,6 +26,7 @@ import {
} from "../../wallet/Transaction.js";
import { State } from "./index.js";
import { TermsOfService } from "../../components/TermsOfService/index.js";
+import { AbsoluteTime, Duration } from "@gnu-taler/taler-util";
export function ReadyView({
accept,
@@ -36,6 +37,12 @@ export function ReadyView({
raw,
}: State.Ready): VNode {
const { i18n } = useTranslationContext();
+ const inFiveMinutes = AbsoluteTime.addDuration(
+ AbsoluteTime.now(),
+ Duration.fromSpec({ minutes: 5 }),
+ );
+ const willExpireSoon =
+ expiration && AbsoluteTime.cmp(expiration, inFiveMinutes) === -1;
return (
<Fragment>
<section style={{ textAlign: "left" }}>
@@ -49,15 +56,16 @@ export function ReadyView({
/>
}
/>
-
- <Part
- title={i18n.str`Valid until`}
- text={<Time timestamp={expiration} format="dd MMMM yyyy, HH:mm" />}
- kind="neutral"
- />
+ {willExpireSoon && (
+ <Part
+ title={i18n.str`Expires at`}
+ text={<Time timestamp={expiration} format="HH:mm" />}
+ kind="neutral"
+ />
+ )}
</section>
<section>
- <TermsOfService key="terms" exchangeUrl={exchangeBaseUrl} >
+ <TermsOfService key="terms" exchangeUrl={exchangeBaseUrl}>
<Button variant="contained" color="success" onClick={accept.onClick}>
<i18n.Translate>
Receive {<Amount value={effective} />}
diff --git a/packages/taler-wallet-webextension/src/popup/BalancePage.tsx
b/packages/taler-wallet-webextension/src/popup/BalancePage.tsx
index 93770312e..73bd8e96d 100644
--- a/packages/taler-wallet-webextension/src/popup/BalancePage.tsx
+++ b/packages/taler-wallet-webextension/src/popup/BalancePage.tsx
@@ -180,7 +180,7 @@ export function BalanceView(state: State.Balances): VNode {
variant="contained"
onClick={state.goToWalletManualWithdraw.onClick}
>
- <i18n.Translate>Add</i18n.Translate>
+ <i18n.Translate>Receive</i18n.Translate>
</Button>
{currencyWithNonZeroAmount.length > 0 && (
<MultiActionButton
diff --git a/packages/taler-wallet-webextension/src/wallet/DepositPage/index.ts
b/packages/taler-wallet-webextension/src/wallet/DepositPage/index.ts
index 838739ad1..daba6aba4 100644
--- a/packages/taler-wallet-webextension/src/wallet/DepositPage/index.ts
+++ b/packages/taler-wallet-webextension/src/wallet/DepositPage/index.ts
@@ -94,9 +94,9 @@ export namespace State {
currentAccount: PaytoUri;
totalFee: AmountJson;
- totalToDeposit: AmountJson;
amount: AmountFieldHandler;
+ totalToDeposit: AmountFieldHandler;
account: SelectFieldHandler;
cancelHandler: ButtonHandler;
depositHandler: ButtonHandler;
diff --git a/packages/taler-wallet-webextension/src/wallet/DepositPage/state.ts
b/packages/taler-wallet-webextension/src/wallet/DepositPage/state.ts
index 97b2ab517..b674665cf 100644
--- a/packages/taler-wallet-webextension/src/wallet/DepositPage/state.ts
+++ b/packages/taler-wallet-webextension/src/wallet/DepositPage/state.ts
@@ -15,19 +15,18 @@
*/
import {
- AmountJson,
Amounts,
- DepositGroupFees,
KnownBankAccountsInfo,
parsePaytoUri,
PaytoUri,
stringifyPaytoUri,
+ TransactionAmountMode
} from "@gnu-taler/taler-util";
import { WalletApiOperation } from "@gnu-taler/taler-wallet-core";
+import { useTranslationContext } from "@gnu-taler/web-util/browser";
import { useState } from "preact/hooks";
import { alertFromError, useAlertContext } from "../../context/alert.js";
import { useBackendContext } from "../../context/backend.js";
-import { useTranslationContext } from "@gnu-taler/web-util/browser";
import { useAsyncAsHook } from "../../hooks/useAsyncAsHook.js";
import { RecursiveState } from "../../utils/index.js";
import { Props, State } from "./index.js";
@@ -83,8 +82,11 @@ export function useComponentState({
if (hook.hasError) {
return {
status: "error",
- error: alertFromError(i18n,
- i18n.str`Could not load balance information`, hook),
+ error: alertFromError(
+ i18n,
+ i18n.str`Could not load balance information`,
+ hook,
+ ),
};
}
const { accounts, balances } = hook.response;
@@ -141,21 +143,23 @@ export function useComponentState({
}
const firstAccount = accounts[0].uri;
const currentAccount = !selectedAccount ? firstAccount : selectedAccount;
-
- return () => {
- // eslint-disable-next-line react-hooks/rules-of-hooks
- const [amount, setAmount] = useState<AmountJson>(
- initialValue ?? ({} as any),
+ const zero = Amounts.zeroOfCurrency(currency)
+ return (): State => {
+ const [instructed, setInstructed] = useState(
+ {amount: initialValue ?? zero, type: TransactionAmountMode.Raw},
);
- const amountStr = Amounts.stringify(amount);
+ const amountStr = Amounts.stringify(instructed.amount);
const depositPaytoUri = stringifyPaytoUri(currentAccount);
- // eslint-disable-next-line react-hooks/rules-of-hooks
const hook = useAsyncAsHook(async () => {
- const fee = await api.wallet.call(WalletApiOperation.PrepareDeposit, {
- amount: amountStr,
- depositPaytoUri,
- });
+ const fee = await api.wallet.call(
+ WalletApiOperation.ConvertDepositAmount,
+ {
+ amount: amountStr,
+ type: instructed.type,
+ depositPaytoUri,
+ },
+ );
return { fee };
}, [amountStr, depositPaytoUri]);
@@ -183,18 +187,16 @@ export function useComponentState({
const totalFee =
fee !== undefined
- ? Amounts.sum([fee.fees.wire, fee.fees.coin, fee.fees.refresh]).amount
+ ? Amounts.sub(fee.effectiveAmount, fee.rawAmount).amount
: Amounts.zeroOfCurrency(currency);
- const totalToDeposit =
- fee !== undefined
- ? Amounts.sub(amount, totalFee).amount
- : Amounts.zeroOfCurrency(currency);
+ const totalToDeposit = Amounts.parseOrThrow(fee.rawAmount);
+ const totalEffective = Amounts.parseOrThrow(fee.effectiveAmount);
- const isDirty = amount !== initialValue;
+ const isDirty = instructed.amount !== initialValue;
const amountError = !isDirty
? undefined
- : Amounts.cmp(balance, amount) === -1
+ : Amounts.cmp(balance, totalEffective) === -1
? `Too much, your current balance is
${Amounts.stringifyValue(balance)}`
: undefined;
@@ -207,7 +209,7 @@ export function useComponentState({
if (!currency) return;
const depositPaytoUri = stringifyPaytoUri(currentAccount);
- const amountStr = Amounts.stringify(amount);
+ const amountStr = Amounts.stringify(totalEffective);
await api.wallet.call(WalletApiOperation.CreateDepositGroup, {
amount: amountStr,
depositPaytoUri,
@@ -220,8 +222,19 @@ export function useComponentState({
error: undefined,
currency,
amount: {
- value: amount,
- onInput: pushAlertOnError(async (a) => setAmount(a)),
+ value: totalEffective,
+ onInput: pushAlertOnError(async (a) => setInstructed({
+ amount: a,
+ type: TransactionAmountMode.Effective,
+ })),
+ error: amountError,
+ },
+ totalToDeposit: {
+ value: totalToDeposit,
+ onInput: pushAlertOnError(async (a) => setInstructed({
+ amount: a,
+ type: TransactionAmountMode.Raw,
+ })),
error: amountError,
},
onAddAccount: {
@@ -244,7 +257,6 @@ export function useComponentState({
onClick: unableToDeposit ? undefined : pushAlertOnError(doSend),
},
totalFee,
- totalToDeposit,
};
};
}
@@ -269,7 +281,7 @@ export function createLabelsForBankAccount(
): { [value: string]: string } {
const initialList: Record<string, string> = {};
if (!knownBankAccounts.length) return initialList;
- return knownBankAccounts.reduce((prev, cur, i) => {
+ return knownBankAccounts.reduce((prev, cur) => {
prev[stringifyPaytoUri(cur.uri)] = cur.alias;
return prev;
}, initialList);
diff --git
a/packages/taler-wallet-webextension/src/wallet/DepositPage/stories.tsx
b/packages/taler-wallet-webextension/src/wallet/DepositPage/stories.tsx
index c23f83fdd..0ed62220b 100644
--- a/packages/taler-wallet-webextension/src/wallet/DepositPage/stories.tsx
+++ b/packages/taler-wallet-webextension/src/wallet/DepositPage/stories.tsx
@@ -53,7 +53,10 @@ export const WithNoAccountForIBAN =
tests.createExample(ReadyView, {
onClick: nullFunction,
},
totalFee: Amounts.zeroOfCurrency("USD"),
- totalToDeposit: Amounts.parseOrThrow("USD:10"),
+ totalToDeposit: {
+ onInput:nullFunction,
+ value: Amounts.parseOrThrow("USD:10"),
+ },
// onCalculateFee: alwaysReturnFeeToOne,
});
@@ -82,7 +85,10 @@ export const WithIBANAccountTypeSelected =
tests.createExample(ReadyView, {
onClick: nullFunction,
},
totalFee: Amounts.zeroOfCurrency("USD"),
- totalToDeposit: Amounts.parseOrThrow("USD:10"),
+ totalToDeposit: {
+ onInput:nullFunction,
+ value: Amounts.parseOrThrow("USD:10"),
+ },
// onCalculateFee: alwaysReturnFeeToOne,
});
@@ -111,6 +117,9 @@ export const NewBitcoinAccountTypeSelected =
tests.createExample(ReadyView, {
onClick: nullFunction,
},
totalFee: Amounts.zeroOfCurrency("USD"),
- totalToDeposit: Amounts.parseOrThrow("USD:10"),
+ totalToDeposit: {
+ onInput:nullFunction,
+ value: Amounts.parseOrThrow("USD:10"),
+ },
// onCalculateFee: alwaysReturnFeeToOne,
});
diff --git a/packages/taler-wallet-webextension/src/wallet/DepositPage/test.ts
b/packages/taler-wallet-webextension/src/wallet/DepositPage/test.ts
index 157cb868a..1144095e1 100644
--- a/packages/taler-wallet-webextension/src/wallet/DepositPage/test.ts
+++ b/packages/taler-wallet-webextension/src/wallet/DepositPage/test.ts
@@ -20,17 +20,16 @@
*/
import {
+ AmountResponse,
Amounts,
AmountString,
- DepositGroupFees,
parsePaytoUri,
- PrepareDepositResponse,
ScopeType,
- stringifyPaytoUri,
+ stringifyPaytoUri
} from "@gnu-taler/taler-util";
import { WalletApiOperation } from "@gnu-taler/taler-wallet-core";
-import { expect } from "chai";
import * as tests from "@gnu-taler/web-util/testing";
+import { expect } from "chai";
import { nullFunction } from "../../mui/handlers.js";
import { createWalletApiMock } from "../../test-utils.js";
@@ -38,24 +37,14 @@ import { useComponentState } from "./state.js";
const currency = "EUR";
const amount = `${currency}:0`;
-const withoutFee = (): PrepareDepositResponse => ({
- effectiveDepositAmount: `${currency}:5` as AmountString,
- totalDepositCost: `${currency}:5` as AmountString,
- fees: {
- coin: Amounts.stringify(`${currency}:0`),
- wire: Amounts.stringify(`${currency}:0`),
- refresh: Amounts.stringify(`${currency}:0`),
- },
+const withoutFee = (value: number): AmountResponse => ({
+ effectiveAmount: `${currency}:${value}` as AmountString,
+ rawAmount: `${currency}:${value}` as AmountString,
});
-const withSomeFee = (): PrepareDepositResponse => ({
- effectiveDepositAmount: `${currency}:5` as AmountString,
- totalDepositCost: `${currency}:5` as AmountString,
- fees: {
- coin: Amounts.stringify(`${currency}:1`),
- wire: Amounts.stringify(`${currency}:1`),
- refresh: Amounts.stringify(`${currency}:1`),
- },
+const withSomeFee = (value: number, fee: number): AmountResponse => ({
+ effectiveAmount: `${currency}:${value}` as AmountString,
+ rawAmount: `${currency}:${value - fee}` as AmountString,
});
describe("DepositPage states", () => {
@@ -195,9 +184,9 @@ describe("DepositPage states", () => {
},
);
handler.addWalletCallResponse(
- WalletApiOperation.PrepareDeposit,
+ WalletApiOperation.ConvertDepositAmount,
undefined,
- withoutFee(),
+ withoutFee(0),
);
const hookBehavior = await tests.hookBehaveLikeThis(
@@ -255,15 +244,15 @@ describe("DepositPage states", () => {
},
);
handler.addWalletCallResponse(
- WalletApiOperation.PrepareDeposit,
+ WalletApiOperation.ConvertDepositAmount,
undefined,
- withoutFee(),
+ withoutFee(0),
);
handler.addWalletCallResponse(
- WalletApiOperation.PrepareDeposit,
+ WalletApiOperation.ConvertDepositAmount,
undefined,
- withoutFee(),
+ withoutFee(0),
);
const accountSelected = stringifyPaytoUri(ibanPayto.uri);
@@ -345,19 +334,19 @@ describe("DepositPage states", () => {
},
);
handler.addWalletCallResponse(
- WalletApiOperation.PrepareDeposit,
+ WalletApiOperation.ConvertDepositAmount,
undefined,
- withoutFee(),
+ withoutFee(0),
);
handler.addWalletCallResponse(
- WalletApiOperation.PrepareDeposit,
+ WalletApiOperation.ConvertDepositAmount,
undefined,
- withSomeFee(),
+ withSomeFee(10,3),
);
handler.addWalletCallResponse(
- WalletApiOperation.PrepareDeposit,
+ WalletApiOperation.ConvertDepositAmount,
undefined,
- withSomeFee(),
+ withSomeFee(10,3),
);
const accountSelected = stringifyPaytoUri(ibanPayto.uri);
@@ -404,7 +393,7 @@ describe("DepositPage states", () => {
expect(state.account.value).eq(accountSelected);
expect(state.amount.value).deep.eq(Amounts.parseOrThrow("EUR:10"));
expect(state.totalFee).deep.eq(Amounts.parseOrThrow(`${currency}:3`));
- expect(state.totalToDeposit).deep.eq(
+ expect(state.totalToDeposit.value).deep.eq(
Amounts.parseOrThrow(`${currency}:7`),
);
expect(state.depositHandler.onClick).not.undefined;
@@ -416,7 +405,7 @@ describe("DepositPage states", () => {
expect(state.account.value).eq(accountSelected);
expect(state.amount.value).deep.eq(Amounts.parseOrThrow("EUR:10"));
expect(state.totalFee).deep.eq(Amounts.parseOrThrow(`${currency}:3`));
- expect(state.totalToDeposit).deep.eq(
+ expect(state.totalToDeposit.value).deep.eq(
Amounts.parseOrThrow(`${currency}:7`),
);
expect(state.depositHandler.onClick).not.undefined;
diff --git
a/packages/taler-wallet-webextension/src/wallet/DepositPage/views.tsx
b/packages/taler-wallet-webextension/src/wallet/DepositPage/views.tsx
index 908becb04..b3607ebba 100644
--- a/packages/taler-wallet-webextension/src/wallet/DepositPage/views.tsx
+++ b/packages/taler-wallet-webextension/src/wallet/DepositPage/views.tsx
@@ -26,7 +26,7 @@ import { Grid } from "../../mui/Grid.js";
import { State } from "./index.js";
export function AmountOrCurrencyErrorView(
- p: State.AmountOrCurrencyError,
+ _p: State.AmountOrCurrencyError,
): VNode {
const { i18n } = useTranslationContext();
@@ -145,7 +145,7 @@ export function ReadyView(state: State.Ready): VNode {
</p>
<Grid container spacing={2} columns={1}>
<Grid item xs={1}>
- <AmountField label={i18n.str`Amount`} handler={state.amount} />
+ <AmountField label={i18n.str`Brut amount`} handler={state.amount}
/>
</Grid>
<Grid item xs={1}>
<AmountField
@@ -156,12 +156,7 @@ export function ReadyView(state: State.Ready): VNode {
/>
</Grid>
<Grid item xs={1}>
- <AmountField
- label={i18n.str`Total deposit`}
- handler={{
- value: state.totalToDeposit,
- }}
- />
+ <AmountField label={i18n.str`Net amount`}
handler={state.totalToDeposit} />
</Grid>
</Grid>
</section>
@@ -180,7 +175,7 @@ export function ReadyView(state: State.Ready): VNode {
) : (
<Button variant="contained" onClick={state.depositHandler.onClick}>
<i18n.Translate>
- Deposit {Amounts.stringifyValue(state.totalToDeposit)}{" "}
+
Deposit {Amounts.stringifyValue(state.totalToDeposit.value)}{" "}
{state.currency}
</i18n.Translate>
</Button>
diff --git a/packages/taler-wallet-webextension/src/wallet/DeveloperPage.tsx
b/packages/taler-wallet-webextension/src/wallet/DeveloperPage.tsx
index 7b6ac8895..8f23c0685 100644
--- a/packages/taler-wallet-webextension/src/wallet/DeveloperPage.tsx
+++ b/packages/taler-wallet-webextension/src/wallet/DeveloperPage.tsx
@@ -17,13 +17,12 @@
import {
AbsoluteTime,
Amounts,
- CoinDumpJson,
CoinStatus,
ExchangeTosStatus,
LogLevel,
NotificationType,
ScopeType,
- stringifyWithdrawExchange,
+ stringifyWithdrawExchange
} from "@gnu-taler/taler-util";
import { WalletApiOperation } from "@gnu-taler/taler-wallet-core";
import { useTranslationContext } from "@gnu-taler/web-util/browser";
@@ -52,7 +51,6 @@ import { Grid } from "../mui/Grid.js";
import { Paper } from "../mui/Paper.js";
import { TextField } from "../mui/TextField.js";
-type CoinsInfo = CoinDumpJson["coins"];
type CalculatedCoinfInfo = {
// ageKeysCount: number | undefined;
denom_value: number;
@@ -68,15 +66,7 @@ type SplitedCoinInfo = {
usable: CalculatedCoinfInfo[];
};
-export interface Props {
- // FIXME: Pending operations don't exist anymore.
-}
-
-function hashObjectId(o: any): string {
- return JSON.stringify(o);
-}
-
-export function DeveloperPage({}: Props): VNode {
+export function DeveloperPage(): VNode {
const { i18n } = useTranslationContext();
const [downloadedDatabase, setDownloadedDatabase] = useState<
{ time: Date; content: string } | undefined
@@ -361,6 +351,7 @@ export function DeveloperPage({}: Props): VNode {
<a
href={new URL(`/keys`, e.exchangeBaseUrl).href}
target="_blank"
+ rel="noreferrer"
>
{e.exchangeBaseUrl}
</a>
diff --git
a/packages/taler-wallet-webextension/src/wallet/ManageAccount/views.tsx
b/packages/taler-wallet-webextension/src/wallet/ManageAccount/views.tsx
index 7b80977f3..b995a44d0 100644
--- a/packages/taler-wallet-webextension/src/wallet/ManageAccount/views.tsx
+++ b/packages/taler-wallet-webextension/src/wallet/ManageAccount/views.tsx
@@ -130,7 +130,6 @@ export function ReadyView({
))}
</div>
<div style={{ border: "1px solid gray", padding: 8, borderRadius: 5 }}>
- --- {uri.value} ---
<p>
<CustomFieldByAccountType
type={accountType.value as AccountType}
--
To stop receiving notification emails like this one, please contact
gnunet@gnunet.org.
- [taler-wallet-core] branch master updated (ca179ef3a -> 02ceacd75),
gnunet <=
- [taler-wallet-core] 01/04: dd53: Inconsistent to aldready have the “add” and “send” buttons on this page, gnunet, 2024/05/28
- [taler-wallet-core] 03/04: dd 53: "amount" is a bad label, "brut amount" might be good, then use "net deposit", gnunet, 2024/05/28
- [taler-wallet-core] 04/04: fix #8828, gnunet, 2024/05/28
- [taler-wallet-core] 02/04: dd53: Valid until” is likely confusing, gnunet, 2024/05/28