gnunet-svn
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[taler-wallet-core] branch master updated (4b61945f6 -> 2779086a3)


From: gnunet
Subject: [taler-wallet-core] branch master updated (4b61945f6 -> 2779086a3)
Date: Mon, 26 Jun 2023 19:23:38 +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 4b61945f6 wallet-core: return numCoins in checkPeerPullCredit response
     new 74579ac2f withdraw exchange URI
     new 1e173e279 added master pub to add-exchange (for validation)
     new 87fc6ebf4 if checkmasterpub is specified, throw if master pub is not 
equal to the expected value
     new 2779086a3 support for exchange-withdraw call to action, pending use 
case when the user need to specify the amount

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/taleruri.test.ts           | 41 ++++++++++++++++
 packages/taler-util/src/taleruri.ts                | 56 ++++++++++++++++++++++
 packages/taler-util/src/wallet-types.ts            |  2 +
 .../taler-wallet-core/src/operations/exchanges.ts  | 23 ++++++++-
 packages/taler-wallet-core/src/wallet.ts           | 35 ++++++++++----
 .../src/NavigationBar.tsx                          |  9 +++-
 .../src/cta/Withdraw/index.ts                      | 21 +++++---
 .../src/cta/Withdraw/state.ts                      | 31 +++++++++++-
 .../src/cta/Withdraw/views.tsx                     |  9 ++++
 .../src/platform/chrome.ts                         |  1 +
 .../src/popup/TalerActionFound.tsx                 |  1 +
 .../src/wallet/Application.tsx                     |  9 +++-
 .../src/wallet/Settings.tsx                        | 11 ++---
 13 files changed, 220 insertions(+), 29 deletions(-)

diff --git a/packages/taler-util/src/taleruri.test.ts 
b/packages/taler-util/src/taleruri.test.ts
index ffc56a723..3244bbbd9 100644
--- a/packages/taler-util/src/taleruri.test.ts
+++ b/packages/taler-util/src/taleruri.test.ts
@@ -22,10 +22,12 @@ import {
   parseRefundUri,
   parseRestoreUri,
   parseTipUri,
+  parseWithdrawExchangeUri,
   parseWithdrawUri,
   stringifyPayPushUri,
   stringifyPayUri,
   stringifyRestoreUri,
+  stringifyWithdrawExchange,
 } from "./taleruri.js";
 
 test("taler pay url parsing: wrong scheme", (t) => {
@@ -329,3 +331,42 @@ test("taler restore URI (stringify)", (t) => {
     
"taler://restore/GJKG23V4ZBHEH45YRK7TWQE8ZTY7JWTY5094TQJSRZN5DSDBX8E0/http%3A%2F%2Fprov1.example.com%2F,https%3A%2F%2Fprov2.example.com%3A234%2F",
   );
 });
+
+test("taler withdraw exchange URI (parse)", (t) => {
+  const r1 = parseWithdrawExchangeUri(
+    
"taler://withdraw-exchange/exchange.demo.taler.net/someroot/GJKG23V4ZBHEH45YRK7TWQE8ZTY7JWTY5094TQJSRZN5DSDBX8E0?a=KUDOS%3A2",
+  );
+  if (!r1) {
+    t.fail();
+    return;
+  }
+  t.deepEqual(
+    r1.exchangePub,
+    "GJKG23V4ZBHEH45YRK7TWQE8ZTY7JWTY5094TQJSRZN5DSDBX8E0",
+  );
+  t.deepEqual(r1.exchangeBaseUrl, "https://exchange.demo.taler.net/someroot/";);
+  t.deepEqual(r1.amount, "KUDOS:2");
+});
+
+test("taler withdraw exchange URI (stringify)", (t) => {
+  const url = stringifyWithdrawExchange({
+    exchangeBaseUrl: "https://exchange.demo.taler.net";,
+    exchangePub: "GJKG23V4ZBHEH45YRK7TWQE8ZTY7JWTY5094TQJSRZN5DSDBX8E0",
+  });
+  t.deepEqual(
+    url,
+    
"taler://withdraw-exchange/exchange.demo.taler.net/GJKG23V4ZBHEH45YRK7TWQE8ZTY7JWTY5094TQJSRZN5DSDBX8E0",
+  );
+});
+
+test("taler withdraw exchange URI with amount (stringify)", (t) => {
+  const url = stringifyWithdrawExchange({
+    exchangeBaseUrl: "https://exchange.demo.taler.net";,
+    exchangePub: "GJKG23V4ZBHEH45YRK7TWQE8ZTY7JWTY5094TQJSRZN5DSDBX8E0",
+    amount: "KUDOS:19",
+  });
+  t.deepEqual(
+    url,
+    
"taler://withdraw-exchange/exchange.demo.taler.net/GJKG23V4ZBHEH45YRK7TWQE8ZTY7JWTY5094TQJSRZN5DSDBX8E0?a=KUDOS%3A19",
+  );
+});
diff --git a/packages/taler-util/src/taleruri.ts 
b/packages/taler-util/src/taleruri.ts
index cb0d74a12..fc140811b 100644
--- a/packages/taler-util/src/taleruri.ts
+++ b/packages/taler-util/src/taleruri.ts
@@ -15,6 +15,7 @@
  */
 
 import { canonicalizeBaseUrl } from "./helpers.js";
+import { AmountString } from "./taler-types.js";
 import { URLSearchParams, URL } from "./url.js";
 
 export type TalerUri =
@@ -28,6 +29,7 @@ export type TalerUri =
   | TipUriResult
   | WithdrawUriResult
   | ExchangeUri
+  | WithdrawExchangeUri
   | AuditorUri;
 
 export interface PayUriResult {
@@ -99,6 +101,13 @@ export interface BackupRestoreUri {
   providers: Array<string>;
 }
 
+export interface WithdrawExchangeUri {
+  type: TalerUriAction.WithdrawExchange;
+  exchangeBaseUrl: string;
+  exchangePub: string;
+  amount?: AmountString;
+}
+
 /**
  * Parse a taler[+http]://withdraw URI.
  * Return undefined if not passed a valid URI.
@@ -166,6 +175,7 @@ export enum TalerUriAction {
   Auditor = "auditor",
   Restore = "restore",
   DevExperiment = "dev-experiment",
+  WithdrawExchange = "withdraw-exchange",
 }
 
 interface TalerUriProtoInfo {
@@ -207,6 +217,7 @@ const parsers: { [A in TalerUriAction]: Parser } = {
   [TalerUriAction.DevExperiment]: parseDevExperimentUri,
   [TalerUriAction.Exchange]: parseExchangeUri,
   [TalerUriAction.Auditor]: parseAuditorUri,
+  [TalerUriAction.WithdrawExchange]: parseWithdrawExchangeUri,
 };
 
 export function parseTalerUri(string: string): TalerUri | undefined {
@@ -253,6 +264,9 @@ export function stringifyTalerUri(uri: TalerUri): string {
     case TalerUriAction.Exchange: {
       return stringifyExchangeUri(uri);
     }
+    case TalerUriAction.WithdrawExchange: {
+      return stringifyWithdrawExchange(uri);
+    }
     case TalerUriAction.Auditor: {
       return stringifyAuditorUri(uri);
     }
@@ -432,6 +446,37 @@ export function parseExchangeUri(s: string): ExchangeUri | 
undefined {
     exchangePub,
   };
 }
+
+export function parseWithdrawExchangeUri(
+  s: string,
+): WithdrawExchangeUri | undefined {
+  const pi = parseProtoInfo(s, "withdraw-exchange");
+  if (!pi) {
+    return undefined;
+  }
+  const c = pi?.rest.split("?");
+  const parts = c[0].split("/");
+  if (parts.length < 2) {
+    return undefined;
+  }
+  const host = parts[0].toLowerCase();
+  const exchangePub = parts[parts.length - 1];
+  const pathSegments = parts.slice(1, parts.length - 1);
+  const hostAndSegments = [host, ...pathSegments].join("/");
+  const exchangeBaseUrl = canonicalizeBaseUrl(
+    `${pi.innerProto}://${hostAndSegments}/`,
+  );
+  const q = new URLSearchParams(c[1] ?? "");
+  const amount = q.get("a") ?? undefined;
+
+  return {
+    type: TalerUriAction.WithdrawExchange,
+    exchangeBaseUrl,
+    exchangePub,
+    amount,
+  };
+}
+
 export function parseAuditorUri(s: string): AuditorUri | undefined {
   const pi = parseProtoInfo(s, "auditor");
   if (!pi) {
@@ -622,6 +667,17 @@ export function stringifyRestoreUri({
   return `taler://restore/${walletRootPriv}/${list}`;
 }
 
+export function stringifyWithdrawExchange({
+  exchangeBaseUrl,
+  exchangePub,
+  amount,
+}: Omit<WithdrawExchangeUri, "type">): string {
+  const { proto, path, query } = getUrlInfo(exchangeBaseUrl, {
+    a: amount,
+  });
+  return `${proto}://withdraw-exchange/${path}${exchangePub}${query}`;
+}
+
 export function stringifyDevExperimentUri({
   devExperimentId,
 }: Omit<DevExperimentUri, "type">): string {
diff --git a/packages/taler-util/src/wallet-types.ts 
b/packages/taler-util/src/wallet-types.ts
index 3710e6d3c..1b55591b1 100644
--- a/packages/taler-util/src/wallet-types.ts
+++ b/packages/taler-util/src/wallet-types.ts
@@ -1544,6 +1544,7 @@ export const codecForIntegrationTestV2Args = (): 
Codec<IntegrationTestV2Args> =>
 
 export interface AddExchangeRequest {
   exchangeBaseUrl: string;
+  masterPub?: string;
   forceUpdate?: boolean;
 }
 
@@ -1551,6 +1552,7 @@ export const codecForAddExchangeRequest = (): 
Codec<AddExchangeRequest> =>
   buildCodecForObject<AddExchangeRequest>()
     .property("exchangeBaseUrl", codecForString())
     .property("forceUpdate", codecOptional(codecForBoolean()))
+    .property("masterPub", codecOptional(codecForString()))
     .build("AddExchangeRequest");
 
 export interface ForceExchangeUpdateRequest {
diff --git a/packages/taler-wallet-core/src/operations/exchanges.ts 
b/packages/taler-wallet-core/src/operations/exchanges.ts
index 29c370e2c..56ef672dc 100644
--- a/packages/taler-wallet-core/src/operations/exchanges.ts
+++ b/packages/taler-wallet-core/src/operations/exchanges.ts
@@ -75,7 +75,13 @@ import {
   GetReadWriteAccess,
 } from "../util/query.js";
 import { WALLET_EXCHANGE_PROTOCOL_VERSION } from "../versions.js";
-import { OperationAttemptResult, OperationAttemptResultType, 
runTaskWithErrorReporting, TaskIdentifiers, unwrapOperationHandlerResultOrThrow 
} from "./common.js";
+import {
+  OperationAttemptResult,
+  OperationAttemptResultType,
+  runTaskWithErrorReporting,
+  TaskIdentifiers,
+  unwrapOperationHandlerResultOrThrow,
+} from "./common.js";
 
 const logger = new Logger("exchanges.ts");
 
@@ -544,6 +550,7 @@ export async function updateExchangeFromUrl(
   ws: InternalWalletState,
   baseUrl: string,
   options: {
+    checkMasterPub?: string;
     forceNow?: boolean;
     cancellationToken?: CancellationToken;
   } = {},
@@ -570,6 +577,7 @@ export async function updateExchangeFromUrlHandler(
   ws: InternalWalletState,
   exchangeBaseUrl: string,
   options: {
+    checkMasterPub?: string;
     forceNow?: boolean;
     cancellationToken?: CancellationToken;
   } = {},
@@ -605,6 +613,13 @@ export async function updateExchangeFromUrlHandler(
     )
   ) {
     logger.info("using existing exchange info");
+
+    if (options.checkMasterPub) {
+      if (exchangeDetails.masterPublicKey !== options.checkMasterPub) {
+        throw Error(`master public key mismatch`);
+      }
+    }
+
     return {
       type: OperationAttemptResultType.Finished,
       result: { exchange, exchangeDetails },
@@ -621,6 +636,12 @@ export async function updateExchangeFromUrlHandler(
     timeout,
   );
 
+  if (options.checkMasterPub) {
+    if (keysInfo.masterPublicKey !== options.checkMasterPub) {
+      throw Error(`master public key mismatch`);
+    }
+  }
+
   logger.info("updating exchange /wire info");
   const wireInfoDownload = await downloadExchangeWireInfo(
     exchangeBaseUrl,
diff --git a/packages/taler-wallet-core/src/wallet.ts 
b/packages/taler-wallet-core/src/wallet.ts
index 3ceb6b069..df4fd0d94 100644
--- a/packages/taler-wallet-core/src/wallet.ts
+++ b/packages/taler-wallet-core/src/wallet.ts
@@ -243,7 +243,12 @@ import {
   testPay,
   withdrawTestBalance,
 } from "./operations/testing.js";
-import { acceptTip, computeTipTransactionStatus, prepareTip, processTip } from 
"./operations/tip.js";
+import {
+  acceptTip,
+  computeTipTransactionStatus,
+  prepareTip,
+  processTip,
+} from "./operations/tip.js";
 import {
   abortTransaction,
   deleteTransaction,
@@ -281,7 +286,10 @@ import {
   GetReadOnlyAccess,
   GetReadWriteAccess,
 } from "./util/query.js";
-import { OperationAttemptResult, TaskIdentifiers } from 
"./operations/common.js";
+import {
+  OperationAttemptResult,
+  TaskIdentifiers,
+} from "./operations/common.js";
 import { TimerAPI, TimerGroup } from "./util/timer.js";
 import {
   WALLET_BANK_INTEGRATION_PROTOCOL_VERSION,
@@ -1068,6 +1076,7 @@ async function dispatchRequestInternal<Op extends 
WalletApiOperation>(
     case WalletApiOperation.AddExchange: {
       const req = codecForAddExchangeRequest().decode(payload);
       await updateExchangeFromUrl(ws, req.exchangeBaseUrl, {
+        checkMasterPub: req.masterPub,
         forceNow: req.forceUpdate,
       });
       return {};
@@ -1783,36 +1792,42 @@ class InternalWalletStateImpl implements 
InternalWalletState {
         return computePayMerchantTransactionState(rec);
       }
       case TransactionType.Refund: {
-        const rec = await tx.refundGroups.get(
-          parsedTxId.refundGroupId,
-        );
+        const rec = await tx.refundGroups.get(parsedTxId.refundGroupId);
         if (!rec) {
           return undefined;
         }
         return computeRefundTransactionState(rec);
       }
       case TransactionType.PeerPullCredit:
-        const rec = await 
tx.peerPullPaymentInitiations.get(parsedTxId.pursePub);
+        const rec = await tx.peerPullPaymentInitiations.get(
+          parsedTxId.pursePub,
+        );
         if (!rec) {
           return undefined;
         }
         return computePeerPullCreditTransactionState(rec);
       case TransactionType.PeerPullDebit: {
-        const rec = await 
tx.peerPullPaymentIncoming.get(parsedTxId.peerPullPaymentIncomingId);
+        const rec = await tx.peerPullPaymentIncoming.get(
+          parsedTxId.peerPullPaymentIncomingId,
+        );
         if (!rec) {
           return undefined;
         }
         return computePeerPullDebitTransactionState(rec);
       }
       case TransactionType.PeerPushCredit: {
-        const rec = await 
tx.peerPushPaymentIncoming.get(parsedTxId.peerPushPaymentIncomingId);
+        const rec = await tx.peerPushPaymentIncoming.get(
+          parsedTxId.peerPushPaymentIncomingId,
+        );
         if (!rec) {
           return undefined;
         }
         return computePeerPushCreditTransactionState(rec);
       }
       case TransactionType.PeerPushDebit: {
-        const rec = await 
tx.peerPushPaymentInitiations.get(parsedTxId.pursePub);
+        const rec = await tx.peerPushPaymentInitiations.get(
+          parsedTxId.pursePub,
+        );
         if (!rec) {
           return undefined;
         }
@@ -1823,7 +1838,7 @@ class InternalWalletStateImpl implements 
InternalWalletState {
         if (!rec) {
           return undefined;
         }
-        return computeRefreshTransactionState(rec)
+        return computeRefreshTransactionState(rec);
       }
       case TransactionType.Tip: {
         const rec = await tx.tips.get(parsedTxId.walletTipId);
diff --git a/packages/taler-wallet-webextension/src/NavigationBar.tsx 
b/packages/taler-wallet-webextension/src/NavigationBar.tsx
index dd2d31c3d..231418861 100644
--- a/packages/taler-wallet-webextension/src/NavigationBar.tsx
+++ b/packages/taler-wallet-webextension/src/NavigationBar.tsx
@@ -84,7 +84,7 @@ function pageDefinition<T extends object>(pattern: string): 
PageLocation<T> {
     return { ...prev, [name]: cur };
   }, {} as Record<string, string>);
 
-  const f = (values: T): string => replaceAll(pattern, vars, values);
+  const f = (values: T): string => replaceAll(pattern, vars, values ?? {});
   f.pattern = pattern;
   return f;
 }
@@ -152,6 +152,7 @@ const talerUriActionToPageName: {
   [TalerUriAction.PayPush]: "ctaTransferPickup",
   [TalerUriAction.Restore]: "ctaRecovery",
   [TalerUriAction.PayTemplate]: "ctaPayTemplate",
+  [TalerUriAction.WithdrawExchange]: "ctaWithdrawManual",
   [TalerUriAction.DevExperiment]: undefined,
   [TalerUriAction.Exchange]: undefined,
   [TalerUriAction.Auditor]: undefined,
@@ -166,7 +167,11 @@ export function getPathnameForTalerURI(talerUri: string): 
string | undefined {
   if (!pageName) {
     return undefined;
   }
-  return `${Pages[pageName]}?talerUri=${encodeURIComponent(talerUri)}`;
+  const pageString: string =
+    typeof Pages[pageName] === "function"
+      ? (Pages[pageName] as any)()
+      : Pages[pageName];
+  return `${pageString}?talerUri=${encodeURIComponent(talerUri)}`;
 }
 
 export type PopupNavBarOptions = "balance" | "backup" | "dev";
diff --git a/packages/taler-wallet-webextension/src/cta/Withdraw/index.ts 
b/packages/taler-wallet-webextension/src/cta/Withdraw/index.ts
index 45c37ba5c..ae4b3c436 100644
--- a/packages/taler-wallet-webextension/src/cta/Withdraw/index.ts
+++ b/packages/taler-wallet-webextension/src/cta/Withdraw/index.ts
@@ -16,20 +16,19 @@
 
 import { AmountJson, ExchangeListItem } from "@gnu-taler/taler-util";
 import { Loading } from "../../components/Loading.js";
-import { HookError } from "../../hooks/useAsyncAsHook.js";
 import { State as SelectExchangeState } from 
"../../hooks/useSelectedExchange.js";
 import { ButtonHandler, SelectFieldHandler } from "../../mui/handlers.js";
-import { compose, StateViewMap } from "../../utils/index.js";
+import { StateViewMap, compose } from "../../utils/index.js";
 import {
   useComponentStateFromParams,
   useComponentStateFromURI,
 } from "./state.js";
 
+import { ErrorAlertView } from "../../components/CurrentAlerts.js";
+import { ErrorAlert } from "../../context/alert.js";
 import { ExchangeSelectionPage } from 
"../../wallet/ExchangeSelection/index.js";
 import { NoExchangesView } from "../../wallet/ExchangeSelection/views.js";
-import { SuccessView } from "./views.js";
-import { ErrorAlert } from "../../context/alert.js";
-import { ErrorAlertView } from "../../components/CurrentAlerts.js";
+import { SelectAmountView, SuccessView } from "./views.js";
 
 export interface PropsFromURI {
   talerWithdrawUri: string | undefined;
@@ -38,6 +37,7 @@ export interface PropsFromURI {
 }
 
 export interface PropsFromParams {
+  talerExchangeWithdrawUri: string;
   amount: string;
   cancel: () => Promise<void>;
   onSuccess: (txid: string) => Promise<void>;
@@ -48,6 +48,7 @@ export type State =
   | State.LoadingUriError
   | SelectExchangeState.NoExchangeFound
   | SelectExchangeState.Selecting
+  | State.SelectAmount
   | State.Success;
 
 export namespace State {
@@ -60,6 +61,13 @@ export namespace State {
     error: ErrorAlert;
   }
 
+  export interface SelectAmount {
+    status: "select-amount";
+    error: undefined;
+    currentExchange: ExchangeListItem;
+    currency: string;
+  }
+
   export type Success = {
     status: "success";
     error: undefined;
@@ -84,13 +92,14 @@ export namespace State {
 const viewMapping: StateViewMap<State> = {
   loading: Loading,
   error: ErrorAlertView,
+  "select-amount": SelectAmountView,
   "no-exchange-found": NoExchangesView,
   "selecting-exchange": ExchangeSelectionPage,
   success: SuccessView,
 };
 
 export const WithdrawPageFromURI = compose(
-  "WithdrawPageFromURI",
+  "WithdrawPageFromURI_Withdraw",
   (p: PropsFromURI) => useComponentStateFromURI(p),
   viewMapping,
 );
diff --git a/packages/taler-wallet-webextension/src/cta/Withdraw/state.ts 
b/packages/taler-wallet-webextension/src/cta/Withdraw/state.ts
index 717d3ba6b..f19f32ec0 100644
--- a/packages/taler-wallet-webextension/src/cta/Withdraw/state.ts
+++ b/packages/taler-wallet-webextension/src/cta/Withdraw/state.ts
@@ -18,9 +18,12 @@
 import {
   AmountJson,
   Amounts,
+  ExchangeFullDetails,
   ExchangeListItem,
   ExchangeTosStatus,
   TalerError,
+  parseWithdrawExchangeUri,
+  stringifyWithdrawUri,
 } from "@gnu-taler/taler-util";
 import { WalletApiOperation } from "@gnu-taler/taler-wallet-core";
 import { useState } from "preact/hooks";
@@ -33,6 +36,7 @@ import { RecursiveState } from "../../utils/index.js";
 import { PropsFromParams, PropsFromURI, State } from "./index.js";
 
 export function useComponentStateFromParams({
+  talerExchangeWithdrawUri: maybeTalerUri,
   amount,
   cancel,
   onSuccess,
@@ -44,7 +48,29 @@ export function useComponentStateFromParams({
       WalletApiOperation.ListExchanges,
       {},
     );
-    return { amount: Amounts.parseOrThrow(amount), exchanges };
+    const uri = parseWithdrawExchangeUri(maybeTalerUri);
+    const exchangeByTalerUri = uri?.exchangeBaseUrl;
+    let ex: ExchangeFullDetails | undefined;
+    if (exchangeByTalerUri && uri.exchangePub) {
+      await api.wallet.call(WalletApiOperation.AddExchange, {
+        exchangeBaseUrl: exchangeByTalerUri,
+        masterPub: uri.exchangePub,
+      });
+      const info = await api.wallet.call(
+        WalletApiOperation.GetExchangeDetailedInfo,
+        {
+          exchangeBaseUrl: exchangeByTalerUri,
+        },
+      );
+
+      ex = info.exchange;
+    }
+    const chosenAmount = uri
+      ? uri.amount
+        ? Amounts.parseOrThrow(uri.amount)
+        : Amounts.parseOrThrow(`${ex ? ex.currency : "KUDOS"}:66`)
+      : Amounts.parseOrThrow(amount);
+    return { amount: chosenAmount, exchanges, exchange: ex };
   });
 
   if (!uriInfoHook) return { status: "loading", error: undefined };
@@ -60,6 +86,7 @@ export function useComponentStateFromParams({
   }
 
   const chosenAmount = uriInfoHook.response.amount;
+  const exchangeByTalerUri = uriInfoHook.response.exchange?.exchangeBaseUrl;
   const exchangeList = uriInfoHook.response.exchanges.exchanges;
 
   async function doManualWithdraw(
@@ -92,7 +119,7 @@ export function useComponentStateFromParams({
       undefined,
       chosenAmount,
       exchangeList,
-      undefined,
+      exchangeByTalerUri,
     );
 }
 
diff --git a/packages/taler-wallet-webextension/src/cta/Withdraw/views.tsx 
b/packages/taler-wallet-webextension/src/cta/Withdraw/views.tsx
index 50bf99a0c..57d6238b2 100644
--- a/packages/taler-wallet-webextension/src/cta/Withdraw/views.tsx
+++ b/packages/taler-wallet-webextension/src/cta/Withdraw/views.tsx
@@ -142,3 +142,12 @@ function WithdrawWithMobile({
     </section>
   );
 }
+
+export function SelectAmountView({ currency }: State.SelectAmount): VNode {
+  const { i18n } = useTranslationContext();
+  return (
+    <Fragment>
+      <p>select the amount for ${currency}</p>
+    </Fragment>
+  );
+}
diff --git a/packages/taler-wallet-webextension/src/platform/chrome.ts 
b/packages/taler-wallet-webextension/src/platform/chrome.ts
index 34057a310..65670fb69 100644
--- a/packages/taler-wallet-webextension/src/platform/chrome.ts
+++ b/packages/taler-wallet-webextension/src/platform/chrome.ts
@@ -259,6 +259,7 @@ function openWalletURIFromPopup(uri: TalerUri): void {
   encodeURIComponent;
   let url: string | undefined = undefined;
   switch (uri.type) {
+    case TalerUriAction.WithdrawExchange:
     case TalerUriAction.Withdraw:
       url = chrome.runtime.getURL(
         `static/wallet.html#/cta/withdraw?talerUri=${encodeURIComponent(
diff --git a/packages/taler-wallet-webextension/src/popup/TalerActionFound.tsx 
b/packages/taler-wallet-webextension/src/popup/TalerActionFound.tsx
index af966a5ae..6a0585907 100644
--- a/packages/taler-wallet-webextension/src/popup/TalerActionFound.tsx
+++ b/packages/taler-wallet-webextension/src/popup/TalerActionFound.tsx
@@ -40,6 +40,7 @@ function ContentByUriType({
 }) {
   const { i18n } = useTranslationContext();
   switch (uri.type) {
+    case TalerUriAction.WithdrawExchange:
     case TalerUriAction.Withdraw:
       return (
         <div>
diff --git a/packages/taler-wallet-webextension/src/wallet/Application.tsx 
b/packages/taler-wallet-webextension/src/wallet/Application.tsx
index 13afccb6c..7d4dafb56 100644
--- a/packages/taler-wallet-webextension/src/wallet/Application.tsx
+++ b/packages/taler-wallet-webextension/src/wallet/Application.tsx
@@ -391,9 +391,16 @@ export function Application(): VNode {
           />
           <Route
             path={Pages.ctaWithdrawManual.pattern}
-            component={({ amount }: { amount: string }) => (
+            component={({
+              amount,
+              talerUri,
+            }: {
+              amount: string;
+              talerUri: string;
+            }) => (
               <CallToActionTemplate title={i18n.str`Digital cash withdrawal`}>
                 <WithdrawPageFromParams
+                  talerExchangeWithdrawUri={talerUri}
                   amount={amount}
                   cancel={() => redirectTo(Pages.balance)}
                   onSuccess={(tid: string) =>
diff --git a/packages/taler-wallet-webextension/src/wallet/Settings.tsx 
b/packages/taler-wallet-webextension/src/wallet/Settings.tsx
index 6ca443d10..10bcee314 100644
--- a/packages/taler-wallet-webextension/src/wallet/Settings.tsx
+++ b/packages/taler-wallet-webextension/src/wallet/Settings.tsx
@@ -250,13 +250,6 @@ export function SettingsView({
         <EnabledBySettings name="advanceMode">
           <AdvanceSettings />
         </EnabledBySettings>
-        <Checkbox
-          label={i18n.str`Lang selector`}
-          name="langSelector"
-          description={i18n.str`Allows to manually change the language of the 
UI. Otherwise it will be automatically selected by your browser configuration.`}
-          enabled={langToggle.value!}
-          onToggle={langToggle.button.onClick!}
-        />
         <EnabledBySettings name="langSelector">
           <SubTitle>
             <i18n.Translate>Display</i18n.Translate>
@@ -340,6 +333,10 @@ function AdvanceSettings(): VNode {
       label: i18n.str`Allow batch withdrawals`,
       description: i18n.str`Using the batch withdrawal API allows faster 
withdrawals (wallet restart required)`,
     },
+    langSelector: {
+      label: i18n.str`Lang selector`,
+      description: i18n.str`Allows to manually change the language of the UI. 
Otherwise it will be automatically selected by your browser configuration.`,
+    },
   };
   return (
     <Fragment>

-- 
To stop receiving notification emails like this one, please contact
gnunet@gnunet.org.



reply via email to

[Prev in Thread] Current Thread [Next in Thread]