gnunet-svn
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[taler-wallet-core] branch master updated (65148a9e9 -> 1faa908c2)


From: gnunet
Subject: [taler-wallet-core] branch master updated (65148a9e9 -> 1faa908c2)
Date: Wed, 13 Mar 2024 13:54:54 +0100

This is an automated email from the git hooks/post-receive script.

sebasjm pushed a change to branch master
in repository wallet-core.

    from 65148a9e9 fix #8173
     new ce4786955 allow text in copy button
     new 18e024d13 expose address in its own field
     new 1faa908c2 fix #8460

The 3 revisions listed above as "new" are entirely new to this
repository and will be described in separate emails.  The revisions
listed as "add" were already present in the repository and have only
been added to this reference.


Summary of changes:
 .../bank-ui/src/components/Transactions/state.ts   |   2 +-
 .../bank-ui/src/components/Transactions/views.tsx  |   2 +-
 .../bank-ui/src/pages/PaytoWireTransferForm.tsx    | 236 +++++++++++++--------
 packages/bank-ui/src/pages/SolveChallengePage.tsx  |   1 -
 packages/bank-ui/src/pages/WalletWithdrawForm.tsx  |  14 +-
 .../src/pages/WithdrawalConfirmationQuestion.tsx   |  74 +++++--
 .../src/pages/account/ShowAccountDetails.tsx       | 224 ++++++++++++++++++-
 packages/bank-ui/src/pages/admin/DownloadStats.tsx |   6 +-
 .../src/pages/regional/ConversionConfig.tsx        |   4 +-
 .../bank-ui/src/pages/regional/CreateCashout.tsx   |  26 +--
 .../src/pages/regional/ShowCashoutDetails.tsx      |   2 +-
 packages/taler-util/src/payto.ts                   |   5 +
 .../src/wallet/ManageAccount/stories.tsx           |   4 +
 packages/web-util/src/components/CopyButton.tsx    |   6 +-
 14 files changed, 469 insertions(+), 137 deletions(-)

diff --git a/packages/bank-ui/src/components/Transactions/state.ts 
b/packages/bank-ui/src/components/Transactions/state.ts
index e792ddfa0..4e4552a82 100644
--- a/packages/bank-ui/src/components/Transactions/state.ts
+++ b/packages/bank-ui/src/components/Transactions/state.ts
@@ -55,7 +55,7 @@ export function useComponentState({
             : cp.targetType === "x-taler-bank"
               ? cp.account
               : cp.targetType === "bitcoin"
-                ? `${cp.targetPath.substring(0, 6)}...`
+                ? `${cp.address.substring(0, 6)}...`
                 : undefined) ?? "unknown";
 
       const when = AbsoluteTime.fromProtocolTimestamp(tx.date);
diff --git a/packages/bank-ui/src/components/Transactions/views.tsx 
b/packages/bank-ui/src/components/Transactions/views.tsx
index da64efdb2..4397651e2 100644
--- a/packages/bank-ui/src/components/Transactions/views.tsx
+++ b/packages/bank-ui/src/components/Transactions/views.tsx
@@ -120,7 +120,7 @@ export function ReadyView({
                             <Time
                               format="HH:mm:ss"
                               timestamp={item.when}
-                            // relative={Duration.fromSpec({ days: 1 })}
+                              // relative={Duration.fromSpec({ days: 1 })}
                             />
                           </div>
                           <dl class="font-normal sm:hidden">
diff --git a/packages/bank-ui/src/pages/PaytoWireTransferForm.tsx 
b/packages/bank-ui/src/pages/PaytoWireTransferForm.tsx
index d5bb5f88f..7812a1da0 100644
--- a/packages/bank-ui/src/pages/PaytoWireTransferForm.tsx
+++ b/packages/bank-ui/src/pages/PaytoWireTransferForm.tsx
@@ -78,7 +78,6 @@ export function PaytoWireTransferForm({
   onAuthorizationRequired,
   limit,
 }: Props): VNode {
-
   const [inputType, setInputType] = useState<"form" | "payto" | "qr">("form");
   const isRawPayto = inputType !== "form";
 
@@ -150,7 +149,7 @@ export function PaytoWireTransferForm({
         : p.targetType === "iban"
           ? p.iban
           : p.targetType === "bitcoin"
-            ? p.targetPath
+            ? p.address
             : p.targetType === "x-taler-bank"
               ? p.account
               : assertUnreachable(p);
@@ -215,7 +214,8 @@ export function PaytoWireTransferForm({
           case TalerErrorCode.BANK_UNKNOWN_CREDITOR:
             return notify({
               type: "error",
-              title: i18n.str`The destination account "${acName ?? puri}" was 
not found.`,
+              title: i18n.str`The destination account "${acName ?? puri
+                }" was not found.`,
               description: resp.detail.hint as TranslatedString,
               debug: resp.detail,
               when: AbsoluteTime.now(),
@@ -351,106 +351,168 @@ export function PaytoWireTransferForm({
             <i18n.Translate>Input wire transfer detail</i18n.Translate>
           </legend>
           <div class="-space-y-px rounded-md ">
-            <label data-checked={inputType === "form"} class="group 
rounded-tl-md rounded-tr-md relative flex cursor-pointer border p-4 
focus:outline-none bg-white data-[checked=true]:z-10 
data-[checked=true]:border-indigo-200 data-[checked=true]:bg-indigo-50">
-              <input type="radio" name="input-type" onChange={() => {
-                if (parsed && parsed.isKnown) {
-                  switch (parsed.targetType) {
-                    case "iban": {
-                      setAccount(parsed.iban);
-                      break;
-                    }
-                    case "x-taler-bank": {
-                      setAccount(parsed.account);
-                      break;
-                    }
-                    case "bitcoin": {
-                      break;
+            <label
+              data-checked={inputType === "form"}
+              class="group rounded-tl-md rounded-tr-md relative flex 
cursor-pointer border p-4 focus:outline-none bg-white data-[checked=true]:z-10 
data-[checked=true]:border-indigo-200 data-[checked=true]:bg-indigo-50"
+            >
+              <input
+                type="radio"
+                name="input-type"
+                onChange={() => {
+                  if (parsed && parsed.isKnown) {
+                    switch (parsed.targetType) {
+                      case "iban": {
+                        setAccount(parsed.iban);
+                        break;
+                      }
+                      case "x-taler-bank": {
+                        setAccount(parsed.account);
+                        break;
+                      }
+                      case "bitcoin": {
+                        break;
+                      }
+                      default: {
+                        assertUnreachable(parsed);
+                      }
                     }
-                    default: {
-                      assertUnreachable(parsed);
+                    const amountStr = !parsed.params
+                      ? undefined
+                      : parsed.params["amount"];
+                    if (amountStr) {
+                      const amount = Amounts.parse(amountStr);
+                      if (amount) {
+                        setAmount(Amounts.stringifyValue(amount));
+                      }
                     }
-                  }
-                  const amountStr = !parsed.params
-                    ? undefined
-                    : parsed.params["amount"];
-                  if (amountStr) {
-                    const amount = Amounts.parse(amountStr);
-                    if (amount) {
-                      setAmount(Amounts.stringifyValue(amount));
+                    const subject = parsed.params["message"];
+                    if (subject) {
+                      setSubject(subject);
                     }
                   }
-                  const subject = parsed.params["message"];
-                  if (subject) {
-                    setSubject(subject);
-                  }
-                }
-                setInputType("form")
-              }} checked={inputType === "form"} value="form" class="mt-0.5 h-4 
w-4 shrink-0 cursor-pointer text-indigo-600 border-gray-300 
focus:ring-indigo-600 active:ring-2 active:ring-offset-2 
active:ring-indigo-600" />
+                  setInputType("form");
+                }}
+                checked={inputType === "form"}
+                value="form"
+                class="mt-0.5 h-4 w-4 shrink-0 cursor-pointer text-indigo-600 
border-gray-300 focus:ring-indigo-600 active:ring-2 active:ring-offset-2 
active:ring-indigo-600"
+              />
               <span class="ml-3 flex flex-col">
                 {/* <!-- Checked: "text-indigo-900", Not Checked: 
"text-gray-900" --> */}
-                <span data-checked={inputType === "form"} class="block text-sm 
font-medium data-[checked=true]:text-indigo-900">
+                <span
+                  data-checked={inputType === "form"}
+                  class="block text-sm font-medium 
data-[checked=true]:text-indigo-900"
+                >
                   <i18n.Translate>Using a form</i18n.Translate>
                 </span>
               </span>
             </label>
-            {sendingToFixedAccount ? undefined : (<Fragment>
-              <label data-checked={inputType === "payto"} class="relative flex 
cursor-pointer border p-4 focus:outline-none bg-white data-[checked=true]:z-10 
data-[checked=true]:border-indigo-200 data-[checked=true]:bg-indigo-50">
-                <input type="radio" name="input-type" onChange={() => {
-                  if (account) {
-                    let payto;
-                    switch (paytoType) {
-                      case "x-taler-bank": {
-                        payto = buildPayto("x-taler-bank", url.host, account);
-                        if (parsedAmount) {
-                          payto.params["amount"] =
-                            Amounts.stringify(parsedAmount);
-                        }
-                        if (subject) {
-                          payto.params["message"] = subject;
-                        }
-                        break;
-                      }
-                      case "iban": {
-                        payto = buildPayto("iban", account, undefined);
-                        if (parsedAmount) {
-                          payto.params["amount"] =
-                            Amounts.stringify(parsedAmount);
-                        }
-                        if (subject) {
-                          payto.params["message"] = subject;
+            {sendingToFixedAccount ? undefined : (
+              <Fragment>
+                <label
+                  data-checked={inputType === "payto"}
+                  class="relative flex cursor-pointer border p-4 
focus:outline-none bg-white data-[checked=true]:z-10 
data-[checked=true]:border-indigo-200 data-[checked=true]:bg-indigo-50"
+                >
+                  <input
+                    type="radio"
+                    name="input-type"
+                    onChange={() => {
+                      if (account) {
+                        let payto;
+                        switch (paytoType) {
+                          case "x-taler-bank": {
+                            payto = buildPayto(
+                              "x-taler-bank",
+                              url.host,
+                              account,
+                            );
+                            if (parsedAmount) {
+                              payto.params["amount"] =
+                                Amounts.stringify(parsedAmount);
+                            }
+                            if (subject) {
+                              payto.params["message"] = subject;
+                            }
+                            break;
+                          }
+                          case "iban": {
+                            payto = buildPayto("iban", account, undefined);
+                            if (parsedAmount) {
+                              payto.params["amount"] =
+                                Amounts.stringify(parsedAmount);
+                            }
+                            if (subject) {
+                              payto.params["message"] = subject;
+                            }
+                            break;
+                          }
+                          default:
+                            assertUnreachable(paytoType);
                         }
-                        break;
+                        rawPaytoInputSetter(stringifyPaytoUri(payto));
                       }
-                      default:
-                        assertUnreachable(paytoType);
-                    }
-                    rawPaytoInputSetter(stringifyPaytoUri(payto));
-                  } setInputType("payto")
-                }} checked={inputType === "payto"} value="payto" class="mt-0.5 
h-4 w-4 shrink-0 cursor-pointer text-indigo-600 border-gray-300 
focus:ring-indigo-600 active:ring-2 active:ring-offset-2 
active:ring-indigo-600" />
-                <span class="ml-3 flex flex-col">
-                  <span data-checked={inputType === "payto"} class="block  
font-medium data-[checked=true]:text-indigo-900">payto:// URI</span>
-                  <span data-checked={inputType === "payto"} class="block 
text-sm text-gray-500 data-[checked=true]:text-indigo-600">
-                    <i18n.Translate>A special URI that indicate the transfer 
amount and account target.</i18n.Translate>
-                  </span>
-                </span>
-              </label>
-              { //FIXME: add QR support
-                false && <label data-checked={inputType === "qr"} 
class="rounded-bl-md rounded-br-md relative flex cursor-pointer border p-4 
focus:outline-none bg-white data-[checked=true]:z-10 
data-[checked=true]:border-indigo-200 data-[checked=true]:bg-indigo-50">
-                  <input type="radio" name="input-type" onChange={() => {
-                    setInputType("qr")
-                  }} checked={inputType === "qr"} value="qr" class="mt-0.5 h-4 
w-4 shrink-0 cursor-pointer text-indigo-600 border-gray-300 
focus:ring-indigo-600 active:ring-2 active:ring-offset-2 
active:ring-indigo-600" />
+                      setInputType("payto");
+                    }}
+                    checked={inputType === "payto"}
+                    value="payto"
+                    class="mt-0.5 h-4 w-4 shrink-0 cursor-pointer 
text-indigo-600 border-gray-300 focus:ring-indigo-600 active:ring-2 
active:ring-offset-2 active:ring-indigo-600"
+                  />
                   <span class="ml-3 flex flex-col">
-                    <span data-checked={inputType === "qr"} class="block 
font-medium data-[checked=true]:text-indigo-900">
-                      <i18n.Translate>QR code</i18n.Translate>
+                    <span
+                      data-checked={inputType === "payto"}
+                      class="block  font-medium 
data-[checked=true]:text-indigo-900"
+                    >
+                      payto:// URI
                     </span>
-                    <span data-checked={inputType === "qr"} class="block 
text-sm text-gray-500 data-[checked=true]:text-indigo-600">
-                      <i18n.Translate>If you have a camera in this device you 
can import a payto:// URI from a QR code.</i18n.Translate>
+                    <span
+                      data-checked={inputType === "payto"}
+                      class="block text-sm text-gray-500 
data-[checked=true]:text-indigo-600"
+                    >
+                      <i18n.Translate>
+                        A special URI that indicate the transfer amount and
+                        account target.
+                      </i18n.Translate>
                     </span>
                   </span>
                 </label>
-              }
-            </Fragment>)}
-
+                {
+                  //FIXME: add QR support
+                  false && (
+                    <label
+                      data-checked={inputType === "qr"}
+                      class="rounded-bl-md rounded-br-md relative flex 
cursor-pointer border p-4 focus:outline-none bg-white data-[checked=true]:z-10 
data-[checked=true]:border-indigo-200 data-[checked=true]:bg-indigo-50"
+                    >
+                      <input
+                        type="radio"
+                        name="input-type"
+                        onChange={() => {
+                          setInputType("qr");
+                        }}
+                        checked={inputType === "qr"}
+                        value="qr"
+                        class="mt-0.5 h-4 w-4 shrink-0 cursor-pointer 
text-indigo-600 border-gray-300 focus:ring-indigo-600 active:ring-2 
active:ring-offset-2 active:ring-indigo-600"
+                      />
+                      <span class="ml-3 flex flex-col">
+                        <span
+                          data-checked={inputType === "qr"}
+                          class="block font-medium 
data-[checked=true]:text-indigo-900"
+                        >
+                          <i18n.Translate>QR code</i18n.Translate>
+                        </span>
+                        <span
+                          data-checked={inputType === "qr"}
+                          class="block text-sm text-gray-500 
data-[checked=true]:text-indigo-600"
+                        >
+                          <i18n.Translate>
+                            If you have a camera in this device you can import 
a
+                            payto:// URI from a QR code.
+                          </i18n.Translate>
+                        </span>
+                      </span>
+                    </label>
+                  )
+                }
+              </Fragment>
+            )}
           </div>
           {routeCashout ? (
             <a
@@ -461,11 +523,9 @@ export function PaytoWireTransferForm({
               <i18n.Translate>Cashout</i18n.Translate>
             </a>
           ) : undefined}
-
         </fieldset>
       </div>
 
-
       <form
         class="bg-white shadow-sm ring-1 ring-gray-900/5 rounded-md 
sm:rounded-xl md:col-span-2 w-fit mx-auto"
         autoCapitalize="none"
diff --git a/packages/bank-ui/src/pages/SolveChallengePage.tsx 
b/packages/bank-ui/src/pages/SolveChallengePage.tsx
index 23f3de1d2..30ca122bf 100644
--- a/packages/bank-ui/src/pages/SolveChallengePage.tsx
+++ b/packages/bank-ui/src/pages/SolveChallengePage.tsx
@@ -264,7 +264,6 @@ export function SolveChallengePage({
               authentication channel you provided.
             </i18n.Translate>
           </p>
-          <span></span>
         </div>
 
         <div class="bg-white shadow-sm ring-1 ring-gray-900/5 sm:rounded-xl 
md:col-span-2">
diff --git a/packages/bank-ui/src/pages/WalletWithdrawForm.tsx 
b/packages/bank-ui/src/pages/WalletWithdrawForm.tsx
index 8e9529190..2aa0338ad 100644
--- a/packages/bank-ui/src/pages/WalletWithdrawForm.tsx
+++ b/packages/bank-ui/src/pages/WalletWithdrawForm.tsx
@@ -105,12 +105,12 @@ function OldWithdrawalForm({
           class="font-semibold text-yellow-700 hover:text-yellow-600"
           name="complete operation"
           href={url}
-        // onClick={(e) => {
-        //   e.preventDefault()
-        //   walletInegrationApi.publishTalerAction(uri, () => {
-        //     navigateTo(url)
-        //   })
-        // }}
+          // onClick={(e) => {
+          //   e.preventDefault()
+          //   walletInegrationApi.publishTalerAction(uri, () => {
+          //     navigateTo(url)
+          //   })
+          // }}
         >
           <i18n.Translate>this page</i18n.Translate>
         </a>
@@ -392,7 +392,7 @@ export function WalletWithdrawForm({
             routeClose={routeCancel}
             routeHere={routeOperationDetails}
             onAbort={onOperationAborted}
-          // route={routeCancel}
+            // route={routeCancel}
           />
         )}
       </div>
diff --git a/packages/bank-ui/src/pages/WithdrawalConfirmationQuestion.tsx 
b/packages/bank-ui/src/pages/WithdrawalConfirmationQuestion.tsx
index 965650eb0..c7bdaaf21 100644
--- a/packages/bank-ui/src/pages/WithdrawalConfirmationQuestion.tsx
+++ b/packages/bank-ui/src/pages/WithdrawalConfirmationQuestion.tsx
@@ -222,10 +222,21 @@ export function WithdrawalConfirmationQuestion({
                       <div class="mt-6 border-t border-gray-100">
                         <dl class="divide-y divide-gray-100">
                           {((): VNode => {
+                            if (!details.account.isKnown) {
+                              return <div class="px-4 py-2 sm:grid 
sm:grid-cols-3 sm:gap-4 sm:px-0">
+                                <dt class="text-sm font-medium leading-6 
text-gray-900">
+                                  <i18n.Translate>
+                                    Payment provider's account
+                                  </i18n.Translate>
+                                </dt>
+                                <dd class="mt-1 text-sm leading-6 
text-gray-700 sm:col-span-2 sm:mt-0">
+                                  {details.account.targetPath}
+                                </dd>
+                              </div>
+                            }
                             switch (details.account.targetType) {
                               case "iban": {
-                                const p = details.account as PaytoUriIBAN;
-                                const name = p.params["receiver-name"];
+                                const name = 
details.account.params["receiver-name"];
                                 return (
                                   <Fragment>
                                     <div class="px-4 py-2 sm:grid 
sm:grid-cols-3 sm:gap-4 sm:px-0">
@@ -235,7 +246,7 @@ export function WithdrawalConfirmationQuestion({
                                         </i18n.Translate>
                                       </dt>
                                       <dd class="mt-1 text-sm leading-6 
text-gray-700 sm:col-span-2 sm:mt-0">
-                                        {p.iban}
+                                        {details.account.iban}
                                       </dd>
                                     </div>
                                     {name && (
@@ -254,10 +265,19 @@ export function WithdrawalConfirmationQuestion({
                                 );
                               }
                               case "x-taler-bank": {
-                                const p = details.account as PaytoUriTalerBank;
-                                const name = p.params["receiver-name"];
+                                const name = 
details.account.params["receiver-name"];
                                 return (
                                   <Fragment>
+                                    <div class="px-4 py-2 sm:grid 
sm:grid-cols-3 sm:gap-4 sm:px-0">
+                                      <dt class="text-sm font-medium leading-6 
text-gray-900">
+                                        <i18n.Translate>
+                                          Payment provider's account bank 
hostname
+                                        </i18n.Translate>
+                                      </dt>
+                                      <dd class="mt-1 text-sm leading-6 
text-gray-700 sm:col-span-2 sm:mt-0">
+                                        {details.account.host}
+                                      </dd>
+                                    </div>
                                     <div class="px-4 py-2 sm:grid 
sm:grid-cols-3 sm:gap-4 sm:px-0">
                                       <dt class="text-sm font-medium leading-6 
text-gray-900">
                                         <i18n.Translate>
@@ -265,7 +285,7 @@ export function WithdrawalConfirmationQuestion({
                                         </i18n.Translate>
                                       </dt>
                                       <dd class="mt-1 text-sm leading-6 
text-gray-700 sm:col-span-2 sm:mt-0">
-                                        {p.account}
+                                        {details.account.account}
                                       </dd>
                                     </div>
                                     {name && (
@@ -283,19 +303,39 @@ export function WithdrawalConfirmationQuestion({
                                   </Fragment>
                                 );
                               }
-                              default:
+                              case "bitcoin": {
+                                const name = 
details.account.params["receiver-name"];
                                 return (
-                                  <div class="px-4 py-2 sm:grid sm:grid-cols-3 
sm:gap-4 sm:px-0">
-                                    <dt class="text-sm font-medium leading-6 
text-gray-900">
-                                      <i18n.Translate>
-                                        Payment provider's account
-                                      </i18n.Translate>
-                                    </dt>
-                                    <dd class="mt-1 text-sm leading-6 
text-gray-700 sm:col-span-2 sm:mt-0">
-                                      {details.account.targetPath}
-                                    </dd>
-                                  </div>
+                                  <Fragment>
+                                    <div class="px-4 py-2 sm:grid 
sm:grid-cols-3 sm:gap-4 sm:px-0">
+                                      <dt class="text-sm font-medium leading-6 
text-gray-900">
+                                        <i18n.Translate>
+                                          Payment provider's account address
+                                        </i18n.Translate>
+                                      </dt>
+                                      <dd class="mt-1 text-sm leading-6 
text-gray-700 sm:col-span-2 sm:mt-0">
+                                        {details.account.address}
+                                      </dd>
+                                    </div>
+                                    {name && (
+                                      <div class="px-4 py-2 sm:grid 
sm:grid-cols-3 sm:gap-4 sm:px-0">
+                                        <dt class="text-sm font-medium 
leading-6 text-gray-900">
+                                          <i18n.Translate>
+                                            Payment provider's name
+                                          </i18n.Translate>
+                                        </dt>
+                                        <dd class="mt-1 text-sm leading-6 
text-gray-700 sm:col-span-2 sm:mt-0">
+                                          {name}
+                                        </dd>
+                                      </div>
+                                    )}
+                                  </Fragment>
                                 );
+                              }
+                              default: {
+                                assertUnreachable(details.account)
+                              }
+
                             }
                           })()}
                           <div class="px-4 py-2 sm:grid sm:grid-cols-3 
sm:gap-4 sm:px-0">
diff --git a/packages/bank-ui/src/pages/account/ShowAccountDetails.tsx 
b/packages/bank-ui/src/pages/account/ShowAccountDetails.tsx
index e81d46d77..13685c2c8 100644
--- a/packages/bank-ui/src/pages/account/ShowAccountDetails.tsx
+++ b/packages/bank-ui/src/pages/account/ShowAccountDetails.tsx
@@ -19,10 +19,13 @@ import {
   TalerCorebankApi,
   TalerError,
   TalerErrorCode,
+  TalerRevenueHttpClient,
   TranslatedString,
   assertUnreachable,
+  parsePaytoUri,
 } from "@gnu-taler/taler-util";
 import {
+  CopyButton,
   Loading,
   LocalNotificationBanner,
   notifyInfo,
@@ -67,7 +70,7 @@ export function ShowAccountDetails({
   const { i18n } = useTranslationContext();
   const { state: credentials } = useSessionState();
   const creds = credentials.status !== "loggedIn" ? undefined : credentials;
-  const { bank: api } = useBankCoreApiContext();
+  const { bank } = useBankCoreApiContext();
   const accountIsTheCurrentUser =
     credentials.status === "loggedIn"
       ? credentials.username === account
@@ -99,7 +102,7 @@ export function ShowAccountDetails({
   async function doUpdate() {
     if (!submitAccount || !creds) return;
     await handleError(async () => {
-      const resp = await api.updateAccount(
+      const resp = await bank.updateAccount(
         {
           token: creds.token,
           username: account,
@@ -186,6 +189,31 @@ export function ShowAccountDetails({
     });
   }
 
+
+  const url = bank.getRevenueAPI(account)
+  url.username = account;
+  const baseURL = url.href;
+
+  const ac = parsePaytoUri(result.body.payto_uri);
+  const payto = !ac?.isKnown ? undefined : ac;
+  let accountLetter: string | undefined = undefined;
+  if (payto) {
+    switch (payto.targetType) {
+      case "iban": {
+        accountLetter = 
`account-info-url=${url.href}\naccount-type=${payto.targetType}\niban=${payto.iban}\nreceiver-name=${result.body.name}\n`;
+        break;
+      }
+      case "x-taler-bank": {
+        accountLetter = 
`account-info-url=${url.href}\naccount-type=${payto.targetType}\naccount=${payto.account}\nhost=${payto.host}\nreceiver-name=${result.body.name}\n`;
+        break;
+      }
+      case "bitcoin": {
+        accountLetter = 
`account-info-url=${url.href}\naccount-type=${payto.targetType}\naddress=${payto.address}\nreceiver-name=${result.body.name}\n`;
+        break;
+      }
+    }
+  }
+
   return (
     <Fragment>
       <LocalNotificationBanner notification={notification} showDebug={true} />
@@ -247,6 +275,198 @@ export function ShowAccountDetails({
           </div>
         </AccountForm>
       </div>
+      <div class="grid grid-cols-1 gap-x-8 gap-y-8 pt-6 md:grid-cols-3 
bg-gray-100 my-4 px-4 pb-4 rounded-lg">
+        <div class="px-4 sm:px-0">
+          <h2 class="text-base font-semibold leading-7 text-gray-900">
+            <div class="flex items-center justify-between">
+              <span class="flex flex-grow flex-col">
+                <span
+                  class="text-sm text-black font-semibold leading-6 "
+                  id="availability-label"
+                >
+                  <i18n.Translate>Merchant integration</i18n.Translate>
+                </span>
+              </span>
+            </div>
+          </h2>
+          <p class="mt-2 text-sm text-gray-500">
+            <i18n.Translate>
+              Use this information to link your Taler Merchant Backoffice 
account
+              with the current bank account. You can start by copying the 
values,
+              then go to your merchant backoffice service provider, login into
+              your account and look for the "import" button in the "bank 
account" section.
+            </i18n.Translate>
+          </p>
+        </div>
+
+        {payto !== undefined &&
+          <div class="bg-white shadow-sm ring-1 ring-gray-900/5 sm:rounded-xl 
md:col-span-2">
+            <div class="px-4 py-6 sm:p-8">
+              <div class="grid max-w-2xl grid-cols-1 gap-x-6 gap-y-8 
sm:grid-cols-6">
+                <div class="sm:col-span-5">
+                  <label
+                    class="block text-sm font-medium leading-6 text-gray-900"
+                    for="account-type"
+                  >
+                    {i18n.str`Account type`}
+                  </label>
+                  <div class="mt-2">
+                    <input
+                      type="text"
+                      class="block w-full disabled:bg-gray-100 rounded-md 
border-0 py-1.5 text-gray-900 shadow-sm ring-1 ring-inset ring-gray-300 
data-[error=true]:ring-red-500 placeholder:text-gray-400 focus:ring-2 
focus:ring-inset focus:ring-indigo-600 sm:text-sm sm:leading-6"
+                      name="account-type"
+                      id="account-type"
+                      disabled={true}
+                      value={account}
+                      autocomplete="off"
+                    />
+                  </div>
+                  <p class="mt-2 text-sm text-gray-500">
+                    <i18n.Translate>Method to use for wire 
transfer.</i18n.Translate>
+                  </p>
+                </div>
+                {((payto) => {
+                  switch (payto.targetType) {
+                    case "iban": {
+                      return <div class="sm:col-span-5">
+                        <label
+                          class="block text-sm font-medium leading-6 
text-gray-900"
+                          for="iban"
+                        >
+                          {i18n.str`IBAN`}
+                        </label>
+                        <div class="mt-2">
+                          <input
+                            type="text"
+                            class="block w-full disabled:bg-gray-100 
rounded-md border-0 py-1.5 text-gray-900 shadow-sm ring-1 ring-inset 
ring-gray-300 data-[error=true]:ring-red-500 placeholder:text-gray-400 
focus:ring-2 focus:ring-inset focus:ring-indigo-600 sm:text-sm sm:leading-6"
+                            name="iban"
+                            id="iban"
+                            disabled={true}
+                            value={payto.iban}
+                            autocomplete="off"
+                          />
+                        </div>
+                        <p class="mt-2 text-sm text-gray-500">
+                          <i18n.Translate>International Bank Account 
Number.</i18n.Translate>
+                        </p>
+                      </div>
+                    }
+                    case "x-taler-bank": {
+                      return <div class="sm:col-span-5">
+                        <label
+                          class="block text-sm font-medium leading-6 
text-gray-900"
+                          for="iban"
+                        >
+                          {i18n.str`IBAN`}
+                        </label>
+                        <div class="mt-2">
+                          <input
+                            type="text"
+                            class="block w-full disabled:bg-gray-100 
rounded-md border-0 py-1.5 text-gray-900 shadow-sm ring-1 ring-inset 
ring-gray-300 data-[error=true]:ring-red-500 placeholder:text-gray-400 
focus:ring-2 focus:ring-inset focus:ring-indigo-600 sm:text-sm sm:leading-6"
+                            name="iban"
+                            id="iban"
+                            disabled={true}
+                            value={payto.account}
+                            autocomplete="off"
+                          />
+                        </div>
+                        <p class="mt-2 text-sm text-gray-500">
+                          <i18n.Translate>International Bank Account 
Number.</i18n.Translate>
+                        </p>
+                      </div>
+                    }
+                    case "bitcoin": {
+                      return <div class="sm:col-span-5">
+                        <label
+                          class="block text-sm font-medium leading-6 
text-gray-900"
+                          for="iban"
+                        >
+                          {i18n.str`Address`}
+                        </label>
+                        <div class="mt-2">
+                          <input
+                            type="text"
+                            class="block w-full disabled:bg-gray-100 
rounded-md border-0 py-1.5 text-gray-900 shadow-sm ring-1 ring-inset 
ring-gray-300 data-[error=true]:ring-red-500 placeholder:text-gray-400 
focus:ring-2 focus:ring-inset focus:ring-indigo-600 sm:text-sm sm:leading-6"
+                            name="iban"
+                            id="iban"
+                            disabled={true}
+                            value={"DE1231231231"}
+                            autocomplete="off"
+                          />
+                        </div>
+                        <p class="mt-2 text-sm text-gray-500">
+                          <i18n.Translate>International Bank Account 
Number.</i18n.Translate>
+                        </p>
+                      </div>
+                    }
+                  }
+                })(payto)}
+
+                <div class="sm:col-span-5">
+                  <label
+                    class="block text-sm font-medium leading-6 text-gray-900"
+                    for="iban"
+                  >
+                    {i18n.str`Owner's name`}
+                  </label>
+                  <div class="mt-2">
+                    <input
+                      type="text"
+                      class="block w-full disabled:bg-gray-100 rounded-md 
border-0 py-1.5 text-gray-900 shadow-sm ring-1 ring-inset ring-gray-300 
data-[error=true]:ring-red-500 placeholder:text-gray-400 focus:ring-2 
focus:ring-inset focus:ring-indigo-600 sm:text-sm sm:leading-6"
+                      name="iban"
+                      id="iban"
+                      disabled={true}
+                      value={result.body.name}
+                      autocomplete="off"
+                    />
+                  </div>
+                  <p class="mt-2 text-sm text-gray-500">
+                    <i18n.Translate>Legal name of the person holding the 
account.</i18n.Translate>
+                  </p>
+                </div>
+                <div class="sm:col-span-5">
+                  <label
+                    class="block text-sm font-medium leading-6 text-gray-900"
+                    for="iban"
+                  >
+                    {i18n.str`Account info URL`}
+                  </label>
+                  <div class="mt-2">
+                    <input
+                      type="text"
+                      class="block w-full disabled:bg-gray-100 rounded-md 
border-0 py-1.5 text-gray-900 shadow-sm ring-1 ring-inset ring-gray-300 
data-[error=true]:ring-red-500 placeholder:text-gray-400 focus:ring-2 
focus:ring-inset focus:ring-indigo-600 sm:text-sm sm:leading-6"
+                      name="iban"
+                      id="iban"
+                      disabled={true}
+                      value={baseURL}
+                      autocomplete="off"
+                    />
+                  </div>
+                  <p class="mt-2 text-sm text-gray-500">
+                    <i18n.Translate>From where the merchant can download 
information about incoming wire transfers to this account.</i18n.Translate>
+                  </p>
+                </div>
+              </div>
+            </div>
+            <div class="flex items-center justify-between gap-x-6 border-t 
border-gray-900/10 px-4 py-4 sm:px-8">
+              <a
+                href={routeClose.url({})}
+                name="cancel"
+                class="text-sm font-semibold leading-6 text-gray-900"
+              >
+                <i18n.Translate>Cancel</i18n.Translate>
+              </a>
+              <CopyButton
+                getContent={() => accountLetter ?? ""}
+                class="flex text-center disabled:opacity-50 
disabled:cursor-default cursor-pointer rounded-md bg-indigo-600 px-3 py-2 
text-sm font-semibold text-white shadow-sm hover:bg-indigo-500 
focus-visible:outline focus-visible:outline-2 focus-visible:outline-offset-2 
focus-visible:outline-indigo-600">
+                <i18n.Translate>Copy</i18n.Translate>
+              </CopyButton>
+            </div>
+          </div>
+        }
+
+      </div>
+
     </Fragment>
   );
 }
diff --git a/packages/bank-ui/src/pages/admin/DownloadStats.tsx 
b/packages/bank-ui/src/pages/admin/DownloadStats.tsx
index 078435fe9..bef12c580 100644
--- a/packages/bank-ui/src/pages/admin/DownloadStats.tsx
+++ b/packages/bank-ui/src/pages/admin/DownloadStats.tsx
@@ -460,9 +460,9 @@ async function fetchAllStatus(
       // await delay()
       const previous = options.compareWithPrevious
         ? await api.getMonitor(token, {
-          timeframe: frame.timeframe,
-          which: frame.moment.previous,
-        })
+            timeframe: frame.timeframe,
+            which: frame.moment.previous,
+          })
         : undefined;
 
       if (previous && previous.type === "fail" && options.endOnFirstFail) {
diff --git a/packages/bank-ui/src/pages/regional/ConversionConfig.tsx 
b/packages/bank-ui/src/pages/regional/ConversionConfig.tsx
index 8602580a0..014142e97 100644
--- a/packages/bank-ui/src/pages/regional/ConversionConfig.tsx
+++ b/packages/bank-ui/src/pages/regional/ConversionConfig.tsx
@@ -519,8 +519,8 @@ function useComponentState({
                     </div>
 
                     {cashoutCalc &&
-                      status.status === "ok" &&
-                      Amounts.cmp(status.result.amount, cashoutCalc.credit) <
+                    status.status === "ok" &&
+                    Amounts.cmp(status.result.amount, cashoutCalc.credit) <
                       0 ? (
                       <div class="p-4">
                         <Attention
diff --git a/packages/bank-ui/src/pages/regional/CreateCashout.tsx 
b/packages/bank-ui/src/pages/regional/CreateCashout.tsx
index 8f16e31be..20d6b0bff 100644
--- a/packages/bank-ui/src/pages/regional/CreateCashout.tsx
+++ b/packages/bank-ui/src/pages/regional/CreateCashout.tsx
@@ -198,7 +198,8 @@ export function CreateCashout({
    * depending on the isDebit flag
    */
   const inputAmount = Amounts.parseOrThrow(
-    `${form.isDebit ? regional_currency : fiat_currency}:${!form.amount ? "0" 
: form.amount
+    `${form.isDebit ? regional_currency : fiat_currency}:${
+      !form.amount ? "0" : form.amount
     }`,
   );
 
@@ -239,11 +240,12 @@ export function CreateCashout({
         : Amounts.cmp(limit, calc.debit) === -1
           ? i18n.str`Balance is not enough`
           : form.isDebit &&
-            Amounts.cmp(inputAmount, conversionInfo.cashout_min_amount) < 1
-            ? i18n.str`Needs to be higher than 
${Amounts.stringifyValueWithSpec(
-              Amounts.parseOrThrow(conversionInfo.cashout_min_amount),
-              regional_currency_specification,
-            ).normal
+              Amounts.cmp(inputAmount, conversionInfo.cashout_min_amount) < 1
+            ? i18n.str`Needs to be higher than ${
+                Amounts.stringifyValueWithSpec(
+                  Amounts.parseOrThrow(conversionInfo.cashout_min_amount),
+                  regional_currency_specification,
+                ).normal
               }`
             : calculationResult === "amount-is-too-small"
               ? i18n.str`Amount needs to be higher`
@@ -611,9 +613,9 @@ export function CreateCashout({
                       cashoutDisabled
                         ? undefined
                         : (value) => {
-                          form.amount = value;
-                          updateForm(structuredClone(form));
-                        }
+                            form.amount = value;
+                            updateForm(structuredClone(form));
+                          }
                     }
                   />
                   <ShowInputErrorLabel
@@ -654,7 +656,7 @@ export function CreateCashout({
                       </dd>
                     </div>
                     {Amounts.isZero(sellFee) ||
-                      Amounts.isZero(calc.beforeFee) ? undefined : (
+                    Amounts.isZero(calc.beforeFee) ? undefined : (
                       <div class="flex items-center justify-between border-t-2 
afu pt-4">
                         <dt class="flex items-center text-sm text-gray-600">
                           <span>
@@ -687,7 +689,7 @@ export function CreateCashout({
 
               {/* channel, not shown if new cashout api */}
               {!OLD_CASHOUT_API ? undefined : config.supported_tan_channels
-                .length === 0 ? (
+                  .length === 0 ? (
                 <div class="sm:col-span-5">
                   <Attention
                     type="warning"
@@ -759,7 +761,7 @@ export function CreateCashout({
                       )}
 
                       {config.supported_tan_channels.indexOf(TanChannel.SMS) 
===
-                        -1 ? undefined : (
+                      -1 ? undefined : (
                         <label
                           onClick={() => {
                             if (!resultAccount.body.contact_data?.phone) 
return;
diff --git a/packages/bank-ui/src/pages/regional/ShowCashoutDetails.tsx 
b/packages/bank-ui/src/pages/regional/ShowCashoutDetails.tsx
index 0f9f2d1b7..849da77aa 100644
--- a/packages/bank-ui/src/pages/regional/ShowCashoutDetails.tsx
+++ b/packages/bank-ui/src/pages/regional/ShowCashoutDetails.tsx
@@ -138,7 +138,7 @@ export function ShowCashoutDetails({ id, routeClose }: 
Props): VNode {
                           timestamp={AbsoluteTime.fromProtocolTimestamp(
                             result.body.creation_time,
                           )}
-                        // relative={Duration.fromSpec({ days: 1 })}
+                          // relative={Duration.fromSpec({ days: 1 })}
                         />
                       </dd>
                     </div>
diff --git a/packages/taler-util/src/payto.ts b/packages/taler-util/src/payto.ts
index 314c8cdbc..a471d0b87 100644
--- a/packages/taler-util/src/payto.ts
+++ b/packages/taler-util/src/payto.ts
@@ -72,6 +72,7 @@ export interface PaytoUriTalerBank extends PaytoUriGeneric {
 export interface PaytoUriBitcoin extends PaytoUriGeneric {
   isKnown: true;
   targetType: "bitcoin";
+  address: string;
   segwitAddrs: Array<string>;
 }
 
@@ -101,10 +102,12 @@ export function buildPayto(
 ): PaytoUriGeneric {
   switch (type) {
     case "bitcoin": {
+      const uppercased = first.toUpperCase();
       const result: PaytoUriBitcoin = {
         isKnown: true,
         targetType: "bitcoin",
         targetPath: first,
+        address: uppercased,
         params: {},
         segwitAddrs: !second ? [] : generateFakeSegwitAddress(second, first),
       };
@@ -247,10 +250,12 @@ export function parsePaytoUri(s: string): PaytoUri | 
undefined {
       ? []
       : generateFakeSegwitAddress(reserve, targetPath);
 
+    const uppercased = targetType.toUpperCase();
     const result: PaytoUriBitcoin = {
       isKnown: true,
       targetPath,
       targetType,
+      address: uppercased,
       params,
       segwitAddrs,
     };
diff --git 
a/packages/taler-wallet-webextension/src/wallet/ManageAccount/stories.tsx 
b/packages/taler-wallet-webextension/src/wallet/ManageAccount/stories.tsx
index b77c456e5..c01797e31 100644
--- a/packages/taler-wallet-webextension/src/wallet/ManageAccount/stories.tsx
+++ b/packages/taler-wallet-webextension/src/wallet/ManageAccount/stories.tsx
@@ -58,6 +58,7 @@ export const JustTwoBitcoinAccounts = 
tests.createExample(ReadyView, {
           targetType: "bitcoin",
           segwitAddrs: [],
           isKnown: true,
+          address: "bc1qxy2kgdygjrsqtzq2n0yrf2493p83kkfjhx0wlh",
           targetPath: "bc1qxy2kgdygjrsqtzq2n0yrf2493p83kkfjhx0wlh",
           params: {},
         },
@@ -69,6 +70,7 @@ export const JustTwoBitcoinAccounts = 
tests.createExample(ReadyView, {
         uri: {
           targetType: "bitcoin",
           segwitAddrs: [],
+          address: "bc1qxy2kgdygjrsqtzq2n0yrf2493p83kkfjhx0wlh",
           isKnown: true,
           targetPath: "bc1qxy2kgdygjrsqtzq2n0yrf2493p83kkfjhx0wlh",
           params: {},
@@ -138,6 +140,7 @@ export const WithAllTypeOfAccounts = 
tests.createExample(ReadyView, {
           targetType: "bitcoin",
           segwitAddrs: [],
           isKnown: true,
+          address: "bc1qxy2kgdygjrsqtzq2n0yrf2493p83kkfjhx0wlh",
           targetPath: "bc1qxy2kgdygjrsqtzq2n0yrf2493p83kkfjhx0wlh",
           params: {},
         },
@@ -150,6 +153,7 @@ export const WithAllTypeOfAccounts = 
tests.createExample(ReadyView, {
           targetType: "bitcoin",
           segwitAddrs: [],
           isKnown: true,
+          address: "bc1qxy2kgdygjrsqtzq2n0yrf2493p83kkfjhx0wlh",
           targetPath: "bc1qxy2kgdygjrsqtzq2n0yrf2493p83kkfjhx0wlh",
           params: {},
         },
diff --git a/packages/web-util/src/components/CopyButton.tsx 
b/packages/web-util/src/components/CopyButton.tsx
index fd7f8b3b4..dbb38b474 100644
--- a/packages/web-util/src/components/CopyButton.tsx
+++ b/packages/web-util/src/components/CopyButton.tsx
@@ -1,4 +1,4 @@
-import { h, VNode } from "preact";
+import { ComponentChildren, h, VNode } from "preact";
 import { useEffect, useState } from "preact/hooks";
 
 export function CopyIcon(): VNode {
@@ -17,7 +17,7 @@ export function CopiedIcon(): VNode {
   )
 };
 
-export function CopyButton({ class: clazz, getContent }: { class: string, 
getContent: () => string }): VNode {
+export function CopyButton({ class: clazz, children, getContent }: { 
children?: ComponentChildren, class: string, getContent: () => string }): VNode 
{
   const [copied, setCopied] = useState(false);
   function copyText(): void {
     if (!navigator.clipboard && !window.isSecureContext) {
@@ -43,12 +43,14 @@ export function CopyButton({ class: clazz, getContent }: { 
class: string, getCon
         copyText()
       }} >
         <CopyIcon />
+        {children}
       </button>
     );
   }
   return (
     <button class={clazz} disabled>
       <CopiedIcon />
+      {children}
     </button>
   );
 }

-- 
To stop receiving notification emails like this one, please contact
gnunet@gnunet.org.



reply via email to

[Prev in Thread] Current Thread [Next in Thread]