summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorSebastian <sebasjm@gmail.com>2022-09-06 17:17:44 -0300
committerSebastian <sebasjm@gmail.com>2022-09-06 17:17:50 -0300
commit1e00724a0dcd0d65e6d786a1d8d7cdffc9fe2a85 (patch)
tree34eb327ac3370174cec4365ecc375309462d239b
parent49c9279c1e06a90757b2bd3e75b4887e71345d1d (diff)
downloadwallet-core-1e00724a0dcd0d65e6d786a1d8d7cdffc9fe2a85.tar.gz
wallet-core-1e00724a0dcd0d65e6d786a1d8d7cdffc9fe2a85.tar.bz2
wallet-core-1e00724a0dcd0d65e6d786a1d8d7cdffc9fe2a85.zip
listExchangesDetailed to getExchangeDetailedInfo & ageRestriction taken from the denoms
-rw-r--r--packages/taler-util/src/transactionsTypes.ts1
-rw-r--r--packages/taler-util/src/walletTypes.ts24
-rw-r--r--packages/taler-wallet-core/src/operations/tip.ts5
-rw-r--r--packages/taler-wallet-core/src/operations/transactions.ts4
-rw-r--r--packages/taler-wallet-core/src/operations/withdraw.ts25
-rw-r--r--packages/taler-wallet-core/src/wallet-api-types.ts4
-rw-r--r--packages/taler-wallet-core/src/wallet.ts91
-rw-r--r--packages/taler-wallet-webextension/src/cta/InvoiceCreate/state.ts2
-rw-r--r--packages/taler-wallet-webextension/src/cta/Withdraw/state.ts28
-rw-r--r--packages/taler-wallet-webextension/src/cta/Withdraw/test.ts4
-rw-r--r--packages/taler-wallet-webextension/src/wallet/DestinationSelection.tsx2
-rw-r--r--packages/taler-wallet-webextension/src/wallet/DeveloperPage.tsx2
-rw-r--r--packages/taler-wallet-webextension/src/wallet/ExchangeAddPage.tsx2
-rw-r--r--packages/taler-wallet-webextension/src/wallet/ExchangeSelection/example.ts6
-rw-r--r--packages/taler-wallet-webextension/src/wallet/ExchangeSelection/index.ts4
-rw-r--r--packages/taler-wallet-webextension/src/wallet/ExchangeSelection/state.ts25
-rw-r--r--packages/taler-wallet-webextension/src/wallet/ExchangeSelection/stories.tsx8
-rw-r--r--packages/taler-wallet-webextension/src/wallet/ManualWithdrawPage.tsx2
-rw-r--r--packages/taler-wallet-webextension/src/wallet/Settings.tsx2
-rw-r--r--packages/taler-wallet-webextension/src/wallet/Transaction.stories.tsx7
-rw-r--r--packages/taler-wallet-webextension/src/wallet/Transaction.tsx17
-rw-r--r--packages/taler-wallet-webextension/src/wxApi.ts12
22 files changed, 157 insertions, 120 deletions
diff --git a/packages/taler-util/src/transactionsTypes.ts b/packages/taler-util/src/transactionsTypes.ts
index e4b1faf2e..a46f304d1 100644
--- a/packages/taler-util/src/transactionsTypes.ts
+++ b/packages/taler-util/src/transactionsTypes.ts
@@ -190,7 +190,6 @@ export interface TransactionWithdrawal extends TransactionCommon {
export interface PeerInfoShort {
expiration: TalerProtocolTimestamp | undefined;
summary: string | undefined;
- completed: boolean;
}
/**
diff --git a/packages/taler-util/src/walletTypes.ts b/packages/taler-util/src/walletTypes.ts
index 095266f22..7ca56b4ff 100644
--- a/packages/taler-util/src/walletTypes.ts
+++ b/packages/taler-util/src/walletTypes.ts
@@ -568,12 +568,12 @@ export interface DepositInfo {
ageCommitmentProof?: AgeCommitmentProof;
}
-export interface ExchangesListRespose {
+export interface ExchangesListResponse {
exchanges: ExchangeListItem[];
}
-export interface ExchangeDetailledListRespose {
- exchanges: ExchangeFullDetailsListItem[];
+export interface ExchangeDetailedResponse {
+ exchange: ExchangeFullDetails;
}
export interface WalletCoreVersion {
@@ -733,7 +733,7 @@ export interface DenominationInfo {
stampExpireDeposit: TalerProtocolTimestamp;
}
-export interface ExchangeFullDetailsListItem {
+export interface ExchangeFullDetails {
exchangeBaseUrl: string;
currency: string;
paytoUris: string[];
@@ -771,9 +771,9 @@ const codecForExchangeTos = (): Codec<ExchangeTos> =>
.property("content", codecOptional(codecForString()))
.build("ExchangeTos");
-export const codecForExchangeFullDetailsListItem =
- (): Codec<ExchangeFullDetailsListItem> =>
- buildCodecForObject<ExchangeFullDetailsListItem>()
+export const codecForExchangeFullDetails =
+ (): Codec<ExchangeFullDetails> =>
+ buildCodecForObject<ExchangeFullDetails>()
.property("currency", codecForString())
.property("exchangeBaseUrl", codecForString())
.property("paytoUris", codecForList(codecForString()))
@@ -791,10 +791,10 @@ export const codecForExchangeListItem = (): Codec<ExchangeListItem> =>
.property("tos", codecForExchangeTos())
.build("ExchangeListItem");
-export const codecForExchangesListResponse = (): Codec<ExchangesListRespose> =>
- buildCodecForObject<ExchangesListRespose>()
- .property("exchanges", codecForList(codecForExchangeFullDetailsListItem()))
- .build("ExchangesListRespose");
+export const codecForExchangesListResponse = (): Codec<ExchangesListResponse> =>
+ buildCodecForObject<ExchangesListResponse>()
+ .property("exchanges", codecForList(codecForExchangeListItem()))
+ .build("ExchangesListResponse");
export interface AcceptManualWithdrawalResult {
/**
@@ -965,6 +965,7 @@ export const codecForGetWithdrawalDetailsForAmountRequest =
buildCodecForObject<GetWithdrawalDetailsForAmountRequest>()
.property("exchangeBaseUrl", codecForString())
.property("amount", codecForString())
+ .property("restrictAge", codecOptional(codecForNumber()))
.build("GetWithdrawalDetailsForAmountRequest");
export interface AcceptExchangeTosRequest {
@@ -1022,6 +1023,7 @@ export interface GetExchangeWithdrawalInfo {
exchangeBaseUrl: string;
amount: AmountJson;
tosAcceptedFormat?: string[];
+ ageRestricted?: number;
}
export const codecForGetExchangeWithdrawalInfo =
diff --git a/packages/taler-wallet-core/src/operations/tip.ts b/packages/taler-wallet-core/src/operations/tip.ts
index 9ca1ccb5a..7148999c5 100644
--- a/packages/taler-wallet-core/src/operations/tip.ts
+++ b/packages/taler-wallet-core/src/operations/tip.ts
@@ -82,10 +82,15 @@ export async function prepareTip(
logger.trace("new tip, creating tip record");
await updateExchangeFromUrl(ws, tipPickupStatus.exchange_url);
+
+ //FIXME: is this needed? withdrawDetails is not used
+ // * if the intention is to update the exchange information in the database
+ // maybe we can use another name. `get` seems like a pure-function
const withdrawDetails = await getExchangeWithdrawalInfo(
ws,
tipPickupStatus.exchange_url,
amount,
+ undefined
);
const walletTipId = encodeCrock(getRandomBytes(32));
diff --git a/packages/taler-wallet-core/src/operations/transactions.ts b/packages/taler-wallet-core/src/operations/transactions.ts
index 11f47d8a0..956d565a6 100644
--- a/packages/taler-wallet-core/src/operations/transactions.ts
+++ b/packages/taler-wallet-core/src/operations/transactions.ts
@@ -161,7 +161,6 @@ export async function getTransactions(
info: {
expiration: pi.contractTerms.purse_expiration,
summary: pi.contractTerms.summary,
- completed: Amounts.isZero(amount),
},
frozen: false,
pending: !pi.purseCreated,
@@ -199,7 +198,6 @@ export async function getTransactions(
info: {
expiration: pi.contractTerms.purse_expiration,
summary: pi.contractTerms.summary,
- completed: pi.paid
},
timestamp: pi.timestampCreated,
transactionId: makeEventId(
@@ -234,7 +232,6 @@ export async function getTransactions(
info: {
expiration: wsr.wgInfo.contractTerms.purse_expiration,
summary: wsr.wgInfo.contractTerms.summary,
- completed: !!wsr.timestampFinish
},
talerUri: constructPayPullUri({
exchangeBaseUrl: wsr.exchangeBaseUrl,
@@ -259,7 +256,6 @@ export async function getTransactions(
info: {
expiration: wsr.wgInfo.contractTerms.purse_expiration,
summary: wsr.wgInfo.contractTerms.summary,
- completed: !!wsr.timestampFinish,
},
pending: !wsr.timestampFinish,
timestamp: wsr.timestampStart,
diff --git a/packages/taler-wallet-core/src/operations/withdraw.ts b/packages/taler-wallet-core/src/operations/withdraw.ts
index 2b981e117..b80745316 100644
--- a/packages/taler-wallet-core/src/operations/withdraw.ts
+++ b/packages/taler-wallet-core/src/operations/withdraw.ts
@@ -192,6 +192,13 @@ export interface ExchangeWithdrawDetails {
* Amount that will actually be added to the wallet's balance.
*/
withdrawalAmountEffective: AmountString;
+
+ /**
+ * If the exchange supports age-restricted coins it will return
+ * the array of ages.
+ *
+ */
+ ageRestrictionOptions?: number[],
}
/**
@@ -242,7 +249,7 @@ export function selectWithdrawalDenominations(
for (const d of denoms) {
let count = 0;
const cost = Amounts.add(d.value, d.feeWithdraw).amount;
- for (;;) {
+ for (; ;) {
if (Amounts.cmp(remaining, cost) < 0) {
break;
}
@@ -903,8 +910,7 @@ export async function updateWithdrawalDenoms(
denom.verificationStatus === DenominationVerificationStatus.Unverified
) {
logger.trace(
- `Validating denomination (${current + 1}/${
- denominations.length
+ `Validating denomination (${current + 1}/${denominations.length
}) signature of ${denom.denomPubHash}`,
);
let valid = false;
@@ -1031,7 +1037,7 @@ async function queryReserve(
if (
resp.status === 404 &&
result.talerErrorResponse.code ===
- TalerErrorCode.EXCHANGE_RESERVES_STATUS_UNKNOWN
+ TalerErrorCode.EXCHANGE_RESERVES_STATUS_UNKNOWN
) {
ws.notify({
type: NotificationType.ReserveNotYetFound,
@@ -1255,10 +1261,13 @@ async function processWithdrawGroupImpl(
}
}
+const AGE_MASK_GROUPS = "8:10:12:14:16:18".split(":").map(n => parseInt(n, 10))
+
export async function getExchangeWithdrawalInfo(
ws: InternalWalletState,
exchangeBaseUrl: string,
instructedAmount: AmountJson,
+ ageRestricted: number | undefined,
): Promise<ExchangeWithdrawDetails> {
const { exchange, exchangeDetails } =
await ws.exchangeOps.updateExchangeFromUrl(ws, exchangeBaseUrl);
@@ -1287,6 +1296,8 @@ export async function getExchangeWithdrawalInfo(
exchange,
);
+ let hasDenomWithAgeRestriction = false
+
let earliestDepositExpiration: TalerProtocolTimestamp | undefined;
for (let i = 0; i < selectedDenoms.selectedDenoms.length; i++) {
const ds = selectedDenoms.selectedDenoms[i];
@@ -1310,6 +1321,7 @@ export async function getExchangeWithdrawalInfo(
) {
earliestDepositExpiration = expireDeposit;
}
+ hasDenomWithAgeRestriction = hasDenomWithAgeRestriction || denom.denomPub.age_mask > 0
}
checkLogicInvariant(!!earliestDepositExpiration);
@@ -1337,7 +1349,7 @@ export async function getExchangeWithdrawalInfo(
) {
logger.warn(
`wallet's support for exchange protocol version ${WALLET_EXCHANGE_PROTOCOL_VERSION} might be outdated ` +
- `(exchange has ${exchangeDetails.protocolVersion}), checking for updates`,
+ `(exchange has ${exchangeDetails.protocolVersion}), checking for updates`,
);
}
}
@@ -1370,6 +1382,9 @@ export async function getExchangeWithdrawalInfo(
termsOfServiceAccepted: tosAccepted,
withdrawalAmountEffective: Amounts.stringify(selectedDenoms.totalCoinValue),
withdrawalAmountRaw: Amounts.stringify(instructedAmount),
+ // TODO: remove hardcoding, this should be calculated from the denominations info
+ // force enabled for testing
+ ageRestrictionOptions: hasDenomWithAgeRestriction ? AGE_MASK_GROUPS : undefined
};
return ret;
}
diff --git a/packages/taler-wallet-core/src/wallet-api-types.ts b/packages/taler-wallet-core/src/wallet-api-types.ts
index 14c40a8db..665be80fb 100644
--- a/packages/taler-wallet-core/src/wallet-api-types.ts
+++ b/packages/taler-wallet-core/src/wallet-api-types.ts
@@ -46,7 +46,7 @@ import {
CreateDepositGroupRequest,
CreateDepositGroupResponse,
DeleteTransactionRequest,
- ExchangesListRespose,
+ ExchangesListResponse,
ForceRefreshRequest,
GetExchangeTosRequest,
GetExchangeTosResult,
@@ -227,7 +227,7 @@ export type WalletOperations = {
};
[WalletApiOperation.ListExchanges]: {
request: {};
- response: ExchangesListRespose;
+ response: ExchangesListResponse;
};
[WalletApiOperation.AddExchange]: {
request: AddExchangeRequest;
diff --git a/packages/taler-wallet-core/src/wallet.ts b/packages/taler-wallet-core/src/wallet.ts
index a7a39c5a9..a23bcb12a 100644
--- a/packages/taler-wallet-core/src/wallet.ts
+++ b/packages/taler-wallet-core/src/wallet.ts
@@ -72,8 +72,8 @@ import {
Duration,
durationFromSpec,
durationMin,
- ExchangeFullDetailsListItem,
- ExchangesListRespose,
+ ExchangeFullDetails,
+ ExchangesListResponse,
GetExchangeTosResult,
j2s,
KnownBankAccounts,
@@ -232,8 +232,9 @@ async function getWithdrawalDetailsForAmount(
ws: InternalWalletState,
exchangeBaseUrl: string,
amount: AmountJson,
+ restrictAge: number | undefined,
): Promise<ManualWithdrawalDetails> {
- const wi = await getExchangeWithdrawalInfo(ws, exchangeBaseUrl, amount);
+ const wi = await getExchangeWithdrawalInfo(ws, exchangeBaseUrl, amount, restrictAge);
const paytoUris = wi.exchangeDetails.wireInfo.accounts.map(
(x) => x.payto_uri,
);
@@ -568,7 +569,7 @@ async function listKnownBankAccounts(
async function getExchanges(
ws: InternalWalletState,
-): Promise<ExchangesListRespose> {
+): Promise<ExchangesListResponse> {
const exchanges: ExchangeListItem[] = [];
await ws.db
.mktx((x) => ({
@@ -613,54 +614,56 @@ async function getExchanges(
return { exchanges };
}
-async function getExchangesDetailled(
+async function getExchangeDetailedInfo(
ws: InternalWalletState,
-): Promise<ExchangesListRespose> {
- const exchanges: ExchangeFullDetailsListItem[] = [];
- await ws.db
+ exchangeBaseurl: string,
+): Promise<ExchangeFullDetails> {
+ //TODO: should we use the forceUpdate parameter?
+ const exchange = await ws.db
.mktx((x) => ({
exchanges: x.exchanges,
exchangeDetails: x.exchangeDetails,
denominations: x.denominations,
}))
.runReadOnly(async (tx) => {
- const exchangeRecords = await tx.exchanges.iter().toArray();
- for (const r of exchangeRecords) {
- const dp = r.detailsPointer;
- if (!dp) {
- continue;
- }
- const { currency } = dp;
- const exchangeDetails = await getExchangeDetails(tx, r.baseUrl);
- if (!exchangeDetails) {
- continue;
- }
+ const ex = await tx.exchanges.get(exchangeBaseurl)
+ const dp = ex?.detailsPointer;
+ if (!dp) {
+ return;
+ }
+ const { currency } = dp;
+ const exchangeDetails = await getExchangeDetails(tx, ex.baseUrl);
+ if (!exchangeDetails) {
+ return;
+ }
- const denominations = await tx.denominations.indexes.byExchangeBaseUrl
- .iter(r.baseUrl)
- .toArray();
+ const denominations = await tx.denominations.indexes.byExchangeBaseUrl
+ .iter(ex.baseUrl)
+ .toArray();
- if (!denominations) {
- continue;
- }
+ if (!denominations) {
+ return;
+ }
- exchanges.push({
- exchangeBaseUrl: r.baseUrl,
- currency,
- tos: {
- acceptedVersion: exchangeDetails.termsOfServiceAcceptedEtag,
- currentVersion: exchangeDetails.termsOfServiceLastEtag,
- contentType: exchangeDetails.termsOfServiceContentType,
- content: exchangeDetails.termsOfServiceText,
- },
- paytoUris: exchangeDetails.wireInfo.accounts.map((x) => x.payto_uri),
- auditors: exchangeDetails.auditors,
- wireInfo: exchangeDetails.wireInfo,
- denominations: denominations,
- });
+ return {
+ exchangeBaseUrl: ex.baseUrl,
+ currency,
+ tos: {
+ acceptedVersion: exchangeDetails.termsOfServiceAcceptedEtag,
+ currentVersion: exchangeDetails.termsOfServiceLastEtag,
+ contentType: exchangeDetails.termsOfServiceContentType,
+ content: exchangeDetails.termsOfServiceText,
+ },
+ paytoUris: exchangeDetails.wireInfo.accounts.map((x) => x.payto_uri),
+ auditors: exchangeDetails.auditors,
+ wireInfo: exchangeDetails.wireInfo,
+ denominations: denominations,
}
});
- return { exchanges };
+ if (!exchange) {
+ throw Error(`exchange with base url "${exchangeBaseurl}" not found`)
+ }
+ return exchange;
}
async function setCoinSuspended(
@@ -834,8 +837,9 @@ async function dispatchRequestInternal(
case "listExchanges": {
return await getExchanges(ws);
}
- case "listExchangesDetailled": {
- return await getExchangesDetailled(ws);
+ case "getExchangeDetailedInfo": {
+ const req = codecForAddExchangeRequest().decode(payload);
+ return await getExchangeDetailedInfo(ws, req.exchangeBaseUrl);
}
case "listKnownBankAccounts": {
const req = codecForListKnownBankAccounts().decode(payload);
@@ -852,6 +856,7 @@ async function dispatchRequestInternal(
ws,
req.exchangeBaseUrl,
req.amount,
+ req.ageRestricted,
);
}
case "acceptManualWithdrawal": {
@@ -870,6 +875,7 @@ async function dispatchRequestInternal(
ws,
req.exchangeBaseUrl,
Amounts.parseOrThrow(req.amount),
+ req.restrictAge
);
}
case "getBalances": {
@@ -1067,6 +1073,7 @@ async function dispatchRequestInternal(
ws,
req.exchange,
amount,
+ undefined
);
const wres = await createManualWithdrawal(ws, {
amount: amount,
diff --git a/packages/taler-wallet-webextension/src/cta/InvoiceCreate/state.ts b/packages/taler-wallet-webextension/src/cta/InvoiceCreate/state.ts
index bb0f0d1af..804d216eb 100644
--- a/packages/taler-wallet-webextension/src/cta/InvoiceCreate/state.ts
+++ b/packages/taler-wallet-webextension/src/cta/InvoiceCreate/state.ts
@@ -30,7 +30,7 @@ export function useComponentState(
const [subject, setSubject] = useState("");
const [talerUri, setTalerUri] = useState("")
- const hook = useAsyncAsHook(api.listExchangesDetailled);
+ const hook = useAsyncAsHook(api.listExchanges);
const [exchangeIdx, setExchangeIdx] = useState("0")
const [operationError, setOperationError] = useState<TalerErrorDetail | undefined>(undefined)
diff --git a/packages/taler-wallet-webextension/src/cta/Withdraw/state.ts b/packages/taler-wallet-webextension/src/cta/Withdraw/state.ts
index 58d3cfedf..015c9aaca 100644
--- a/packages/taler-wallet-webextension/src/cta/Withdraw/state.ts
+++ b/packages/taler-wallet-webextension/src/cta/Withdraw/state.ts
@@ -30,7 +30,7 @@ export function useComponentStateFromParams(
const [ageRestricted, setAgeRestricted] = useState(0);
- const exchangeHook = useAsyncAsHook(api.listExchangesDetailled);
+ const exchangeHook = useAsyncAsHook(api.listExchanges);
const exchangeHookDep =
!exchangeHook || exchangeHook.hasError || !exchangeHook.response
@@ -65,6 +65,7 @@ export function useComponentStateFromParams(
exchangeBaseUrl: exchange.exchangeBaseUrl,
amount: chosenAmount,
tosAcceptedFormat: ["text/xml"],
+ ageRestricted,
});
const withdrawAmount = {
@@ -72,7 +73,7 @@ export function useComponentStateFromParams(
effective: Amounts.parseOrThrow(info.withdrawalAmountEffective),
}
- return { amount: withdrawAmount };
+ return { amount: withdrawAmount, ageRestrictionOptions: info.ageRestrictionOptions };
}, [exchangeHookDep]);
const [reviewing, setReviewing] = useState<boolean>(false);
@@ -172,16 +173,16 @@ export function useComponentStateFromParams(
termsState !== undefined &&
(termsState.status === "changed" || termsState.status === "new");
- const ageRestrictionOptions: Record<string, string> | undefined = "6:12:18"
- .split(":")
- .reduce((p, c) => ({ ...p, [c]: `under ${c}` }), {});
+ const ageRestrictionOptions = amountHook.response.
+ ageRestrictionOptions?.
+ reduce((p, c) => ({ ...p, [c]: `under ${c}` }), {} as Record<string, string>)
- if (ageRestrictionOptions) {
+ const ageRestrictionEnabled = ageRestrictionOptions !== undefined
+ if (ageRestrictionEnabled) {
ageRestrictionOptions["0"] = "Not restricted";
}
//TODO: calculate based on exchange info
- const ageRestrictionEnabled = false;
const ageRestriction = ageRestrictionEnabled ? {
list: ageRestrictionOptions,
value: String(ageRestricted),
@@ -269,6 +270,7 @@ export function useComponentStateFromURI(
exchangeBaseUrl: uriHookDep?.thisExchange,
amount: Amounts.parseOrThrow(uriHookDep.amount),
tosAcceptedFormat: ["text/xml"],
+ ageRestricted,
});
const withdrawAmount = {
@@ -276,7 +278,7 @@ export function useComponentStateFromURI(
effective: Amounts.parseOrThrow(info.withdrawalAmountEffective),
}
- return { amount: withdrawAmount };
+ return { amount: withdrawAmount, ageRestrictionOptions: info.ageRestrictionOptions };
}, [uriHookDep]);
const [reviewing, setReviewing] = useState<boolean>(false);
@@ -385,16 +387,16 @@ export function useComponentStateFromURI(
termsState !== undefined &&
(termsState.status === "changed" || termsState.status === "new");
- const ageRestrictionOptions: Record<string, string> | undefined = "6:12:18"
- .split(":")
- .reduce((p, c) => ({ ...p, [c]: `under ${c}` }), {});
+ const ageRestrictionOptions = amountHook.response.
+ ageRestrictionOptions?.
+ reduce((p, c) => ({ ...p, [c]: `under ${c}` }), {} as Record<string, string>)
- if (ageRestrictionOptions) {
+ const ageRestrictionEnabled = ageRestrictionOptions !== undefined
+ if (ageRestrictionEnabled) {
ageRestrictionOptions["0"] = "Not restricted";
}
//TODO: calculate based on exchange info
- const ageRestrictionEnabled = false;
const ageRestriction = ageRestrictionEnabled ? {
list: ageRestrictionOptions,
value: String(ageRestricted),
diff --git a/packages/taler-wallet-webextension/src/cta/Withdraw/test.ts b/packages/taler-wallet-webextension/src/cta/Withdraw/test.ts
index 6c9e0c3ba..ce964f7f7 100644
--- a/packages/taler-wallet-webextension/src/cta/Withdraw/test.ts
+++ b/packages/taler-wallet-webextension/src/cta/Withdraw/test.ts
@@ -21,7 +21,7 @@
import {
Amounts,
- ExchangeFullDetailsListItem,
+ ExchangeFullDetails,
ExchangeListItem,
GetExchangeTosResult,
} from "@gnu-taler/taler-util";
@@ -30,7 +30,7 @@ import { expect } from "chai";
import { mountHook } from "../../test-utils.js";
import { useComponentStateFromURI } from "./state.js";
-const exchanges: ExchangeFullDetailsListItem[] = [
+const exchanges: ExchangeFullDetails[] = [
{
currency: "ARS",
exchangeBaseUrl: "http://exchange.demo.taler.net",
diff --git a/packages/taler-wallet-webextension/src/wallet/DestinationSelection.tsx b/packages/taler-wallet-webextension/src/wallet/DestinationSelection.tsx
index b63bbacaf..fa1a606f7 100644
--- a/packages/taler-wallet-webextension/src/wallet/DestinationSelection.tsx
+++ b/packages/taler-wallet-webextension/src/wallet/DestinationSelection.tsx
@@ -171,7 +171,7 @@ export function SelectCurrency({
}): VNode {
const { i18n } = useTranslationContext();
- const hook = useAsyncAsHook(wxApi.listExchangesDetailled);
+ const hook = useAsyncAsHook(wxApi.listExchanges);
if (!hook) {
return <Loading />;
diff --git a/packages/taler-wallet-webextension/src/wallet/DeveloperPage.tsx b/packages/taler-wallet-webextension/src/wallet/DeveloperPage.tsx
index 8ba92a8f2..3406b04ef 100644
--- a/packages/taler-wallet-webextension/src/wallet/DeveloperPage.tsx
+++ b/packages/taler-wallet-webextension/src/wallet/DeveloperPage.tsx
@@ -45,7 +45,7 @@ export function DeveloperPage(): VNode {
const response = useAsyncAsHook(async () => {
const op = await wxApi.getPendingOperations();
const c = await wxApi.dumpCoins();
- const ex = await wxApi.listExchangesDetailled();
+ const ex = await wxApi.listExchanges();
return {
operations: op.pendingOperations,
coins: c.coins,
diff --git a/packages/taler-wallet-webextension/src/wallet/ExchangeAddPage.tsx b/packages/taler-wallet-webextension/src/wallet/ExchangeAddPage.tsx
index 8ba5fb7e9..859a7f86b 100644
--- a/packages/taler-wallet-webextension/src/wallet/ExchangeAddPage.tsx
+++ b/packages/taler-wallet-webextension/src/wallet/ExchangeAddPage.tsx
@@ -36,7 +36,7 @@ export function ExchangeAddPage({ currency, onBack }: Props): VNode {
{ url: string; config: TalerConfigResponse } | undefined
>(undefined);
- const knownExchangesResponse = useAsyncAsHook(wxApi.listExchangesDetailled);
+ const knownExchangesResponse = useAsyncAsHook(wxApi.listExchanges);
const knownExchanges = !knownExchangesResponse
? []
: knownExchangesResponse.hasError
diff --git a/packages/taler-wallet-webextension/src/wallet/ExchangeSelection/example.ts b/packages/taler-wallet-webextension/src/wallet/ExchangeSelection/example.ts
index bdbd36596..3f37dda77 100644
--- a/packages/taler-wallet-webextension/src/wallet/ExchangeSelection/example.ts
+++ b/packages/taler-wallet-webextension/src/wallet/ExchangeSelection/example.ts
@@ -15,7 +15,7 @@
*/
import {
- ExchangeFullDetailsListItem,
+ ExchangeFullDetails,
ExchangeListItem,
} from "@gnu-taler/taler-util";
@@ -24,7 +24,7 @@ import {
* @author Sebastian Javier Marchano (sebasjm)
*/
-export const bitcoinExchanges: ExchangeFullDetailsListItem[] = [
+export const bitcoinExchanges: ExchangeFullDetails[] = [
{
exchangeBaseUrl: "https://bitcoin1.ice.bfh.ch/",
currency: "BITCOINBTC",
@@ -11781,7 +11781,7 @@ export const bitcoinExchanges: ExchangeFullDetailsListItem[] = [
},
] as any;
-export const kudosExchanges: ExchangeFullDetailsListItem[] = [
+export const kudosExchanges: ExchangeFullDetails[] = [
{
exchangeBaseUrl: "https://exchange1.demo.taler.net/",
currency: "KUDOS",
diff --git a/packages/taler-wallet-webextension/src/wallet/ExchangeSelection/index.ts b/packages/taler-wallet-webextension/src/wallet/ExchangeSelection/index.ts
index 0dec00b09..061c94ad7 100644
--- a/packages/taler-wallet-webextension/src/wallet/ExchangeSelection/index.ts
+++ b/packages/taler-wallet-webextension/src/wallet/ExchangeSelection/index.ts
@@ -14,7 +14,7 @@
GNU Taler; see the file COPYING. If not, see <http://www.gnu.org/licenses/>
*/
-import { AbsoluteTime, AmountJson, ExchangeFullDetailsListItem } from "@gnu-taler/taler-util";
+import { AbsoluteTime, AmountJson, ExchangeFullDetails } from "@gnu-taler/taler-util";
import { Loading } from "../../components/Loading.js";
import { HookError } from "../../hooks/useAsyncAsHook.js";
import { ButtonHandler, SelectFieldHandler } from "../../mui/handlers.js";
@@ -52,7 +52,7 @@ export namespace State {
export interface BaseInfo {
exchanges: SelectFieldHandler;
- selected: ExchangeFullDetailsListItem;
+ selected: ExchangeFullDetails;
nextFeeUpdate: AbsoluteTime;
error: undefined;
}
diff --git a/packages/taler-wallet-webextension/src/wallet/ExchangeSelection/state.ts b/packages/taler-wallet-webextension/src/wallet/ExchangeSelection/state.ts
index eda755e96..28d34578a 100644
--- a/packages/taler-wallet-webextension/src/wallet/ExchangeSelection/state.ts
+++ b/packages/taler-wallet-webextension/src/wallet/ExchangeSelection/state.ts
@@ -25,11 +25,21 @@ export function useComponentState(
{ onCancel, onSelection, currency }: Props,
api: typeof wxApi,
): State {
- const hook = useAsyncAsHook(api.listExchangesDetailled);
-
const initialValue = 0
const [value, setValue] = useState(String(initialValue));
+ const hook = useAsyncAsHook(async () => {
+ const { exchanges } = await api.listExchanges()
+
+ const selectedIdx = parseInt(value, 10)
+ const selectedExchange = exchanges.length == 0 ? undefined : exchanges[selectedIdx]
+ const selected = !selectedExchange ? undefined : await api.getExchangeDetailedInfo(selectedExchange.exchangeBaseUrl)
+
+ const initialExchange = selectedIdx === initialValue ? undefined : exchanges[initialValue]
+ const original = !initialExchange ? undefined : await api.getExchangeDetailedInfo(initialExchange.exchangeBaseUrl)
+ return { exchanges, selected, original }
+ });
+
if (!hook) {
return {
status: "loading",
@@ -43,18 +53,16 @@ export function useComponentState(
};
}
- const exchanges = hook.response.exchanges;
+ const { exchanges, selected, original } = hook.response;
- if (exchanges.length === 0) {
+ if (!selected) {
+ //!selected <=> exchanges.length === 0
return {
status: "no-exchanges",
error: undefined
}
}
- const original = exchanges[initialValue];
- const selected = exchanges[Number(value)];
-
let nextFeeUpdate = TalerProtocolTimestamp.never();
nextFeeUpdate = Object.values(selected.wireInfo.feesForType).reduce(
@@ -97,7 +105,8 @@ export function useComponentState(
const exchangeMap = exchanges.reduce((prev, cur, idx) => ({ ...prev, [cur.exchangeBaseUrl]: String(idx) }), {} as Record<string, string>)
- if (original === selected) {
+ if (!original) {
+ // !original <=> selected == original
return {
status: "ready",
exchanges: {
diff --git a/packages/taler-wallet-webextension/src/wallet/ExchangeSelection/stories.tsx b/packages/taler-wallet-webextension/src/wallet/ExchangeSelection/stories.tsx
index 094087517..cb4cc7c69 100644
--- a/packages/taler-wallet-webextension/src/wallet/ExchangeSelection/stories.tsx
+++ b/packages/taler-wallet-webextension/src/wallet/ExchangeSelection/stories.tsx
@@ -19,7 +19,7 @@
* @author Sebastian Javier Marchano (sebasjm)
*/
-import { ExchangeFullDetailsListItem, ExchangeListItem } from "@gnu-taler/taler-util";
+import { ExchangeFullDetails, ExchangeListItem } from "@gnu-taler/taler-util";
import { createExample } from "../../test-utils.js";
import { bitcoinExchanges, kudosExchanges } from "./example.js";
import { FeeDescription, FeeDescriptionPair, OperationMap } from "./index.js";
@@ -34,7 +34,7 @@ export default {
};
function timelineForExchange(
- ex: ExchangeFullDetailsListItem,
+ ex: ExchangeFullDetails,
): OperationMap<FeeDescription[]> {
return {
deposit: createDenominationTimeline(
@@ -61,8 +61,8 @@ function timelineForExchange(
}
function timelinePairForExchange(
- ex1: ExchangeFullDetailsListItem,
- ex2: ExchangeFullDetailsListItem,
+ ex1: ExchangeFullDetails,
+ ex2: ExchangeFullDetails,
): OperationMap<FeeDescriptionPair[]> {
const om1 = timelineForExchange(ex1);
const om2 = timelineForExchange(ex2);
diff --git a/packages/taler-wallet-webextension/src/wallet/ManualWithdrawPage.tsx b/packages/taler-wallet-webextension/src/wallet/ManualWithdrawPage.tsx
index 5a82c96ed..a292914fb 100644
--- a/packages/taler-wallet-webextension/src/wallet/ManualWithdrawPage.tsx
+++ b/packages/taler-wallet-webextension/src/wallet/ManualWithdrawPage.tsx
@@ -50,7 +50,7 @@ export function ManualWithdrawPage({ amount, onCancel }: Props): VNode {
>(undefined);
const [error, setError] = useState<string | undefined>(undefined);
- const state = useAsyncAsHook(wxApi.listExchangesDetailled);
+ const state = useAsyncAsHook(wxApi.listExchanges);
useEffect(() => {
return wxApi.onUpdateNotification([NotificationType.ExchangeAdded], () => {
state?.retry();
diff --git a/packages/taler-wallet-webextension/src/wallet/Settings.tsx b/packages/taler-wallet-webextension/src/wallet/Settings.tsx
index 36a356fba..4a520c3bb 100644
--- a/packages/taler-wallet-webextension/src/wallet/Settings.tsx
+++ b/packages/taler-wallet-webextension/src/wallet/Settings.tsx
@@ -49,7 +49,7 @@ export function SettingsPage(): VNode {
const webex = platform.getWalletWebExVersion();
const exchangesHook = useAsyncAsHook(async () => {
- const list = await wxApi.listExchangesDetailled();
+ const list = await wxApi.listExchanges();
const version = await wxApi.getVersion();
return { exchanges: list.exchanges, version };
});
diff --git a/packages/taler-wallet-webextension/src/wallet/Transaction.stories.tsx b/packages/taler-wallet-webextension/src/wallet/Transaction.stories.tsx
index acb50642a..dc8f067a5 100644
--- a/packages/taler-wallet-webextension/src/wallet/Transaction.stories.tsx
+++ b/packages/taler-wallet-webextension/src/wallet/Transaction.stories.tsx
@@ -563,7 +563,7 @@ export const InvoiceCreditComplete = createExample(TestedComponent, {
export const InvoiceCreditIncomplete = createExample(TestedComponent, {
transaction: {
...exampleData.pull_credit,
- info: { ...exampleData.pull_credit.info, completed: false },
+ pending: true,
},
});
@@ -581,9 +581,6 @@ export const TransferDebitComplete = createExample(TestedComponent, {
export const TransferDebitIncomplete = createExample(TestedComponent, {
transaction: {
...exampleData.push_debit,
- info: {
- ...exampleData.push_debit.info,
- completed: false,
- },
+ pending: true,
},
});
diff --git a/packages/taler-wallet-webextension/src/wallet/Transaction.tsx b/packages/taler-wallet-webextension/src/wallet/Transaction.tsx
index 44543c2cd..c1f5861e8 100644
--- a/packages/taler-wallet-webextension/src/wallet/Transaction.tsx
+++ b/packages/taler-wallet-webextension/src/wallet/Transaction.tsx
@@ -167,6 +167,8 @@ export function TransactionView({
}
}
+ const SHOWING_RETRY_THRESHOLD_SECS = 30;
+
const { i18n } = useTranslationContext();
function TransactionTemplate({
@@ -174,15 +176,16 @@ export function TransactionView({
}: {
children: ComponentChildren;
}): VNode {
- const showSend =
- (transaction.type === TransactionType.PeerPullCredit ||
- transaction.type === TransactionType.PeerPushDebit) &&
- !transaction.info.completed;
+ const showSend = false;
+ // (transaction.type === TransactionType.PeerPullCredit ||
+ // transaction.type === TransactionType.PeerPushDebit) &&
+ // !transaction.info.completed;
const showRetry =
transaction.error !== undefined ||
transaction.timestamp.t_s === "never" ||
(transaction.pending &&
- differenceInSeconds(new Date(), transaction.timestamp.t_s * 1000) > 10);
+ differenceInSeconds(new Date(), transaction.timestamp.t_s * 1000) >
+ SHOWING_RETRY_THRESHOLD_SECS);
return (
<Fragment>
@@ -624,7 +627,7 @@ export function TransactionView({
text={transaction.exchangeBaseUrl}
kind="neutral"
/>
- {!transaction.info.completed && (
+ {transaction.pending && (
<Part
title={<i18n.Translate>URI</i18n.Translate>}
text={<ShowQrWithCopy text={transaction.talerUri} />}
@@ -710,7 +713,7 @@ export function TransactionView({
text={transaction.exchangeBaseUrl}
kind="neutral"
/>
- {!transaction.info.completed && (
+ {transaction.pending && (
<Part
title={<i18n.Translate>URI</i18n.Translate>}
text={<ShowQrWithCopy text={transaction.talerUri} />}
diff --git a/packages/taler-wallet-webextension/src/wxApi.ts b/packages/taler-wallet-webextension/src/wxApi.ts
index 1b26ea214..b797179c3 100644
--- a/packages/taler-wallet-webextension/src/wxApi.ts
+++ b/packages/taler-wallet-webextension/src/wxApi.ts
@@ -42,7 +42,7 @@ import {
CreateDepositGroupRequest,
CreateDepositGroupResponse,
DeleteTransactionRequest,
- ExchangesListRespose,
+ ExchangesListResponse,
GetExchangeTosResult,
GetExchangeWithdrawalInfo,
GetFeeForDepositRequest,
@@ -67,7 +67,7 @@ import {
WalletDiagnostics,
WalletCoreVersion,
WithdrawUriInfoResponse,
- ExchangeDetailledListRespose,
+ ExchangeFullDetails,
} from "@gnu-taler/taler-util";
import {
AddBackupProviderRequest,
@@ -253,12 +253,14 @@ export function listKnownCurrencies(): Promise<ListOfKnownCurrencies> {
});
}
-export function listExchanges(): Promise<ExchangesListRespose> {
+export function listExchanges(): Promise<ExchangesListResponse> {
return callBackend("listExchanges", {});
}
-export function listExchangesDetailled(): Promise<ExchangeDetailledListRespose> {
- return callBackend("listExchangesDetailled", {});
+export function getExchangeDetailedInfo(exchangeBaseUrl: string): Promise<ExchangeFullDetails> {
+ return callBackend("getExchangeDetailedInfo", {
+ exchangeBaseUrl
+ });
}
export function getVersion(): Promise<WalletCoreVersion> {