aboutsummaryrefslogtreecommitdiff
path: root/packages/taler-wallet-webextension/src/wallet
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 /packages/taler-wallet-webextension/src/wallet
parent9a0285ee4b41c63d144de90d345f160adb39f30f (diff)
downloadwallet-core-8cde98947ba1a6d8c7928578b053786c4e5db17f.tar.xz
manual withdrawal process
Diffstat (limited to 'packages/taler-wallet-webextension/src/wallet')
-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
8 files changed, 287 insertions, 13 deletions
diff --git a/packages/taler-wallet-webextension/src/wallet/BackupPage.tsx b/packages/taler-wallet-webextension/src/wallet/BackupPage.tsx
index ffc4418e0..712329bf8 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 4846d47f7..e06e884ce 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 000000000..35da52392
--- /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 000000000..be2cbe41d
--- /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 000000000..d4daefc2e
--- /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 000000000..ca524f4e2
--- /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 000000000..e01336e02
--- /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 435753725..052b77dd0 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 {