summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorSebastian <sebasjm@gmail.com>2021-09-20 14:05:40 -0300
committerSebastian <sebasjm@gmail.com>2021-09-20 14:05:40 -0300
commit8cde98947ba1a6d8c7928578b053786c4e5db17f (patch)
treeea0337748c02d71bd2b2f7555a49b4e74e98d3ff
parent9a0285ee4b41c63d144de90d345f160adb39f30f (diff)
downloadwallet-core-8cde98947ba1a6d8c7928578b053786c4e5db17f.tar.gz
wallet-core-8cde98947ba1a6d8c7928578b053786c4e5db17f.tar.bz2
wallet-core-8cde98947ba1a6d8c7928578b053786c4e5db17f.zip
manual withdrawal process
-rw-r--r--packages/taler-wallet-webextension/src/NavigationBar.tsx1
-rw-r--r--packages/taler-wallet-webextension/src/components/styled/index.tsx27
-rw-r--r--packages/taler-wallet-webextension/src/cta/Withdraw.tsx2
-rw-r--r--packages/taler-wallet-webextension/src/popup/BalancePage.tsx23
-rw-r--r--packages/taler-wallet-webextension/src/popupEntryPoint.tsx20
-rw-r--r--packages/taler-wallet-webextension/src/wallet/BackupPage.tsx6
-rw-r--r--packages/taler-wallet-webextension/src/wallet/BalancePage.tsx27
-rw-r--r--packages/taler-wallet-webextension/src/wallet/CreateManualWithdraw.stories.tsx56
-rw-r--r--packages/taler-wallet-webextension/src/wallet/CreateManualWithdraw.tsx57
-rw-r--r--packages/taler-wallet-webextension/src/wallet/ManualWithdrawPage.tsx71
-rw-r--r--packages/taler-wallet-webextension/src/wallet/ReserveCreated.stories.tsx40
-rw-r--r--packages/taler-wallet-webextension/src/wallet/ReserveCreated.tsx41
-rw-r--r--packages/taler-wallet-webextension/src/wallet/Transaction.tsx2
-rw-r--r--packages/taler-wallet-webextension/src/walletEntryPoint.tsx18
-rw-r--r--packages/taler-wallet-webextension/src/wxApi.ts18
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