update SPA for #7810
This commit is contained in:
parent
a957e61a9c
commit
da519af01f
@ -48,6 +48,64 @@ type Amount = string;
|
||||
type UUID = string;
|
||||
type Integer = number;
|
||||
|
||||
interface WireAccount {
|
||||
// payto:// URI identifying the account and wire method
|
||||
payto_uri: string;
|
||||
|
||||
// URI to convert amounts from or to the currency used by
|
||||
// this wire account of the exchange. Missing if no
|
||||
// conversion is applicable.
|
||||
conversion_url?: string;
|
||||
|
||||
// Restrictions that apply to bank accounts that would send
|
||||
// funds to the exchange (crediting this exchange bank account).
|
||||
// Optional, empty array for unrestricted.
|
||||
credit_restrictions: AccountRestriction[];
|
||||
|
||||
// Restrictions that apply to bank accounts that would receive
|
||||
// funds from the exchange (debiting this exchange bank account).
|
||||
// Optional, empty array for unrestricted.
|
||||
debit_restrictions: AccountRestriction[];
|
||||
|
||||
// Signature using the exchange's offline key over
|
||||
// a TALER_MasterWireDetailsPS
|
||||
// with purpose TALER_SIGNATURE_MASTER_WIRE_DETAILS.
|
||||
master_sig: EddsaSignature;
|
||||
}
|
||||
|
||||
type AccountRestriction = RegexAccountRestriction | DenyAllAccountRestriction;
|
||||
|
||||
// Account restriction that disables this type of
|
||||
// account for the indicated operation categorically.
|
||||
interface DenyAllAccountRestriction {
|
||||
type: "deny";
|
||||
}
|
||||
|
||||
// Accounts interacting with this type of account
|
||||
// restriction must have a payto://-URI matching
|
||||
// the given regex.
|
||||
interface RegexAccountRestriction {
|
||||
type: "regex";
|
||||
|
||||
// Regular expression that the payto://-URI of the
|
||||
// partner account must follow. The regular expression
|
||||
// should follow posix-egrep, but without support for character
|
||||
// classes, GNU extensions, back-references or intervals. See
|
||||
// https://www.gnu.org/software/findutils/manual/html_node/find_html/posix_002degrep-regular-expression-syntax.html
|
||||
// for a description of the posix-egrep syntax. Applications
|
||||
// may support regexes with additional features, but exchanges
|
||||
// must not use such regexes.
|
||||
payto_regex: string;
|
||||
|
||||
// Hint for a human to understand the restriction
|
||||
// (that is hopefully easier to comprehend than the regex itself).
|
||||
human_hint: string;
|
||||
|
||||
// Map from IETF BCP 47 language tags to localized
|
||||
// human hints.
|
||||
human_hint_i18n?: { [lang_tag: string]: string };
|
||||
}
|
||||
|
||||
export namespace ExchangeBackend {
|
||||
interface WireResponse {
|
||||
// Master public key of the exchange, must match the key returned in /keys.
|
||||
@ -61,14 +119,6 @@ export namespace ExchangeBackend {
|
||||
// to wire fees.
|
||||
fees: { method: AggregateTransferFee };
|
||||
}
|
||||
interface WireAccount {
|
||||
// payto:// URI identifying the account and wire method
|
||||
payto_uri: string;
|
||||
|
||||
// Signature using the exchange's offline key
|
||||
// with purpose TALER_SIGNATURE_MASTER_WIRE_DETAILS.
|
||||
master_sig: EddsaSignature;
|
||||
}
|
||||
interface AggregateTransferFee {
|
||||
// Per transfer wire transfer fee.
|
||||
wire_fee: Amount;
|
||||
@ -1028,8 +1078,8 @@ export namespace MerchantBackend {
|
||||
// Public key identifying the reserve
|
||||
reserve_pub: EddsaPublicKey;
|
||||
|
||||
// Wire account of the exchange where to transfer the funds
|
||||
payto_uri: string;
|
||||
// Wire accounts of the exchange where to transfer the funds.
|
||||
accounts: WireAccount[];
|
||||
}
|
||||
interface TipCreateRequest {
|
||||
// Amount that the customer should be tipped
|
||||
@ -1084,9 +1134,10 @@ export namespace MerchantBackend {
|
||||
// Is this reserve active (false if it was deleted but not purged)?
|
||||
active: boolean;
|
||||
|
||||
// URI to use to fill the reserve, can be NULL
|
||||
// Array of wire accounts of the exchange that could
|
||||
// be used to fill the reserve, can be NULL
|
||||
// if the reserve is inactive or was already filled
|
||||
payto_uri: string;
|
||||
accounts?: WireAccount[];
|
||||
|
||||
// URL of the exchange hosting the reserve,
|
||||
// NULL if the reserve is inactive
|
||||
|
@ -16,3 +16,4 @@
|
||||
|
||||
export * as details from "./details/stories.js";
|
||||
export * as kycList from "./kyc/list/ListPage.stories.js";
|
||||
export * as reserve from "./reserves/create/CreatedSuccessfully.stories.js";
|
||||
|
@ -21,6 +21,7 @@
|
||||
|
||||
import { h, VNode, FunctionalComponent } from "preact";
|
||||
import { CreatedSuccessfully as TestedComponent } from "./CreatedSuccessfully.js";
|
||||
import { tests } from "@gnu-taler/web-util/lib/index.browser";
|
||||
|
||||
export default {
|
||||
title: "Pages/Reserve/CreatedSuccessfully",
|
||||
@ -31,16 +32,7 @@ export default {
|
||||
},
|
||||
};
|
||||
|
||||
function createExample<Props>(
|
||||
Component: FunctionalComponent<Props>,
|
||||
props: Partial<Props>,
|
||||
) {
|
||||
const r = (args: any) => <Component {...args} />;
|
||||
r.args = props;
|
||||
return r;
|
||||
}
|
||||
|
||||
export const Example = createExample(TestedComponent, {
|
||||
export const OneBankAccount = tests.createExample(TestedComponent, {
|
||||
entity: {
|
||||
request: {
|
||||
exchange_url: "http://exchange.taler/",
|
||||
@ -48,7 +40,80 @@ export const Example = createExample(TestedComponent, {
|
||||
wire_method: "x-taler-bank",
|
||||
},
|
||||
response: {
|
||||
payto_uri: "payto://x-taler-bank/bank.taler:8080/exchange_account",
|
||||
accounts: [
|
||||
{
|
||||
payto_uri: "payto://x-taler-bank/bank.taler:8080/exchange_account",
|
||||
credit_restrictions: [],
|
||||
debit_restrictions: [],
|
||||
master_sig: "asd",
|
||||
conversion_url: "",
|
||||
},
|
||||
],
|
||||
reserve_pub: "WEQWDASDQWEASDADASDQWEQWEASDAS",
|
||||
},
|
||||
},
|
||||
});
|
||||
|
||||
export const ThreeBankAccount = tests.createExample(TestedComponent, {
|
||||
entity: {
|
||||
request: {
|
||||
exchange_url: "http://exchange.taler/",
|
||||
initial_balance: "TESTKUDOS:1",
|
||||
wire_method: "x-taler-bank",
|
||||
},
|
||||
response: {
|
||||
accounts: [
|
||||
{
|
||||
payto_uri: "payto://x-taler-bank/bank.taler:8080/exchange_account",
|
||||
credit_restrictions: [],
|
||||
debit_restrictions: [],
|
||||
master_sig: "asd",
|
||||
conversion_url: "",
|
||||
},
|
||||
{
|
||||
payto_uri: "payto://x-taler-bank/bank1.taler:8080/asd",
|
||||
credit_restrictions: [],
|
||||
debit_restrictions: [],
|
||||
master_sig: "asd",
|
||||
conversion_url: "",
|
||||
},
|
||||
{
|
||||
payto_uri: "payto://x-taler-bank/bank2.taler:8080/qwe",
|
||||
credit_restrictions: [],
|
||||
debit_restrictions: [],
|
||||
master_sig: "asd",
|
||||
conversion_url: "",
|
||||
},
|
||||
],
|
||||
reserve_pub: "WEQWDASDQWEASDADASDQWEQWEASDAS",
|
||||
},
|
||||
},
|
||||
});
|
||||
|
||||
export const NoBankAccount = tests.createExample(TestedComponent, {
|
||||
entity: {
|
||||
request: {
|
||||
exchange_url: "http://exchange.taler/",
|
||||
initial_balance: "TESTKUDOS:1",
|
||||
wire_method: "x-taler-bank",
|
||||
},
|
||||
response: {
|
||||
accounts: [
|
||||
{
|
||||
payto_uri: "payo://x-talr-bank/bank.taler:8080/exchange_account",
|
||||
credit_restrictions: [],
|
||||
debit_restrictions: [],
|
||||
master_sig: "asd",
|
||||
conversion_url: "",
|
||||
},
|
||||
{
|
||||
payto_uri: "payto://x-taler-bank",
|
||||
credit_restrictions: [],
|
||||
debit_restrictions: [],
|
||||
master_sig: "asd",
|
||||
conversion_url: "",
|
||||
},
|
||||
],
|
||||
reserve_pub: "WEQWDASDQWEASDADASDQWEQWEASDAS",
|
||||
},
|
||||
},
|
||||
|
@ -16,7 +16,7 @@
|
||||
|
||||
import { parsePaytoUri, stringifyPaytoUri } from "@gnu-taler/taler-util";
|
||||
import { useTranslationContext } from "@gnu-taler/web-util/lib/index.browser";
|
||||
import { h, VNode } from "preact";
|
||||
import { Fragment, h, VNode } from "preact";
|
||||
import { QR } from "../../../../components/exception/QR.js";
|
||||
import { CreatedSuccessfully as Template } from "../../../../components/notifications/CreatedSuccessfully.js";
|
||||
import { MerchantBackend } from "../../../../declaration.js";
|
||||
@ -32,18 +32,29 @@ interface Props {
|
||||
onCreateAnother?: () => void;
|
||||
}
|
||||
|
||||
function isNotUndefined<X>(x: X | undefined): x is X {
|
||||
return !!x;
|
||||
}
|
||||
|
||||
export function CreatedSuccessfully({
|
||||
entity,
|
||||
onConfirm,
|
||||
onCreateAnother,
|
||||
}: Props): VNode {
|
||||
const p = parsePaytoUri(entity.response.payto_uri);
|
||||
if (p) {
|
||||
p.params["message"] = entity.response.reserve_pub;
|
||||
p.params["amount"] = entity.request.initial_balance;
|
||||
}
|
||||
const accountsInfo = !entity.response.accounts
|
||||
? []
|
||||
: entity.response.accounts
|
||||
.map((acc) => {
|
||||
const p = parsePaytoUri(acc.payto_uri);
|
||||
if (p) {
|
||||
p.params["message"] = entity.response.reserve_pub;
|
||||
p.params["amount"] = entity.request.initial_balance;
|
||||
}
|
||||
return p;
|
||||
})
|
||||
.filter(isNotUndefined);
|
||||
|
||||
const link = !p ? entity.response.payto_uri : stringifyPaytoUri(p);
|
||||
const links = accountsInfo.map((a) => stringifyPaytoUri(a));
|
||||
const { i18n } = useTranslationContext();
|
||||
return (
|
||||
<Template onConfirm={onConfirm} onCreateAnother={onCreateAnother}>
|
||||
@ -63,18 +74,6 @@ export function CreatedSuccessfully({
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="field is-horizontal">
|
||||
<div class="field-label is-normal">
|
||||
<label class="label">Exchange bank account</label>
|
||||
</div>
|
||||
<div class="field-body is-flex-grow-3">
|
||||
<div class="field">
|
||||
<p class="control">
|
||||
<input readonly class="input" value={entity.response.payto_uri} />
|
||||
</p>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="field is-horizontal">
|
||||
<div class="field-label is-normal">
|
||||
<label class="label">Wire transfer subject</label>
|
||||
@ -91,24 +90,76 @@ export function CreatedSuccessfully({
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<p class="is-size-5">
|
||||
<i18n.Translate>
|
||||
To complete the setup of the reserve, you must now initiate a wire
|
||||
transfer using the given wire transfer subject and crediting the
|
||||
specified amount to the indicated account of the exchange.
|
||||
</i18n.Translate>
|
||||
</p>
|
||||
<p class="is-size-5">
|
||||
<i18n.Translate>
|
||||
If your system supports RFC 8905, you can do this by opening this URI:
|
||||
</i18n.Translate>
|
||||
</p>
|
||||
<pre>
|
||||
<a target="_blank" rel="noreferrer" href={link}>
|
||||
{link}
|
||||
</a>
|
||||
</pre>
|
||||
<QR text={link} />
|
||||
{links.length === 0 ? (
|
||||
<Fragment>
|
||||
<p class="is-size-5">
|
||||
The response of the reserve creation have invalid accounts. List of
|
||||
invalid payto URIs below:
|
||||
</p>
|
||||
<ul>
|
||||
{entity.response.accounts.map((a, idx) => {
|
||||
return <li key={idx}>{a.payto_uri}</li>;
|
||||
})}
|
||||
</ul>
|
||||
</Fragment>
|
||||
) : links.length === 1 ? (
|
||||
<Fragment>
|
||||
<p class="is-size-5">
|
||||
<i18n.Translate>
|
||||
To complete the setup of the reserve, you must now initiate a wire
|
||||
transfer using the given wire transfer subject and crediting the
|
||||
specified amount to the indicated account of the exchange.
|
||||
</i18n.Translate>
|
||||
</p>
|
||||
<p style={{ margin: 10 }}>
|
||||
<b>Exchange bank account</b>
|
||||
</p>
|
||||
<QR text={links[0]} />
|
||||
<p class="is-size-5">
|
||||
<i18n.Translate>
|
||||
If your system supports RFC 8905, you can do this by opening this
|
||||
URI:
|
||||
</i18n.Translate>
|
||||
</p>
|
||||
<pre>
|
||||
<a target="_blank" rel="noreferrer" href={links[0]}>
|
||||
{links[0]}
|
||||
</a>
|
||||
</pre>
|
||||
</Fragment>
|
||||
) : (
|
||||
<div>
|
||||
<p class="is-size-5">
|
||||
<i18n.Translate>
|
||||
To complete the setup of the reserve, you must now initiate a wire
|
||||
transfer using the given wire transfer subject and crediting the
|
||||
specified amount to one of the indicated account of the exchange.
|
||||
</i18n.Translate>
|
||||
</p>
|
||||
|
||||
<p style={{ margin: 10 }}>
|
||||
<b>Exchange bank accounts</b>
|
||||
</p>
|
||||
<p class="is-size-5">
|
||||
<i18n.Translate>
|
||||
If your system supports RFC 8905, you can do this by clicking on
|
||||
the URI below the QR code:
|
||||
</i18n.Translate>
|
||||
</p>
|
||||
{links.map((link) => {
|
||||
return (
|
||||
<Fragment>
|
||||
<QR text={link} />
|
||||
<pre>
|
||||
<a target="_blank" rel="noreferrer" href={link}>
|
||||
{link}
|
||||
</a>
|
||||
</pre>
|
||||
</Fragment>
|
||||
);
|
||||
})}
|
||||
</div>
|
||||
)}
|
||||
</Template>
|
||||
);
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user