aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--packages/taler-util/src/walletTypes.ts124
-rw-r--r--packages/taler-wallet-core/src/db.ts16
-rw-r--r--packages/taler-wallet-core/src/operations/backup/import.ts2
-rw-r--r--packages/taler-wallet-core/src/operations/withdraw.ts107
-rw-r--r--packages/taler-wallet-core/src/wallet.ts55
-rw-r--r--packages/taler-wallet-webextension/src/cta/Withdraw/state.ts11
-rw-r--r--packages/taler-wallet-webextension/src/cta/Withdraw/test.ts41
-rw-r--r--packages/taler-wallet-webextension/src/wxApi.ts16
8 files changed, 158 insertions, 214 deletions
diff --git a/packages/taler-util/src/walletTypes.ts b/packages/taler-util/src/walletTypes.ts
index d0765ae31..0891f5cf9 100644
--- a/packages/taler-util/src/walletTypes.ts
+++ b/packages/taler-util/src/walletTypes.ts
@@ -68,6 +68,7 @@ import { BackupRecovery } from "./backupTypes.js";
import { PaytoUri } from "./payto.js";
import { TalerErrorCode } from "./taler-error-codes.js";
import { AgeCommitmentProof } from "./talerCrypto.js";
+import { VersionMatchResult } from "./libtool-version.js";
/**
* Response for the create reserve request to the wallet.
@@ -692,6 +693,7 @@ export interface ExchangeGlobalFees {
signature: string;
}
+
const codecForExchangeAccount = (): Codec<ExchangeAccount> =>
buildCodecForObject<ExchangeAccount>()
.property("payto_uri", codecForString())
@@ -929,6 +931,110 @@ export interface ManualWithdrawalDetails {
* Ways to pay the exchange.
*/
paytoUris: string[];
+
+ /**
+ * If the exchange supports age-restricted coins it will return
+ * the array of ages.
+ */
+ ageRestrictionOptions?: number[];
+}
+
+/**
+ * Selected denominations withn some extra info.
+ */
+ export interface DenomSelectionState {
+ totalCoinValue: AmountJson;
+ totalWithdrawCost: AmountJson;
+ selectedDenoms: {
+ denomPubHash: string;
+ count: number;
+ }[];
+}
+
+/**
+ * Information about what will happen doing a withdrawal.
+ *
+ * Sent to the wallet frontend to be rendered and shown to the user.
+ */
+ export interface ExchangeWithdrawalDetails {
+ exchangePaytoUris: string[];
+
+ /**
+ * Filtered wire info to send to the bank.
+ */
+ exchangeWireAccounts: string[];
+
+ /**
+ * Selected denominations for withdraw.
+ */
+ selectedDenoms: DenomSelectionState;
+
+ /**
+ * Does the wallet know about an auditor for
+ * the exchange that the reserve.
+ */
+ isAudited: boolean;
+
+ /**
+ * Did the user already accept the current terms of service for the exchange?
+ */
+ termsOfServiceAccepted: boolean;
+
+ /**
+ * The exchange is trusted directly.
+ */
+ isTrusted: boolean;
+
+ /**
+ * The earliest deposit expiration of the selected coins.
+ */
+ earliestDepositExpiration: TalerProtocolTimestamp;
+
+ /**
+ * Number of currently offered denominations.
+ */
+ numOfferedDenoms: number;
+
+ /**
+ * Public keys of trusted auditors for the currency we're withdrawing.
+ */
+ trustedAuditorPubs: string[];
+
+ /**
+ * Result of checking the wallet's version
+ * against the exchange's version.
+ *
+ * Older exchanges don't return version information.
+ */
+ versionMatch: VersionMatchResult | undefined;
+
+ /**
+ * Libtool-style version string for the exchange or "unknown"
+ * for older exchanges.
+ */
+ exchangeVersion: string;
+
+ /**
+ * Libtool-style version string for the wallet.
+ */
+ walletVersion: string;
+
+ /**
+ * Amount that will be subtracted from the reserve's balance.
+ */
+ withdrawalAmountRaw: AmountString;
+
+ /**
+ * 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[];
}
export interface GetExchangeTosResult {
@@ -1142,24 +1248,6 @@ export const codecForForgetKnownBankAccounts =
.property("payto", codecForString())
.build("ForgetKnownBankAccountsRequest");
-export interface GetExchangeWithdrawalInfo {
- exchangeBaseUrl: string;
- amount: AmountJson;
- tosAcceptedFormat?: string[];
- ageRestricted?: number;
-}
-
-export const codecForGetExchangeWithdrawalInfo =
- (): Codec<GetExchangeWithdrawalInfo> =>
- buildCodecForObject<GetExchangeWithdrawalInfo>()
- .property("exchangeBaseUrl", codecForString())
- .property("amount", codecForAmountJson())
- .property(
- "tosAcceptedFormat",
- codecOptional(codecForList(codecForString())),
- )
- .build("GetExchangeWithdrawalInfo");
-
export interface AbortProposalRequest {
proposalId: string;
}
diff --git a/packages/taler-wallet-core/src/db.ts b/packages/taler-wallet-core/src/db.ts
index f4cdb68c1..8f7f22292 100644
--- a/packages/taler-wallet-core/src/db.ts
+++ b/packages/taler-wallet-core/src/db.ts
@@ -47,6 +47,7 @@ import {
DenominationInfo,
GlobalFees,
ExchangeGlobalFees,
+ DenomSelectionState,
} from "@gnu-taler/taler-util";
import { RetryInfo, RetryTags } from "./util/retries.js";
import { Event, IDBDatabase } from "@gnu-taler/idb-bridge";
@@ -430,8 +431,11 @@ export interface ExchangeDetailsRecord {
/**
* Fees for exchange services
+ *
+ * FIXME: Put in separate object store!
*/
globalFees: ExchangeGlobalFees[];
+
/**
* Signing keys we got from the exchange, can also contain
* older signing keys that are not returned by /keys anymore.
@@ -1280,18 +1284,6 @@ export interface WalletBackupConfState {
lastBackupNonce?: string;
}
-/**
- * Selected denominations withn some extra info.
- */
-export interface DenomSelectionState {
- totalCoinValue: AmountJson;
- totalWithdrawCost: AmountJson;
- selectedDenoms: {
- denomPubHash: string;
- count: number;
- }[];
-}
-
export const enum WithdrawalRecordType {
BankManual = "bank-manual",
BankIntegrated = "bank-integrated",
diff --git a/packages/taler-wallet-core/src/operations/backup/import.ts b/packages/taler-wallet-core/src/operations/backup/import.ts
index e631845f6..f4e6ab5eb 100644
--- a/packages/taler-wallet-core/src/operations/backup/import.ts
+++ b/packages/taler-wallet-core/src/operations/backup/import.ts
@@ -28,6 +28,7 @@ import {
BackupWgType,
codecForContractTerms,
DenomKeyType,
+ DenomSelectionState,
j2s,
Logger,
PayCoinSelection,
@@ -43,7 +44,6 @@ import {
CoinStatus,
DenominationRecord,
DenominationVerificationStatus,
- DenomSelectionState,
OperationStatus,
ProposalDownload,
PurchaseStatus,
diff --git a/packages/taler-wallet-core/src/operations/withdraw.ts b/packages/taler-wallet-core/src/operations/withdraw.ts
index 3c2541e9a..e4bf6cd11 100644
--- a/packages/taler-wallet-core/src/operations/withdraw.ts
+++ b/packages/taler-wallet-core/src/operations/withdraw.ts
@@ -37,10 +37,12 @@ import {
codecForWithdrawOperationStatusResponse,
codecForWithdrawResponse,
DenomKeyType,
+ DenomSelectionState,
Duration,
durationFromSpec,
encodeCrock,
ExchangeListItem,
+ ExchangeWithdrawalDetails,
ExchangeWithdrawRequest,
ForcedDenomSel,
getRandomBytes,
@@ -67,9 +69,6 @@ import {
CoinStatus,
DenominationRecord,
DenominationVerificationStatus,
- DenomSelectionState,
- ExchangeDetailsRecord,
- ExchangeRecord,
PlanchetRecord,
WalletStoresV1,
WgInfo,
@@ -127,96 +126,6 @@ import {
const logger = new Logger("operations/withdraw.ts");
/**
- * Information about what will happen when creating a reserve.
- *
- * Sent to the wallet frontend to be rendered and shown to the user.
- */
-export interface ExchangeWithdrawDetails {
- /**
- * Exchange that the reserve will be created at.
- *
- * FIXME: Should be its own record.
- */
- exchangeInfo: ExchangeRecord;
-
- exchangeDetails: ExchangeDetailsRecord;
-
- /**
- * Filtered wire info to send to the bank.
- */
- exchangeWireAccounts: string[];
-
- /**
- * Selected denominations for withdraw.
- */
- selectedDenoms: DenomSelectionState;
-
- /**
- * Does the wallet know about an auditor for
- * the exchange that the reserve.
- */
- isAudited: boolean;
-
- /**
- * Did the user already accept the current terms of service for the exchange?
- */
- termsOfServiceAccepted: boolean;
-
- /**
- * The exchange is trusted directly.
- */
- isTrusted: boolean;
-
- /**
- * The earliest deposit expiration of the selected coins.
- */
- earliestDepositExpiration: TalerProtocolTimestamp;
-
- /**
- * Number of currently offered denominations.
- */
- numOfferedDenoms: number;
-
- /**
- * Public keys of trusted auditors for the currency we're withdrawing.
- */
- trustedAuditorPubs: string[];
-
- /**
- * Result of checking the wallet's version
- * against the exchange's version.
- *
- * Older exchanges don't return version information.
- */
- versionMatch: VersionMatchResult | undefined;
-
- /**
- * Libtool-style version string for the exchange or "unknown"
- * for older exchanges.
- */
- exchangeVersion: string;
-
- /**
- * Libtool-style version string for the wallet.
- */
- walletVersion: string;
-
- withdrawalAmountRaw: AmountString;
-
- /**
- * 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[];
-}
-
-/**
* Check if a denom is withdrawable based on the expiration time,
* revocation and offered state.
*/
@@ -1280,7 +1189,7 @@ export async function getExchangeWithdrawalInfo(
exchangeBaseUrl: string,
instructedAmount: AmountJson,
ageRestricted: number | undefined,
-): Promise<ExchangeWithdrawDetails> {
+): Promise<ExchangeWithdrawalDetails> {
const { exchange, exchangeDetails } =
await ws.exchangeOps.updateExchangeFromUrl(ws, exchangeBaseUrl);
await updateWithdrawalDenoms(ws, exchangeBaseUrl);
@@ -1378,10 +1287,14 @@ export async function getExchangeWithdrawalInfo(
}
}
- const ret: ExchangeWithdrawDetails = {
+ const paytoUris = exchangeDetails.wireInfo.accounts.map((x) => x.payto_uri);
+ if (!paytoUris) {
+ throw Error("exchange is in invalid state");
+ }
+
+ const ret: ExchangeWithdrawalDetails = {
earliestDepositExpiration,
- exchangeInfo: exchange,
- exchangeDetails,
+ exchangePaytoUris: paytoUris,
exchangeWireAccounts,
exchangeVersion: exchangeDetails.protocolVersion || "unknown",
isAudited,
diff --git a/packages/taler-wallet-core/src/wallet.ts b/packages/taler-wallet-core/src/wallet.ts
index 254648064..22cbeb4b8 100644
--- a/packages/taler-wallet-core/src/wallet.ts
+++ b/packages/taler-wallet-core/src/wallet.ts
@@ -47,7 +47,6 @@ import {
codecForForgetKnownBankAccounts,
codecForGetContractTermsDetails,
codecForGetExchangeTosRequest,
- codecForGetExchangeWithdrawalInfo,
codecForGetFeeForDeposit,
codecForGetWithdrawalDetailsForAmountRequest,
codecForGetWithdrawalDetailsForUri,
@@ -112,7 +111,11 @@ import {
importDb,
WalletStoresV1,
} from "./db.js";
-import { applyDevExperiment, maybeInitDevMode, setDevMode } from "./dev-experiments.js";
+import {
+ applyDevExperiment,
+ maybeInitDevMode,
+ setDevMode,
+} from "./dev-experiments.js";
import { getErrorDetailFromException, TalerError } from "./errors.js";
import {
ActiveLongpollInfo,
@@ -248,32 +251,6 @@ const builtinExchanges: string[] = ["https://exchange.demo.taler.net/"];
const logger = new Logger("wallet.ts");
-async function getWithdrawalDetailsForAmount(
- ws: InternalWalletState,
- exchangeBaseUrl: string,
- amount: AmountJson,
- restrictAge: number | undefined,
-): Promise<ManualWithdrawalDetails> {
- const wi = await getExchangeWithdrawalInfo(
- ws,
- exchangeBaseUrl,
- amount,
- restrictAge,
- );
- const paytoUris = wi.exchangeDetails.wireInfo.accounts.map(
- (x) => x.payto_uri,
- );
- if (!paytoUris) {
- throw Error("exchange is in invalid state");
- }
- return {
- amountRaw: Amounts.stringify(amount),
- amountEffective: Amounts.stringify(wi.selectedDenoms.totalCoinValue),
- paytoUris,
- tosAccepted: wi.termsOfServiceAccepted,
- };
-}
-
/**
* Call the right handler for a pending operation without doing
* any special error handling.
@@ -1038,16 +1015,6 @@ async function dispatchRequestInternal(
const req = codecForGetWithdrawalDetailsForUri().decode(payload);
return await getWithdrawalDetailsForUri(ws, req.talerWithdrawUri);
}
-
- case "getExchangeWithdrawalInfo": {
- const req = codecForGetExchangeWithdrawalInfo().decode(payload);
- return await getExchangeWithdrawalInfo(
- ws,
- req.exchangeBaseUrl,
- req.amount,
- req.ageRestricted,
- );
- }
case "acceptManualWithdrawal": {
const req = codecForAcceptManualWithdrawalRequet().decode(payload);
const res = await createManualWithdrawal(ws, {
@@ -1060,12 +1027,18 @@ async function dispatchRequestInternal(
case "getWithdrawalDetailsForAmount": {
const req =
codecForGetWithdrawalDetailsForAmountRequest().decode(payload);
- return await getWithdrawalDetailsForAmount(
+ const wi = await getExchangeWithdrawalInfo(
ws,
req.exchangeBaseUrl,
Amounts.parseOrThrow(req.amount),
req.restrictAge,
);
+ return {
+ amountRaw: req.amount,
+ amountEffective: Amounts.stringify(wi.selectedDenoms.totalCoinValue),
+ paytoUris: wi.exchangePaytoUris,
+ tosAccepted: wi.termsOfServiceAccepted,
+ };
}
case "getBalances": {
return await getBalances(ws);
@@ -1255,7 +1228,7 @@ async function dispatchRequestInternal(
case "withdrawFakebank": {
const req = codecForWithdrawFakebankRequest().decode(payload);
const amount = Amounts.parseOrThrow(req.amount);
- const details = await getWithdrawalDetailsForAmount(
+ const details = await getExchangeWithdrawalInfo(
ws,
req.exchange,
amount,
@@ -1265,7 +1238,7 @@ async function dispatchRequestInternal(
amount: amount,
exchangeBaseUrl: req.exchange,
});
- const paytoUri = details.paytoUris[0];
+ const paytoUri = details.exchangePaytoUris[0];
const pt = parsePaytoUri(paytoUri);
if (!pt) {
throw Error("failed to parse payto URI");
diff --git a/packages/taler-wallet-webextension/src/cta/Withdraw/state.ts b/packages/taler-wallet-webextension/src/cta/Withdraw/state.ts
index c2b9e375f..53bac579e 100644
--- a/packages/taler-wallet-webextension/src/cta/Withdraw/state.ts
+++ b/packages/taler-wallet-webextension/src/cta/Withdraw/state.ts
@@ -182,16 +182,15 @@ function exchangeSelectionState(
* about the withdrawal
*/
const amountHook = useAsyncAsHook(async () => {
- const info = await api.getExchangeWithdrawalInfo({
+ const info = await api.getWithdrawalDetailsForAmount({
exchangeBaseUrl: currentExchange.exchangeBaseUrl,
- amount: chosenAmount,
- tosAcceptedFormat: ["text/xml"],
- ageRestricted,
+ amount: Amounts.stringify(chosenAmount),
+ restrictAge: ageRestricted,
});
const withdrawAmount = {
- raw: Amounts.parseOrThrow(info.withdrawalAmountRaw),
- effective: Amounts.parseOrThrow(info.withdrawalAmountEffective),
+ raw: Amounts.parseOrThrow(info.amountRaw),
+ effective: Amounts.parseOrThrow(info.amountEffective),
};
return {
diff --git a/packages/taler-wallet-webextension/src/cta/Withdraw/test.ts b/packages/taler-wallet-webextension/src/cta/Withdraw/test.ts
index f3598b557..d86771208 100644
--- a/packages/taler-wallet-webextension/src/cta/Withdraw/test.ts
+++ b/packages/taler-wallet-webextension/src/cta/Withdraw/test.ts
@@ -22,14 +22,11 @@
import {
Amounts,
ExchangeFullDetails,
- ExchangeListItem,
GetExchangeTosResult,
} from "@gnu-taler/taler-util";
-import { ExchangeWithdrawDetails } from "@gnu-taler/taler-wallet-core";
import { expect } from "chai";
import { mountHook } from "../../test-utils.js";
import { useComponentStateFromURI } from "./state.js";
-import * as wxApi from "../../wxApi.js";
const exchanges: ExchangeFullDetails[] = [
{
@@ -162,20 +159,11 @@ describe("Withdraw CTA states", () => {
},
{
listExchanges: async () => ({ exchanges }),
- getWithdrawalDetailsForUri: async ({
- talerWithdrawUri,
- }: any): Promise<ExchangeWithdrawDetails> =>
- ({
- amount: "ARS:2",
- possibleExchanges: exchanges,
- defaultExchangeBaseUrl: exchanges[0].exchangeBaseUrl,
- } as Partial<ExchangeWithdrawDetails> as ExchangeWithdrawDetails),
- getExchangeWithdrawalInfo:
- async (): Promise<ExchangeWithdrawDetails> =>
- ({
- withdrawalAmountRaw: "ARS:2",
- withdrawalAmountEffective: "ARS:2",
- } as any),
+ getWithdrawalDetailsForUri: async ({ talerWithdrawUri }: any) => ({
+ amount: "ARS:2",
+ possibleExchanges: exchanges,
+ defaultExchangeBaseUrl: exchanges[0].exchangeBaseUrl,
+ }),
getExchangeTos: async (): Promise<GetExchangeTosResult> => ({
contentType: "text",
content: "just accept",
@@ -255,19 +243,12 @@ describe("Withdraw CTA states", () => {
},
},
{
- listExchanges: async () => listExchangesResponse,
- getWithdrawalDetailsForUri: async ({ talerWithdrawUri }: any) =>
- ({
- amount: "ARS:2",
- possibleExchanges: exchanges,
- defaultExchangeBaseUrl: exchanges[0].exchangeBaseUrl,
- } as Partial<ExchangeWithdrawDetails> as ExchangeWithdrawDetails),
- getExchangeWithdrawalInfo:
- async (): Promise<ExchangeWithdrawDetails> =>
- ({
- withdrawalAmountRaw: "ARS:2",
- withdrawalAmountEffective: "ARS:2",
- } as any),
+ listExchanges: async () => ({ exchanges }),
+ getWithdrawalDetailsForUri: async ({ talerWithdrawUri }: any) => ({
+ amount: "ARS:2",
+ possibleExchanges: exchanges,
+ defaultExchangeBaseUrl: exchanges[0].exchangeBaseUrl,
+ }),
getExchangeTos: async (): Promise<GetExchangeTosResult> => ({
contentType: "text",
content: "just accept",
diff --git a/packages/taler-wallet-webextension/src/wxApi.ts b/packages/taler-wallet-webextension/src/wxApi.ts
index e0a1ee238..17083cb5b 100644
--- a/packages/taler-wallet-webextension/src/wxApi.ts
+++ b/packages/taler-wallet-webextension/src/wxApi.ts
@@ -51,8 +51,8 @@ import {
ExchangesListResponse,
ForgetKnownBankAccountsRequest,
GetExchangeTosResult,
- GetExchangeWithdrawalInfo,
GetFeeForDepositRequest,
+ GetWithdrawalDetailsForAmountRequest,
GetWithdrawalDetailsForUriRequest,
InitiatePeerPullPaymentRequest,
InitiatePeerPullPaymentResponse,
@@ -60,6 +60,7 @@ import {
InitiatePeerPushPaymentResponse,
KnownBankAccounts,
Logger,
+ ManualWithdrawalDetails,
NotificationType,
PaytoUri,
PrepareDepositRequest,
@@ -81,7 +82,6 @@ import {
import {
AddBackupProviderRequest,
BackupInfo,
- ExchangeWithdrawDetails,
PendingOperationsResponse,
RemoveBackupProviderRequest,
TalerError,
@@ -459,14 +459,12 @@ export function getWithdrawalDetailsForUri(
return callBackend("getWithdrawalDetailsForUri", req);
}
-/**
- * Get diagnostics information
- */
-export function getExchangeWithdrawalInfo(
- req: GetExchangeWithdrawalInfo,
-): Promise<ExchangeWithdrawDetails> {
- return callBackend("getExchangeWithdrawalInfo", req);
+export function getWithdrawalDetailsForAmount(
+ req: GetWithdrawalDetailsForAmountRequest,
+): Promise<ManualWithdrawalDetails> {
+ return callBackend("getWithdrawalDetailsForAmount", req);
}
+
export function getExchangeTos(
exchangeBaseUrl: string,
acceptedFormat: string[],