diff options
-rw-r--r-- | API_CHANGES.md | 2 | ||||
-rw-r--r-- | packages/taler-util/src/wallet-types.ts | 28 | ||||
-rw-r--r-- | packages/taler-wallet-core/src/wallet-api-types.ts | 13 | ||||
-rw-r--r-- | packages/taler-wallet-core/src/wallet.ts | 35 |
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); |