summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--API_CHANGES.md2
-rw-r--r--packages/taler-util/src/wallet-types.ts28
-rw-r--r--packages/taler-wallet-core/src/wallet-api-types.ts13
-rw-r--r--packages/taler-wallet-core/src/wallet.ts35
4 files changed, 77 insertions, 1 deletions
diff --git a/API_CHANGES.md b/API_CHANGES.md
index 3777dc068..3705aca3f 100644
--- a/API_CHANGES.md
+++ b/API_CHANGES.md
@@ -19,3 +19,5 @@ This files contains all the API changes for the current release:
- 2023-12-06 dold: Deprecate the tosStatus in the withdrawal details response.
This field does not conform to DD48 semantics and the client should
request the ToS status separately via a getExchangeEntryForUri request.
+- 2023-12-07 dold: Add the prepareWithdrawExchange request for withdrawals
+ via a taler://withdraw-exchange URI.
diff --git a/packages/taler-util/src/wallet-types.ts b/packages/taler-util/src/wallet-types.ts
index bca8a92a8..d0bf5006d 100644
--- a/packages/taler-util/src/wallet-types.ts
+++ b/packages/taler-util/src/wallet-types.ts
@@ -2843,3 +2843,31 @@ export interface WithdrawalExchangeAccountDetails {
*/
conversionError?: TalerErrorDetail;
}
+
+export interface PrepareWithdrawExchangeRequest {
+ /**
+ * A taler://withdraw-exchange URI.
+ */
+ talerUri: string;
+}
+
+export const codecForPrepareWithdrawExchangeRequest =
+ (): Codec<PrepareWithdrawExchangeRequest> =>
+ buildCodecForObject<PrepareWithdrawExchangeRequest>()
+ .property("talerUri", codecForString())
+ .build("PrepareWithdrawExchangeRequest");
+
+export interface PrepareWithdrawExchangeResponse {
+ /**
+ * Base URL of the exchange that already existed
+ * or was ephemerally added as an exchange entry to
+ * the wallet.
+ */
+ exchangeBaseUrl: string;
+
+ /**
+ * Amount from the taler://withdraw-exchange URI.
+ * Only present if specified in the URI.
+ */
+ amount?: AmountString;
+}
diff --git a/packages/taler-wallet-core/src/wallet-api-types.ts b/packages/taler-wallet-core/src/wallet-api-types.ts
index f1a4d5acf..b83813874 100644
--- a/packages/taler-wallet-core/src/wallet-api-types.ts
+++ b/packages/taler-wallet-core/src/wallet-api-types.ts
@@ -95,6 +95,8 @@ import {
PrepareRefundRequest,
PrepareRewardRequest,
PrepareTipResult as PrepareRewardResult,
+ PrepareWithdrawExchangeRequest,
+ PrepareWithdrawExchangeResponse,
RecoverStoredBackupRequest,
RecoveryLoadRequest,
RetryTransactionRequest,
@@ -231,6 +233,7 @@ export enum WalletApiOperation {
UpdateExchangeEntry = "updateExchangeEntry",
TestingWaitTasksProcessed = "testingWaitTasksProcessed",
ListExchangesForScopedCurrency = "listExchangesForScopedCurrency",
+ PrepareWithdrawExchange = "prepareWithdrawExchange",
}
// group: Initialization
@@ -574,6 +577,15 @@ export type ListExchangesForScopedCurrencyOp = {
};
/**
+ * Prepare for withdrawing via a taler://withdraw-exchange URI.
+ */
+export type PrepareWithdrawExchangeOp = {
+ op: WalletApiOperation.PrepareWithdrawExchange;
+ request: PrepareWithdrawExchangeRequest;
+ response: PrepareWithdrawExchangeResponse;
+};
+
+/**
* Add / force-update an exchange.
*/
export type AddExchangeOp = {
@@ -1181,6 +1193,7 @@ export type WalletOperations = {
[WalletApiOperation.DeleteStoredBackup]: DeleteStoredBackupOp;
[WalletApiOperation.RecoverStoredBackup]: RecoverStoredBackupsOp;
[WalletApiOperation.UpdateExchangeEntry]: UpdateExchangeEntryOp;
+ [WalletApiOperation.PrepareWithdrawExchange]: PrepareWithdrawExchangeOp;
};
export type WalletCoreRequestType<
diff --git a/packages/taler-wallet-core/src/wallet.ts b/packages/taler-wallet-core/src/wallet.ts
index 6092830f6..25cfd7f6f 100644
--- a/packages/taler-wallet-core/src/wallet.ts
+++ b/packages/taler-wallet-core/src/wallet.ts
@@ -51,12 +51,15 @@ import {
ManualWithdrawalDetails,
MerchantUsingTemplateDetails,
NotificationType,
+ PrepareWithdrawExchangeRequest,
+ PrepareWithdrawExchangeResponse,
RecoverStoredBackupRequest,
RefreshReason,
ScopeType,
StoredBackupList,
TalerError,
TalerErrorCode,
+ TalerUriAction,
TaskThrottler,
TestingWaitTransactionRequest,
TransactionState,
@@ -109,6 +112,7 @@ import {
codecForPreparePeerPushCreditRequest,
codecForPrepareRefundRequest,
codecForPrepareRewardRequest,
+ codecForPrepareWithdrawExchangeRequest,
codecForRecoverStoredBackupRequest,
codecForResumeTransaction,
codecForRetryTransactionRequest,
@@ -133,6 +137,7 @@ import {
j2s,
parsePayTemplateUri,
parsePaytoUri,
+ parseTalerUri,
sampleWalletCoreTransactions,
setDangerousTimetravel,
validateIban,
@@ -1045,6 +1050,31 @@ async function recoverStoredBackup(
logger.info(`import done`);
}
+async function handlePrepareWithdrawExchange(
+ ws: InternalWalletState,
+ req: PrepareWithdrawExchangeRequest,
+): Promise<PrepareWithdrawExchangeResponse> {
+ const parsedUri = parseTalerUri(req.talerUri);
+ if (parsedUri?.type !== TalerUriAction.WithdrawExchange) {
+ throw Error("expected a taler://withdraw-exchange URI");
+ }
+ const exchangeBaseUrl = parsedUri.exchangeBaseUrl;
+ const exchange = await updateExchangeFromUrl(ws, exchangeBaseUrl);
+ if (exchange.exchangeDetails.masterPublicKey != parsedUri.exchangePub) {
+ throw Error("mismatch of exchange master public key (URI vs actual)");
+ }
+ if (parsedUri.amount) {
+ const amt = Amounts.parseOrThrow(parsedUri.amount);
+ if (amt.currency !== exchange.exchangeDetails.currency) {
+ throw Error("mismatch of currency (URI vs exchange)");
+ }
+ }
+ return {
+ exchangeBaseUrl,
+ amount: parsedUri.amount,
+ };
+}
+
/**
* Implementation of the "wallet-core" API.
*/
@@ -1313,7 +1343,10 @@ async function dispatchRequestInternal<Op extends WalletApiOperation>(
const req = codecForSharePaymentRequest().decode(payload);
return await sharePayment(ws, req.merchantBaseUrl, req.orderId);
}
-
+ case WalletApiOperation.PrepareWithdrawExchange: {
+ const req = codecForPrepareWithdrawExchangeRequest().decode(payload);
+ return handlePrepareWithdrawExchange(ws, req);
+ }
case WalletApiOperation.PreparePayForUri: {
const req = codecForPreparePayRequest().decode(payload);
return await preparePayForUri(ws, req.talerPayUri);