update SPA for #7810
This commit is contained in:
parent
a957e61a9c
commit
da519af01f
@ -48,6 +48,64 @@ type Amount = string;
|
|||||||
type UUID = string;
|
type UUID = string;
|
||||||
type Integer = number;
|
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 {
|
export namespace ExchangeBackend {
|
||||||
interface WireResponse {
|
interface WireResponse {
|
||||||
// Master public key of the exchange, must match the key returned in /keys.
|
// Master public key of the exchange, must match the key returned in /keys.
|
||||||
@ -61,14 +119,6 @@ export namespace ExchangeBackend {
|
|||||||
// to wire fees.
|
// to wire fees.
|
||||||
fees: { method: AggregateTransferFee };
|
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 {
|
interface AggregateTransferFee {
|
||||||
// Per transfer wire transfer fee.
|
// Per transfer wire transfer fee.
|
||||||
wire_fee: Amount;
|
wire_fee: Amount;
|
||||||
@ -1028,8 +1078,8 @@ export namespace MerchantBackend {
|
|||||||
// Public key identifying the reserve
|
// Public key identifying the reserve
|
||||||
reserve_pub: EddsaPublicKey;
|
reserve_pub: EddsaPublicKey;
|
||||||
|
|
||||||
// Wire account of the exchange where to transfer the funds
|
// Wire accounts of the exchange where to transfer the funds.
|
||||||
payto_uri: string;
|
accounts: WireAccount[];
|
||||||
}
|
}
|
||||||
interface TipCreateRequest {
|
interface TipCreateRequest {
|
||||||
// Amount that the customer should be tipped
|
// 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)?
|
// Is this reserve active (false if it was deleted but not purged)?
|
||||||
active: boolean;
|
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
|
// if the reserve is inactive or was already filled
|
||||||
payto_uri: string;
|
accounts?: WireAccount[];
|
||||||
|
|
||||||
// URL of the exchange hosting the reserve,
|
// URL of the exchange hosting the reserve,
|
||||||
// NULL if the reserve is inactive
|
// NULL if the reserve is inactive
|
||||||
|
@ -16,3 +16,4 @@
|
|||||||
|
|
||||||
export * as details from "./details/stories.js";
|
export * as details from "./details/stories.js";
|
||||||
export * as kycList from "./kyc/list/ListPage.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 { h, VNode, FunctionalComponent } from "preact";
|
||||||
import { CreatedSuccessfully as TestedComponent } from "./CreatedSuccessfully.js";
|
import { CreatedSuccessfully as TestedComponent } from "./CreatedSuccessfully.js";
|
||||||
|
import { tests } from "@gnu-taler/web-util/lib/index.browser";
|
||||||
|
|
||||||
export default {
|
export default {
|
||||||
title: "Pages/Reserve/CreatedSuccessfully",
|
title: "Pages/Reserve/CreatedSuccessfully",
|
||||||
@ -31,16 +32,7 @@ export default {
|
|||||||
},
|
},
|
||||||
};
|
};
|
||||||
|
|
||||||
function createExample<Props>(
|
export const OneBankAccount = tests.createExample(TestedComponent, {
|
||||||
Component: FunctionalComponent<Props>,
|
|
||||||
props: Partial<Props>,
|
|
||||||
) {
|
|
||||||
const r = (args: any) => <Component {...args} />;
|
|
||||||
r.args = props;
|
|
||||||
return r;
|
|
||||||
}
|
|
||||||
|
|
||||||
export const Example = createExample(TestedComponent, {
|
|
||||||
entity: {
|
entity: {
|
||||||
request: {
|
request: {
|
||||||
exchange_url: "http://exchange.taler/",
|
exchange_url: "http://exchange.taler/",
|
||||||
@ -48,7 +40,80 @@ export const Example = createExample(TestedComponent, {
|
|||||||
wire_method: "x-taler-bank",
|
wire_method: "x-taler-bank",
|
||||||
},
|
},
|
||||||
response: {
|
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",
|
reserve_pub: "WEQWDASDQWEASDADASDQWEQWEASDAS",
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
|
@ -16,7 +16,7 @@
|
|||||||
|
|
||||||
import { parsePaytoUri, stringifyPaytoUri } from "@gnu-taler/taler-util";
|
import { parsePaytoUri, stringifyPaytoUri } from "@gnu-taler/taler-util";
|
||||||
import { useTranslationContext } from "@gnu-taler/web-util/lib/index.browser";
|
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 { QR } from "../../../../components/exception/QR.js";
|
||||||
import { CreatedSuccessfully as Template } from "../../../../components/notifications/CreatedSuccessfully.js";
|
import { CreatedSuccessfully as Template } from "../../../../components/notifications/CreatedSuccessfully.js";
|
||||||
import { MerchantBackend } from "../../../../declaration.js";
|
import { MerchantBackend } from "../../../../declaration.js";
|
||||||
@ -32,18 +32,29 @@ interface Props {
|
|||||||
onCreateAnother?: () => void;
|
onCreateAnother?: () => void;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function isNotUndefined<X>(x: X | undefined): x is X {
|
||||||
|
return !!x;
|
||||||
|
}
|
||||||
|
|
||||||
export function CreatedSuccessfully({
|
export function CreatedSuccessfully({
|
||||||
entity,
|
entity,
|
||||||
onConfirm,
|
onConfirm,
|
||||||
onCreateAnother,
|
onCreateAnother,
|
||||||
}: Props): VNode {
|
}: Props): VNode {
|
||||||
const p = parsePaytoUri(entity.response.payto_uri);
|
const accountsInfo = !entity.response.accounts
|
||||||
if (p) {
|
? []
|
||||||
p.params["message"] = entity.response.reserve_pub;
|
: entity.response.accounts
|
||||||
p.params["amount"] = entity.request.initial_balance;
|
.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();
|
const { i18n } = useTranslationContext();
|
||||||
return (
|
return (
|
||||||
<Template onConfirm={onConfirm} onCreateAnother={onCreateAnother}>
|
<Template onConfirm={onConfirm} onCreateAnother={onCreateAnother}>
|
||||||
@ -63,18 +74,6 @@ export function CreatedSuccessfully({
|
|||||||
</div>
|
</div>
|
||||||
</div>
|
</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 is-horizontal">
|
||||||
<div class="field-label is-normal">
|
<div class="field-label is-normal">
|
||||||
<label class="label">Wire transfer subject</label>
|
<label class="label">Wire transfer subject</label>
|
||||||
@ -91,24 +90,76 @@ export function CreatedSuccessfully({
|
|||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<p class="is-size-5">
|
{links.length === 0 ? (
|
||||||
<i18n.Translate>
|
<Fragment>
|
||||||
To complete the setup of the reserve, you must now initiate a wire
|
<p class="is-size-5">
|
||||||
transfer using the given wire transfer subject and crediting the
|
The response of the reserve creation have invalid accounts. List of
|
||||||
specified amount to the indicated account of the exchange.
|
invalid payto URIs below:
|
||||||
</i18n.Translate>
|
</p>
|
||||||
</p>
|
<ul>
|
||||||
<p class="is-size-5">
|
{entity.response.accounts.map((a, idx) => {
|
||||||
<i18n.Translate>
|
return <li key={idx}>{a.payto_uri}</li>;
|
||||||
If your system supports RFC 8905, you can do this by opening this URI:
|
})}
|
||||||
</i18n.Translate>
|
</ul>
|
||||||
</p>
|
</Fragment>
|
||||||
<pre>
|
) : links.length === 1 ? (
|
||||||
<a target="_blank" rel="noreferrer" href={link}>
|
<Fragment>
|
||||||
{link}
|
<p class="is-size-5">
|
||||||
</a>
|
<i18n.Translate>
|
||||||
</pre>
|
To complete the setup of the reserve, you must now initiate a wire
|
||||||
<QR text={link} />
|
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>
|
</Template>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user