add exchange feature
This commit is contained in:
parent
a35604fd56
commit
829a59e1a2
@ -42,6 +42,7 @@ export enum Pages {
|
|||||||
transaction = "/transaction/:tid",
|
transaction = "/transaction/:tid",
|
||||||
provider_detail = "/provider/:pid",
|
provider_detail = "/provider/:pid",
|
||||||
provider_add = "/provider/add",
|
provider_add = "/provider/add",
|
||||||
|
exchange_add = "/exchange/add",
|
||||||
|
|
||||||
reset_required = "/reset-required",
|
reset_required = "/reset-required",
|
||||||
payback = "/payback",
|
payback = "/payback",
|
||||||
|
@ -48,8 +48,8 @@ export function CheckboxOutlined({
|
|||||||
label,
|
label,
|
||||||
}: Props): VNode {
|
}: Props): VNode {
|
||||||
return (
|
return (
|
||||||
<Outlined>
|
<StyledCheckboxLabel onClick={onToggle}>
|
||||||
<StyledCheckboxLabel onClick={onToggle}>
|
<Outlined>
|
||||||
<span>
|
<span>
|
||||||
<input
|
<input
|
||||||
type="checkbox"
|
type="checkbox"
|
||||||
@ -62,7 +62,7 @@ export function CheckboxOutlined({
|
|||||||
</div>
|
</div>
|
||||||
<label for={name}>{label}</label>
|
<label for={name}>{label}</label>
|
||||||
</span>
|
</span>
|
||||||
</StyledCheckboxLabel>
|
</Outlined>
|
||||||
</Outlined>
|
</StyledCheckboxLabel>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
@ -476,6 +476,14 @@ const ButtonVariant = styled(Button)`
|
|||||||
text-shadow: 0 1px 1px rgba(0, 0, 0, 0.2);
|
text-shadow: 0 1px 1px rgba(0, 0, 0, 0.2);
|
||||||
`;
|
`;
|
||||||
|
|
||||||
|
export const LinkDestructive = styled(Link)`
|
||||||
|
background-color: rgb(202, 60, 60);
|
||||||
|
`;
|
||||||
|
|
||||||
|
export const LinkPrimary = styled(Link)`
|
||||||
|
color: rgb(66, 184, 221);
|
||||||
|
`;
|
||||||
|
|
||||||
export const ButtonPrimary = styled(ButtonVariant)<{ small?: boolean }>`
|
export const ButtonPrimary = styled(ButtonVariant)<{ small?: boolean }>`
|
||||||
font-size: ${({ small }) => (small ? "small" : "inherit")};
|
font-size: ${({ small }) => (small ? "small" : "inherit")};
|
||||||
background-color: rgb(66, 184, 221);
|
background-color: rgb(66, 184, 221);
|
||||||
@ -892,12 +900,14 @@ export const StyledCheckboxLabel = styled.div`
|
|||||||
text-transform: uppercase;
|
text-transform: uppercase;
|
||||||
/* font-weight: bold; */
|
/* font-weight: bold; */
|
||||||
text-align: center;
|
text-align: center;
|
||||||
|
cursor: pointer;
|
||||||
span {
|
span {
|
||||||
input {
|
input {
|
||||||
display: none;
|
display: none;
|
||||||
opacity: 0;
|
opacity: 0;
|
||||||
width: 1em;
|
width: 1em;
|
||||||
height: 1em;
|
height: 1em;
|
||||||
|
cursor: pointer;
|
||||||
}
|
}
|
||||||
div {
|
div {
|
||||||
display: inline-grid;
|
display: inline-grid;
|
||||||
@ -916,6 +926,7 @@ export const StyledCheckboxLabel = styled.div`
|
|||||||
label {
|
label {
|
||||||
padding: 0px;
|
padding: 0px;
|
||||||
font-size: small;
|
font-size: small;
|
||||||
|
cursor: pointer;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -0,0 +1,129 @@
|
|||||||
|
import { i18n } from "@gnu-taler/taler-util";
|
||||||
|
import { Fragment, h, VNode } from "preact";
|
||||||
|
import { CheckboxOutlined } from "../components/CheckboxOutlined";
|
||||||
|
import { ExchangeXmlTos } from "../components/ExchangeToS";
|
||||||
|
import {
|
||||||
|
ButtonSuccess,
|
||||||
|
ButtonWarning,
|
||||||
|
LinkSuccess,
|
||||||
|
TermsOfService,
|
||||||
|
WarningBox,
|
||||||
|
} from "../components/styled";
|
||||||
|
import { TermsState } from "../utils";
|
||||||
|
|
||||||
|
interface Props {
|
||||||
|
reviewing: boolean;
|
||||||
|
reviewed: boolean;
|
||||||
|
terms: TermsState;
|
||||||
|
onReview?: (b: boolean) => void;
|
||||||
|
onAccept: (b: boolean) => void;
|
||||||
|
}
|
||||||
|
export function TermsOfServiceSection({
|
||||||
|
reviewed,
|
||||||
|
reviewing,
|
||||||
|
terms,
|
||||||
|
onAccept,
|
||||||
|
onReview,
|
||||||
|
}: Props): VNode {
|
||||||
|
if (!reviewing) {
|
||||||
|
if (!reviewed) {
|
||||||
|
if (!onReview) {
|
||||||
|
return <section>Terms of service status: {terms.status}</section>;
|
||||||
|
}
|
||||||
|
return (
|
||||||
|
<Fragment>
|
||||||
|
{terms.status === "new" && (
|
||||||
|
<section>
|
||||||
|
<ButtonSuccess upperCased onClick={() => onReview(true)}>
|
||||||
|
{i18n.str`Review exchange terms of service`}
|
||||||
|
</ButtonSuccess>
|
||||||
|
</section>
|
||||||
|
)}
|
||||||
|
{terms.status === "changed" && (
|
||||||
|
<section>
|
||||||
|
<ButtonWarning upperCased onClick={() => onReview(true)}>
|
||||||
|
{i18n.str`Review new version of terms of service`}
|
||||||
|
</ButtonWarning>
|
||||||
|
</section>
|
||||||
|
)}
|
||||||
|
</Fragment>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
return (
|
||||||
|
<Fragment>
|
||||||
|
{onReview && (
|
||||||
|
<section>
|
||||||
|
<LinkSuccess upperCased onClick={() => onReview(true)}>
|
||||||
|
{i18n.str`Show terms of service`}
|
||||||
|
</LinkSuccess>
|
||||||
|
</section>
|
||||||
|
)}
|
||||||
|
<section>
|
||||||
|
<CheckboxOutlined
|
||||||
|
name="terms"
|
||||||
|
enabled={reviewed}
|
||||||
|
label={i18n.str`I accept the exchange terms of service`}
|
||||||
|
onToggle={() => {
|
||||||
|
console.log("asdasd", reviewed);
|
||||||
|
onAccept(!reviewed);
|
||||||
|
if (onReview) onReview(false);
|
||||||
|
}}
|
||||||
|
/>
|
||||||
|
</section>
|
||||||
|
</Fragment>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
return (
|
||||||
|
<Fragment>
|
||||||
|
{terms.status !== "notfound" && !terms.content && (
|
||||||
|
<section>
|
||||||
|
<WarningBox>
|
||||||
|
The exchange reply with a empty terms of service
|
||||||
|
</WarningBox>
|
||||||
|
</section>
|
||||||
|
)}
|
||||||
|
{terms.status !== "accepted" && terms.content && (
|
||||||
|
<section>
|
||||||
|
{terms.content.type === "xml" && (
|
||||||
|
<TermsOfService>
|
||||||
|
<ExchangeXmlTos doc={terms.content.document} />
|
||||||
|
</TermsOfService>
|
||||||
|
)}
|
||||||
|
{terms.content.type === "plain" && (
|
||||||
|
<div style={{ textAlign: "left" }}>
|
||||||
|
<pre>{terms.content.content}</pre>
|
||||||
|
</div>
|
||||||
|
)}
|
||||||
|
{terms.content.type === "html" && (
|
||||||
|
<iframe src={terms.content.href.toString()} />
|
||||||
|
)}
|
||||||
|
{terms.content.type === "pdf" && (
|
||||||
|
<a href={terms.content.location.toString()} download="tos.pdf">
|
||||||
|
Download Terms of Service
|
||||||
|
</a>
|
||||||
|
)}
|
||||||
|
</section>
|
||||||
|
)}
|
||||||
|
{reviewed && onReview && (
|
||||||
|
<section>
|
||||||
|
<LinkSuccess upperCased onClick={() => onReview(false)}>
|
||||||
|
{i18n.str`Hide terms of service`}
|
||||||
|
</LinkSuccess>
|
||||||
|
</section>
|
||||||
|
)}
|
||||||
|
{terms.status !== "notfound" && (
|
||||||
|
<section>
|
||||||
|
<CheckboxOutlined
|
||||||
|
name="terms"
|
||||||
|
enabled={reviewed}
|
||||||
|
label={i18n.str`I accept the exchange terms of service`}
|
||||||
|
onToggle={() => {
|
||||||
|
onAccept(!reviewed);
|
||||||
|
if (onReview) onReview(false);
|
||||||
|
}}
|
||||||
|
/>
|
||||||
|
</section>
|
||||||
|
)}
|
||||||
|
</Fragment>
|
||||||
|
);
|
||||||
|
}
|
@ -21,6 +21,7 @@
|
|||||||
|
|
||||||
import { amountFractionalBase } from "@gnu-taler/taler-util";
|
import { amountFractionalBase } from "@gnu-taler/taler-util";
|
||||||
import { createExample } from "../test-utils";
|
import { createExample } from "../test-utils";
|
||||||
|
import { termsHtml, termsPdf, termsPlain, termsXml } from "./termsExample";
|
||||||
import { View as TestedComponent } from "./Withdraw";
|
import { View as TestedComponent } from "./Withdraw";
|
||||||
|
|
||||||
export default {
|
export default {
|
||||||
@ -31,751 +32,6 @@ export default {
|
|||||||
},
|
},
|
||||||
};
|
};
|
||||||
|
|
||||||
const termsHtml = `<html xmlns="http://www.w3.org/1999/xhtml" lang="en">
|
|
||||||
<head>
|
|
||||||
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
|
|
||||||
<title>Terms Of Service — Taler Terms of Service</title>
|
|
||||||
</head><body>
|
|
||||||
<div>
|
|
||||||
Terms of service
|
|
||||||
</div>
|
|
||||||
<div>
|
|
||||||
A complete separated html with it's own design
|
|
||||||
</div>
|
|
||||||
</body>
|
|
||||||
</html>
|
|
||||||
`;
|
|
||||||
const termsPlain = `
|
|
||||||
Terms Of Service
|
|
||||||
****************
|
|
||||||
|
|
||||||
Last Updated: 12.4.2019
|
|
||||||
|
|
||||||
Welcome! Taler Systems SA (“we,” “our,” or “us”) provides a payment
|
|
||||||
service through our Internet presence (collectively the “Services”).
|
|
||||||
Before using our Services, please read the Terms of Service (the
|
|
||||||
“Terms” or the “Agreement”) carefully.
|
|
||||||
|
|
||||||
|
|
||||||
Overview
|
|
||||||
========
|
|
||||||
|
|
||||||
This section provides a brief summary of the highlights of this
|
|
||||||
Agreement. Please note that when you accept this Agreement, you are
|
|
||||||
accepting all of the terms and conditions and not just this section.
|
|
||||||
We and possibly other third parties provide Internet services which
|
|
||||||
interact with the Taler Wallet’s self-hosted personal payment
|
|
||||||
application. When using the Taler Wallet to interact with our
|
|
||||||
Services, you are agreeing to our Terms, so please read carefully.
|
|
||||||
|
|
||||||
|
|
||||||
Highlights:
|
|
||||||
-----------
|
|
||||||
|
|
||||||
* You are responsible for keeping the data in your Taler Wallet at
|
|
||||||
all times under your control. Any losses arising from you not
|
|
||||||
being in control of your private information are your problem.
|
|
||||||
|
|
||||||
* We will try to transfer funds we hold in escrow for our users to
|
|
||||||
any legal recipient to the best of our ability within the
|
|
||||||
limitations of the law and our implementation. However, the
|
|
||||||
Services offered today are highly experimental and the set of
|
|
||||||
recipients of funds is severely restricted.
|
|
||||||
|
|
||||||
* For our Services, we may charge transaction fees. The specific
|
|
||||||
fee structure is provided based on the Taler protocol and should
|
|
||||||
be shown to you when you withdraw electronic coins using a Taler
|
|
||||||
Wallet. You agree and understand that the Taler protocol allows
|
|
||||||
for the fee structure to change.
|
|
||||||
|
|
||||||
* You agree to not intentionally overwhelm our systems with
|
|
||||||
requests and follow responsible disclosure if you find security
|
|
||||||
issues in our services.
|
|
||||||
|
|
||||||
* We cannot be held accountable for our Services not being
|
|
||||||
available due to circumstances beyond our control. If we modify
|
|
||||||
or terminate our services, we will try to give you the
|
|
||||||
opportunity to recover your funds. However, given the
|
|
||||||
experimental state of the Services today, this may not be
|
|
||||||
possible. You are strongly advised to limit your use of the
|
|
||||||
Service to small-scale experiments expecting total loss of all
|
|
||||||
funds.
|
|
||||||
|
|
||||||
These terms outline approved uses of our Services. The Services and
|
|
||||||
these Terms are still at an experimental stage. If you have any
|
|
||||||
questions or comments related to this Agreement, please send us a
|
|
||||||
message to legal@taler-systems.com. If you do not agree to this
|
|
||||||
Agreement, you must not use our Services.
|
|
||||||
|
|
||||||
|
|
||||||
How you accept this policy
|
|
||||||
==========================
|
|
||||||
|
|
||||||
By sending funds to us (to top-up your Taler Wallet), you acknowledge
|
|
||||||
that you have read, understood, and agreed to these Terms. We reserve
|
|
||||||
the right to change these Terms at any time. If you disagree with the
|
|
||||||
change, we may in the future offer you with an easy option to recover
|
|
||||||
your unspent funds. However, in the current experimental period you
|
|
||||||
acknowledge that this feature is not yet available, resulting in your
|
|
||||||
funds being lost unless you accept the new Terms. If you continue to
|
|
||||||
use our Services other than to recover your unspent funds, your
|
|
||||||
continued use of our Services following any such change will signify
|
|
||||||
your acceptance to be bound by the then current Terms. Please check
|
|
||||||
the effective date above to determine if there have been any changes
|
|
||||||
since you have last reviewed these Terms.
|
|
||||||
|
|
||||||
|
|
||||||
Services
|
|
||||||
========
|
|
||||||
|
|
||||||
We will try to transfer funds that we hold in escrow for our users to
|
|
||||||
any legal recipient to the best of our ability and within the
|
|
||||||
limitations of the law and our implementation. However, the Services
|
|
||||||
offered today are highly experimental and the set of recipients of
|
|
||||||
funds is severely restricted. The Taler Wallet can be loaded by
|
|
||||||
exchanging fiat currencies against electronic coins. We are providing
|
|
||||||
this exchange service. Once your Taler Wallet is loaded with
|
|
||||||
electronic coins they can be spent for purchases if the seller is
|
|
||||||
accepting Taler as a means of payment. We are not guaranteeing that
|
|
||||||
any seller is accepting Taler at all or a particular seller. The
|
|
||||||
seller or recipient of deposits of electronic coins must specify the
|
|
||||||
target account, as per the design of the Taler protocol. They are
|
|
||||||
responsible for following the protocol and specifying the correct bank
|
|
||||||
account, and are solely liable for any losses that may arise from
|
|
||||||
specifying the wrong account. We will allow the government to link
|
|
||||||
wire transfers to the underlying contract hash. It is the
|
|
||||||
responsibility of recipients to preserve the full contracts and to pay
|
|
||||||
whatever taxes and charges may be applicable. Technical issues may
|
|
||||||
lead to situations where we are unable to make transfers at all or
|
|
||||||
lead to incorrect transfers that cannot be reversed. We will only
|
|
||||||
refuse to execute transfers if the transfers are prohibited by a
|
|
||||||
competent legal authority and we are ordered to do so.
|
|
||||||
|
|
||||||
|
|
||||||
Fees
|
|
||||||
====
|
|
||||||
|
|
||||||
You agree to pay the fees for exchanges and withdrawals completed via
|
|
||||||
the Taler Wallet ("Fees") as defined by us, which we may change from
|
|
||||||
time to time. With the exception of wire transfer fees, Taler
|
|
||||||
transaction fees are set for any electronic coin at the time of
|
|
||||||
withdrawal and fixed throughout the validity period of the respective
|
|
||||||
electronic coin. Your wallet should obtain and display applicable fees
|
|
||||||
when withdrawing funds. Fees for coins obtained as change may differ
|
|
||||||
from the fees applicable to the original coin. Wire transfer fees that
|
|
||||||
are independent from electronic coins may change annually. You
|
|
||||||
authorize us to charge or deduct applicable fees owed in connection
|
|
||||||
with deposits, exchanges and withdrawals following the rules of the
|
|
||||||
Taler protocol. We reserve the right to provide different types of
|
|
||||||
rewards to users either in the form of discount for our Services or in
|
|
||||||
any other form at our discretion and without prior notice to you.
|
|
||||||
|
|
||||||
|
|
||||||
Eligibility
|
|
||||||
===========
|
|
||||||
|
|
||||||
To be eligible to use our Services, you must be able to form legally
|
|
||||||
binding contracts or have the permission of your legal guardian. By
|
|
||||||
using our Services, you represent and warrant that you meet all
|
|
||||||
eligibility requirements that we outline in these Terms.
|
|
||||||
|
|
||||||
|
|
||||||
Financial self-responsibility
|
|
||||||
=============================
|
|
||||||
|
|
||||||
You will be responsible for maintaining the availability, integrity
|
|
||||||
and confidentiality of the data stored in your wallet. When you setup
|
|
||||||
a Taler Wallet, you are strongly advised to follow the precautionary
|
|
||||||
measures offered by the software to minimize the chances to losse
|
|
||||||
access to or control over your Wallet data. We will not be liable for
|
|
||||||
any loss or damage arising from your failure to comply with this
|
|
||||||
paragraph.
|
|
||||||
|
|
||||||
|
|
||||||
Copyrights and trademarks
|
|
||||||
=========================
|
|
||||||
|
|
||||||
The Taler Wallet is released under the terms of the GNU General Public
|
|
||||||
License (GNU GPL). You have the right to access, use, and share the
|
|
||||||
Taler Wallet, in modified or unmodified form. However, the GPL is a
|
|
||||||
strong copyleft license, which means that any derivative works must be
|
|
||||||
distributed under the same license terms as the original software. If
|
|
||||||
you have any questions, you should review the GNU GPL’s full terms and
|
|
||||||
conditions at https://www.gnu.org/licenses/gpl-3.0.en.html. “Taler”
|
|
||||||
itself is a trademark of Taler Systems SA. You are welcome to use the
|
|
||||||
name in relation to processing payments using the Taler protocol,
|
|
||||||
assuming your use is compatible with an official release from the GNU
|
|
||||||
Project that is not older than two years.
|
|
||||||
|
|
||||||
|
|
||||||
Your use of our services
|
|
||||||
========================
|
|
||||||
|
|
||||||
When using our Services, you agree to not take any action that
|
|
||||||
intentionally imposes an unreasonable load on our infrastructure. If
|
|
||||||
you find security problems in our Services, you agree to first report
|
|
||||||
them to security@taler-systems.com and grant us the right to publish
|
|
||||||
your report. We warrant that we will ourselves publicly disclose any
|
|
||||||
issues reported within 3 months, and that we will not prosecute anyone
|
|
||||||
reporting security issues if they did not exploit the issue beyond a
|
|
||||||
proof-of-concept, and followed the above responsible disclosure
|
|
||||||
practice.
|
|
||||||
|
|
||||||
|
|
||||||
Limitation of liability & disclaimer of warranties
|
|
||||||
==================================================
|
|
||||||
|
|
||||||
You understand and agree that we have no control over, and no duty to
|
|
||||||
take any action regarding: Failures, disruptions, errors, or delays in
|
|
||||||
processing that you may experience while using our Services; The risk
|
|
||||||
of failure of hardware, software, and Internet connections; The risk
|
|
||||||
of malicious software being introduced or found in the software
|
|
||||||
underlying the Taler Wallet; The risk that third parties may obtain
|
|
||||||
unauthorized access to information stored within your Taler Wallet,
|
|
||||||
including, but not limited to your Taler Wallet coins or backup
|
|
||||||
encryption keys. You release us from all liability related to any
|
|
||||||
losses, damages, or claims arising from:
|
|
||||||
|
|
||||||
1. user error such as forgotten passwords, incorrectly constructed
|
|
||||||
transactions;
|
|
||||||
|
|
||||||
2. server failure or data loss;
|
|
||||||
|
|
||||||
3. unauthorized access to the Taler Wallet application;
|
|
||||||
|
|
||||||
4. bugs or other errors in the Taler Wallet software; and
|
|
||||||
|
|
||||||
5. any unauthorized third party activities, including, but not limited
|
|
||||||
to, the use of viruses, phishing, brute forcing, or other means of
|
|
||||||
attack against the Taler Wallet. We make no representations
|
|
||||||
concerning any Third Party Content contained in or accessed through
|
|
||||||
our Services.
|
|
||||||
|
|
||||||
Any other terms, conditions, warranties, or representations associated
|
|
||||||
with such content, are solely between you and such organizations
|
|
||||||
and/or individuals.
|
|
||||||
|
|
||||||
|
|
||||||
Limitation of liability
|
|
||||||
=======================
|
|
||||||
|
|
||||||
To the fullest extent permitted by applicable law, in no event will we
|
|
||||||
or any of our officers, directors, representatives, agents, servants,
|
|
||||||
counsel, employees, consultants, lawyers, and other personnel
|
|
||||||
authorized to act, acting, or purporting to act on our behalf
|
|
||||||
(collectively the “Taler Parties”) be liable to you under contract,
|
|
||||||
tort, strict liability, negligence, or any other legal or equitable
|
|
||||||
theory, for:
|
|
||||||
|
|
||||||
1. any lost profits, data loss, cost of procurement of substitute
|
|
||||||
goods or services, or direct, indirect, incidental, special,
|
|
||||||
punitive, compensatory, or consequential damages of any kind
|
|
||||||
whatsoever resulting from:
|
|
||||||
|
|
||||||
1. your use of, or conduct in connection with, our services;
|
|
||||||
|
|
||||||
2. any unauthorized use of your wallet and/or private key due to
|
|
||||||
your failure to maintain the confidentiality of your wallet;
|
|
||||||
|
|
||||||
3. any interruption or cessation of transmission to or from the
|
|
||||||
services; or
|
|
||||||
|
|
||||||
4. any bugs, viruses, trojan horses, or the like that are found in
|
|
||||||
the Taler Wallet software or that may be transmitted to or
|
|
||||||
through our services by any third party (regardless of the
|
|
||||||
source of origination), or
|
|
||||||
|
|
||||||
2. any direct damages.
|
|
||||||
|
|
||||||
These limitations apply regardless of legal theory, whether based on
|
|
||||||
tort, strict liability, breach of contract, breach of warranty, or any
|
|
||||||
other legal theory, and whether or not we were advised of the
|
|
||||||
possibility of such damages. Some jurisdictions do not allow the
|
|
||||||
exclusion or limitation of liability for consequential or incidental
|
|
||||||
damages, so the above limitation may not apply to you.
|
|
||||||
|
|
||||||
|
|
||||||
Warranty disclaimer
|
|
||||||
===================
|
|
||||||
|
|
||||||
Our services are provided "as is" and without warranty of any kind. To
|
|
||||||
the maximum extent permitted by law, we disclaim all representations
|
|
||||||
and warranties, express or implied, relating to the services and
|
|
||||||
underlying software or any content on the services, whether provided
|
|
||||||
or owned by us or by any third party, including without limitation,
|
|
||||||
warranties of merchantability, fitness for a particular purpose,
|
|
||||||
title, non-infringement, freedom from computer virus, and any implied
|
|
||||||
warranties arising from course of dealing, course of performance, or
|
|
||||||
usage in trade, all of which are expressly disclaimed. In addition, we
|
|
||||||
do not represent or warrant that the content accessible via the
|
|
||||||
services is accurate, complete, available, current, free of viruses or
|
|
||||||
other harmful components, or that the results of using the services
|
|
||||||
will meet your requirements. Some states do not allow the disclaimer
|
|
||||||
of implied warranties, so the foregoing disclaimers may not apply to
|
|
||||||
you. This paragraph gives you specific legal rights and you may also
|
|
||||||
have other legal rights that vary from state to state.
|
|
||||||
|
|
||||||
|
|
||||||
Indemnity
|
|
||||||
=========
|
|
||||||
|
|
||||||
To the extent permitted by applicable law, you agree to defend,
|
|
||||||
indemnify, and hold harmless the Taler Parties from and against any
|
|
||||||
and all claims, damages, obligations, losses, liabilities, costs or
|
|
||||||
debt, and expenses (including, but not limited to, attorney’s fees)
|
|
||||||
arising from: (a) your use of and access to the Services; (b) any
|
|
||||||
feedback or submissions you provide to us concerning the Taler Wallet;
|
|
||||||
(c) your violation of any term of this Agreement; or (d) your
|
|
||||||
violation of any law, rule, or regulation, or the rights of any third
|
|
||||||
party.
|
|
||||||
|
|
||||||
|
|
||||||
Time limitation on claims
|
|
||||||
=========================
|
|
||||||
|
|
||||||
You agree that any claim you may have arising out of or related to
|
|
||||||
your relationship with us must be filed within one year after such
|
|
||||||
claim arises, otherwise, your claim in permanently barred.
|
|
||||||
|
|
||||||
|
|
||||||
Governing law
|
|
||||||
=============
|
|
||||||
|
|
||||||
No matter where you’re located, the laws of Switzerland will govern
|
|
||||||
these Terms. If any provisions of these Terms are inconsistent with
|
|
||||||
any applicable law, those provisions will be superseded or modified
|
|
||||||
only to the extent such provisions are inconsistent. The parties agree
|
|
||||||
to submit to the ordinary courts in Zurich, Switzerland for exclusive
|
|
||||||
jurisdiction of any dispute arising out of or related to your use of
|
|
||||||
the Services or your breach of these Terms.
|
|
||||||
|
|
||||||
|
|
||||||
Termination
|
|
||||||
===========
|
|
||||||
|
|
||||||
In the event of termination concerning your use of our Services, your
|
|
||||||
obligations under this Agreement will still continue.
|
|
||||||
|
|
||||||
|
|
||||||
Discontinuance of services
|
|
||||||
==========================
|
|
||||||
|
|
||||||
We may, in our sole discretion and without cost to you, with or
|
|
||||||
without prior notice, and at any time, modify or discontinue,
|
|
||||||
temporarily or permanently, any portion of our Services. We will use
|
|
||||||
the Taler protocol’s provisions to notify Wallets if our Services are
|
|
||||||
to be discontinued. It is your responsibility to ensure that the Taler
|
|
||||||
Wallet is online at least once every three months to observe these
|
|
||||||
notifications. We shall not be held responsible or liable for any loss
|
|
||||||
of funds in the event that we discontinue or depreciate the Services
|
|
||||||
and your Taler Wallet fails to transfer out the coins within a three
|
|
||||||
months notification period.
|
|
||||||
|
|
||||||
|
|
||||||
No waiver
|
|
||||||
=========
|
|
||||||
|
|
||||||
Our failure to exercise or delay in exercising any right, power, or
|
|
||||||
privilege under this Agreement shall not operate as a waiver; nor
|
|
||||||
shall any single or partial exercise of any right, power, or privilege
|
|
||||||
preclude any other or further exercise thereof.
|
|
||||||
|
|
||||||
|
|
||||||
Severability
|
|
||||||
============
|
|
||||||
|
|
||||||
If it turns out that any part of this Agreement is invalid, void, or
|
|
||||||
for any reason unenforceable, that term will be deemed severable and
|
|
||||||
limited or eliminated to the minimum extent necessary.
|
|
||||||
|
|
||||||
|
|
||||||
Force majeure
|
|
||||||
=============
|
|
||||||
|
|
||||||
We shall not be held liable for any delays, failure in performance, or
|
|
||||||
interruptions of service which result directly or indirectly from any
|
|
||||||
cause or condition beyond our reasonable control, including but not
|
|
||||||
limited to: any delay or failure due to any act of God, act of civil
|
|
||||||
or military authorities, act of terrorism, civil disturbance, war,
|
|
||||||
strike or other labor dispute, fire, interruption in
|
|
||||||
telecommunications or Internet services or network provider services,
|
|
||||||
failure of equipment and/or software, other catastrophe, or any other
|
|
||||||
occurrence which is beyond our reasonable control and shall not affect
|
|
||||||
the validity and enforceability of any remaining provisions.
|
|
||||||
|
|
||||||
|
|
||||||
Assignment
|
|
||||||
==========
|
|
||||||
|
|
||||||
You agree that we may assign any of our rights and/or transfer, sub-
|
|
||||||
contract, or delegate any of our obligations under these Terms.
|
|
||||||
|
|
||||||
|
|
||||||
Entire agreement
|
|
||||||
================
|
|
||||||
|
|
||||||
This Agreement sets forth the entire understanding and agreement as to
|
|
||||||
the subject matter hereof and supersedes any and all prior
|
|
||||||
discussions, agreements, and understandings of any kind (including,
|
|
||||||
without limitation, any prior versions of this Agreement) and every
|
|
||||||
nature between us. Except as provided for above, any modification to
|
|
||||||
this Agreement must be in writing and must be signed by both parties.
|
|
||||||
|
|
||||||
|
|
||||||
Questions or comments
|
|
||||||
=====================
|
|
||||||
|
|
||||||
We welcome comments, questions, concerns, or suggestions. Please send
|
|
||||||
us a message on our contact page at legal@taler-systems.com.
|
|
||||||
|
|
||||||
`;
|
|
||||||
|
|
||||||
const termsXml = `<?xml version="1.0" encoding="utf-8"?>
|
|
||||||
<!DOCTYPE document PUBLIC "+//IDN docutils.sourceforge.net//DTD Docutils Generic//EN//XML" "http://docutils.sourceforge.net/docs/ref/docutils.dtd">
|
|
||||||
<!-- Generated by Docutils 0.14 -->
|
|
||||||
<document source="/home/grothoff/research/taler/exchange/contrib/tos/tos.rst">
|
|
||||||
<section ids="terms-of-service" names="terms\ of\ service">
|
|
||||||
<title>Terms Of Service</title>
|
|
||||||
<paragraph>Last Updated: 12.4.2019</paragraph>
|
|
||||||
<paragraph>Welcome! Taler Systems SA (“we,” “our,” or “us”) provides a payment service
|
|
||||||
through our Internet presence (collectively the “Services”). Before using our
|
|
||||||
Services, please read the Terms of Service (the “Terms” or the “Agreement”)
|
|
||||||
carefully.</paragraph>
|
|
||||||
<section ids="overview" names="overview">
|
|
||||||
<title>Overview</title>
|
|
||||||
<paragraph>This section provides a brief summary of the highlights of this
|
|
||||||
Agreement. Please note that when you accept this Agreement, you are accepting
|
|
||||||
all of the terms and conditions and not just this section. We and possibly
|
|
||||||
other third parties provide Internet services which interact with the Taler
|
|
||||||
Wallet’s self-hosted personal payment application. When using the Taler Wallet
|
|
||||||
to interact with our Services, you are agreeing to our Terms, so please read
|
|
||||||
carefully.</paragraph>
|
|
||||||
<section ids="highlights" names="highlights:">
|
|
||||||
<title>Highlights:</title>
|
|
||||||
<block_quote>
|
|
||||||
<bullet_list bullet="•">
|
|
||||||
<list_item>
|
|
||||||
<paragraph>You are responsible for keeping the data in your Taler Wallet at all times
|
|
||||||
under your control. Any losses arising from you not being in control of
|
|
||||||
your private information are your problem.</paragraph>
|
|
||||||
</list_item>
|
|
||||||
<list_item>
|
|
||||||
<paragraph>We will try to transfer funds we hold in escrow for our users to any legal
|
|
||||||
recipient to the best of our ability within the limitations of the law and
|
|
||||||
our implementation. However, the Services offered today are highly
|
|
||||||
experimental and the set of recipients of funds is severely restricted.</paragraph>
|
|
||||||
</list_item>
|
|
||||||
<list_item>
|
|
||||||
<paragraph>For our Services, we may charge transaction fees. The specific fee structure
|
|
||||||
is provided based on the Taler protocol and should be shown to you when you
|
|
||||||
withdraw electronic coins using a Taler Wallet. You agree and understand
|
|
||||||
that the Taler protocol allows for the fee structure to change.</paragraph>
|
|
||||||
</list_item>
|
|
||||||
<list_item>
|
|
||||||
<paragraph>You agree to not intentionally overwhelm our systems with requests and
|
|
||||||
follow responsible disclosure if you find security issues in our services.</paragraph>
|
|
||||||
</list_item>
|
|
||||||
<list_item>
|
|
||||||
<paragraph>We cannot be held accountable for our Services not being available due to
|
|
||||||
circumstances beyond our control. If we modify or terminate our services,
|
|
||||||
we will try to give you the opportunity to recover your funds. However,
|
|
||||||
given the experimental state of the Services today, this may not be
|
|
||||||
possible. You are strongly advised to limit your use of the Service
|
|
||||||
to small-scale experiments expecting total loss of all funds.</paragraph>
|
|
||||||
</list_item>
|
|
||||||
</bullet_list>
|
|
||||||
</block_quote>
|
|
||||||
<paragraph>These terms outline approved uses of our Services. The Services and these
|
|
||||||
Terms are still at an experimental stage. If you have any questions or
|
|
||||||
comments related to this Agreement, please send us a message to
|
|
||||||
<reference refuri="mailto:legal@taler-systems.com">legal@taler-systems.com</reference>. If you do not agree to this Agreement, you must not
|
|
||||||
use our Services.</paragraph>
|
|
||||||
</section>
|
|
||||||
</section>
|
|
||||||
<section ids="how-you-accept-this-policy" names="how\ you\ accept\ this\ policy">
|
|
||||||
<title>How you accept this policy</title>
|
|
||||||
<paragraph>By sending funds to us (to top-up your Taler Wallet), you acknowledge that you
|
|
||||||
have read, understood, and agreed to these Terms. We reserve the right to
|
|
||||||
change these Terms at any time. If you disagree with the change, we may in the
|
|
||||||
future offer you with an easy option to recover your unspent funds. However,
|
|
||||||
in the current experimental period you acknowledge that this feature is not
|
|
||||||
yet available, resulting in your funds being lost unless you accept the new
|
|
||||||
Terms. If you continue to use our Services other than to recover your unspent
|
|
||||||
funds, your continued use of our Services following any such change will
|
|
||||||
signify your acceptance to be bound by the then current Terms. Please check
|
|
||||||
the effective date above to determine if there have been any changes since you
|
|
||||||
have last reviewed these Terms.</paragraph>
|
|
||||||
</section>
|
|
||||||
<section ids="services" names="services">
|
|
||||||
<title>Services</title>
|
|
||||||
<paragraph>We will try to transfer funds that we hold in escrow for our users to any
|
|
||||||
legal recipient to the best of our ability and within the limitations of the
|
|
||||||
law and our implementation. However, the Services offered today are highly
|
|
||||||
experimental and the set of recipients of funds is severely restricted. The
|
|
||||||
Taler Wallet can be loaded by exchanging fiat currencies against electronic
|
|
||||||
coins. We are providing this exchange service. Once your Taler Wallet is
|
|
||||||
loaded with electronic coins they can be spent for purchases if the seller is
|
|
||||||
accepting Taler as a means of payment. We are not guaranteeing that any seller
|
|
||||||
is accepting Taler at all or a particular seller. The seller or recipient of
|
|
||||||
deposits of electronic coins must specify the target account, as per the
|
|
||||||
design of the Taler protocol. They are responsible for following the protocol
|
|
||||||
and specifying the correct bank account, and are solely liable for any losses
|
|
||||||
that may arise from specifying the wrong account. We will allow the government
|
|
||||||
to link wire transfers to the underlying contract hash. It is the
|
|
||||||
responsibility of recipients to preserve the full contracts and to pay
|
|
||||||
whatever taxes and charges may be applicable. Technical issues may lead to
|
|
||||||
situations where we are unable to make transfers at all or lead to incorrect
|
|
||||||
transfers that cannot be reversed. We will only refuse to execute transfers if
|
|
||||||
the transfers are prohibited by a competent legal authority and we are ordered
|
|
||||||
to do so.</paragraph>
|
|
||||||
</section>
|
|
||||||
<section ids="fees" names="fees">
|
|
||||||
<title>Fees</title>
|
|
||||||
<paragraph>You agree to pay the fees for exchanges and withdrawals completed via the
|
|
||||||
Taler Wallet (“Fees”) as defined by us, which we may change from time to
|
|
||||||
time. With the exception of wire transfer fees, Taler transaction fees are set
|
|
||||||
for any electronic coin at the time of withdrawal and fixed throughout the
|
|
||||||
validity period of the respective electronic coin. Your wallet should obtain
|
|
||||||
and display applicable fees when withdrawing funds. Fees for coins obtained as
|
|
||||||
change may differ from the fees applicable to the original coin. Wire transfer
|
|
||||||
fees that are independent from electronic coins may change annually. You
|
|
||||||
authorize us to charge or deduct applicable fees owed in connection with
|
|
||||||
deposits, exchanges and withdrawals following the rules of the Taler protocol.
|
|
||||||
We reserve the right to provide different types of rewards to users either in
|
|
||||||
the form of discount for our Services or in any other form at our discretion
|
|
||||||
and without prior notice to you.</paragraph>
|
|
||||||
</section>
|
|
||||||
<section ids="eligibility" names="eligibility">
|
|
||||||
<title>Eligibility</title>
|
|
||||||
<paragraph>To be eligible to use our Services, you must be able to form legally binding
|
|
||||||
contracts or have the permission of your legal guardian. By using our
|
|
||||||
Services, you represent and warrant that you meet all eligibility requirements
|
|
||||||
that we outline in these Terms.</paragraph>
|
|
||||||
</section>
|
|
||||||
<section ids="financial-self-responsibility" names="financial\ self-responsibility">
|
|
||||||
<title>Financial self-responsibility</title>
|
|
||||||
<paragraph>You will be responsible for maintaining the availability, integrity and
|
|
||||||
confidentiality of the data stored in your wallet. When you setup a Taler
|
|
||||||
Wallet, you are strongly advised to follow the precautionary measures offered
|
|
||||||
by the software to minimize the chances to losse access to or control over
|
|
||||||
your Wallet data. We will not be liable for any loss or damage arising from
|
|
||||||
your failure to comply with this paragraph.</paragraph>
|
|
||||||
</section>
|
|
||||||
<section ids="copyrights-and-trademarks" names="copyrights\ and\ trademarks">
|
|
||||||
<title>Copyrights and trademarks</title>
|
|
||||||
<paragraph>The Taler Wallet is released under the terms of the GNU General Public License
|
|
||||||
(GNU GPL). You have the right to access, use, and share the Taler Wallet, in
|
|
||||||
modified or unmodified form. However, the GPL is a strong copyleft license,
|
|
||||||
which means that any derivative works must be distributed under the same
|
|
||||||
license terms as the original software. If you have any questions, you should
|
|
||||||
review the GNU GPL’s full terms and conditions at
|
|
||||||
<reference refuri="https://www.gnu.org/licenses/gpl-3.0.en.html">https://www.gnu.org/licenses/gpl-3.0.en.html</reference>. “Taler” itself is a trademark
|
|
||||||
of Taler Systems SA. You are welcome to use the name in relation to processing
|
|
||||||
payments using the Taler protocol, assuming your use is compatible with an
|
|
||||||
official release from the GNU Project that is not older than two years.</paragraph>
|
|
||||||
</section>
|
|
||||||
<section ids="your-use-of-our-services" names="your\ use\ of\ our\ services">
|
|
||||||
<title>Your use of our services</title>
|
|
||||||
<paragraph>When using our Services, you agree to not take any action that intentionally
|
|
||||||
imposes an unreasonable load on our infrastructure. If you find security
|
|
||||||
problems in our Services, you agree to first report them to
|
|
||||||
<reference refuri="mailto:security@taler-systems.com">security@taler-systems.com</reference> and grant us the right to publish your report. We
|
|
||||||
warrant that we will ourselves publicly disclose any issues reported within 3
|
|
||||||
months, and that we will not prosecute anyone reporting security issues if
|
|
||||||
they did not exploit the issue beyond a proof-of-concept, and followed the
|
|
||||||
above responsible disclosure practice.</paragraph>
|
|
||||||
</section>
|
|
||||||
<section ids="limitation-of-liability-disclaimer-of-warranties" names="limitation\ of\ liability\ &\ disclaimer\ of\ warranties">
|
|
||||||
<title>Limitation of liability & disclaimer of warranties</title>
|
|
||||||
<paragraph>You understand and agree that we have no control over, and no duty to take any
|
|
||||||
action regarding: Failures, disruptions, errors, or delays in processing that
|
|
||||||
you may experience while using our Services; The risk of failure of hardware,
|
|
||||||
software, and Internet connections; The risk of malicious software being
|
|
||||||
introduced or found in the software underlying the Taler Wallet; The risk that
|
|
||||||
third parties may obtain unauthorized access to information stored within your
|
|
||||||
Taler Wallet, including, but not limited to your Taler Wallet coins or backup
|
|
||||||
encryption keys. You release us from all liability related to any losses,
|
|
||||||
damages, or claims arising from:</paragraph>
|
|
||||||
<enumerated_list enumtype="loweralpha" prefix="(" suffix=")">
|
|
||||||
<list_item>
|
|
||||||
<paragraph>user error such as forgotten passwords, incorrectly constructed
|
|
||||||
transactions;</paragraph>
|
|
||||||
</list_item>
|
|
||||||
<list_item>
|
|
||||||
<paragraph>server failure or data loss;</paragraph>
|
|
||||||
</list_item>
|
|
||||||
<list_item>
|
|
||||||
<paragraph>unauthorized access to the Taler Wallet application;</paragraph>
|
|
||||||
</list_item>
|
|
||||||
<list_item>
|
|
||||||
<paragraph>bugs or other errors in the Taler Wallet software; and</paragraph>
|
|
||||||
</list_item>
|
|
||||||
<list_item>
|
|
||||||
<paragraph>any unauthorized third party activities, including, but not limited to,
|
|
||||||
the use of viruses, phishing, brute forcing, or other means of attack
|
|
||||||
against the Taler Wallet. We make no representations concerning any
|
|
||||||
Third Party Content contained in or accessed through our Services.</paragraph>
|
|
||||||
</list_item>
|
|
||||||
</enumerated_list>
|
|
||||||
<paragraph>Any other terms, conditions, warranties, or representations associated with
|
|
||||||
such content, are solely between you and such organizations and/or
|
|
||||||
individuals.</paragraph>
|
|
||||||
</section>
|
|
||||||
<section ids="limitation-of-liability" names="limitation\ of\ liability">
|
|
||||||
<title>Limitation of liability</title>
|
|
||||||
<paragraph>To the fullest extent permitted by applicable law, in no event will we or any
|
|
||||||
of our officers, directors, representatives, agents, servants, counsel,
|
|
||||||
employees, consultants, lawyers, and other personnel authorized to act,
|
|
||||||
acting, or purporting to act on our behalf (collectively the “Taler Parties”)
|
|
||||||
be liable to you under contract, tort, strict liability, negligence, or any
|
|
||||||
other legal or equitable theory, for:</paragraph>
|
|
||||||
<enumerated_list enumtype="loweralpha" prefix="(" suffix=")">
|
|
||||||
<list_item>
|
|
||||||
<paragraph>any lost profits, data loss, cost of procurement of substitute goods or
|
|
||||||
services, or direct, indirect, incidental, special, punitive, compensatory,
|
|
||||||
or consequential damages of any kind whatsoever resulting from:</paragraph>
|
|
||||||
</list_item>
|
|
||||||
</enumerated_list>
|
|
||||||
<block_quote>
|
|
||||||
<enumerated_list enumtype="lowerroman" prefix="(" suffix=")">
|
|
||||||
<list_item>
|
|
||||||
<paragraph>your use of, or conduct in connection with, our services;</paragraph>
|
|
||||||
</list_item>
|
|
||||||
<list_item>
|
|
||||||
<paragraph>any unauthorized use of your wallet and/or private key due to your
|
|
||||||
failure to maintain the confidentiality of your wallet;</paragraph>
|
|
||||||
</list_item>
|
|
||||||
<list_item>
|
|
||||||
<paragraph>any interruption or cessation of transmission to or from the services; or</paragraph>
|
|
||||||
</list_item>
|
|
||||||
<list_item>
|
|
||||||
<paragraph>any bugs, viruses, trojan horses, or the like that are found in the Taler
|
|
||||||
Wallet software or that may be transmitted to or through our services by
|
|
||||||
any third party (regardless of the source of origination), or</paragraph>
|
|
||||||
</list_item>
|
|
||||||
</enumerated_list>
|
|
||||||
</block_quote>
|
|
||||||
<enumerated_list enumtype="loweralpha" prefix="(" start="2" suffix=")">
|
|
||||||
<list_item>
|
|
||||||
<paragraph>any direct damages.</paragraph>
|
|
||||||
</list_item>
|
|
||||||
</enumerated_list>
|
|
||||||
<paragraph>These limitations apply regardless of legal theory, whether based on tort,
|
|
||||||
strict liability, breach of contract, breach of warranty, or any other legal
|
|
||||||
theory, and whether or not we were advised of the possibility of such
|
|
||||||
damages. Some jurisdictions do not allow the exclusion or limitation of
|
|
||||||
liability for consequential or incidental damages, so the above limitation may
|
|
||||||
not apply to you.</paragraph>
|
|
||||||
</section>
|
|
||||||
<section ids="warranty-disclaimer" names="warranty\ disclaimer">
|
|
||||||
<title>Warranty disclaimer</title>
|
|
||||||
<paragraph>Our services are provided “as is” and without warranty of any kind. To the
|
|
||||||
maximum extent permitted by law, we disclaim all representations and
|
|
||||||
warranties, express or implied, relating to the services and underlying
|
|
||||||
software or any content on the services, whether provided or owned by us or by
|
|
||||||
any third party, including without limitation, warranties of merchantability,
|
|
||||||
fitness for a particular purpose, title, non-infringement, freedom from
|
|
||||||
computer virus, and any implied warranties arising from course of dealing,
|
|
||||||
course of performance, or usage in trade, all of which are expressly
|
|
||||||
disclaimed. In addition, we do not represent or warrant that the content
|
|
||||||
accessible via the services is accurate, complete, available, current, free of
|
|
||||||
viruses or other harmful components, or that the results of using the services
|
|
||||||
will meet your requirements. Some states do not allow the disclaimer of
|
|
||||||
implied warranties, so the foregoing disclaimers may not apply to you. This
|
|
||||||
paragraph gives you specific legal rights and you may also have other legal
|
|
||||||
rights that vary from state to state.</paragraph>
|
|
||||||
</section>
|
|
||||||
<section ids="indemnity" names="indemnity">
|
|
||||||
<title>Indemnity</title>
|
|
||||||
<paragraph>To the extent permitted by applicable law, you agree to defend, indemnify, and
|
|
||||||
hold harmless the Taler Parties from and against any and all claims, damages,
|
|
||||||
obligations, losses, liabilities, costs or debt, and expenses (including, but
|
|
||||||
not limited to, attorney’s fees) arising from: (a) your use of and access to
|
|
||||||
the Services; (b) any feedback or submissions you provide to us concerning the
|
|
||||||
Taler Wallet; (c) your violation of any term of this Agreement; or (d) your
|
|
||||||
violation of any law, rule, or regulation, or the rights of any third party.</paragraph>
|
|
||||||
</section>
|
|
||||||
<section ids="time-limitation-on-claims" names="time\ limitation\ on\ claims">
|
|
||||||
<title>Time limitation on claims</title>
|
|
||||||
<paragraph>You agree that any claim you may have arising out of or related to your
|
|
||||||
relationship with us must be filed within one year after such claim arises,
|
|
||||||
otherwise, your claim in permanently barred.</paragraph>
|
|
||||||
</section>
|
|
||||||
<section ids="governing-law" names="governing\ law">
|
|
||||||
<title>Governing law</title>
|
|
||||||
<paragraph>No matter where you’re located, the laws of Switzerland will govern these
|
|
||||||
Terms. If any provisions of these Terms are inconsistent with any applicable
|
|
||||||
law, those provisions will be superseded or modified only to the extent such
|
|
||||||
provisions are inconsistent. The parties agree to submit to the ordinary
|
|
||||||
courts in Zurich, Switzerland for exclusive jurisdiction of any dispute
|
|
||||||
arising out of or related to your use of the Services or your breach of these
|
|
||||||
Terms.</paragraph>
|
|
||||||
</section>
|
|
||||||
<section ids="termination" names="termination">
|
|
||||||
<title>Termination</title>
|
|
||||||
<paragraph>In the event of termination concerning your use of our Services, your
|
|
||||||
obligations under this Agreement will still continue.</paragraph>
|
|
||||||
</section>
|
|
||||||
<section ids="discontinuance-of-services" names="discontinuance\ of\ services">
|
|
||||||
<title>Discontinuance of services</title>
|
|
||||||
<paragraph>We may, in our sole discretion and without cost to you, with or without prior
|
|
||||||
notice, and at any time, modify or discontinue, temporarily or permanently,
|
|
||||||
any portion of our Services. We will use the Taler protocol’s provisions to
|
|
||||||
notify Wallets if our Services are to be discontinued. It is your
|
|
||||||
responsibility to ensure that the Taler Wallet is online at least once every
|
|
||||||
three months to observe these notifications. We shall not be held responsible
|
|
||||||
or liable for any loss of funds in the event that we discontinue or depreciate
|
|
||||||
the Services and your Taler Wallet fails to transfer out the coins within a
|
|
||||||
three months notification period.</paragraph>
|
|
||||||
</section>
|
|
||||||
<section ids="no-waiver" names="no\ waiver">
|
|
||||||
<title>No waiver</title>
|
|
||||||
<paragraph>Our failure to exercise or delay in exercising any right, power, or privilege
|
|
||||||
under this Agreement shall not operate as a waiver; nor shall any single or
|
|
||||||
partial exercise of any right, power, or privilege preclude any other or
|
|
||||||
further exercise thereof.</paragraph>
|
|
||||||
</section>
|
|
||||||
<section ids="severability" names="severability">
|
|
||||||
<title>Severability</title>
|
|
||||||
<paragraph>If it turns out that any part of this Agreement is invalid, void, or for any
|
|
||||||
reason unenforceable, that term will be deemed severable and limited or
|
|
||||||
eliminated to the minimum extent necessary.</paragraph>
|
|
||||||
</section>
|
|
||||||
<section ids="force-majeure" names="force\ majeure">
|
|
||||||
<title>Force majeure</title>
|
|
||||||
<paragraph>We shall not be held liable for any delays, failure in performance, or
|
|
||||||
interruptions of service which result directly or indirectly from any cause or
|
|
||||||
condition beyond our reasonable control, including but not limited to: any
|
|
||||||
delay or failure due to any act of God, act of civil or military authorities,
|
|
||||||
act of terrorism, civil disturbance, war, strike or other labor dispute, fire,
|
|
||||||
interruption in telecommunications or Internet services or network provider
|
|
||||||
services, failure of equipment and/or software, other catastrophe, or any
|
|
||||||
other occurrence which is beyond our reasonable control and shall not affect
|
|
||||||
the validity and enforceability of any remaining provisions.</paragraph>
|
|
||||||
</section>
|
|
||||||
<section ids="assignment" names="assignment">
|
|
||||||
<title>Assignment</title>
|
|
||||||
<paragraph>You agree that we may assign any of our rights and/or transfer, sub-contract,
|
|
||||||
or delegate any of our obligations under these Terms.</paragraph>
|
|
||||||
</section>
|
|
||||||
<section ids="entire-agreement" names="entire\ agreement">
|
|
||||||
<title>Entire agreement</title>
|
|
||||||
<paragraph>This Agreement sets forth the entire understanding and agreement as to the
|
|
||||||
subject matter hereof and supersedes any and all prior discussions,
|
|
||||||
agreements, and understandings of any kind (including, without limitation, any
|
|
||||||
prior versions of this Agreement) and every nature between us. Except as
|
|
||||||
provided for above, any modification to this Agreement must be in writing and
|
|
||||||
must be signed by both parties.</paragraph>
|
|
||||||
</section>
|
|
||||||
<section ids="questions-or-comments" names="questions\ or\ comments">
|
|
||||||
<title>Questions or comments</title>
|
|
||||||
<paragraph>We welcome comments, questions, concerns, or suggestions. Please send us a
|
|
||||||
message on our contact page at <reference refuri="mailto:legal@taler-systems.com">legal@taler-systems.com</reference>.</paragraph>
|
|
||||||
</section>
|
|
||||||
</section>
|
|
||||||
</document>
|
|
||||||
`;
|
|
||||||
|
|
||||||
export const NewTerms = createExample(TestedComponent, {
|
export const NewTerms = createExample(TestedComponent, {
|
||||||
knownExchanges: [
|
knownExchanges: [
|
||||||
{
|
{
|
||||||
@ -805,11 +61,12 @@ export const NewTerms = createExample(TestedComponent, {
|
|||||||
null;
|
null;
|
||||||
},
|
},
|
||||||
terms: {
|
terms: {
|
||||||
value: {
|
content: {
|
||||||
type: "xml",
|
type: "xml",
|
||||||
document: new DOMParser().parseFromString(termsXml, "text/xml"),
|
document: new DOMParser().parseFromString(termsXml, "text/xml"),
|
||||||
},
|
},
|
||||||
status: "new",
|
status: "new",
|
||||||
|
version: "",
|
||||||
},
|
},
|
||||||
});
|
});
|
||||||
|
|
||||||
@ -842,11 +99,12 @@ export const TermsReviewingPLAIN = createExample(TestedComponent, {
|
|||||||
null;
|
null;
|
||||||
},
|
},
|
||||||
terms: {
|
terms: {
|
||||||
value: {
|
content: {
|
||||||
type: "plain",
|
type: "plain",
|
||||||
content: termsPlain,
|
content: termsPlain,
|
||||||
},
|
},
|
||||||
status: "new",
|
status: "new",
|
||||||
|
version: "",
|
||||||
},
|
},
|
||||||
reviewing: true,
|
reviewing: true,
|
||||||
});
|
});
|
||||||
@ -880,32 +138,18 @@ export const TermsReviewingHTML = createExample(TestedComponent, {
|
|||||||
null;
|
null;
|
||||||
},
|
},
|
||||||
terms: {
|
terms: {
|
||||||
value: {
|
content: {
|
||||||
type: "html",
|
type: "html",
|
||||||
href: new URL(
|
href: new URL(
|
||||||
`data:text/html;base64,${Buffer.from(termsHtml).toString("base64")}`,
|
`data:text/html;base64,${Buffer.from(termsHtml).toString("base64")}`,
|
||||||
),
|
),
|
||||||
},
|
},
|
||||||
|
version: "",
|
||||||
status: "new",
|
status: "new",
|
||||||
},
|
},
|
||||||
reviewing: true,
|
reviewing: true,
|
||||||
});
|
});
|
||||||
|
|
||||||
const termsPdf = `
|
|
||||||
%PDF-1.2
|
|
||||||
9 0 obj << >>
|
|
||||||
stream
|
|
||||||
BT/ 9 Tf(This is the Exchange TERMS OF SERVICE)' ET
|
|
||||||
endstream
|
|
||||||
endobj
|
|
||||||
4 0 obj << /Type /Page /Parent 5 0 R /Contents 9 0 R >> endobj
|
|
||||||
5 0 obj << /Kids [4 0 R ] /Count 1 /Type /Pages /MediaBox [ 0 0 180 20 ] >> endobj
|
|
||||||
3 0 obj << /Pages 5 0 R /Type /Catalog >> endobj
|
|
||||||
trailer
|
|
||||||
<< /Root 3 0 R >>
|
|
||||||
%%EOF
|
|
||||||
`;
|
|
||||||
|
|
||||||
export const TermsReviewingPDF = createExample(TestedComponent, {
|
export const TermsReviewingPDF = createExample(TestedComponent, {
|
||||||
knownExchanges: [
|
knownExchanges: [
|
||||||
{
|
{
|
||||||
@ -935,13 +179,14 @@ export const TermsReviewingPDF = createExample(TestedComponent, {
|
|||||||
null;
|
null;
|
||||||
},
|
},
|
||||||
terms: {
|
terms: {
|
||||||
value: {
|
content: {
|
||||||
type: "pdf",
|
type: "pdf",
|
||||||
location: new URL(
|
location: new URL(
|
||||||
`data:text/html;base64,${Buffer.from(termsPdf).toString("base64")}`,
|
`data:text/html;base64,${Buffer.from(termsPdf).toString("base64")}`,
|
||||||
),
|
),
|
||||||
},
|
},
|
||||||
status: "new",
|
status: "new",
|
||||||
|
version: "",
|
||||||
},
|
},
|
||||||
reviewing: true,
|
reviewing: true,
|
||||||
});
|
});
|
||||||
@ -975,11 +220,12 @@ export const TermsReviewingXML = createExample(TestedComponent, {
|
|||||||
null;
|
null;
|
||||||
},
|
},
|
||||||
terms: {
|
terms: {
|
||||||
value: {
|
content: {
|
||||||
type: "xml",
|
type: "xml",
|
||||||
document: new DOMParser().parseFromString(termsXml, "text/xml"),
|
document: new DOMParser().parseFromString(termsXml, "text/xml"),
|
||||||
},
|
},
|
||||||
status: "new",
|
status: "new",
|
||||||
|
version: "",
|
||||||
},
|
},
|
||||||
reviewing: true,
|
reviewing: true,
|
||||||
});
|
});
|
||||||
@ -1012,11 +258,12 @@ export const NewTermsAccepted = createExample(TestedComponent, {
|
|||||||
null;
|
null;
|
||||||
},
|
},
|
||||||
terms: {
|
terms: {
|
||||||
value: {
|
content: {
|
||||||
type: "xml",
|
type: "xml",
|
||||||
document: new DOMParser().parseFromString(termsXml, "text/xml"),
|
document: new DOMParser().parseFromString(termsXml, "text/xml"),
|
||||||
},
|
},
|
||||||
status: "new",
|
status: "new",
|
||||||
|
version: "",
|
||||||
},
|
},
|
||||||
reviewed: true,
|
reviewed: true,
|
||||||
});
|
});
|
||||||
@ -1050,10 +297,11 @@ export const TermsShowAgainXML = createExample(TestedComponent, {
|
|||||||
null;
|
null;
|
||||||
},
|
},
|
||||||
terms: {
|
terms: {
|
||||||
value: {
|
content: {
|
||||||
type: "xml",
|
type: "xml",
|
||||||
document: new DOMParser().parseFromString(termsXml, "text/xml"),
|
document: new DOMParser().parseFromString(termsXml, "text/xml"),
|
||||||
},
|
},
|
||||||
|
version: "",
|
||||||
status: "new",
|
status: "new",
|
||||||
},
|
},
|
||||||
reviewed: true,
|
reviewed: true,
|
||||||
@ -1089,10 +337,11 @@ export const TermsChanged = createExample(TestedComponent, {
|
|||||||
null;
|
null;
|
||||||
},
|
},
|
||||||
terms: {
|
terms: {
|
||||||
value: {
|
content: {
|
||||||
type: "xml",
|
type: "xml",
|
||||||
document: new DOMParser().parseFromString(termsXml, "text/xml"),
|
document: new DOMParser().parseFromString(termsXml, "text/xml"),
|
||||||
},
|
},
|
||||||
|
version: "",
|
||||||
status: "changed",
|
status: "changed",
|
||||||
},
|
},
|
||||||
});
|
});
|
||||||
@ -1126,7 +375,9 @@ export const TermsNotFound = createExample(TestedComponent, {
|
|||||||
null;
|
null;
|
||||||
},
|
},
|
||||||
terms: {
|
terms: {
|
||||||
|
content: undefined,
|
||||||
status: "notfound",
|
status: "notfound",
|
||||||
|
version: "",
|
||||||
},
|
},
|
||||||
});
|
});
|
||||||
|
|
||||||
@ -1160,6 +411,8 @@ export const TermsAlreadyAccepted = createExample(TestedComponent, {
|
|||||||
},
|
},
|
||||||
terms: {
|
terms: {
|
||||||
status: "accepted",
|
status: "accepted",
|
||||||
|
content: undefined,
|
||||||
|
version: "",
|
||||||
},
|
},
|
||||||
});
|
});
|
||||||
|
|
||||||
@ -1192,10 +445,11 @@ export const WithoutFee = createExample(TestedComponent, {
|
|||||||
null;
|
null;
|
||||||
},
|
},
|
||||||
terms: {
|
terms: {
|
||||||
value: {
|
content: {
|
||||||
type: "xml",
|
type: "xml",
|
||||||
document: new DOMParser().parseFromString(termsXml, "text/xml"),
|
document: new DOMParser().parseFromString(termsXml, "text/xml"),
|
||||||
},
|
},
|
||||||
status: "accepted",
|
status: "accepted",
|
||||||
|
version: "",
|
||||||
},
|
},
|
||||||
});
|
});
|
||||||
|
@ -25,14 +25,11 @@ import {
|
|||||||
AmountJson,
|
AmountJson,
|
||||||
Amounts,
|
Amounts,
|
||||||
ExchangeListItem,
|
ExchangeListItem,
|
||||||
GetExchangeTosResult,
|
|
||||||
i18n,
|
i18n,
|
||||||
WithdrawUriInfoResponse,
|
WithdrawUriInfoResponse,
|
||||||
} from "@gnu-taler/taler-util";
|
} from "@gnu-taler/taler-util";
|
||||||
import { VNode, h, Fragment } from "preact";
|
import { Fragment, h, VNode } from "preact";
|
||||||
import { useState } from "preact/hooks";
|
import { useState } from "preact/hooks";
|
||||||
import { CheckboxOutlined } from "../components/CheckboxOutlined";
|
|
||||||
import { ExchangeXmlTos } from "../components/ExchangeToS";
|
|
||||||
import { LogoHeader } from "../components/LogoHeader";
|
import { LogoHeader } from "../components/LogoHeader";
|
||||||
import { Part } from "../components/Part";
|
import { Part } from "../components/Part";
|
||||||
import { SelectList } from "../components/SelectList";
|
import { SelectList } from "../components/SelectList";
|
||||||
@ -40,19 +37,13 @@ import {
|
|||||||
ButtonSuccess,
|
ButtonSuccess,
|
||||||
ButtonWarning,
|
ButtonWarning,
|
||||||
LinkSuccess,
|
LinkSuccess,
|
||||||
TermsOfService,
|
|
||||||
WalletAction,
|
WalletAction,
|
||||||
WarningText,
|
WarningText,
|
||||||
} from "../components/styled";
|
} from "../components/styled";
|
||||||
import { useAsyncAsHook } from "../hooks/useAsyncAsHook";
|
import { useAsyncAsHook } from "../hooks/useAsyncAsHook";
|
||||||
import {
|
import { amountToString, buildTermsOfServiceState, TermsState } from "../utils";
|
||||||
acceptWithdrawal,
|
import * as wxApi from "../wxApi";
|
||||||
getExchangeTos,
|
import { TermsOfServiceSection } from "./TermsOfServiceSection";
|
||||||
getExchangeWithdrawalInfo,
|
|
||||||
getWithdrawalDetailsForUri,
|
|
||||||
listExchanges,
|
|
||||||
setExchangeTosAccepted,
|
|
||||||
} from "../wxApi";
|
|
||||||
|
|
||||||
interface Props {
|
interface Props {
|
||||||
talerWithdrawUri?: string;
|
talerWithdrawUri?: string;
|
||||||
@ -60,7 +51,7 @@ interface Props {
|
|||||||
|
|
||||||
export interface ViewProps {
|
export interface ViewProps {
|
||||||
withdrawalFee: AmountJson;
|
withdrawalFee: AmountJson;
|
||||||
exchangeBaseUrl: string;
|
exchangeBaseUrl?: string;
|
||||||
amount: AmountJson;
|
amount: AmountJson;
|
||||||
onSwitchExchange: (ex: string) => void;
|
onSwitchExchange: (ex: string) => void;
|
||||||
onWithdraw: () => Promise<void>;
|
onWithdraw: () => Promise<void>;
|
||||||
@ -69,53 +60,10 @@ export interface ViewProps {
|
|||||||
reviewing: boolean;
|
reviewing: boolean;
|
||||||
reviewed: boolean;
|
reviewed: boolean;
|
||||||
confirmed: boolean;
|
confirmed: boolean;
|
||||||
terms: {
|
terms: TermsState;
|
||||||
value?: TermsDocument;
|
|
||||||
status: TermsStatus;
|
|
||||||
};
|
|
||||||
knownExchanges: ExchangeListItem[];
|
knownExchanges: ExchangeListItem[];
|
||||||
}
|
}
|
||||||
|
|
||||||
type TermsStatus = "new" | "accepted" | "changed" | "notfound";
|
|
||||||
|
|
||||||
type TermsDocument =
|
|
||||||
| TermsDocumentXml
|
|
||||||
| TermsDocumentHtml
|
|
||||||
| TermsDocumentPlain
|
|
||||||
| TermsDocumentJson
|
|
||||||
| TermsDocumentPdf;
|
|
||||||
|
|
||||||
interface TermsDocumentXml {
|
|
||||||
type: "xml";
|
|
||||||
document: Document;
|
|
||||||
}
|
|
||||||
|
|
||||||
interface TermsDocumentHtml {
|
|
||||||
type: "html";
|
|
||||||
href: URL;
|
|
||||||
}
|
|
||||||
|
|
||||||
interface TermsDocumentPlain {
|
|
||||||
type: "plain";
|
|
||||||
content: string;
|
|
||||||
}
|
|
||||||
|
|
||||||
interface TermsDocumentJson {
|
|
||||||
type: "json";
|
|
||||||
data: any;
|
|
||||||
}
|
|
||||||
|
|
||||||
interface TermsDocumentPdf {
|
|
||||||
type: "pdf";
|
|
||||||
location: URL;
|
|
||||||
}
|
|
||||||
|
|
||||||
function amountToString(text: AmountJson): string {
|
|
||||||
const aj = Amounts.jsonifyAmount(text);
|
|
||||||
const amount = Amounts.stringifyValue(aj);
|
|
||||||
return `${amount} ${aj.currency}`;
|
|
||||||
}
|
|
||||||
|
|
||||||
export function View({
|
export function View({
|
||||||
withdrawalFee,
|
withdrawalFee,
|
||||||
exchangeBaseUrl,
|
exchangeBaseUrl,
|
||||||
@ -162,7 +110,9 @@ export function View({
|
|||||||
kind="negative"
|
kind="negative"
|
||||||
/>
|
/>
|
||||||
)}
|
)}
|
||||||
<Part title="Exchange" text={exchangeBaseUrl} kind="neutral" big />
|
{exchangeBaseUrl && (
|
||||||
|
<Part title="Exchange" text={exchangeBaseUrl} kind="neutral" big />
|
||||||
|
)}
|
||||||
</section>
|
</section>
|
||||||
{!reviewing && (
|
{!reviewing && (
|
||||||
<section>
|
<section>
|
||||||
@ -190,13 +140,6 @@ export function View({
|
|||||||
)}
|
)}
|
||||||
</section>
|
</section>
|
||||||
)}
|
)}
|
||||||
{!reviewing && reviewed && (
|
|
||||||
<section>
|
|
||||||
<LinkSuccess upperCased onClick={() => onReview(true)}>
|
|
||||||
{i18n.str`Show terms of service`}
|
|
||||||
</LinkSuccess>
|
|
||||||
</section>
|
|
||||||
)}
|
|
||||||
{terms.status === "notfound" && (
|
{terms.status === "notfound" && (
|
||||||
<section>
|
<section>
|
||||||
<WarningText>
|
<WarningText>
|
||||||
@ -204,79 +147,14 @@ export function View({
|
|||||||
</WarningText>
|
</WarningText>
|
||||||
</section>
|
</section>
|
||||||
)}
|
)}
|
||||||
{reviewing && (
|
<TermsOfServiceSection
|
||||||
<section>
|
reviewed={reviewed}
|
||||||
{terms.status !== "accepted" &&
|
reviewing={reviewing}
|
||||||
terms.value &&
|
terms={terms}
|
||||||
terms.value.type === "xml" && (
|
onAccept={onAccept}
|
||||||
<TermsOfService>
|
onReview={onReview}
|
||||||
<ExchangeXmlTos doc={terms.value.document} />
|
/>
|
||||||
</TermsOfService>
|
|
||||||
)}
|
|
||||||
{terms.status !== "accepted" &&
|
|
||||||
terms.value &&
|
|
||||||
terms.value.type === "plain" && (
|
|
||||||
<div style={{ textAlign: "left" }}>
|
|
||||||
<pre>{terms.value.content}</pre>
|
|
||||||
</div>
|
|
||||||
)}
|
|
||||||
{terms.status !== "accepted" &&
|
|
||||||
terms.value &&
|
|
||||||
terms.value.type === "html" && (
|
|
||||||
<iframe src={terms.value.href.toString()} />
|
|
||||||
)}
|
|
||||||
{terms.status !== "accepted" &&
|
|
||||||
terms.value &&
|
|
||||||
terms.value.type === "pdf" && (
|
|
||||||
<a href={terms.value.location.toString()} download="tos.pdf">
|
|
||||||
Download Terms of Service
|
|
||||||
</a>
|
|
||||||
)}
|
|
||||||
</section>
|
|
||||||
)}
|
|
||||||
{reviewing && reviewed && (
|
|
||||||
<section>
|
|
||||||
<LinkSuccess upperCased onClick={() => onReview(false)}>
|
|
||||||
{i18n.str`Hide terms of service`}
|
|
||||||
</LinkSuccess>
|
|
||||||
</section>
|
|
||||||
)}
|
|
||||||
{(reviewing || reviewed) && (
|
|
||||||
<section>
|
|
||||||
<CheckboxOutlined
|
|
||||||
name="terms"
|
|
||||||
enabled={reviewed}
|
|
||||||
label={i18n.str`I accept the exchange terms of service`}
|
|
||||||
onToggle={() => {
|
|
||||||
onAccept(!reviewed);
|
|
||||||
onReview(false);
|
|
||||||
}}
|
|
||||||
/>
|
|
||||||
</section>
|
|
||||||
)}
|
|
||||||
|
|
||||||
{/**
|
|
||||||
* Main action section
|
|
||||||
*/}
|
|
||||||
<section>
|
<section>
|
||||||
{terms.status === "new" && !reviewed && !reviewing && (
|
|
||||||
<ButtonSuccess
|
|
||||||
upperCased
|
|
||||||
disabled={!exchangeBaseUrl}
|
|
||||||
onClick={() => onReview(true)}
|
|
||||||
>
|
|
||||||
{i18n.str`Review exchange terms of service`}
|
|
||||||
</ButtonSuccess>
|
|
||||||
)}
|
|
||||||
{terms.status === "changed" && !reviewed && !reviewing && (
|
|
||||||
<ButtonWarning
|
|
||||||
upperCased
|
|
||||||
disabled={!exchangeBaseUrl}
|
|
||||||
onClick={() => onReview(true)}
|
|
||||||
>
|
|
||||||
{i18n.str`Review new version of terms of service`}
|
|
||||||
</ButtonWarning>
|
|
||||||
)}
|
|
||||||
{(terms.status === "accepted" || (needsReview && reviewed)) && (
|
{(terms.status === "accepted" || (needsReview && reviewed)) && (
|
||||||
<ButtonSuccess
|
<ButtonSuccess
|
||||||
upperCased
|
upperCased
|
||||||
@ -310,15 +188,15 @@ export function WithdrawPageWithParsedURI({
|
|||||||
const [customExchange, setCustomExchange] = useState<string | undefined>(
|
const [customExchange, setCustomExchange] = useState<string | undefined>(
|
||||||
undefined,
|
undefined,
|
||||||
);
|
);
|
||||||
const [errorAccepting, setErrorAccepting] = useState<string | undefined>(
|
// const [errorAccepting, setErrorAccepting] = useState<string | undefined>(
|
||||||
undefined,
|
// undefined,
|
||||||
);
|
// );
|
||||||
|
|
||||||
const [reviewing, setReviewing] = useState<boolean>(false);
|
const [reviewing, setReviewing] = useState<boolean>(false);
|
||||||
const [reviewed, setReviewed] = useState<boolean>(false);
|
const [reviewed, setReviewed] = useState<boolean>(false);
|
||||||
const [confirmed, setConfirmed] = useState<boolean>(false);
|
const [confirmed, setConfirmed] = useState<boolean>(false);
|
||||||
|
|
||||||
const knownExchangesHook = useAsyncAsHook(() => listExchanges());
|
const knownExchangesHook = useAsyncAsHook(() => wxApi.listExchanges());
|
||||||
|
|
||||||
const knownExchanges =
|
const knownExchanges =
|
||||||
!knownExchangesHook || knownExchangesHook.hasError
|
!knownExchangesHook || knownExchangesHook.hasError
|
||||||
@ -329,19 +207,25 @@ export function WithdrawPageWithParsedURI({
|
|||||||
(ex) => ex.currency === withdrawAmount.currency,
|
(ex) => ex.currency === withdrawAmount.currency,
|
||||||
);
|
);
|
||||||
|
|
||||||
const exchange =
|
const exchange: string | undefined =
|
||||||
customExchange ||
|
customExchange ??
|
||||||
uriInfo.defaultExchangeBaseUrl ||
|
uriInfo.defaultExchangeBaseUrl ??
|
||||||
thisCurrencyExchanges[0]?.exchangeBaseUrl;
|
(thisCurrencyExchanges[0]
|
||||||
|
? thisCurrencyExchanges[0].exchangeBaseUrl
|
||||||
|
: undefined);
|
||||||
|
|
||||||
const detailsHook = useAsyncAsHook(async () => {
|
const detailsHook = useAsyncAsHook(async () => {
|
||||||
if (!exchange) throw Error("no default exchange");
|
if (!exchange) throw Error("no default exchange");
|
||||||
const tos = await getExchangeTos(exchange, ["text/xml"]);
|
const tos = await wxApi.getExchangeTos(exchange, ["text/xml"]);
|
||||||
const info = await getExchangeWithdrawalInfo({
|
|
||||||
|
const tosState = buildTermsOfServiceState(tos);
|
||||||
|
|
||||||
|
const info = await wxApi.getExchangeWithdrawalInfo({
|
||||||
exchangeBaseUrl: exchange,
|
exchangeBaseUrl: exchange,
|
||||||
amount: withdrawAmount,
|
amount: withdrawAmount,
|
||||||
tosAcceptedFormat: ["text/xml"],
|
tosAcceptedFormat: ["text/xml"],
|
||||||
});
|
});
|
||||||
return { tos, info };
|
return { tos: tosState, info };
|
||||||
});
|
});
|
||||||
|
|
||||||
if (!detailsHook) {
|
if (!detailsHook) {
|
||||||
@ -364,21 +248,24 @@ export function WithdrawPageWithParsedURI({
|
|||||||
const details = detailsHook.response;
|
const details = detailsHook.response;
|
||||||
|
|
||||||
const onAccept = async (): Promise<void> => {
|
const onAccept = async (): Promise<void> => {
|
||||||
|
if (!exchange) return;
|
||||||
try {
|
try {
|
||||||
await setExchangeTosAccepted(exchange, details.tos.currentEtag);
|
await wxApi.setExchangeTosAccepted(exchange, details.tos.version);
|
||||||
setReviewed(true);
|
setReviewed(true);
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
if (e instanceof Error) {
|
if (e instanceof Error) {
|
||||||
setErrorAccepting(e.message);
|
//FIXME: uncomment this and display error
|
||||||
|
// setErrorAccepting(e.message);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
const onWithdraw = async (): Promise<void> => {
|
const onWithdraw = async (): Promise<void> => {
|
||||||
|
if (!exchange) return;
|
||||||
setConfirmed(true);
|
setConfirmed(true);
|
||||||
console.log("accepting exchange", exchange);
|
console.log("accepting exchange", exchange);
|
||||||
try {
|
try {
|
||||||
const res = await acceptWithdrawal(uri, exchange);
|
const res = await wxApi.acceptWithdrawal(uri, exchange);
|
||||||
console.log("accept withdrawal response", res);
|
console.log("accept withdrawal response", res);
|
||||||
if (res.confirmTransferUrl) {
|
if (res.confirmTransferUrl) {
|
||||||
document.location.href = res.confirmTransferUrl;
|
document.location.href = res.confirmTransferUrl;
|
||||||
@ -388,30 +275,13 @@ export function WithdrawPageWithParsedURI({
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
const termsContent: TermsDocument | undefined = parseTermsOfServiceContent(
|
|
||||||
details.tos.contentType,
|
|
||||||
details.tos.content,
|
|
||||||
);
|
|
||||||
|
|
||||||
const status: TermsStatus = !termsContent
|
|
||||||
? "notfound"
|
|
||||||
: !details.tos.acceptedEtag
|
|
||||||
? "new"
|
|
||||||
: details.tos.acceptedEtag !== details.tos.currentEtag
|
|
||||||
? "changed"
|
|
||||||
: "accepted";
|
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<View
|
<View
|
||||||
onWithdraw={onWithdraw}
|
onWithdraw={onWithdraw}
|
||||||
// details={details.tos}
|
|
||||||
amount={withdrawAmount}
|
amount={withdrawAmount}
|
||||||
exchangeBaseUrl={exchange}
|
exchangeBaseUrl={exchange}
|
||||||
withdrawalFee={details.info.withdrawFee} //FIXME
|
withdrawalFee={details.info.withdrawFee} //FIXME
|
||||||
terms={{
|
terms={detailsHook.response.tos}
|
||||||
status,
|
|
||||||
value: termsContent,
|
|
||||||
}}
|
|
||||||
onSwitchExchange={setCustomExchange}
|
onSwitchExchange={setCustomExchange}
|
||||||
knownExchanges={knownExchanges}
|
knownExchanges={knownExchanges}
|
||||||
confirmed={confirmed}
|
confirmed={confirmed}
|
||||||
@ -426,7 +296,7 @@ export function WithdrawPage({ talerWithdrawUri }: Props): VNode {
|
|||||||
const uriInfoHook = useAsyncAsHook(() =>
|
const uriInfoHook = useAsyncAsHook(() =>
|
||||||
!talerWithdrawUri
|
!talerWithdrawUri
|
||||||
? Promise.reject(undefined)
|
? Promise.reject(undefined)
|
||||||
: getWithdrawalDetailsForUri({ talerWithdrawUri }),
|
: wxApi.getWithdrawalDetailsForUri({ talerWithdrawUri }),
|
||||||
);
|
);
|
||||||
|
|
||||||
if (!talerWithdrawUri) {
|
if (!talerWithdrawUri) {
|
||||||
@ -459,46 +329,3 @@ export function WithdrawPage({ talerWithdrawUri }: Props): VNode {
|
|||||||
/>
|
/>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
function parseTermsOfServiceContent(
|
|
||||||
type: string,
|
|
||||||
text: string,
|
|
||||||
): TermsDocument | undefined {
|
|
||||||
if (type === "text/xml") {
|
|
||||||
try {
|
|
||||||
const document = new DOMParser().parseFromString(text, "text/xml");
|
|
||||||
return { type: "xml", document };
|
|
||||||
} catch (e) {
|
|
||||||
console.log(e);
|
|
||||||
}
|
|
||||||
} else if (type === "text/html") {
|
|
||||||
try {
|
|
||||||
const href = new URL(text);
|
|
||||||
return { type: "html", href };
|
|
||||||
} catch (e) {
|
|
||||||
console.log(e);
|
|
||||||
}
|
|
||||||
} else if (type === "text/json") {
|
|
||||||
try {
|
|
||||||
const data = JSON.parse(text);
|
|
||||||
return { type: "json", data };
|
|
||||||
} catch (e) {
|
|
||||||
console.log(e);
|
|
||||||
}
|
|
||||||
} else if (type === "text/pdf") {
|
|
||||||
try {
|
|
||||||
const location = new URL(text);
|
|
||||||
return { type: "pdf", location };
|
|
||||||
} catch (e) {
|
|
||||||
console.log(e);
|
|
||||||
}
|
|
||||||
} else if (type === "text/plain") {
|
|
||||||
try {
|
|
||||||
const content = text;
|
|
||||||
return { type: "plain", content };
|
|
||||||
} catch (e) {
|
|
||||||
console.log(e);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return undefined;
|
|
||||||
}
|
|
||||||
|
781
packages/taler-wallet-webextension/src/cta/termsExample.ts
Normal file
781
packages/taler-wallet-webextension/src/cta/termsExample.ts
Normal file
@ -0,0 +1,781 @@
|
|||||||
|
/*
|
||||||
|
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)
|
||||||
|
*/
|
||||||
|
|
||||||
|
export const termsHtml = `<html xmlns="http://www.w3.org/1999/xhtml" lang="en">
|
||||||
|
<head>
|
||||||
|
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
|
||||||
|
<title>Terms Of Service — Taler Terms of Service</title>
|
||||||
|
</head><body>
|
||||||
|
<div>
|
||||||
|
Terms of service
|
||||||
|
</div>
|
||||||
|
<div>
|
||||||
|
A complete separated html with it's own design
|
||||||
|
</div>
|
||||||
|
</body>
|
||||||
|
</html>
|
||||||
|
`;
|
||||||
|
export const termsPlain = `
|
||||||
|
Terms Of Service
|
||||||
|
****************
|
||||||
|
|
||||||
|
Last Updated: 12.4.2019
|
||||||
|
|
||||||
|
Welcome! Taler Systems SA (“we,” “our,” or “us”) provides a payment
|
||||||
|
service through our Internet presence (collectively the “Services”).
|
||||||
|
Before using our Services, please read the Terms of Service (the
|
||||||
|
“Terms” or the “Agreement”) carefully.
|
||||||
|
|
||||||
|
|
||||||
|
Overview
|
||||||
|
========
|
||||||
|
|
||||||
|
This section provides a brief summary of the highlights of this
|
||||||
|
Agreement. Please note that when you accept this Agreement, you are
|
||||||
|
accepting all of the terms and conditions and not just this section.
|
||||||
|
We and possibly other third parties provide Internet services which
|
||||||
|
interact with the Taler Wallet’s self-hosted personal payment
|
||||||
|
application. When using the Taler Wallet to interact with our
|
||||||
|
Services, you are agreeing to our Terms, so please read carefully.
|
||||||
|
|
||||||
|
|
||||||
|
Highlights:
|
||||||
|
-----------
|
||||||
|
|
||||||
|
* You are responsible for keeping the data in your Taler Wallet at
|
||||||
|
all times under your control. Any losses arising from you not
|
||||||
|
being in control of your private information are your problem.
|
||||||
|
|
||||||
|
* We will try to transfer funds we hold in escrow for our users to
|
||||||
|
any legal recipient to the best of our ability within the
|
||||||
|
limitations of the law and our implementation. However, the
|
||||||
|
Services offered today are highly experimental and the set of
|
||||||
|
recipients of funds is severely restricted.
|
||||||
|
|
||||||
|
* For our Services, we may charge transaction fees. The specific
|
||||||
|
fee structure is provided based on the Taler protocol and should
|
||||||
|
be shown to you when you withdraw electronic coins using a Taler
|
||||||
|
Wallet. You agree and understand that the Taler protocol allows
|
||||||
|
for the fee structure to change.
|
||||||
|
|
||||||
|
* You agree to not intentionally overwhelm our systems with
|
||||||
|
requests and follow responsible disclosure if you find security
|
||||||
|
issues in our services.
|
||||||
|
|
||||||
|
* We cannot be held accountable for our Services not being
|
||||||
|
available due to circumstances beyond our control. If we modify
|
||||||
|
or terminate our services, we will try to give you the
|
||||||
|
opportunity to recover your funds. However, given the
|
||||||
|
experimental state of the Services today, this may not be
|
||||||
|
possible. You are strongly advised to limit your use of the
|
||||||
|
Service to small-scale experiments expecting total loss of all
|
||||||
|
funds.
|
||||||
|
|
||||||
|
These terms outline approved uses of our Services. The Services and
|
||||||
|
these Terms are still at an experimental stage. If you have any
|
||||||
|
questions or comments related to this Agreement, please send us a
|
||||||
|
message to legal@taler-systems.com. If you do not agree to this
|
||||||
|
Agreement, you must not use our Services.
|
||||||
|
|
||||||
|
|
||||||
|
How you accept this policy
|
||||||
|
==========================
|
||||||
|
|
||||||
|
By sending funds to us (to top-up your Taler Wallet), you acknowledge
|
||||||
|
that you have read, understood, and agreed to these Terms. We reserve
|
||||||
|
the right to change these Terms at any time. If you disagree with the
|
||||||
|
change, we may in the future offer you with an easy option to recover
|
||||||
|
your unspent funds. However, in the current experimental period you
|
||||||
|
acknowledge that this feature is not yet available, resulting in your
|
||||||
|
funds being lost unless you accept the new Terms. If you continue to
|
||||||
|
use our Services other than to recover your unspent funds, your
|
||||||
|
continued use of our Services following any such change will signify
|
||||||
|
your acceptance to be bound by the then current Terms. Please check
|
||||||
|
the effective date above to determine if there have been any changes
|
||||||
|
since you have last reviewed these Terms.
|
||||||
|
|
||||||
|
|
||||||
|
Services
|
||||||
|
========
|
||||||
|
|
||||||
|
We will try to transfer funds that we hold in escrow for our users to
|
||||||
|
any legal recipient to the best of our ability and within the
|
||||||
|
limitations of the law and our implementation. However, the Services
|
||||||
|
offered today are highly experimental and the set of recipients of
|
||||||
|
funds is severely restricted. The Taler Wallet can be loaded by
|
||||||
|
exchanging fiat currencies against electronic coins. We are providing
|
||||||
|
this exchange service. Once your Taler Wallet is loaded with
|
||||||
|
electronic coins they can be spent for purchases if the seller is
|
||||||
|
accepting Taler as a means of payment. We are not guaranteeing that
|
||||||
|
any seller is accepting Taler at all or a particular seller. The
|
||||||
|
seller or recipient of deposits of electronic coins must specify the
|
||||||
|
target account, as per the design of the Taler protocol. They are
|
||||||
|
responsible for following the protocol and specifying the correct bank
|
||||||
|
account, and are solely liable for any losses that may arise from
|
||||||
|
specifying the wrong account. We will allow the government to link
|
||||||
|
wire transfers to the underlying contract hash. It is the
|
||||||
|
responsibility of recipients to preserve the full contracts and to pay
|
||||||
|
whatever taxes and charges may be applicable. Technical issues may
|
||||||
|
lead to situations where we are unable to make transfers at all or
|
||||||
|
lead to incorrect transfers that cannot be reversed. We will only
|
||||||
|
refuse to execute transfers if the transfers are prohibited by a
|
||||||
|
competent legal authority and we are ordered to do so.
|
||||||
|
|
||||||
|
|
||||||
|
Fees
|
||||||
|
====
|
||||||
|
|
||||||
|
You agree to pay the fees for exchanges and withdrawals completed via
|
||||||
|
the Taler Wallet ("Fees") as defined by us, which we may change from
|
||||||
|
time to time. With the exception of wire transfer fees, Taler
|
||||||
|
transaction fees are set for any electronic coin at the time of
|
||||||
|
withdrawal and fixed throughout the validity period of the respective
|
||||||
|
electronic coin. Your wallet should obtain and display applicable fees
|
||||||
|
when withdrawing funds. Fees for coins obtained as change may differ
|
||||||
|
from the fees applicable to the original coin. Wire transfer fees that
|
||||||
|
are independent from electronic coins may change annually. You
|
||||||
|
authorize us to charge or deduct applicable fees owed in connection
|
||||||
|
with deposits, exchanges and withdrawals following the rules of the
|
||||||
|
Taler protocol. We reserve the right to provide different types of
|
||||||
|
rewards to users either in the form of discount for our Services or in
|
||||||
|
any other form at our discretion and without prior notice to you.
|
||||||
|
|
||||||
|
|
||||||
|
Eligibility
|
||||||
|
===========
|
||||||
|
|
||||||
|
To be eligible to use our Services, you must be able to form legally
|
||||||
|
binding contracts or have the permission of your legal guardian. By
|
||||||
|
using our Services, you represent and warrant that you meet all
|
||||||
|
eligibility requirements that we outline in these Terms.
|
||||||
|
|
||||||
|
|
||||||
|
Financial self-responsibility
|
||||||
|
=============================
|
||||||
|
|
||||||
|
You will be responsible for maintaining the availability, integrity
|
||||||
|
and confidentiality of the data stored in your wallet. When you setup
|
||||||
|
a Taler Wallet, you are strongly advised to follow the precautionary
|
||||||
|
measures offered by the software to minimize the chances to losse
|
||||||
|
access to or control over your Wallet data. We will not be liable for
|
||||||
|
any loss or damage arising from your failure to comply with this
|
||||||
|
paragraph.
|
||||||
|
|
||||||
|
|
||||||
|
Copyrights and trademarks
|
||||||
|
=========================
|
||||||
|
|
||||||
|
The Taler Wallet is released under the terms of the GNU General Public
|
||||||
|
License (GNU GPL). You have the right to access, use, and share the
|
||||||
|
Taler Wallet, in modified or unmodified form. However, the GPL is a
|
||||||
|
strong copyleft license, which means that any derivative works must be
|
||||||
|
distributed under the same license terms as the original software. If
|
||||||
|
you have any questions, you should review the GNU GPL’s full terms and
|
||||||
|
conditions at https://www.gnu.org/licenses/gpl-3.0.en.html. “Taler”
|
||||||
|
itself is a trademark of Taler Systems SA. You are welcome to use the
|
||||||
|
name in relation to processing payments using the Taler protocol,
|
||||||
|
assuming your use is compatible with an official release from the GNU
|
||||||
|
Project that is not older than two years.
|
||||||
|
|
||||||
|
|
||||||
|
Your use of our services
|
||||||
|
========================
|
||||||
|
|
||||||
|
When using our Services, you agree to not take any action that
|
||||||
|
intentionally imposes an unreasonable load on our infrastructure. If
|
||||||
|
you find security problems in our Services, you agree to first report
|
||||||
|
them to security@taler-systems.com and grant us the right to publish
|
||||||
|
your report. We warrant that we will ourselves publicly disclose any
|
||||||
|
issues reported within 3 months, and that we will not prosecute anyone
|
||||||
|
reporting security issues if they did not exploit the issue beyond a
|
||||||
|
proof-of-concept, and followed the above responsible disclosure
|
||||||
|
practice.
|
||||||
|
|
||||||
|
|
||||||
|
Limitation of liability & disclaimer of warranties
|
||||||
|
==================================================
|
||||||
|
|
||||||
|
You understand and agree that we have no control over, and no duty to
|
||||||
|
take any action regarding: Failures, disruptions, errors, or delays in
|
||||||
|
processing that you may experience while using our Services; The risk
|
||||||
|
of failure of hardware, software, and Internet connections; The risk
|
||||||
|
of malicious software being introduced or found in the software
|
||||||
|
underlying the Taler Wallet; The risk that third parties may obtain
|
||||||
|
unauthorized access to information stored within your Taler Wallet,
|
||||||
|
including, but not limited to your Taler Wallet coins or backup
|
||||||
|
encryption keys. You release us from all liability related to any
|
||||||
|
losses, damages, or claims arising from:
|
||||||
|
|
||||||
|
1. user error such as forgotten passwords, incorrectly constructed
|
||||||
|
transactions;
|
||||||
|
|
||||||
|
2. server failure or data loss;
|
||||||
|
|
||||||
|
3. unauthorized access to the Taler Wallet application;
|
||||||
|
|
||||||
|
4. bugs or other errors in the Taler Wallet software; and
|
||||||
|
|
||||||
|
5. any unauthorized third party activities, including, but not limited
|
||||||
|
to, the use of viruses, phishing, brute forcing, or other means of
|
||||||
|
attack against the Taler Wallet. We make no representations
|
||||||
|
concerning any Third Party Content contained in or accessed through
|
||||||
|
our Services.
|
||||||
|
|
||||||
|
Any other terms, conditions, warranties, or representations associated
|
||||||
|
with such content, are solely between you and such organizations
|
||||||
|
and/or individuals.
|
||||||
|
|
||||||
|
|
||||||
|
Limitation of liability
|
||||||
|
=======================
|
||||||
|
|
||||||
|
To the fullest extent permitted by applicable law, in no event will we
|
||||||
|
or any of our officers, directors, representatives, agents, servants,
|
||||||
|
counsel, employees, consultants, lawyers, and other personnel
|
||||||
|
authorized to act, acting, or purporting to act on our behalf
|
||||||
|
(collectively the “Taler Parties”) be liable to you under contract,
|
||||||
|
tort, strict liability, negligence, or any other legal or equitable
|
||||||
|
theory, for:
|
||||||
|
|
||||||
|
1. any lost profits, data loss, cost of procurement of substitute
|
||||||
|
goods or services, or direct, indirect, incidental, special,
|
||||||
|
punitive, compensatory, or consequential damages of any kind
|
||||||
|
whatsoever resulting from:
|
||||||
|
|
||||||
|
1. your use of, or conduct in connection with, our services;
|
||||||
|
|
||||||
|
2. any unauthorized use of your wallet and/or private key due to
|
||||||
|
your failure to maintain the confidentiality of your wallet;
|
||||||
|
|
||||||
|
3. any interruption or cessation of transmission to or from the
|
||||||
|
services; or
|
||||||
|
|
||||||
|
4. any bugs, viruses, trojan horses, or the like that are found in
|
||||||
|
the Taler Wallet software or that may be transmitted to or
|
||||||
|
through our services by any third party (regardless of the
|
||||||
|
source of origination), or
|
||||||
|
|
||||||
|
2. any direct damages.
|
||||||
|
|
||||||
|
These limitations apply regardless of legal theory, whether based on
|
||||||
|
tort, strict liability, breach of contract, breach of warranty, or any
|
||||||
|
other legal theory, and whether or not we were advised of the
|
||||||
|
possibility of such damages. Some jurisdictions do not allow the
|
||||||
|
exclusion or limitation of liability for consequential or incidental
|
||||||
|
damages, so the above limitation may not apply to you.
|
||||||
|
|
||||||
|
|
||||||
|
Warranty disclaimer
|
||||||
|
===================
|
||||||
|
|
||||||
|
Our services are provided "as is" and without warranty of any kind. To
|
||||||
|
the maximum extent permitted by law, we disclaim all representations
|
||||||
|
and warranties, express or implied, relating to the services and
|
||||||
|
underlying software or any content on the services, whether provided
|
||||||
|
or owned by us or by any third party, including without limitation,
|
||||||
|
warranties of merchantability, fitness for a particular purpose,
|
||||||
|
title, non-infringement, freedom from computer virus, and any implied
|
||||||
|
warranties arising from course of dealing, course of performance, or
|
||||||
|
usage in trade, all of which are expressly disclaimed. In addition, we
|
||||||
|
do not represent or warrant that the content accessible via the
|
||||||
|
services is accurate, complete, available, current, free of viruses or
|
||||||
|
other harmful components, or that the results of using the services
|
||||||
|
will meet your requirements. Some states do not allow the disclaimer
|
||||||
|
of implied warranties, so the foregoing disclaimers may not apply to
|
||||||
|
you. This paragraph gives you specific legal rights and you may also
|
||||||
|
have other legal rights that vary from state to state.
|
||||||
|
|
||||||
|
|
||||||
|
Indemnity
|
||||||
|
=========
|
||||||
|
|
||||||
|
To the extent permitted by applicable law, you agree to defend,
|
||||||
|
indemnify, and hold harmless the Taler Parties from and against any
|
||||||
|
and all claims, damages, obligations, losses, liabilities, costs or
|
||||||
|
debt, and expenses (including, but not limited to, attorney’s fees)
|
||||||
|
arising from: (a) your use of and access to the Services; (b) any
|
||||||
|
feedback or submissions you provide to us concerning the Taler Wallet;
|
||||||
|
(c) your violation of any term of this Agreement; or (d) your
|
||||||
|
violation of any law, rule, or regulation, or the rights of any third
|
||||||
|
party.
|
||||||
|
|
||||||
|
|
||||||
|
Time limitation on claims
|
||||||
|
=========================
|
||||||
|
|
||||||
|
You agree that any claim you may have arising out of or related to
|
||||||
|
your relationship with us must be filed within one year after such
|
||||||
|
claim arises, otherwise, your claim in permanently barred.
|
||||||
|
|
||||||
|
|
||||||
|
Governing law
|
||||||
|
=============
|
||||||
|
|
||||||
|
No matter where you’re located, the laws of Switzerland will govern
|
||||||
|
these Terms. If any provisions of these Terms are inconsistent with
|
||||||
|
any applicable law, those provisions will be superseded or modified
|
||||||
|
only to the extent such provisions are inconsistent. The parties agree
|
||||||
|
to submit to the ordinary courts in Zurich, Switzerland for exclusive
|
||||||
|
jurisdiction of any dispute arising out of or related to your use of
|
||||||
|
the Services or your breach of these Terms.
|
||||||
|
|
||||||
|
|
||||||
|
Termination
|
||||||
|
===========
|
||||||
|
|
||||||
|
In the event of termination concerning your use of our Services, your
|
||||||
|
obligations under this Agreement will still continue.
|
||||||
|
|
||||||
|
|
||||||
|
Discontinuance of services
|
||||||
|
==========================
|
||||||
|
|
||||||
|
We may, in our sole discretion and without cost to you, with or
|
||||||
|
without prior notice, and at any time, modify or discontinue,
|
||||||
|
temporarily or permanently, any portion of our Services. We will use
|
||||||
|
the Taler protocol’s provisions to notify Wallets if our Services are
|
||||||
|
to be discontinued. It is your responsibility to ensure that the Taler
|
||||||
|
Wallet is online at least once every three months to observe these
|
||||||
|
notifications. We shall not be held responsible or liable for any loss
|
||||||
|
of funds in the event that we discontinue or depreciate the Services
|
||||||
|
and your Taler Wallet fails to transfer out the coins within a three
|
||||||
|
months notification period.
|
||||||
|
|
||||||
|
|
||||||
|
No waiver
|
||||||
|
=========
|
||||||
|
|
||||||
|
Our failure to exercise or delay in exercising any right, power, or
|
||||||
|
privilege under this Agreement shall not operate as a waiver; nor
|
||||||
|
shall any single or partial exercise of any right, power, or privilege
|
||||||
|
preclude any other or further exercise thereof.
|
||||||
|
|
||||||
|
|
||||||
|
Severability
|
||||||
|
============
|
||||||
|
|
||||||
|
If it turns out that any part of this Agreement is invalid, void, or
|
||||||
|
for any reason unenforceable, that term will be deemed severable and
|
||||||
|
limited or eliminated to the minimum extent necessary.
|
||||||
|
|
||||||
|
|
||||||
|
Force majeure
|
||||||
|
=============
|
||||||
|
|
||||||
|
We shall not be held liable for any delays, failure in performance, or
|
||||||
|
interruptions of service which result directly or indirectly from any
|
||||||
|
cause or condition beyond our reasonable control, including but not
|
||||||
|
limited to: any delay or failure due to any act of God, act of civil
|
||||||
|
or military authorities, act of terrorism, civil disturbance, war,
|
||||||
|
strike or other labor dispute, fire, interruption in
|
||||||
|
telecommunications or Internet services or network provider services,
|
||||||
|
failure of equipment and/or software, other catastrophe, or any other
|
||||||
|
occurrence which is beyond our reasonable control and shall not affect
|
||||||
|
the validity and enforceability of any remaining provisions.
|
||||||
|
|
||||||
|
|
||||||
|
Assignment
|
||||||
|
==========
|
||||||
|
|
||||||
|
You agree that we may assign any of our rights and/or transfer, sub-
|
||||||
|
contract, or delegate any of our obligations under these Terms.
|
||||||
|
|
||||||
|
|
||||||
|
Entire agreement
|
||||||
|
================
|
||||||
|
|
||||||
|
This Agreement sets forth the entire understanding and agreement as to
|
||||||
|
the subject matter hereof and supersedes any and all prior
|
||||||
|
discussions, agreements, and understandings of any kind (including,
|
||||||
|
without limitation, any prior versions of this Agreement) and every
|
||||||
|
nature between us. Except as provided for above, any modification to
|
||||||
|
this Agreement must be in writing and must be signed by both parties.
|
||||||
|
|
||||||
|
|
||||||
|
Questions or comments
|
||||||
|
=====================
|
||||||
|
|
||||||
|
We welcome comments, questions, concerns, or suggestions. Please send
|
||||||
|
us a message on our contact page at legal@taler-systems.com.
|
||||||
|
|
||||||
|
`;
|
||||||
|
|
||||||
|
export const termsXml = `<?xml version="1.0" encoding="utf-8"?>
|
||||||
|
<!DOCTYPE document PUBLIC "+//IDN docutils.sourceforge.net//DTD Docutils Generic//EN//XML" "http://docutils.sourceforge.net/docs/ref/docutils.dtd">
|
||||||
|
<!-- Generated by Docutils 0.14 -->
|
||||||
|
<document source="/home/grothoff/research/taler/exchange/contrib/tos/tos.rst">
|
||||||
|
<section ids="terms-of-service" names="terms\ of\ service">
|
||||||
|
<title>Terms Of Service</title>
|
||||||
|
<paragraph>Last Updated: 12.4.2019</paragraph>
|
||||||
|
<paragraph>Welcome! Taler Systems SA (“we,” “our,” or “us”) provides a payment service
|
||||||
|
through our Internet presence (collectively the “Services”). Before using our
|
||||||
|
Services, please read the Terms of Service (the “Terms” or the “Agreement”)
|
||||||
|
carefully.</paragraph>
|
||||||
|
<section ids="overview" names="overview">
|
||||||
|
<title>Overview</title>
|
||||||
|
<paragraph>This section provides a brief summary of the highlights of this
|
||||||
|
Agreement. Please note that when you accept this Agreement, you are accepting
|
||||||
|
all of the terms and conditions and not just this section. We and possibly
|
||||||
|
other third parties provide Internet services which interact with the Taler
|
||||||
|
Wallet’s self-hosted personal payment application. When using the Taler Wallet
|
||||||
|
to interact with our Services, you are agreeing to our Terms, so please read
|
||||||
|
carefully.</paragraph>
|
||||||
|
<section ids="highlights" names="highlights:">
|
||||||
|
<title>Highlights:</title>
|
||||||
|
<block_quote>
|
||||||
|
<bullet_list bullet="•">
|
||||||
|
<list_item>
|
||||||
|
<paragraph>You are responsible for keeping the data in your Taler Wallet at all times
|
||||||
|
under your control. Any losses arising from you not being in control of
|
||||||
|
your private information are your problem.</paragraph>
|
||||||
|
</list_item>
|
||||||
|
<list_item>
|
||||||
|
<paragraph>We will try to transfer funds we hold in escrow for our users to any legal
|
||||||
|
recipient to the best of our ability within the limitations of the law and
|
||||||
|
our implementation. However, the Services offered today are highly
|
||||||
|
experimental and the set of recipients of funds is severely restricted.</paragraph>
|
||||||
|
</list_item>
|
||||||
|
<list_item>
|
||||||
|
<paragraph>For our Services, we may charge transaction fees. The specific fee structure
|
||||||
|
is provided based on the Taler protocol and should be shown to you when you
|
||||||
|
withdraw electronic coins using a Taler Wallet. You agree and understand
|
||||||
|
that the Taler protocol allows for the fee structure to change.</paragraph>
|
||||||
|
</list_item>
|
||||||
|
<list_item>
|
||||||
|
<paragraph>You agree to not intentionally overwhelm our systems with requests and
|
||||||
|
follow responsible disclosure if you find security issues in our services.</paragraph>
|
||||||
|
</list_item>
|
||||||
|
<list_item>
|
||||||
|
<paragraph>We cannot be held accountable for our Services not being available due to
|
||||||
|
circumstances beyond our control. If we modify or terminate our services,
|
||||||
|
we will try to give you the opportunity to recover your funds. However,
|
||||||
|
given the experimental state of the Services today, this may not be
|
||||||
|
possible. You are strongly advised to limit your use of the Service
|
||||||
|
to small-scale experiments expecting total loss of all funds.</paragraph>
|
||||||
|
</list_item>
|
||||||
|
</bullet_list>
|
||||||
|
</block_quote>
|
||||||
|
<paragraph>These terms outline approved uses of our Services. The Services and these
|
||||||
|
Terms are still at an experimental stage. If you have any questions or
|
||||||
|
comments related to this Agreement, please send us a message to
|
||||||
|
<reference refuri="mailto:legal@taler-systems.com">legal@taler-systems.com</reference>. If you do not agree to this Agreement, you must not
|
||||||
|
use our Services.</paragraph>
|
||||||
|
</section>
|
||||||
|
</section>
|
||||||
|
<section ids="how-you-accept-this-policy" names="how\ you\ accept\ this\ policy">
|
||||||
|
<title>How you accept this policy</title>
|
||||||
|
<paragraph>By sending funds to us (to top-up your Taler Wallet), you acknowledge that you
|
||||||
|
have read, understood, and agreed to these Terms. We reserve the right to
|
||||||
|
change these Terms at any time. If you disagree with the change, we may in the
|
||||||
|
future offer you with an easy option to recover your unspent funds. However,
|
||||||
|
in the current experimental period you acknowledge that this feature is not
|
||||||
|
yet available, resulting in your funds being lost unless you accept the new
|
||||||
|
Terms. If you continue to use our Services other than to recover your unspent
|
||||||
|
funds, your continued use of our Services following any such change will
|
||||||
|
signify your acceptance to be bound by the then current Terms. Please check
|
||||||
|
the effective date above to determine if there have been any changes since you
|
||||||
|
have last reviewed these Terms.</paragraph>
|
||||||
|
</section>
|
||||||
|
<section ids="services" names="services">
|
||||||
|
<title>Services</title>
|
||||||
|
<paragraph>We will try to transfer funds that we hold in escrow for our users to any
|
||||||
|
legal recipient to the best of our ability and within the limitations of the
|
||||||
|
law and our implementation. However, the Services offered today are highly
|
||||||
|
experimental and the set of recipients of funds is severely restricted. The
|
||||||
|
Taler Wallet can be loaded by exchanging fiat currencies against electronic
|
||||||
|
coins. We are providing this exchange service. Once your Taler Wallet is
|
||||||
|
loaded with electronic coins they can be spent for purchases if the seller is
|
||||||
|
accepting Taler as a means of payment. We are not guaranteeing that any seller
|
||||||
|
is accepting Taler at all or a particular seller. The seller or recipient of
|
||||||
|
deposits of electronic coins must specify the target account, as per the
|
||||||
|
design of the Taler protocol. They are responsible for following the protocol
|
||||||
|
and specifying the correct bank account, and are solely liable for any losses
|
||||||
|
that may arise from specifying the wrong account. We will allow the government
|
||||||
|
to link wire transfers to the underlying contract hash. It is the
|
||||||
|
responsibility of recipients to preserve the full contracts and to pay
|
||||||
|
whatever taxes and charges may be applicable. Technical issues may lead to
|
||||||
|
situations where we are unable to make transfers at all or lead to incorrect
|
||||||
|
transfers that cannot be reversed. We will only refuse to execute transfers if
|
||||||
|
the transfers are prohibited by a competent legal authority and we are ordered
|
||||||
|
to do so.</paragraph>
|
||||||
|
</section>
|
||||||
|
<section ids="fees" names="fees">
|
||||||
|
<title>Fees</title>
|
||||||
|
<paragraph>You agree to pay the fees for exchanges and withdrawals completed via the
|
||||||
|
Taler Wallet (“Fees”) as defined by us, which we may change from time to
|
||||||
|
time. With the exception of wire transfer fees, Taler transaction fees are set
|
||||||
|
for any electronic coin at the time of withdrawal and fixed throughout the
|
||||||
|
validity period of the respective electronic coin. Your wallet should obtain
|
||||||
|
and display applicable fees when withdrawing funds. Fees for coins obtained as
|
||||||
|
change may differ from the fees applicable to the original coin. Wire transfer
|
||||||
|
fees that are independent from electronic coins may change annually. You
|
||||||
|
authorize us to charge or deduct applicable fees owed in connection with
|
||||||
|
deposits, exchanges and withdrawals following the rules of the Taler protocol.
|
||||||
|
We reserve the right to provide different types of rewards to users either in
|
||||||
|
the form of discount for our Services or in any other form at our discretion
|
||||||
|
and without prior notice to you.</paragraph>
|
||||||
|
</section>
|
||||||
|
<section ids="eligibility" names="eligibility">
|
||||||
|
<title>Eligibility</title>
|
||||||
|
<paragraph>To be eligible to use our Services, you must be able to form legally binding
|
||||||
|
contracts or have the permission of your legal guardian. By using our
|
||||||
|
Services, you represent and warrant that you meet all eligibility requirements
|
||||||
|
that we outline in these Terms.</paragraph>
|
||||||
|
</section>
|
||||||
|
<section ids="financial-self-responsibility" names="financial\ self-responsibility">
|
||||||
|
<title>Financial self-responsibility</title>
|
||||||
|
<paragraph>You will be responsible for maintaining the availability, integrity and
|
||||||
|
confidentiality of the data stored in your wallet. When you setup a Taler
|
||||||
|
Wallet, you are strongly advised to follow the precautionary measures offered
|
||||||
|
by the software to minimize the chances to losse access to or control over
|
||||||
|
your Wallet data. We will not be liable for any loss or damage arising from
|
||||||
|
your failure to comply with this paragraph.</paragraph>
|
||||||
|
</section>
|
||||||
|
<section ids="copyrights-and-trademarks" names="copyrights\ and\ trademarks">
|
||||||
|
<title>Copyrights and trademarks</title>
|
||||||
|
<paragraph>The Taler Wallet is released under the terms of the GNU General Public License
|
||||||
|
(GNU GPL). You have the right to access, use, and share the Taler Wallet, in
|
||||||
|
modified or unmodified form. However, the GPL is a strong copyleft license,
|
||||||
|
which means that any derivative works must be distributed under the same
|
||||||
|
license terms as the original software. If you have any questions, you should
|
||||||
|
review the GNU GPL’s full terms and conditions at
|
||||||
|
<reference refuri="https://www.gnu.org/licenses/gpl-3.0.en.html">https://www.gnu.org/licenses/gpl-3.0.en.html</reference>. “Taler” itself is a trademark
|
||||||
|
of Taler Systems SA. You are welcome to use the name in relation to processing
|
||||||
|
payments using the Taler protocol, assuming your use is compatible with an
|
||||||
|
official release from the GNU Project that is not older than two years.</paragraph>
|
||||||
|
</section>
|
||||||
|
<section ids="your-use-of-our-services" names="your\ use\ of\ our\ services">
|
||||||
|
<title>Your use of our services</title>
|
||||||
|
<paragraph>When using our Services, you agree to not take any action that intentionally
|
||||||
|
imposes an unreasonable load on our infrastructure. If you find security
|
||||||
|
problems in our Services, you agree to first report them to
|
||||||
|
<reference refuri="mailto:security@taler-systems.com">security@taler-systems.com</reference> and grant us the right to publish your report. We
|
||||||
|
warrant that we will ourselves publicly disclose any issues reported within 3
|
||||||
|
months, and that we will not prosecute anyone reporting security issues if
|
||||||
|
they did not exploit the issue beyond a proof-of-concept, and followed the
|
||||||
|
above responsible disclosure practice.</paragraph>
|
||||||
|
</section>
|
||||||
|
<section ids="limitation-of-liability-disclaimer-of-warranties" names="limitation\ of\ liability\ &\ disclaimer\ of\ warranties">
|
||||||
|
<title>Limitation of liability & disclaimer of warranties</title>
|
||||||
|
<paragraph>You understand and agree that we have no control over, and no duty to take any
|
||||||
|
action regarding: Failures, disruptions, errors, or delays in processing that
|
||||||
|
you may experience while using our Services; The risk of failure of hardware,
|
||||||
|
software, and Internet connections; The risk of malicious software being
|
||||||
|
introduced or found in the software underlying the Taler Wallet; The risk that
|
||||||
|
third parties may obtain unauthorized access to information stored within your
|
||||||
|
Taler Wallet, including, but not limited to your Taler Wallet coins or backup
|
||||||
|
encryption keys. You release us from all liability related to any losses,
|
||||||
|
damages, or claims arising from:</paragraph>
|
||||||
|
<enumerated_list enumtype="loweralpha" prefix="(" suffix=")">
|
||||||
|
<list_item>
|
||||||
|
<paragraph>user error such as forgotten passwords, incorrectly constructed
|
||||||
|
transactions;</paragraph>
|
||||||
|
</list_item>
|
||||||
|
<list_item>
|
||||||
|
<paragraph>server failure or data loss;</paragraph>
|
||||||
|
</list_item>
|
||||||
|
<list_item>
|
||||||
|
<paragraph>unauthorized access to the Taler Wallet application;</paragraph>
|
||||||
|
</list_item>
|
||||||
|
<list_item>
|
||||||
|
<paragraph>bugs or other errors in the Taler Wallet software; and</paragraph>
|
||||||
|
</list_item>
|
||||||
|
<list_item>
|
||||||
|
<paragraph>any unauthorized third party activities, including, but not limited to,
|
||||||
|
the use of viruses, phishing, brute forcing, or other means of attack
|
||||||
|
against the Taler Wallet. We make no representations concerning any
|
||||||
|
Third Party Content contained in or accessed through our Services.</paragraph>
|
||||||
|
</list_item>
|
||||||
|
</enumerated_list>
|
||||||
|
<paragraph>Any other terms, conditions, warranties, or representations associated with
|
||||||
|
such content, are solely between you and such organizations and/or
|
||||||
|
individuals.</paragraph>
|
||||||
|
</section>
|
||||||
|
<section ids="limitation-of-liability" names="limitation\ of\ liability">
|
||||||
|
<title>Limitation of liability</title>
|
||||||
|
<paragraph>To the fullest extent permitted by applicable law, in no event will we or any
|
||||||
|
of our officers, directors, representatives, agents, servants, counsel,
|
||||||
|
employees, consultants, lawyers, and other personnel authorized to act,
|
||||||
|
acting, or purporting to act on our behalf (collectively the “Taler Parties”)
|
||||||
|
be liable to you under contract, tort, strict liability, negligence, or any
|
||||||
|
other legal or equitable theory, for:</paragraph>
|
||||||
|
<enumerated_list enumtype="loweralpha" prefix="(" suffix=")">
|
||||||
|
<list_item>
|
||||||
|
<paragraph>any lost profits, data loss, cost of procurement of substitute goods or
|
||||||
|
services, or direct, indirect, incidental, special, punitive, compensatory,
|
||||||
|
or consequential damages of any kind whatsoever resulting from:</paragraph>
|
||||||
|
</list_item>
|
||||||
|
</enumerated_list>
|
||||||
|
<block_quote>
|
||||||
|
<enumerated_list enumtype="lowerroman" prefix="(" suffix=")">
|
||||||
|
<list_item>
|
||||||
|
<paragraph>your use of, or conduct in connection with, our services;</paragraph>
|
||||||
|
</list_item>
|
||||||
|
<list_item>
|
||||||
|
<paragraph>any unauthorized use of your wallet and/or private key due to your
|
||||||
|
failure to maintain the confidentiality of your wallet;</paragraph>
|
||||||
|
</list_item>
|
||||||
|
<list_item>
|
||||||
|
<paragraph>any interruption or cessation of transmission to or from the services; or</paragraph>
|
||||||
|
</list_item>
|
||||||
|
<list_item>
|
||||||
|
<paragraph>any bugs, viruses, trojan horses, or the like that are found in the Taler
|
||||||
|
Wallet software or that may be transmitted to or through our services by
|
||||||
|
any third party (regardless of the source of origination), or</paragraph>
|
||||||
|
</list_item>
|
||||||
|
</enumerated_list>
|
||||||
|
</block_quote>
|
||||||
|
<enumerated_list enumtype="loweralpha" prefix="(" start="2" suffix=")">
|
||||||
|
<list_item>
|
||||||
|
<paragraph>any direct damages.</paragraph>
|
||||||
|
</list_item>
|
||||||
|
</enumerated_list>
|
||||||
|
<paragraph>These limitations apply regardless of legal theory, whether based on tort,
|
||||||
|
strict liability, breach of contract, breach of warranty, or any other legal
|
||||||
|
theory, and whether or not we were advised of the possibility of such
|
||||||
|
damages. Some jurisdictions do not allow the exclusion or limitation of
|
||||||
|
liability for consequential or incidental damages, so the above limitation may
|
||||||
|
not apply to you.</paragraph>
|
||||||
|
</section>
|
||||||
|
<section ids="warranty-disclaimer" names="warranty\ disclaimer">
|
||||||
|
<title>Warranty disclaimer</title>
|
||||||
|
<paragraph>Our services are provided “as is” and without warranty of any kind. To the
|
||||||
|
maximum extent permitted by law, we disclaim all representations and
|
||||||
|
warranties, express or implied, relating to the services and underlying
|
||||||
|
software or any content on the services, whether provided or owned by us or by
|
||||||
|
any third party, including without limitation, warranties of merchantability,
|
||||||
|
fitness for a particular purpose, title, non-infringement, freedom from
|
||||||
|
computer virus, and any implied warranties arising from course of dealing,
|
||||||
|
course of performance, or usage in trade, all of which are expressly
|
||||||
|
disclaimed. In addition, we do not represent or warrant that the content
|
||||||
|
accessible via the services is accurate, complete, available, current, free of
|
||||||
|
viruses or other harmful components, or that the results of using the services
|
||||||
|
will meet your requirements. Some states do not allow the disclaimer of
|
||||||
|
implied warranties, so the foregoing disclaimers may not apply to you. This
|
||||||
|
paragraph gives you specific legal rights and you may also have other legal
|
||||||
|
rights that vary from state to state.</paragraph>
|
||||||
|
</section>
|
||||||
|
<section ids="indemnity" names="indemnity">
|
||||||
|
<title>Indemnity</title>
|
||||||
|
<paragraph>To the extent permitted by applicable law, you agree to defend, indemnify, and
|
||||||
|
hold harmless the Taler Parties from and against any and all claims, damages,
|
||||||
|
obligations, losses, liabilities, costs or debt, and expenses (including, but
|
||||||
|
not limited to, attorney’s fees) arising from: (a) your use of and access to
|
||||||
|
the Services; (b) any feedback or submissions you provide to us concerning the
|
||||||
|
Taler Wallet; (c) your violation of any term of this Agreement; or (d) your
|
||||||
|
violation of any law, rule, or regulation, or the rights of any third party.</paragraph>
|
||||||
|
</section>
|
||||||
|
<section ids="time-limitation-on-claims" names="time\ limitation\ on\ claims">
|
||||||
|
<title>Time limitation on claims</title>
|
||||||
|
<paragraph>You agree that any claim you may have arising out of or related to your
|
||||||
|
relationship with us must be filed within one year after such claim arises,
|
||||||
|
otherwise, your claim in permanently barred.</paragraph>
|
||||||
|
</section>
|
||||||
|
<section ids="governing-law" names="governing\ law">
|
||||||
|
<title>Governing law</title>
|
||||||
|
<paragraph>No matter where you’re located, the laws of Switzerland will govern these
|
||||||
|
Terms. If any provisions of these Terms are inconsistent with any applicable
|
||||||
|
law, those provisions will be superseded or modified only to the extent such
|
||||||
|
provisions are inconsistent. The parties agree to submit to the ordinary
|
||||||
|
courts in Zurich, Switzerland for exclusive jurisdiction of any dispute
|
||||||
|
arising out of or related to your use of the Services or your breach of these
|
||||||
|
Terms.</paragraph>
|
||||||
|
</section>
|
||||||
|
<section ids="termination" names="termination">
|
||||||
|
<title>Termination</title>
|
||||||
|
<paragraph>In the event of termination concerning your use of our Services, your
|
||||||
|
obligations under this Agreement will still continue.</paragraph>
|
||||||
|
</section>
|
||||||
|
<section ids="discontinuance-of-services" names="discontinuance\ of\ services">
|
||||||
|
<title>Discontinuance of services</title>
|
||||||
|
<paragraph>We may, in our sole discretion and without cost to you, with or without prior
|
||||||
|
notice, and at any time, modify or discontinue, temporarily or permanently,
|
||||||
|
any portion of our Services. We will use the Taler protocol’s provisions to
|
||||||
|
notify Wallets if our Services are to be discontinued. It is your
|
||||||
|
responsibility to ensure that the Taler Wallet is online at least once every
|
||||||
|
three months to observe these notifications. We shall not be held responsible
|
||||||
|
or liable for any loss of funds in the event that we discontinue or depreciate
|
||||||
|
the Services and your Taler Wallet fails to transfer out the coins within a
|
||||||
|
three months notification period.</paragraph>
|
||||||
|
</section>
|
||||||
|
<section ids="no-waiver" names="no\ waiver">
|
||||||
|
<title>No waiver</title>
|
||||||
|
<paragraph>Our failure to exercise or delay in exercising any right, power, or privilege
|
||||||
|
under this Agreement shall not operate as a waiver; nor shall any single or
|
||||||
|
partial exercise of any right, power, or privilege preclude any other or
|
||||||
|
further exercise thereof.</paragraph>
|
||||||
|
</section>
|
||||||
|
<section ids="severability" names="severability">
|
||||||
|
<title>Severability</title>
|
||||||
|
<paragraph>If it turns out that any part of this Agreement is invalid, void, or for any
|
||||||
|
reason unenforceable, that term will be deemed severable and limited or
|
||||||
|
eliminated to the minimum extent necessary.</paragraph>
|
||||||
|
</section>
|
||||||
|
<section ids="force-majeure" names="force\ majeure">
|
||||||
|
<title>Force majeure</title>
|
||||||
|
<paragraph>We shall not be held liable for any delays, failure in performance, or
|
||||||
|
interruptions of service which result directly or indirectly from any cause or
|
||||||
|
condition beyond our reasonable control, including but not limited to: any
|
||||||
|
delay or failure due to any act of God, act of civil or military authorities,
|
||||||
|
act of terrorism, civil disturbance, war, strike or other labor dispute, fire,
|
||||||
|
interruption in telecommunications or Internet services or network provider
|
||||||
|
services, failure of equipment and/or software, other catastrophe, or any
|
||||||
|
other occurrence which is beyond our reasonable control and shall not affect
|
||||||
|
the validity and enforceability of any remaining provisions.</paragraph>
|
||||||
|
</section>
|
||||||
|
<section ids="assignment" names="assignment">
|
||||||
|
<title>Assignment</title>
|
||||||
|
<paragraph>You agree that we may assign any of our rights and/or transfer, sub-contract,
|
||||||
|
or delegate any of our obligations under these Terms.</paragraph>
|
||||||
|
</section>
|
||||||
|
<section ids="entire-agreement" names="entire\ agreement">
|
||||||
|
<title>Entire agreement</title>
|
||||||
|
<paragraph>This Agreement sets forth the entire understanding and agreement as to the
|
||||||
|
subject matter hereof and supersedes any and all prior discussions,
|
||||||
|
agreements, and understandings of any kind (including, without limitation, any
|
||||||
|
prior versions of this Agreement) and every nature between us. Except as
|
||||||
|
provided for above, any modification to this Agreement must be in writing and
|
||||||
|
must be signed by both parties.</paragraph>
|
||||||
|
</section>
|
||||||
|
<section ids="questions-or-comments" names="questions\ or\ comments">
|
||||||
|
<title>Questions or comments</title>
|
||||||
|
<paragraph>We welcome comments, questions, concerns, or suggestions. Please send us a
|
||||||
|
message on our contact page at <reference refuri="mailto:legal@taler-systems.com">legal@taler-systems.com</reference>.</paragraph>
|
||||||
|
</section>
|
||||||
|
</section>
|
||||||
|
</document>
|
||||||
|
`;
|
||||||
|
|
||||||
|
export const termsPdf = `
|
||||||
|
%PDF-1.2
|
||||||
|
9 0 obj << >>
|
||||||
|
stream
|
||||||
|
BT/ 9 Tf(This is the Exchange TERMS OF SERVICE)' ET
|
||||||
|
endstream
|
||||||
|
endobj
|
||||||
|
4 0 obj << /Type /Page /Parent 5 0 R /Contents 9 0 R >> endobj
|
||||||
|
5 0 obj << /Kids [4 0 R ] /Count 1 /Type /Pages /MediaBox [ 0 0 180 20 ] >> endobj
|
||||||
|
3 0 obj << /Pages 5 0 R /Type /Catalog >> endobj
|
||||||
|
trailer
|
||||||
|
<< /Root 3 0 R >>
|
||||||
|
%%EOF
|
||||||
|
`;
|
||||||
|
|
@ -71,6 +71,11 @@ export function BalanceView({
|
|||||||
<Linker pageName="/welcome">help</Linker> getting started?
|
<Linker pageName="/welcome">help</Linker> getting started?
|
||||||
</i18n.Translate>
|
</i18n.Translate>
|
||||||
</p>
|
</p>
|
||||||
|
<footer style={{ justifyContent: "space-around" }}>
|
||||||
|
<ButtonPrimary onClick={goToWalletManualWithdraw}>
|
||||||
|
Withdraw
|
||||||
|
</ButtonPrimary>
|
||||||
|
</footer>
|
||||||
</Fragment>
|
</Fragment>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
@ -30,13 +30,8 @@ export default {
|
|||||||
},
|
},
|
||||||
};
|
};
|
||||||
|
|
||||||
export const AllOff = createExample(TestedComponent, {
|
export const AllOff = createExample(TestedComponent, {});
|
||||||
deviceName: "this-is-the-device-name",
|
|
||||||
setDeviceName: () => Promise.resolve(),
|
|
||||||
});
|
|
||||||
|
|
||||||
export const OneChecked = createExample(TestedComponent, {
|
export const OneChecked = createExample(TestedComponent, {
|
||||||
deviceName: "this-is-the-device-name",
|
|
||||||
permissionsEnabled: true,
|
permissionsEnabled: true,
|
||||||
setDeviceName: () => Promise.resolve(),
|
|
||||||
});
|
});
|
||||||
|
@ -14,36 +14,18 @@
|
|||||||
TALER; see the file COPYING. If not, see <http://www.gnu.org/licenses/>
|
TALER; see the file COPYING. If not, see <http://www.gnu.org/licenses/>
|
||||||
*/
|
*/
|
||||||
|
|
||||||
import { ExchangeListItem, i18n } from "@gnu-taler/taler-util";
|
import { i18n } from "@gnu-taler/taler-util";
|
||||||
import { Fragment, h, VNode } from "preact";
|
import { Fragment, h, VNode } from "preact";
|
||||||
import { Checkbox } from "../components/Checkbox";
|
import { Checkbox } from "../components/Checkbox";
|
||||||
import { ButtonPrimary } from "../components/styled";
|
|
||||||
import { useDevContext } from "../context/devContext";
|
import { useDevContext } from "../context/devContext";
|
||||||
import { useAsyncAsHook } from "../hooks/useAsyncAsHook";
|
|
||||||
import { useBackupDeviceName } from "../hooks/useBackupDeviceName";
|
|
||||||
import { useExtendedPermissions } from "../hooks/useExtendedPermissions";
|
import { useExtendedPermissions } from "../hooks/useExtendedPermissions";
|
||||||
import { useLang } from "../hooks/useLang";
|
|
||||||
// import { strings as messages } from "../i18n/strings";
|
|
||||||
import * as wxApi from "../wxApi";
|
|
||||||
|
|
||||||
export function SettingsPage(): VNode {
|
export function SettingsPage(): VNode {
|
||||||
const [permissionsEnabled, togglePermissions] = useExtendedPermissions();
|
const [permissionsEnabled, togglePermissions] = useExtendedPermissions();
|
||||||
const { devMode, toggleDevMode } = useDevContext();
|
const { devMode, toggleDevMode } = useDevContext();
|
||||||
const { name, update } = useBackupDeviceName();
|
|
||||||
const [lang, changeLang] = useLang();
|
|
||||||
const exchangesHook = useAsyncAsHook(wxApi.listExchanges);
|
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<SettingsView
|
<SettingsView
|
||||||
lang={lang}
|
|
||||||
changeLang={changeLang}
|
|
||||||
knownExchanges={
|
|
||||||
!exchangesHook || exchangesHook.hasError
|
|
||||||
? []
|
|
||||||
: exchangesHook.response.exchanges
|
|
||||||
}
|
|
||||||
deviceName={name}
|
|
||||||
setDeviceName={update}
|
|
||||||
permissionsEnabled={permissionsEnabled}
|
permissionsEnabled={permissionsEnabled}
|
||||||
togglePermissions={togglePermissions}
|
togglePermissions={togglePermissions}
|
||||||
developerMode={devMode}
|
developerMode={devMode}
|
||||||
@ -53,36 +35,13 @@ export function SettingsPage(): VNode {
|
|||||||
}
|
}
|
||||||
|
|
||||||
export interface ViewProps {
|
export interface ViewProps {
|
||||||
lang: string;
|
|
||||||
changeLang: (s: string) => void;
|
|
||||||
deviceName: string;
|
|
||||||
setDeviceName: (s: string) => Promise<void>;
|
|
||||||
permissionsEnabled: boolean;
|
permissionsEnabled: boolean;
|
||||||
togglePermissions: () => void;
|
togglePermissions: () => void;
|
||||||
developerMode: boolean;
|
developerMode: boolean;
|
||||||
toggleDeveloperMode: () => void;
|
toggleDeveloperMode: () => void;
|
||||||
knownExchanges: Array<ExchangeListItem>;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// type LangsNames = {
|
|
||||||
// [P in keyof typeof messages]: string;
|
|
||||||
// };
|
|
||||||
|
|
||||||
// const names: LangsNames = {
|
|
||||||
// es: "Español [es]",
|
|
||||||
// en: "English [en]",
|
|
||||||
// fr: "Français [fr]",
|
|
||||||
// de: "Deutsch [de]",
|
|
||||||
// sv: "Svenska [sv]",
|
|
||||||
// it: "Italiano [it]",
|
|
||||||
// };
|
|
||||||
|
|
||||||
export function SettingsView({
|
export function SettingsView({
|
||||||
knownExchanges,
|
|
||||||
// lang,
|
|
||||||
// changeLang,
|
|
||||||
// deviceName,
|
|
||||||
// setDeviceName,
|
|
||||||
permissionsEnabled,
|
permissionsEnabled,
|
||||||
togglePermissions,
|
togglePermissions,
|
||||||
developerMode,
|
developerMode,
|
||||||
@ -91,45 +50,6 @@ export function SettingsView({
|
|||||||
return (
|
return (
|
||||||
<Fragment>
|
<Fragment>
|
||||||
<section>
|
<section>
|
||||||
<h2>
|
|
||||||
<i18n.Translate>Known exchanges</i18n.Translate>
|
|
||||||
</h2>
|
|
||||||
{!knownExchanges || !knownExchanges.length ? (
|
|
||||||
<div>No exchange yet!</div>
|
|
||||||
) : (
|
|
||||||
<Fragment>
|
|
||||||
<table>
|
|
||||||
{knownExchanges.map((e, idx) => (
|
|
||||||
<tr key={idx}>
|
|
||||||
<td>{e.currency}</td>
|
|
||||||
<td>
|
|
||||||
<a href={e.exchangeBaseUrl}>{e.exchangeBaseUrl}</a>
|
|
||||||
</td>
|
|
||||||
</tr>
|
|
||||||
))}
|
|
||||||
</table>
|
|
||||||
</Fragment>
|
|
||||||
)}
|
|
||||||
<div style={{ display: "flex", justifyContent: "space-between" }}>
|
|
||||||
<div />
|
|
||||||
<ButtonPrimary>Manage exchange</ButtonPrimary>
|
|
||||||
</div>
|
|
||||||
{/* <h2><i18n.Translate>Wallet</i18n.Translate></h2> */}
|
|
||||||
{/* <SelectList
|
|
||||||
value={lang}
|
|
||||||
onChange={changeLang}
|
|
||||||
name="lang"
|
|
||||||
list={names}
|
|
||||||
label={i18n.str`Language`}
|
|
||||||
description="(Choose your preferred lang)"
|
|
||||||
/>
|
|
||||||
<EditableText
|
|
||||||
value={deviceName}
|
|
||||||
onChange={setDeviceName}
|
|
||||||
name="device-id"
|
|
||||||
label={i18n.str`Device name`}
|
|
||||||
description="(This is how you will recognize the wallet in the backup provider)"
|
|
||||||
/> */}
|
|
||||||
<h2>
|
<h2>
|
||||||
<i18n.Translate>Permissions</i18n.Translate>
|
<i18n.Translate>Permissions</i18n.Translate>
|
||||||
</h2>
|
</h2>
|
||||||
|
@ -38,6 +38,7 @@ import { ProviderAddPage } from "./wallet/ProviderAddPage";
|
|||||||
import { ProviderDetailPage } from "./wallet/ProviderDetailPage";
|
import { ProviderDetailPage } from "./wallet/ProviderDetailPage";
|
||||||
import { SettingsPage } from "./popup/Settings";
|
import { SettingsPage } from "./popup/Settings";
|
||||||
import { TalerActionFound } from "./popup/TalerActionFound";
|
import { TalerActionFound } from "./popup/TalerActionFound";
|
||||||
|
import { ExchangeAddPage } from "./wallet/ExchangeAddPage";
|
||||||
|
|
||||||
function main(): void {
|
function main(): void {
|
||||||
try {
|
try {
|
||||||
@ -127,6 +128,15 @@ function Application() {
|
|||||||
route(Pages.backup);
|
route(Pages.backup);
|
||||||
}}
|
}}
|
||||||
/>
|
/>
|
||||||
|
|
||||||
|
<Route
|
||||||
|
path={Pages.exchange_add}
|
||||||
|
component={ExchangeAddPage}
|
||||||
|
onBack={() => {
|
||||||
|
route(Pages.balance);
|
||||||
|
}}
|
||||||
|
/>
|
||||||
|
|
||||||
<Route default component={Redirect} to={Pages.balance} />
|
<Route default component={Redirect} to={Pages.balance} />
|
||||||
</Router>
|
</Router>
|
||||||
</PopupBox>
|
</PopupBox>
|
||||||
|
162
packages/taler-wallet-webextension/src/utils/index.ts
Normal file
162
packages/taler-wallet-webextension/src/utils/index.ts
Normal file
@ -0,0 +1,162 @@
|
|||||||
|
/*
|
||||||
|
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/>
|
||||||
|
*/
|
||||||
|
|
||||||
|
import { AmountJson, Amounts, GetExchangeTosResult } from "@gnu-taler/taler-util";
|
||||||
|
|
||||||
|
|
||||||
|
function getJsonIfOk(r: Response): Promise<any> {
|
||||||
|
if (r.ok) {
|
||||||
|
return r.json();
|
||||||
|
}
|
||||||
|
|
||||||
|
if (r.status >= 400 && r.status < 500) {
|
||||||
|
throw new Error(`URL may not be right: (${r.status}) ${r.statusText}`);
|
||||||
|
}
|
||||||
|
|
||||||
|
throw new Error(
|
||||||
|
`Try another server: (${r.status}) ${r.statusText || "internal server error"
|
||||||
|
}`,
|
||||||
|
);
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
export async function queryToSlashConfig<T>(
|
||||||
|
url: string,
|
||||||
|
): Promise<T> {
|
||||||
|
return fetch(new URL("config", url).href)
|
||||||
|
.catch(() => {
|
||||||
|
throw new Error(`Network error`);
|
||||||
|
})
|
||||||
|
.then(getJsonIfOk);
|
||||||
|
}
|
||||||
|
|
||||||
|
export async function queryToSlashKeys<T>(
|
||||||
|
url: string,
|
||||||
|
): Promise<T> {
|
||||||
|
return fetch(new URL("keys", url).href)
|
||||||
|
.catch(() => {
|
||||||
|
throw new Error(`Network error`);
|
||||||
|
})
|
||||||
|
.then(getJsonIfOk);
|
||||||
|
}
|
||||||
|
|
||||||
|
export function buildTermsOfServiceState(tos: GetExchangeTosResult): TermsState {
|
||||||
|
|
||||||
|
const content: TermsDocument | undefined = parseTermsOfServiceContent(
|
||||||
|
tos.contentType,
|
||||||
|
tos.content,
|
||||||
|
);
|
||||||
|
|
||||||
|
const status: TermsStatus = !content
|
||||||
|
? "notfound"
|
||||||
|
: !tos.acceptedEtag
|
||||||
|
? "new"
|
||||||
|
: tos.acceptedEtag !== tos.currentEtag
|
||||||
|
? "changed"
|
||||||
|
: "accepted";
|
||||||
|
|
||||||
|
return { content, status, version: tos.currentEtag }
|
||||||
|
}
|
||||||
|
|
||||||
|
function parseTermsOfServiceContent(
|
||||||
|
type: string,
|
||||||
|
text: string,
|
||||||
|
): TermsDocument | undefined {
|
||||||
|
if (type === "text/xml") {
|
||||||
|
try {
|
||||||
|
const document = new DOMParser().parseFromString(text, "text/xml");
|
||||||
|
return { type: "xml", document };
|
||||||
|
} catch (e) {
|
||||||
|
console.log(e);
|
||||||
|
}
|
||||||
|
} else if (type === "text/html") {
|
||||||
|
try {
|
||||||
|
const href = new URL(text);
|
||||||
|
return { type: "html", href };
|
||||||
|
} catch (e) {
|
||||||
|
console.log(e);
|
||||||
|
}
|
||||||
|
} else if (type === "text/json") {
|
||||||
|
try {
|
||||||
|
const data = JSON.parse(text);
|
||||||
|
return { type: "json", data };
|
||||||
|
} catch (e) {
|
||||||
|
console.log(e);
|
||||||
|
}
|
||||||
|
} else if (type === "text/pdf") {
|
||||||
|
try {
|
||||||
|
const location = new URL(text);
|
||||||
|
return { type: "pdf", location };
|
||||||
|
} catch (e) {
|
||||||
|
console.log(e);
|
||||||
|
}
|
||||||
|
} else if (type === "text/plain") {
|
||||||
|
try {
|
||||||
|
const content = text;
|
||||||
|
return { type: "plain", content };
|
||||||
|
} catch (e) {
|
||||||
|
console.log(e);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return undefined;
|
||||||
|
}
|
||||||
|
|
||||||
|
export type TermsState = {
|
||||||
|
content: TermsDocument | undefined;
|
||||||
|
status: TermsStatus;
|
||||||
|
version: string;
|
||||||
|
};
|
||||||
|
|
||||||
|
type TermsStatus = "new" | "accepted" | "changed" | "notfound";
|
||||||
|
|
||||||
|
type TermsDocument =
|
||||||
|
| TermsDocumentXml
|
||||||
|
| TermsDocumentHtml
|
||||||
|
| TermsDocumentPlain
|
||||||
|
| TermsDocumentJson
|
||||||
|
| TermsDocumentPdf;
|
||||||
|
|
||||||
|
interface TermsDocumentXml {
|
||||||
|
type: "xml";
|
||||||
|
document: Document;
|
||||||
|
}
|
||||||
|
|
||||||
|
interface TermsDocumentHtml {
|
||||||
|
type: "html";
|
||||||
|
href: URL;
|
||||||
|
}
|
||||||
|
|
||||||
|
interface TermsDocumentPlain {
|
||||||
|
type: "plain";
|
||||||
|
content: string;
|
||||||
|
}
|
||||||
|
|
||||||
|
interface TermsDocumentJson {
|
||||||
|
type: "json";
|
||||||
|
data: any;
|
||||||
|
}
|
||||||
|
|
||||||
|
interface TermsDocumentPdf {
|
||||||
|
type: "pdf";
|
||||||
|
location: URL;
|
||||||
|
}
|
||||||
|
|
||||||
|
export function amountToString(text: AmountJson): string {
|
||||||
|
const aj = Amounts.jsonifyAmount(text);
|
||||||
|
const amount = Amounts.stringifyValue(aj);
|
||||||
|
return `${amount} ${aj.currency}`;
|
||||||
|
}
|
||||||
|
|
@ -17,7 +17,7 @@
|
|||||||
import { BalancesResponse, i18n } from "@gnu-taler/taler-util";
|
import { BalancesResponse, i18n } from "@gnu-taler/taler-util";
|
||||||
import { Fragment, h, VNode } from "preact";
|
import { Fragment, h, VNode } from "preact";
|
||||||
import { BalanceTable } from "../components/BalanceTable";
|
import { BalanceTable } from "../components/BalanceTable";
|
||||||
import { ButtonPrimary, ErrorBox } from "../components/styled/index";
|
import { ButtonPrimary, Centered, ErrorBox } from "../components/styled/index";
|
||||||
import { HookResponse, useAsyncAsHook } from "../hooks/useAsyncAsHook";
|
import { HookResponse, useAsyncAsHook } from "../hooks/useAsyncAsHook";
|
||||||
import { PageLink } from "../renderHtml";
|
import { PageLink } from "../renderHtml";
|
||||||
import * as wxApi from "../wxApi";
|
import * as wxApi from "../wxApi";
|
||||||
@ -66,10 +66,17 @@ export function BalanceView({
|
|||||||
if (balance.response.balances.length === 0) {
|
if (balance.response.balances.length === 0) {
|
||||||
return (
|
return (
|
||||||
<p>
|
<p>
|
||||||
<i18n.Translate>
|
<Centered style={{ marginTop: 100 }}>
|
||||||
You have no balance to show. Need some{" "}
|
<i18n.Translate>
|
||||||
<Linker pageName="/welcome">help</Linker> getting started?
|
You have no balance to show. Need some{" "}
|
||||||
</i18n.Translate>
|
<Linker pageName="/welcome">help</Linker> getting started?
|
||||||
|
</i18n.Translate>
|
||||||
|
<div>
|
||||||
|
<ButtonPrimary onClick={goToWalletManualWithdraw}>
|
||||||
|
Withdraw
|
||||||
|
</ButtonPrimary>
|
||||||
|
</div>
|
||||||
|
</Centered>
|
||||||
</p>
|
</p>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
@ -21,6 +21,7 @@
|
|||||||
|
|
||||||
import { AmountJson, Amounts, i18n } from "@gnu-taler/taler-util";
|
import { AmountJson, Amounts, i18n } from "@gnu-taler/taler-util";
|
||||||
import { Fragment, h, VNode } from "preact";
|
import { Fragment, h, VNode } from "preact";
|
||||||
|
import { route } from "preact-router";
|
||||||
import { useState } from "preact/hooks";
|
import { useState } from "preact/hooks";
|
||||||
import { ErrorMessage } from "../components/ErrorMessage";
|
import { ErrorMessage } from "../components/ErrorMessage";
|
||||||
import { SelectList } from "../components/SelectList";
|
import { SelectList } from "../components/SelectList";
|
||||||
@ -32,7 +33,9 @@ import {
|
|||||||
Input,
|
Input,
|
||||||
InputWithLabel,
|
InputWithLabel,
|
||||||
LightText,
|
LightText,
|
||||||
|
LinkPrimary,
|
||||||
} from "../components/styled";
|
} from "../components/styled";
|
||||||
|
import { Pages } from "../NavigationBar";
|
||||||
|
|
||||||
export interface Props {
|
export interface Props {
|
||||||
error: string | undefined;
|
error: string | undefined;
|
||||||
@ -87,12 +90,7 @@ export function CreateManualWithdraw({
|
|||||||
return (
|
return (
|
||||||
<Centered style={{ marginTop: 100 }}>
|
<Centered style={{ marginTop: 100 }}>
|
||||||
<BoldLight>No exchange configured</BoldLight>
|
<BoldLight>No exchange configured</BoldLight>
|
||||||
<ButtonSuccess
|
<ButtonSuccess onClick={() => route(Pages.exchange_add)}>
|
||||||
//FIXME: add exchange feature
|
|
||||||
onClick={() => {
|
|
||||||
null;
|
|
||||||
}}
|
|
||||||
>
|
|
||||||
<i18n.Translate>Add exchange</i18n.Translate>
|
<i18n.Translate>Add exchange</i18n.Translate>
|
||||||
</ButtonSuccess>
|
</ButtonSuccess>
|
||||||
</Centered>
|
</Centered>
|
||||||
@ -108,8 +106,9 @@ export function CreateManualWithdraw({
|
|||||||
/>
|
/>
|
||||||
<h2>Manual Withdrawal</h2>
|
<h2>Manual Withdrawal</h2>
|
||||||
<LightText>
|
<LightText>
|
||||||
Choose a exchange to create a reserve and then fill the reserve to
|
Choose a exchange from where the coins will be withdrawn. The exchange
|
||||||
withdraw the coins
|
will send the coins to this wallet after receiving a wire transfer
|
||||||
|
with the correct subject.
|
||||||
</LightText>
|
</LightText>
|
||||||
<p>
|
<p>
|
||||||
<Input>
|
<Input>
|
||||||
@ -130,11 +129,14 @@ export function CreateManualWithdraw({
|
|||||||
onChange={changeExchange}
|
onChange={changeExchange}
|
||||||
/>
|
/>
|
||||||
</Input>
|
</Input>
|
||||||
{/* <p style={{ display: "flex", justifyContent: "right" }}>
|
<div style={{ display: "flex", justifyContent: "space-between" }}>
|
||||||
<a href="" style={{ marginLeft: "auto" }}>
|
<LinkPrimary
|
||||||
Add new exchange
|
onClick={() => route(Pages.exchange_add)}
|
||||||
</a>
|
style={{ marginLeft: "auto" }}
|
||||||
</p> */}
|
>
|
||||||
|
<i18n.Translate>Add exchange</i18n.Translate>
|
||||||
|
</LinkPrimary>
|
||||||
|
</div>
|
||||||
{currency && (
|
{currency && (
|
||||||
<InputWithLabel invalid={!!amount && !parsedAmount}>
|
<InputWithLabel invalid={!!amount && !parsedAmount}>
|
||||||
<label>Amount</label>
|
<label>Amount</label>
|
||||||
|
@ -0,0 +1,67 @@
|
|||||||
|
/*
|
||||||
|
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 { termsXml } from "../cta/termsExample";
|
||||||
|
import { createExample } from "../test-utils";
|
||||||
|
import { View as TestedComponent } from "./ExchangeAddConfirm";
|
||||||
|
|
||||||
|
export default {
|
||||||
|
title: "wallet/exchange add/confirm",
|
||||||
|
component: TestedComponent,
|
||||||
|
argTypes: {
|
||||||
|
onRetry: { action: "onRetry" },
|
||||||
|
onDelete: { action: "onDelete" },
|
||||||
|
onBack: { action: "onBack" },
|
||||||
|
},
|
||||||
|
};
|
||||||
|
|
||||||
|
export const TermsNotFound = createExample(TestedComponent, {
|
||||||
|
url: "https://exchange.demo.taler.net/",
|
||||||
|
terms: {
|
||||||
|
status: "notfound",
|
||||||
|
version: "1",
|
||||||
|
content: undefined,
|
||||||
|
},
|
||||||
|
onAccept: async () => undefined,
|
||||||
|
});
|
||||||
|
|
||||||
|
export const NewTerms = createExample(TestedComponent, {
|
||||||
|
url: "https://exchange.demo.taler.net/",
|
||||||
|
terms: {
|
||||||
|
status: "new",
|
||||||
|
version: "1",
|
||||||
|
content: undefined,
|
||||||
|
},
|
||||||
|
onAccept: async () => undefined,
|
||||||
|
});
|
||||||
|
|
||||||
|
export const TermsChanged = createExample(TestedComponent, {
|
||||||
|
url: "https://exchange.demo.taler.net/",
|
||||||
|
terms: {
|
||||||
|
status: "changed",
|
||||||
|
version: "1",
|
||||||
|
content: {
|
||||||
|
type: "xml",
|
||||||
|
document: new DOMParser().parseFromString(termsXml, "text/xml"),
|
||||||
|
},
|
||||||
|
},
|
||||||
|
onAccept: async () => undefined,
|
||||||
|
});
|
@ -0,0 +1,152 @@
|
|||||||
|
import { i18n } from "@gnu-taler/taler-util";
|
||||||
|
import { Fragment, h, VNode } from "preact";
|
||||||
|
import { useState } from "preact/hooks";
|
||||||
|
import {
|
||||||
|
Button,
|
||||||
|
ButtonSuccess,
|
||||||
|
ButtonWarning,
|
||||||
|
WarningBox,
|
||||||
|
} from "../components/styled/index";
|
||||||
|
import { TermsOfServiceSection } from "../cta/TermsOfServiceSection";
|
||||||
|
import { useAsyncAsHook } from "../hooks/useAsyncAsHook";
|
||||||
|
import { buildTermsOfServiceState, TermsState } from "../utils";
|
||||||
|
import * as wxApi from "../wxApi";
|
||||||
|
|
||||||
|
export interface Props {
|
||||||
|
url: string;
|
||||||
|
onCancel: () => void;
|
||||||
|
onConfirm: () => void;
|
||||||
|
}
|
||||||
|
|
||||||
|
export function ExchangeAddConfirmPage({
|
||||||
|
url,
|
||||||
|
onCancel,
|
||||||
|
onConfirm,
|
||||||
|
}: Props): VNode {
|
||||||
|
const detailsHook = useAsyncAsHook(async () => {
|
||||||
|
const tos = await wxApi.getExchangeTos(url, ["text/xml"]);
|
||||||
|
|
||||||
|
const tosState = buildTermsOfServiceState(tos);
|
||||||
|
|
||||||
|
return { tos: tosState };
|
||||||
|
});
|
||||||
|
|
||||||
|
const termsNotFound: TermsState = {
|
||||||
|
status: "notfound",
|
||||||
|
version: "",
|
||||||
|
content: undefined,
|
||||||
|
};
|
||||||
|
const terms = !detailsHook
|
||||||
|
? undefined
|
||||||
|
: detailsHook.hasError
|
||||||
|
? termsNotFound
|
||||||
|
: detailsHook.response.tos;
|
||||||
|
|
||||||
|
// const [errorAccepting, setErrorAccepting] = useState<string | undefined>(
|
||||||
|
// undefined,
|
||||||
|
// );
|
||||||
|
|
||||||
|
const onAccept = async (): Promise<void> => {
|
||||||
|
if (!terms) return;
|
||||||
|
try {
|
||||||
|
await wxApi.setExchangeTosAccepted(url, terms.version);
|
||||||
|
} catch (e) {
|
||||||
|
if (e instanceof Error) {
|
||||||
|
// setErrorAccepting(e.message);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
};
|
||||||
|
return (
|
||||||
|
<View
|
||||||
|
url={url}
|
||||||
|
onAccept={onAccept}
|
||||||
|
onCancel={onCancel}
|
||||||
|
onConfirm={onConfirm}
|
||||||
|
terms={terms}
|
||||||
|
/>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
export interface ViewProps {
|
||||||
|
url: string;
|
||||||
|
terms: TermsState | undefined;
|
||||||
|
onAccept: (b: boolean) => Promise<void>;
|
||||||
|
onCancel: () => void;
|
||||||
|
onConfirm: () => void;
|
||||||
|
}
|
||||||
|
|
||||||
|
export function View({
|
||||||
|
url,
|
||||||
|
terms,
|
||||||
|
onAccept: doAccept,
|
||||||
|
onConfirm,
|
||||||
|
onCancel,
|
||||||
|
}: ViewProps): VNode {
|
||||||
|
const needsReview =
|
||||||
|
!terms || terms.status === "changed" || terms.status === "new";
|
||||||
|
const [reviewed, setReviewed] = useState<boolean>(false);
|
||||||
|
|
||||||
|
return (
|
||||||
|
<Fragment>
|
||||||
|
<section>
|
||||||
|
<h1>Review terms of service</h1>
|
||||||
|
<div>
|
||||||
|
Exchange URL:
|
||||||
|
<a href={url} target="_blank" rel="noreferrer">
|
||||||
|
{url}
|
||||||
|
</a>
|
||||||
|
</div>
|
||||||
|
</section>
|
||||||
|
{terms && terms.status === "notfound" && (
|
||||||
|
<section>
|
||||||
|
<WarningBox>
|
||||||
|
{i18n.str`Exchange doesn't have terms of service`}
|
||||||
|
</WarningBox>
|
||||||
|
</section>
|
||||||
|
)}
|
||||||
|
|
||||||
|
{terms && (
|
||||||
|
<TermsOfServiceSection
|
||||||
|
reviewed={reviewed}
|
||||||
|
reviewing={true}
|
||||||
|
terms={terms}
|
||||||
|
onAccept={(value) =>
|
||||||
|
doAccept(value).then(() => {
|
||||||
|
setReviewed(value);
|
||||||
|
})
|
||||||
|
}
|
||||||
|
/>
|
||||||
|
)}
|
||||||
|
|
||||||
|
<footer>
|
||||||
|
<Button onClick={onCancel}>
|
||||||
|
<i18n.Translate>Cancel</i18n.Translate>
|
||||||
|
</Button>
|
||||||
|
{!terms && (
|
||||||
|
<Button disabled>
|
||||||
|
<i18n.Translate>Loading terms..</i18n.Translate>
|
||||||
|
</Button>
|
||||||
|
)}
|
||||||
|
{terms && (
|
||||||
|
<Fragment>
|
||||||
|
{needsReview && !reviewed && (
|
||||||
|
<ButtonSuccess disabled upperCased onClick={onConfirm}>
|
||||||
|
{i18n.str`Add exchange`}
|
||||||
|
</ButtonSuccess>
|
||||||
|
)}
|
||||||
|
{(terms.status === "accepted" || (needsReview && reviewed)) && (
|
||||||
|
<ButtonSuccess upperCased onClick={onConfirm}>
|
||||||
|
{i18n.str`Add exchange`}
|
||||||
|
</ButtonSuccess>
|
||||||
|
)}
|
||||||
|
{terms.status === "notfound" && (
|
||||||
|
<ButtonWarning upperCased onClick={onConfirm}>
|
||||||
|
{i18n.str`Add exchange anyway`}
|
||||||
|
</ButtonWarning>
|
||||||
|
)}
|
||||||
|
</Fragment>
|
||||||
|
)}
|
||||||
|
</footer>
|
||||||
|
</Fragment>
|
||||||
|
);
|
||||||
|
}
|
@ -0,0 +1,75 @@
|
|||||||
|
/*
|
||||||
|
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/>
|
||||||
|
*/
|
||||||
|
|
||||||
|
import {
|
||||||
|
canonicalizeBaseUrl,
|
||||||
|
TalerConfigResponse,
|
||||||
|
} from "@gnu-taler/taler-util";
|
||||||
|
import { h, VNode } from "preact";
|
||||||
|
import { useState } from "preact/hooks";
|
||||||
|
import { useAsyncAsHook } from "../hooks/useAsyncAsHook";
|
||||||
|
import { queryToSlashKeys } from "../utils";
|
||||||
|
import * as wxApi from "../wxApi";
|
||||||
|
import { ExchangeAddConfirmPage } from "./ExchangeAddConfirm";
|
||||||
|
import { ExchangeSetUrlPage } from "./ExchangeSetUrl";
|
||||||
|
|
||||||
|
interface Props {
|
||||||
|
currency: string;
|
||||||
|
onBack: () => void;
|
||||||
|
}
|
||||||
|
|
||||||
|
export function ExchangeAddPage({ onBack }: Props): VNode {
|
||||||
|
const [verifying, setVerifying] = useState<
|
||||||
|
{ url: string; config: TalerConfigResponse } | undefined
|
||||||
|
>(undefined);
|
||||||
|
|
||||||
|
const knownExchangesResponse = useAsyncAsHook(wxApi.listExchanges);
|
||||||
|
const knownExchanges = !knownExchangesResponse
|
||||||
|
? []
|
||||||
|
: knownExchangesResponse.hasError
|
||||||
|
? []
|
||||||
|
: knownExchangesResponse.response.exchanges;
|
||||||
|
|
||||||
|
if (!verifying) {
|
||||||
|
return (
|
||||||
|
<ExchangeSetUrlPage
|
||||||
|
onCancel={onBack}
|
||||||
|
knownExchanges={knownExchanges}
|
||||||
|
onVerify={(url) => queryToSlashKeys(url)}
|
||||||
|
onConfirm={(url) =>
|
||||||
|
queryToSlashKeys<TalerConfigResponse>(url)
|
||||||
|
.then((config) => {
|
||||||
|
setVerifying({ url, config });
|
||||||
|
})
|
||||||
|
.catch((e) => e.message)
|
||||||
|
}
|
||||||
|
/>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
return (
|
||||||
|
<ExchangeAddConfirmPage
|
||||||
|
url={verifying.url}
|
||||||
|
onCancel={onBack}
|
||||||
|
onConfirm={async () => {
|
||||||
|
await wxApi.addExchange({
|
||||||
|
exchangeBaseUrl: canonicalizeBaseUrl(verifying.url),
|
||||||
|
forceUpdate: true,
|
||||||
|
});
|
||||||
|
onBack();
|
||||||
|
}}
|
||||||
|
/>
|
||||||
|
);
|
||||||
|
}
|
@ -0,0 +1,62 @@
|
|||||||
|
/*
|
||||||
|
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 { queryToSlashKeys } from "../utils";
|
||||||
|
import { ExchangeSetUrlPage as TestedComponent } from "./ExchangeSetUrl";
|
||||||
|
|
||||||
|
export default {
|
||||||
|
title: "wallet/exchange add/set url",
|
||||||
|
component: TestedComponent,
|
||||||
|
argTypes: {
|
||||||
|
onRetry: { action: "onRetry" },
|
||||||
|
onDelete: { action: "onDelete" },
|
||||||
|
onBack: { action: "onBack" },
|
||||||
|
},
|
||||||
|
};
|
||||||
|
|
||||||
|
export const ExpectedUSD = createExample(TestedComponent, {
|
||||||
|
expectedCurrency: "USD",
|
||||||
|
onVerify: queryToSlashKeys,
|
||||||
|
knownExchanges: [],
|
||||||
|
});
|
||||||
|
|
||||||
|
export const ExpectedKUDOS = createExample(TestedComponent, {
|
||||||
|
expectedCurrency: "KUDOS",
|
||||||
|
onVerify: queryToSlashKeys,
|
||||||
|
knownExchanges: [],
|
||||||
|
});
|
||||||
|
|
||||||
|
export const InitialState = createExample(TestedComponent, {
|
||||||
|
onVerify: queryToSlashKeys,
|
||||||
|
knownExchanges: [],
|
||||||
|
});
|
||||||
|
|
||||||
|
export const WithDemoAsKnownExchange = createExample(TestedComponent, {
|
||||||
|
knownExchanges: [
|
||||||
|
{
|
||||||
|
currency: "TESTKUDOS",
|
||||||
|
exchangeBaseUrl: "https://exchange.demo.taler.net/",
|
||||||
|
paytoUris: [],
|
||||||
|
},
|
||||||
|
],
|
||||||
|
onVerify: queryToSlashKeys,
|
||||||
|
});
|
130
packages/taler-wallet-webextension/src/wallet/ExchangeSetUrl.tsx
Normal file
130
packages/taler-wallet-webextension/src/wallet/ExchangeSetUrl.tsx
Normal file
@ -0,0 +1,130 @@
|
|||||||
|
import {
|
||||||
|
canonicalizeBaseUrl,
|
||||||
|
ExchangeListItem,
|
||||||
|
i18n,
|
||||||
|
TalerConfigResponse,
|
||||||
|
} from "@gnu-taler/taler-util";
|
||||||
|
import { Fragment, h } from "preact";
|
||||||
|
import { useEffect, useState } from "preact/hooks";
|
||||||
|
import { ErrorMessage } from "../components/ErrorMessage";
|
||||||
|
import {
|
||||||
|
Button,
|
||||||
|
ButtonPrimary,
|
||||||
|
Input,
|
||||||
|
WarningBox,
|
||||||
|
} from "../components/styled/index";
|
||||||
|
|
||||||
|
export interface Props {
|
||||||
|
initialValue?: string;
|
||||||
|
expectedCurrency?: string;
|
||||||
|
knownExchanges: ExchangeListItem[];
|
||||||
|
onCancel: () => void;
|
||||||
|
onVerify: (s: string) => Promise<TalerConfigResponse | undefined>;
|
||||||
|
onConfirm: (url: string) => Promise<string | undefined>;
|
||||||
|
withError?: string;
|
||||||
|
}
|
||||||
|
|
||||||
|
export function ExchangeSetUrlPage({
|
||||||
|
initialValue,
|
||||||
|
knownExchanges,
|
||||||
|
expectedCurrency,
|
||||||
|
onCancel,
|
||||||
|
onVerify,
|
||||||
|
onConfirm,
|
||||||
|
withError,
|
||||||
|
}: Props) {
|
||||||
|
const [value, setValue] = useState<string>(initialValue || "");
|
||||||
|
const [dirty, setDirty] = useState(false);
|
||||||
|
const [result, setResult] = useState<TalerConfigResponse | undefined>(
|
||||||
|
undefined,
|
||||||
|
);
|
||||||
|
const [error, setError] = useState<string | undefined>(withError);
|
||||||
|
|
||||||
|
useEffect(() => {
|
||||||
|
try {
|
||||||
|
const url = canonicalizeBaseUrl(value);
|
||||||
|
|
||||||
|
const found =
|
||||||
|
knownExchanges.findIndex((e) => e.exchangeBaseUrl === url) !== -1;
|
||||||
|
|
||||||
|
if (found) {
|
||||||
|
setError("This exchange is already known");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
onVerify(url)
|
||||||
|
.then((r) => {
|
||||||
|
setResult(r);
|
||||||
|
})
|
||||||
|
.catch(() => {
|
||||||
|
setResult(undefined);
|
||||||
|
});
|
||||||
|
setDirty(true);
|
||||||
|
} catch {
|
||||||
|
setResult(undefined);
|
||||||
|
}
|
||||||
|
}, [value]);
|
||||||
|
|
||||||
|
return (
|
||||||
|
<Fragment>
|
||||||
|
<section>
|
||||||
|
{!expectedCurrency ? (
|
||||||
|
<h1>Add new exchange</h1>
|
||||||
|
) : (
|
||||||
|
<h2>Add exchange for {expectedCurrency}</h2>
|
||||||
|
)}
|
||||||
|
<ErrorMessage
|
||||||
|
title={error && "Unable to add this exchange"}
|
||||||
|
description={error}
|
||||||
|
/>
|
||||||
|
<p>
|
||||||
|
<Input invalid={dirty && !!error}>
|
||||||
|
<label>URL</label>
|
||||||
|
<input
|
||||||
|
type="text"
|
||||||
|
placeholder="https://"
|
||||||
|
value={value}
|
||||||
|
onInput={(e) => setValue(e.currentTarget.value)}
|
||||||
|
/>
|
||||||
|
</Input>
|
||||||
|
{result && (
|
||||||
|
<Fragment>
|
||||||
|
<Input>
|
||||||
|
<label>Version</label>
|
||||||
|
<input type="text" disabled value={result.version} />
|
||||||
|
</Input>
|
||||||
|
<Input>
|
||||||
|
<label>Currency</label>
|
||||||
|
<input type="text" disabled value={result.currency} />
|
||||||
|
</Input>
|
||||||
|
</Fragment>
|
||||||
|
)}
|
||||||
|
</p>
|
||||||
|
</section>
|
||||||
|
{result && expectedCurrency && expectedCurrency !== result.currency && (
|
||||||
|
<WarningBox>
|
||||||
|
This exchange doesn't match the expected currency{" "}
|
||||||
|
<b>{expectedCurrency}</b>
|
||||||
|
</WarningBox>
|
||||||
|
)}
|
||||||
|
<footer>
|
||||||
|
<Button onClick={onCancel}>
|
||||||
|
<i18n.Translate>Cancel</i18n.Translate>
|
||||||
|
</Button>
|
||||||
|
<ButtonPrimary
|
||||||
|
disabled={
|
||||||
|
!result ||
|
||||||
|
!!error ||
|
||||||
|
(expectedCurrency !== undefined &&
|
||||||
|
expectedCurrency !== result.currency)
|
||||||
|
}
|
||||||
|
onClick={() => {
|
||||||
|
const url = canonicalizeBaseUrl(value);
|
||||||
|
return onConfirm(url).then((r) => (r ? setError(r) : undefined));
|
||||||
|
}}
|
||||||
|
>
|
||||||
|
<i18n.Translate>Next</i18n.Translate>
|
||||||
|
</ButtonPrimary>
|
||||||
|
</footer>
|
||||||
|
</Fragment>
|
||||||
|
);
|
||||||
|
}
|
@ -31,6 +31,7 @@ import {
|
|||||||
LightText,
|
LightText,
|
||||||
SmallLightText,
|
SmallLightText,
|
||||||
} from "../components/styled/index";
|
} from "../components/styled/index";
|
||||||
|
import { queryToSlashConfig } from "../utils";
|
||||||
import * as wxApi from "../wxApi";
|
import * as wxApi from "../wxApi";
|
||||||
|
|
||||||
interface Props {
|
interface Props {
|
||||||
@ -38,45 +39,19 @@ interface Props {
|
|||||||
onBack: () => void;
|
onBack: () => void;
|
||||||
}
|
}
|
||||||
|
|
||||||
function getJsonIfOk(r: Response) {
|
|
||||||
if (r.ok) {
|
|
||||||
return r.json();
|
|
||||||
} else {
|
|
||||||
if (r.status >= 400 && r.status < 500) {
|
|
||||||
throw new Error(`URL may not be right: (${r.status}) ${r.statusText}`);
|
|
||||||
} else {
|
|
||||||
throw new Error(
|
|
||||||
`Try another server: (${r.status}) ${
|
|
||||||
r.statusText || "internal server error"
|
|
||||||
}`,
|
|
||||||
);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
export function ProviderAddPage({ onBack }: Props): VNode {
|
export function ProviderAddPage({ onBack }: Props): VNode {
|
||||||
const [verifying, setVerifying] = useState<
|
const [verifying, setVerifying] = useState<
|
||||||
| { url: string; name: string; provider: BackupBackupProviderTerms }
|
| { url: string; name: string; provider: BackupBackupProviderTerms }
|
||||||
| undefined
|
| undefined
|
||||||
>(undefined);
|
>(undefined);
|
||||||
|
|
||||||
async function getProviderInfo(
|
|
||||||
url: string,
|
|
||||||
): Promise<BackupBackupProviderTerms> {
|
|
||||||
return fetch(new URL("config", url).href)
|
|
||||||
.catch((e) => {
|
|
||||||
throw new Error(`Network error`);
|
|
||||||
})
|
|
||||||
.then(getJsonIfOk);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!verifying) {
|
if (!verifying) {
|
||||||
return (
|
return (
|
||||||
<SetUrlView
|
<SetUrlView
|
||||||
onCancel={onBack}
|
onCancel={onBack}
|
||||||
onVerify={(url) => getProviderInfo(url)}
|
onVerify={(url) => queryToSlashConfig(url)}
|
||||||
onConfirm={(url, name) =>
|
onConfirm={(url, name) =>
|
||||||
getProviderInfo(url)
|
queryToSlashConfig<BackupBackupProviderTerms>(url)
|
||||||
.then((provider) => {
|
.then((provider) => {
|
||||||
setVerifying({ url, name, provider });
|
setVerifying({ url, name, provider });
|
||||||
})
|
})
|
||||||
|
@ -3,6 +3,7 @@ import { Fragment, h, VNode } from "preact";
|
|||||||
import { BankDetailsByPaytoType } from "../components/BankDetailsByPaytoType";
|
import { BankDetailsByPaytoType } from "../components/BankDetailsByPaytoType";
|
||||||
import { QR } from "../components/QR";
|
import { QR } from "../components/QR";
|
||||||
import { ButtonDestructive, WarningBox } from "../components/styled";
|
import { ButtonDestructive, WarningBox } from "../components/styled";
|
||||||
|
import { amountToString } from "../utils";
|
||||||
export interface Props {
|
export interface Props {
|
||||||
reservePub: string;
|
reservePub: string;
|
||||||
payto: string;
|
payto: string;
|
||||||
@ -29,10 +30,10 @@ export function ReserveCreated({
|
|||||||
<h1>Exchange is ready for withdrawal!</h1>
|
<h1>Exchange is ready for withdrawal!</h1>
|
||||||
<p>
|
<p>
|
||||||
To complete the process you need to wire{" "}
|
To complete the process you need to wire{" "}
|
||||||
<b>{Amounts.stringify(amount)}</b> to the exchange bank account
|
<b>{amountToString(amount)}</b> to the exchange bank account
|
||||||
</p>
|
</p>
|
||||||
<BankDetailsByPaytoType
|
<BankDetailsByPaytoType
|
||||||
amount={Amounts.stringify(amount)}
|
amount={amountToString(amount)}
|
||||||
exchangeBaseUrl={exchangeBaseUrl}
|
exchangeBaseUrl={exchangeBaseUrl}
|
||||||
payto={paytoURI}
|
payto={paytoURI}
|
||||||
subject={reservePub}
|
subject={reservePub}
|
||||||
|
@ -17,12 +17,13 @@
|
|||||||
import { ExchangeListItem, i18n } from "@gnu-taler/taler-util";
|
import { ExchangeListItem, i18n } from "@gnu-taler/taler-util";
|
||||||
import { Fragment, h, VNode } from "preact";
|
import { Fragment, h, VNode } from "preact";
|
||||||
import { Checkbox } from "../components/Checkbox";
|
import { Checkbox } from "../components/Checkbox";
|
||||||
import { ButtonPrimary } from "../components/styled";
|
import { LinkPrimary } from "../components/styled";
|
||||||
import { useDevContext } from "../context/devContext";
|
import { useDevContext } from "../context/devContext";
|
||||||
import { useAsyncAsHook } from "../hooks/useAsyncAsHook";
|
import { useAsyncAsHook } from "../hooks/useAsyncAsHook";
|
||||||
import { useBackupDeviceName } from "../hooks/useBackupDeviceName";
|
import { useBackupDeviceName } from "../hooks/useBackupDeviceName";
|
||||||
import { useExtendedPermissions } from "../hooks/useExtendedPermissions";
|
import { useExtendedPermissions } from "../hooks/useExtendedPermissions";
|
||||||
import { useLang } from "../hooks/useLang";
|
import { useLang } from "../hooks/useLang";
|
||||||
|
import { Pages } from "../NavigationBar";
|
||||||
// import { strings as messages } from "../i18n/strings";
|
// import { strings as messages } from "../i18n/strings";
|
||||||
import * as wxApi from "../wxApi";
|
import * as wxApi from "../wxApi";
|
||||||
|
|
||||||
@ -112,7 +113,7 @@ export function SettingsView({
|
|||||||
)}
|
)}
|
||||||
<div style={{ display: "flex", justifyContent: "space-between" }}>
|
<div style={{ display: "flex", justifyContent: "space-between" }}>
|
||||||
<div />
|
<div />
|
||||||
<ButtonPrimary>Manage exchange</ButtonPrimary>
|
<LinkPrimary href={Pages.exchange_add}>Add an exchange</LinkPrimary>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<h2>
|
<h2>
|
||||||
|
@ -44,6 +44,7 @@ import { ManualWithdrawPage } from "./wallet/ManualWithdrawPage";
|
|||||||
import { WalletBox } from "./components/styled";
|
import { WalletBox } from "./components/styled";
|
||||||
import { ProviderDetailPage } from "./wallet/ProviderDetailPage";
|
import { ProviderDetailPage } from "./wallet/ProviderDetailPage";
|
||||||
import { ProviderAddPage } from "./wallet/ProviderAddPage";
|
import { ProviderAddPage } from "./wallet/ProviderAddPage";
|
||||||
|
import { ExchangeAddPage } from "./wallet/ExchangeAddPage";
|
||||||
|
|
||||||
function main(): void {
|
function main(): void {
|
||||||
try {
|
try {
|
||||||
@ -131,6 +132,14 @@ function Application(): VNode {
|
|||||||
}}
|
}}
|
||||||
/>
|
/>
|
||||||
|
|
||||||
|
<Route
|
||||||
|
path={Pages.exchange_add}
|
||||||
|
component={withLogoAndNavBar(ExchangeAddPage)}
|
||||||
|
onBack={() => {
|
||||||
|
route(Pages.balance);
|
||||||
|
}}
|
||||||
|
/>
|
||||||
|
|
||||||
<Route
|
<Route
|
||||||
path={Pages.manual_withdraw}
|
path={Pages.manual_withdraw}
|
||||||
component={withLogoAndNavBar(ManualWithdrawPage)}
|
component={withLogoAndNavBar(ManualWithdrawPage)}
|
||||||
|
Loading…
Reference in New Issue
Block a user