gnunet-svn
[Top][All Lists]
Advanced

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

[taler-wallet-core] branch master updated: manual withdrawal process


From: gnunet
Subject: [taler-wallet-core] branch master updated: manual withdrawal process
Date: Mon, 20 Sep 2021 19:05:54 +0200

This is an automated email from the git hooks/post-receive script.

sebasjm pushed a commit to branch master
in repository wallet-core.

The following commit(s) were added to refs/heads/master by this push:
     new 8cde9894 manual withdrawal process
8cde9894 is described below

commit 8cde98947ba1a6d8c7928578b053786c4e5db17f
Author: Sebastian <sebasjm@gmail.com>
AuthorDate: Mon Sep 20 14:05:40 2021 -0300

    manual withdrawal process
---
 .../src/NavigationBar.tsx                          |  1 +
 .../src/components/styled/index.tsx                | 27 ++++++++
 .../taler-wallet-webextension/src/cta/Withdraw.tsx |  2 +-
 .../src/popup/BalancePage.tsx                      | 23 ++++---
 .../src/popupEntryPoint.tsx                        | 20 +++++-
 .../src/wallet/BackupPage.tsx                      |  6 +-
 .../src/wallet/BalancePage.tsx                     | 27 +++++---
 .../src/wallet/CreateManualWithdraw.stories.tsx    | 56 +++++++++++++++++
 .../src/wallet/CreateManualWithdraw.tsx            | 57 +++++++++++++++++
 .../src/wallet/ManualWithdrawPage.tsx              | 71 ++++++++++++++++++++++
 .../src/wallet/ReserveCreated.stories.tsx          | 40 ++++++++++++
 .../src/wallet/ReserveCreated.tsx                  | 41 +++++++++++++
 .../src/wallet/Transaction.tsx                     |  2 +-
 .../src/walletEntryPoint.tsx                       | 18 ++++--
 packages/taler-wallet-webextension/src/wxApi.ts    | 18 ++++++
 15 files changed, 380 insertions(+), 29 deletions(-)

diff --git a/packages/taler-wallet-webextension/src/NavigationBar.tsx 
b/packages/taler-wallet-webextension/src/NavigationBar.tsx
index 9ddf610c..5345e3ba 100644
--- a/packages/taler-wallet-webextension/src/NavigationBar.tsx
+++ b/packages/taler-wallet-webextension/src/NavigationBar.tsx
@@ -33,6 +33,7 @@ import { PopupNavigation } from './components/styled'
 export enum Pages {
   welcome = '/welcome',
   balance = '/balance',
+  manual_withdraw = '/manual-withdraw',
   settings = '/settings',
   dev = '/dev',
   backup = '/backup',
diff --git a/packages/taler-wallet-webextension/src/components/styled/index.tsx 
b/packages/taler-wallet-webextension/src/components/styled/index.tsx
index 23b0b1b5..0dbf34b5 100644
--- a/packages/taler-wallet-webextension/src/components/styled/index.tsx
+++ b/packages/taler-wallet-webextension/src/components/styled/index.tsx
@@ -486,6 +486,33 @@ export const Input = styled.div<{ invalid?: boolean }>`
   }
 `
 
+export const InputWithLabel = styled.div<{ invalid?: boolean }>`
+  & label {
+    display: block;
+    padding: 5px;
+    color: ${({ invalid }) => !invalid ? 'inherit' : 'red'}
+  }
+  & > div {
+    position: relative;
+    display: flex;
+    top: 0px;
+    bottom: 0px;
+
+    &  > div {
+      position: absolute;
+      background-color: lightgray;
+      padding: 5px;
+      margin: 2px;
+    }
+
+    &  > input {
+      flex: 1;
+      padding: 5px; 
+      border-color: ${({ invalid }) => !invalid ? 'inherit' : 'red'}
+    }
+  }
+`
+
 export const ErrorBox = styled.div`
   border: 2px solid #f5c6cb;
   border-radius: 0.25em;
diff --git a/packages/taler-wallet-webextension/src/cta/Withdraw.tsx 
b/packages/taler-wallet-webextension/src/cta/Withdraw.tsx
index b8b8159f..46451e72 100644
--- a/packages/taler-wallet-webextension/src/cta/Withdraw.tsx
+++ b/packages/taler-wallet-webextension/src/cta/Withdraw.tsx
@@ -141,7 +141,7 @@ export function View({ details, amount, onWithdraw, terms, 
reviewing, onReview,
       }
 
       <section>
-        {terms.status === 'new' && !accepted &&
+        {terms.status === 'new' && !accepted && !reviewing &&
           <ButtonSuccess
             upperCased
             disabled={!details.exchangeInfo.baseUrl}
diff --git a/packages/taler-wallet-webextension/src/popup/BalancePage.tsx 
b/packages/taler-wallet-webextension/src/popup/BalancePage.tsx
index 350d4b86..e3bada8d 100644
--- a/packages/taler-wallet-webextension/src/popup/BalancePage.tsx
+++ b/packages/taler-wallet-webextension/src/popup/BalancePage.tsx
@@ -20,20 +20,21 @@ import {
   i18n
 } from "@gnu-taler/taler-util";
 import { JSX, h } from "preact";
-import { PopupBox, Centered } from "../components/styled/index";
+import { PopupBox, Centered, ButtonPrimary } from "../components/styled/index";
 import { BalancesHook, useBalances } from "../hooks/useBalances";
 import { PageLink, renderAmount } from "../renderHtml";
 
 
-export function BalancePage() {
+export function BalancePage({ goToWalletManualWithdraw }: { 
goToWalletManualWithdraw: () => void }) {
   const balance = useBalances()
-  return <BalanceView balance={balance} Linker={PageLink} />
+  return <BalanceView balance={balance} Linker={PageLink} 
goToWalletManualWithdraw={goToWalletManualWithdraw} />
 }
 export interface BalanceViewProps {
-  balance: BalancesHook,
-  Linker: typeof PageLink,
+  balance: BalancesHook;
+  Linker: typeof PageLink;
+  goToWalletManualWithdraw: () => void;
 }
-export function BalanceView({ balance, Linker }: BalanceViewProps) {
+export function BalanceView({ balance, Linker, goToWalletManualWithdraw }: 
BalanceViewProps) {
   if (!balance) {
     return <span />
   }
@@ -57,7 +58,9 @@ export function BalanceView({ balance, Linker }: 
BalanceViewProps) {
       </i18n.Translate></p>
     )
   }
-  return <ShowBalances wallet={balance.response} />
+  return <ShowBalances wallet={balance.response}
+    onWithdraw={goToWalletManualWithdraw}
+  />
 }
 
 function formatPending(entry: Balance): JSX.Element {
@@ -96,7 +99,7 @@ function formatPending(entry: Balance): JSX.Element {
 }
 
 
-function ShowBalances({ wallet }: { wallet: BalancesResponse }) {
+function ShowBalances({ wallet, onWithdraw }: { wallet: BalancesResponse, 
onWithdraw: () => void }) {
   return <PopupBox>
     <section>
       <Centered>{wallet.balances.map((entry) => {
@@ -113,5 +116,9 @@ function ShowBalances({ wallet }: { wallet: 
BalancesResponse }) {
         );
       })}</Centered>
     </section>
+    <footer>
+      <div />
+      <ButtonPrimary onClick={onWithdraw} >Withdraw</ButtonPrimary>
+    </footer>
   </PopupBox>
 }
diff --git a/packages/taler-wallet-webextension/src/popupEntryPoint.tsx 
b/packages/taler-wallet-webextension/src/popupEntryPoint.tsx
index 15e27486..4bdc2d88 100644
--- a/packages/taler-wallet-webextension/src/popupEntryPoint.tsx
+++ b/packages/taler-wallet-webextension/src/popupEntryPoint.tsx
@@ -22,8 +22,8 @@
 
 import { setupI18n } from "@gnu-taler/taler-util";
 import { createHashHistory } from "history";
-import { render, h } from "preact";
-import Router, { route, Route } from "preact-router";
+import { render, h, VNode } from "preact";
+import Router, { route, Route, getCurrentUrl } from "preact-router";
 import { useEffect, useState } from "preact/hooks";
 import { DevContextProvider } from "./context/devContext";
 import { useTalerActionURL } from "./hooks/useTalerActionURL";
@@ -96,9 +96,16 @@ function Application() {
         <WalletNavBar />
         <div style={{ width: 400, height: 290 }}>
           <Router history={createHashHistory()}>
-            <Route path={Pages.balance} component={BalancePage} />
+            <Route path={Pages.balance} component={BalancePage}
+              goToWalletManualWithdraw={() => 
goToWalletPage(Pages.manual_withdraw)}
+            />
             <Route path={Pages.settings} component={SettingsPage} />
             <Route path={Pages.dev} component={DeveloperPage} />
+
+            <Route path={Pages.transaction}
+              component={({ tid }: { tid: string }) => 
goToWalletPage(Pages.transaction.replace(':tid', tid))}
+            />
+
             <Route path={Pages.history} component={HistoryPage} />
             <Route path={Pages.backup} component={BackupPage}
               onAddProvider={() => {
@@ -123,6 +130,13 @@ function Application() {
   );
 }
 
+function goToWalletPage(page: Pages | string): null {
+  chrome.tabs.create({
+    active: true,
+    url: chrome.extension.getURL(`/static/wallet.html#${page}`),
+  })
+  return null
+}
 
 function Redirect({ to }: { to: string }): null {
   useEffect(() => {
diff --git a/packages/taler-wallet-webextension/src/wallet/BackupPage.tsx 
b/packages/taler-wallet-webextension/src/wallet/BackupPage.tsx
index ffc4418e..712329bf 100644
--- a/packages/taler-wallet-webextension/src/wallet/BackupPage.tsx
+++ b/packages/taler-wallet-webextension/src/wallet/BackupPage.tsx
@@ -57,7 +57,7 @@ export function BackupView({ providers, onAddProvider, 
onSyncAll }: ViewProps):
           title={provider.name}
         />
         )}
-        {!providers.length && <Centered style={{marginTop: 100}}>
+        {!providers.length && <Centered style={{ marginTop: 100 }}>
           <BoldLight>No backup providers configured</BoldLight>
           <ButtonSuccess onClick={onAddProvider}><i18n.Translate>Add 
provider</i18n.Translate></ButtonSuccess>
         </Centered>}
@@ -98,8 +98,8 @@ function BackupLayout(props: TransactionLayoutProps): 
JSX.Element {
       <div style={{ color: !props.active ? "grey" : undefined }}>
         <a href={Pages.provider_detail.replace(':pid', 
encodeURIComponent(props.id))}><span>{props.title}</span></a>
 
-        {dateStr && <SmallText style={{marginTop: 5}}>Last synced: 
{dateStr}</SmallText>}
-        {!dateStr && <SmallLightText style={{marginTop: 5}}>Not 
synced</SmallLightText>}
+        {dateStr && <SmallText style={{ marginTop: 5 }}>Last synced: 
{dateStr}</SmallText>}
+        {!dateStr && <SmallLightText style={{ marginTop: 5 }}>Not 
synced</SmallLightText>}
       </div>
       <div>
         {props.status?.type === 'paid' ?
diff --git a/packages/taler-wallet-webextension/src/wallet/BalancePage.tsx 
b/packages/taler-wallet-webextension/src/wallet/BalancePage.tsx
index 4846d47f..e06e884c 100644
--- a/packages/taler-wallet-webextension/src/wallet/BalancePage.tsx
+++ b/packages/taler-wallet-webextension/src/wallet/BalancePage.tsx
@@ -19,21 +19,24 @@ import {
   Balance, BalancesResponse,
   i18n
 } from "@gnu-taler/taler-util";
-import { JSX, h } from "preact";
-import { WalletBox, Centered } from "../components/styled/index";
+import { JSX } from "preact";
+import { ButtonPrimary, Centered, WalletBox } from 
"../components/styled/index";
 import { BalancesHook, useBalances } from "../hooks/useBalances";
 import { PageLink, renderAmount } from "../renderHtml";
 
 
-export function BalancePage() {
+export function BalancePage({ goToWalletManualWithdraw }: { 
goToWalletManualWithdraw: () => void }) {
   const balance = useBalances()
-  return <BalanceView balance={balance} Linker={PageLink} />
+  return <BalanceView balance={balance} Linker={PageLink} 
goToWalletManualWithdraw={goToWalletManualWithdraw} />
 }
+
 export interface BalanceViewProps {
-  balance: BalancesHook,
-  Linker: typeof PageLink,
+  balance: BalancesHook;
+  Linker: typeof PageLink;
+  goToWalletManualWithdraw: () => void;
 }
-export function BalanceView({ balance, Linker }: BalanceViewProps) {
+
+export function BalanceView({ balance, Linker, goToWalletManualWithdraw }: 
BalanceViewProps) {
   if (!balance) {
     return <span />
   }
@@ -57,7 +60,9 @@ export function BalanceView({ balance, Linker }: 
BalanceViewProps) {
       </i18n.Translate></p>
     )
   }
-  return <ShowBalances wallet={balance.response} />
+  return <ShowBalances wallet={balance.response}
+    onWithdraw={goToWalletManualWithdraw}
+  />
 }
 
 function formatPending(entry: Balance): JSX.Element {
@@ -96,7 +101,7 @@ function formatPending(entry: Balance): JSX.Element {
 }
 
 
-function ShowBalances({ wallet }: { wallet: BalancesResponse }) {
+function ShowBalances({ wallet, onWithdraw }: { wallet: BalancesResponse, 
onWithdraw: () => void }) {
   return <WalletBox>
     <section>
       <Centered>{wallet.balances.map((entry) => {
@@ -113,5 +118,9 @@ function ShowBalances({ wallet }: { wallet: 
BalancesResponse }) {
         );
       })}</Centered>
     </section>
+    <footer>
+      <div />
+      <ButtonPrimary onClick={onWithdraw} >Withdraw</ButtonPrimary>
+    </footer>
   </WalletBox>
 }
diff --git 
a/packages/taler-wallet-webextension/src/wallet/CreateManualWithdraw.stories.tsx
 
b/packages/taler-wallet-webextension/src/wallet/CreateManualWithdraw.stories.tsx
new file mode 100644
index 00000000..35da5239
--- /dev/null
+++ 
b/packages/taler-wallet-webextension/src/wallet/CreateManualWithdraw.stories.tsx
@@ -0,0 +1,56 @@
+/*
+ This file is part of GNU Taler
+ (C) 2021 Taler Systems S.A.
+
+ GNU Taler is free software; you can redistribute it and/or modify it under the
+ terms of the GNU General Public License as published by the Free Software
+ Foundation; either version 3, or (at your option) any later version.
+
+ GNU Taler is distributed in the hope that it will be useful, but WITHOUT ANY
+ WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
+ A PARTICULAR PURPOSE.  See the GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License along with
+ GNU Taler; see the file COPYING.  If not, see <http://www.gnu.org/licenses/>
+ */
+
+/**
+*
+* @author Sebastian Javier Marchano (sebasjm)
+*/
+
+import { createExample } from '../test-utils';
+import { CreateManualWithdraw as TestedComponent } from 
'./CreateManualWithdraw';
+
+export default {
+  title: 'wallet/manual withdraw/creation',
+  component: TestedComponent,
+  argTypes: {
+  }
+};
+
+
+export const InitialState = createExample(TestedComponent, {
+});
+
+export const WithExchangeFilled = createExample(TestedComponent, {
+  currency: 'COL',
+  initialExchange: 'http://exchange.taler:8081',
+});
+
+export const WithExchangeAndAmountFilled = createExample(TestedComponent, {
+  currency: 'COL',
+  initialExchange: 'http://exchange.taler:8081',
+  initialAmount: '10'
+});
+
+export const WithExchangeError = createExample(TestedComponent, {
+  initialExchange: 'http://exchange.tal',
+  error: 'The exchange url seems invalid'
+});
+
+export const WithAmountError = createExample(TestedComponent, {
+  currency: 'COL',
+  initialExchange: 'http://exchange.taler:8081',
+  initialAmount: 'e'
+});
diff --git 
a/packages/taler-wallet-webextension/src/wallet/CreateManualWithdraw.tsx 
b/packages/taler-wallet-webextension/src/wallet/CreateManualWithdraw.tsx
new file mode 100644
index 00000000..be2cbe41
--- /dev/null
+++ b/packages/taler-wallet-webextension/src/wallet/CreateManualWithdraw.tsx
@@ -0,0 +1,57 @@
+import { AmountJson, Amounts } from "@gnu-taler/taler-util";
+import { VNode } from "preact";
+import { useEffect, useRef, useState } from "preact/hooks";
+import { ErrorMessage } from "../components/ErrorMessage";
+import { ButtonPrimary, Input, InputWithLabel, LightText, WalletBox } from 
"../components/styled";
+
+export interface Props {
+  error: string | undefined;
+  currency: string | undefined;
+  initialExchange?: string;
+  initialAmount?: string;
+  onExchangeChange: (exchange: string) => void;
+  onCreate: (exchangeBaseUrl: string, amount: AmountJson) => Promise<void>;
+}
+
+export function CreateManualWithdraw({ onExchangeChange, initialExchange, 
initialAmount, error, currency, onCreate }: Props): VNode {
+  const [exchange, setExchange] = useState(initialExchange || "");
+  const [amount, setAmount] = useState(initialAmount || "");
+  const parsedAmount = Amounts.parse(`${currency}:${amount}`)
+
+  let timeout = useRef<number | undefined>(undefined);
+  useEffect(() => {
+    if (timeout) window.clearTimeout(timeout.current)
+    timeout.current = window.setTimeout(async () => {
+      onExchangeChange(exchange)
+    }, 1000);
+  }, [exchange])
+
+
+  return (
+    <WalletBox>
+      <section>
+        <ErrorMessage title={error && "Can't create the reserve"} 
description={error} />
+        <h2>Manual Withdrawal</h2>
+        <LightText>Choose a exchange to create a reserve and then fill the 
reserve to withdraw the coins</LightText>
+        <p>
+          <Input invalid={!!exchange && !currency}>
+            <label>Exchange</label>
+            <input type="text" placeholder="https://"; value={exchange} 
onChange={(e) => setExchange(e.currentTarget.value)} />
+            <small>http://exchange.taler:8081</small>
+          </Input>
+          {currency && <InputWithLabel invalid={!!amount && !parsedAmount}>
+            <label>Amount</label>
+            <div>
+              <div>{currency}</div>
+              <input type="number" style={{ paddingLeft: 
`${currency.length}em` }} value={amount} onChange={e => 
setAmount(e.currentTarget.value)} />
+            </div>
+          </InputWithLabel>}
+        </p>
+      </section>
+      <footer>
+        <div />
+        <ButtonPrimary disabled={!parsedAmount || !exchange} onClick={() => 
onCreate(exchange, parsedAmount!)}>Create</ButtonPrimary>
+      </footer>
+    </WalletBox>
+  );
+}
diff --git 
a/packages/taler-wallet-webextension/src/wallet/ManualWithdrawPage.tsx 
b/packages/taler-wallet-webextension/src/wallet/ManualWithdrawPage.tsx
new file mode 100644
index 00000000..d4daefc2
--- /dev/null
+++ b/packages/taler-wallet-webextension/src/wallet/ManualWithdrawPage.tsx
@@ -0,0 +1,71 @@
+/*
+ This file is part of TALER
+ (C) 2016 GNUnet e.V.
+
+ TALER is free software; you can redistribute it and/or modify it under the
+ terms of the GNU General Public License as published by the Free Software
+ Foundation; either version 3, or (at your option) any later version.
+
+ TALER is distributed in the hope that it will be useful, but WITHOUT ANY
+ WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
+ A PARTICULAR PURPOSE.  See the GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License along with
+ TALER; see the file COPYING.  If not, see <http://www.gnu.org/licenses/>
+*/
+
+
+import { VNode } from "preact";
+import { useEffect, useRef, useState } from "preact/hooks";
+import { CreateManualWithdraw } from "./CreateManualWithdraw";
+import * as wxApi from '../wxApi'
+import { AcceptManualWithdrawalResult, AmountJson, Amounts } from 
"@gnu-taler/taler-util";
+import { ReserveCreated } from "./ReserveCreated.js";
+
+interface Props {
+
+}
+
+export function ManualWithdrawPage({ }: Props): VNode {
+  const [success, setSuccess] = useState<AcceptManualWithdrawalResult | 
undefined>(undefined)
+  const [currency, setCurrency] = useState<string | undefined>(undefined)
+  const [error, setError] = useState<string | undefined>(undefined)
+
+  async function onExchangeChange(exchange: string | undefined) {
+    if (!exchange) return
+    try {
+      const r = await fetch(`${exchange}/keys`)
+      const j = await r.json()
+      setCurrency(j.currency)
+    } catch (e) {
+      setError('The exchange url seems invalid')
+      setCurrency(undefined)
+    }
+  }
+
+  async function doCreate(exchangeBaseUrl: string, amount: AmountJson) {
+    try {
+      const resp = await wxApi.acceptManualWithdrawal(exchangeBaseUrl, 
Amounts.stringify(amount))
+      setSuccess(resp)
+    } catch (e) {
+      if (e instanceof Error) {
+        setError(e.message)
+      } else {
+        setError('unexpected error')
+      }
+      setSuccess(undefined)
+    }
+  }
+
+  if (success) {
+    return <ReserveCreated reservePub={success.reservePub} 
paytos={success.exchangePaytoUris} onBack={() => {}}/>
+  }
+
+  return <CreateManualWithdraw
+    error={error} currency={currency}
+    onCreate={doCreate} onExchangeChange={onExchangeChange}
+  />;
+}
+
+
+
diff --git 
a/packages/taler-wallet-webextension/src/wallet/ReserveCreated.stories.tsx 
b/packages/taler-wallet-webextension/src/wallet/ReserveCreated.stories.tsx
new file mode 100644
index 00000000..ca524f4e
--- /dev/null
+++ b/packages/taler-wallet-webextension/src/wallet/ReserveCreated.stories.tsx
@@ -0,0 +1,40 @@
+/*
+ This file is part of GNU Taler
+ (C) 2021 Taler Systems S.A.
+
+ GNU Taler is free software; you can redistribute it and/or modify it under the
+ terms of the GNU General Public License as published by the Free Software
+ Foundation; either version 3, or (at your option) any later version.
+
+ GNU Taler is distributed in the hope that it will be useful, but WITHOUT ANY
+ WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
+ A PARTICULAR PURPOSE.  See the GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License along with
+ GNU Taler; see the file COPYING.  If not, see <http://www.gnu.org/licenses/>
+ */
+
+/**
+*
+* @author Sebastian Javier Marchano (sebasjm)
+*/
+
+import { createExample } from '../test-utils';
+import { ReserveCreated as TestedComponent } from './ReserveCreated';
+
+export default {
+  title: 'wallet/manual withdraw/reserve created',
+  component: TestedComponent,
+  argTypes: {
+  }
+};
+
+
+export const InitialState = createExample(TestedComponent, {
+  reservePub: 'ASLKDJQWLKEJASLKDJSADLKASJDLKSADJ',
+  paytos: [
+    
'payto://x-taler-bank/bank.taler:5882/exchangeminator?amount=COL%3A1&message=Taler+Withdrawal+A05AJGMFNSK4Q62NXR2FKNDB1J4EXTYQTE7VA4M9GZQ4TR06YBNG',
+    
'payto://x-taler-bank/international-bank.com/myaccount?amount=COL%3A1&message=Taler+Withdrawal+TYQTE7VA4M9GZQ4TR06YBNGA05AJGMFNSK4Q62NXR2FKNDB1J4EX',
+  ]
+});
+
diff --git a/packages/taler-wallet-webextension/src/wallet/ReserveCreated.tsx 
b/packages/taler-wallet-webextension/src/wallet/ReserveCreated.tsx
new file mode 100644
index 00000000..e01336e0
--- /dev/null
+++ b/packages/taler-wallet-webextension/src/wallet/ReserveCreated.tsx
@@ -0,0 +1,41 @@
+import { Fragment, VNode } from "preact";
+import { useState } from "preact/hooks";
+import { QR } from "../components/QR";
+import { ButtonBox, FontIcon, WalletBox } from "../components/styled";
+
+export interface Props {
+  reservePub: string;
+  paytos: string[];
+  onBack: () => void;
+}
+
+export function ReserveCreated({ reservePub, paytos, onBack }: Props): VNode {
+  const [opened, setOpened] = useState(-1)
+  return (
+    <WalletBox>
+      <section>
+        <h2>Reserve created!</h2>
+        <p>Now you need to send money to the exchange to one of the following 
accounts</p>
+        <p>To complete the setup of the reserve, you must now initiate a wire 
transfer using the given wire transfer subject and crediting the specified 
amount to the indicated account of the exchange.</p>
+      </section>
+      <section>
+        <ul>
+          {paytos.map((href, idx) => {
+            const url = new URL(href)
+            return <li key={idx}><p>
+              <a href="" onClick={(e) => { setOpened(o => o === idx ? -1 : 
idx); e.preventDefault() }}>{url.pathname}</a>
+              {opened === idx && <Fragment>
+                <p>If your system supports RFC 8905, you can do this by 
opening <a href={href}>this URI</a> or scan the QR with your wallet</p>
+                <QR text={href} />
+              </Fragment>}
+            </p></li>
+          })}
+        </ul>
+      </section>
+      <footer>
+        <ButtonBox onClick={onBack}><FontIcon>&#x2190;</FontIcon></ButtonBox>
+        <div />
+      </footer>
+    </WalletBox>
+  );
+}
diff --git a/packages/taler-wallet-webextension/src/wallet/Transaction.tsx 
b/packages/taler-wallet-webextension/src/wallet/Transaction.tsx
index 43575372..052b77dd 100644
--- a/packages/taler-wallet-webextension/src/wallet/Transaction.tsx
+++ b/packages/taler-wallet-webextension/src/wallet/Transaction.tsx
@@ -51,7 +51,7 @@ export function TransactionPage({ tid }: { tid: string; }): 
JSX.Element {
     transaction={transaction}
     onDelete={() => wxApi.deleteTransaction(tid).then(_ => history.go(-1))}
     onRetry={() => wxApi.retryTransaction(tid).then(_ => history.go(-1))}
-    onBack={() => { history.go(-1); }} />;
+    onBack={() => { route(Pages.history) }} />;
 }
 
 export interface WalletTransactionProps {
diff --git a/packages/taler-wallet-webextension/src/walletEntryPoint.tsx 
b/packages/taler-wallet-webextension/src/walletEntryPoint.tsx
index aa007786..023ee94c 100644
--- a/packages/taler-wallet-webextension/src/walletEntryPoint.tsx
+++ b/packages/taler-wallet-webextension/src/walletEntryPoint.tsx
@@ -41,6 +41,8 @@ import { SettingsPage } from "./wallet/Settings";
 import { TransactionPage } from './wallet/Transaction';
 import { WelcomePage } from "./wallet/Welcome";
 import { BackupPage } from './wallet/BackupPage';
+import { DeveloperPage } from "./popup/Debug.js";
+import { ManualWithdrawPage } from "./wallet/ManualWithdrawPage.js";
 
 
 function main(): void {
@@ -52,7 +54,9 @@ function main(): void {
     render(<Application />, container);
   } catch (e) {
     console.error("got error", e);
-    document.body.innerText = `Fatal error: "${e.message}".  Please report 
this bug at https://bugs.gnunet.org/.`;
+    if (e instanceof Error) {
+      document.body.innerText = `Fatal error: "${e.message}".  Please report 
this bug at https://bugs.gnunet.org/.`;
+    }
   }
 }
 
@@ -65,10 +69,10 @@ if (document.readyState === "loading") {
 }
 
 function withLogoAndNavBar(Component: any) {
-  return () => <Fragment>
+  return (props: any) => <Fragment>
     <LogoHeader />
     <WalletNavBar />
-    <Component />
+    <Component {...props} />
   </Fragment>
 }
 
@@ -81,14 +85,20 @@ function Application() {
 
         <Route path={Pages.history} component={withLogoAndNavBar(HistoryPage)} 
/>
         <Route path={Pages.transaction} 
component={withLogoAndNavBar(TransactionPage)} />
-        <Route path={Pages.balance} component={withLogoAndNavBar(BalancePage)} 
/>
+        <Route path={Pages.balance} component={withLogoAndNavBar(BalancePage)} 
+              goToWalletManualWithdraw={() => route(Pages.manual_withdraw)} 
+        />
         <Route path={Pages.settings} 
component={withLogoAndNavBar(SettingsPage)} />
         <Route path={Pages.backup} component={withLogoAndNavBar(BackupPage)} />
 
+        <Route path={Pages.manual_withdraw} 
component={withLogoAndNavBar(ManualWithdrawPage)} />
+
         <Route path={Pages.reset_required} component={() => <div>no yet 
implemented</div>} />
         <Route path={Pages.payback} component={() => <div>no yet 
implemented</div>} />
         <Route path={Pages.return_coins} component={() => <div>no yet 
implemented</div>} />
 
+        <Route path={Pages.dev} component={withLogoAndNavBar(DeveloperPage)} />
+
         {/** call to action */}
         <Route path={Pages.pay} component={PayPage} />
         <Route path={Pages.refund} component={RefundPage} />
diff --git a/packages/taler-wallet-webextension/src/wxApi.ts 
b/packages/taler-wallet-webextension/src/wxApi.ts
index 63774b00..8a0881a6 100644
--- a/packages/taler-wallet-webextension/src/wxApi.ts
+++ b/packages/taler-wallet-webextension/src/wxApi.ts
@@ -40,6 +40,9 @@ import {
   SetWalletDeviceIdRequest,
   GetExchangeWithdrawalInfo,
   AcceptExchangeTosRequest,
+  AcceptManualWithdrawalResult,
+  AcceptManualWithdrawalRequest,
+  AmountJson,
 } from "@gnu-taler/taler-util";
 import { AddBackupProviderRequest, BackupProviderState, OperationFailedError, 
RemoveBackupProviderRequest } from "@gnu-taler/taler-wallet-core";
 import { BackupInfo } from "@gnu-taler/taler-wallet-core";
@@ -252,6 +255,21 @@ export function acceptWithdrawal(
   });
 }
 
+/**
+ * Create a reserve into the exchange that expect the amount indicated
+ * @param exchangeBaseUrl 
+ * @param amount 
+ * @returns 
+ */
+export function acceptManualWithdrawal(
+  exchangeBaseUrl: string,
+  amount: string,
+): Promise<AcceptManualWithdrawalResult> {
+  return callBackend("acceptManualWithdrawal", {
+    amount, exchangeBaseUrl
+  });
+}
+
 export function setExchangeTosAccepted(
   exchangeBaseUrl: string,
   etag: string | undefined

-- 
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]