gnunet-svn
[Top][All Lists]
Advanced

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

[GNUnet-SVN] [taler-wallet-core] 01/02: cli refunds


From: gnunet
Subject: [GNUnet-SVN] [taler-wallet-core] 01/02: cli refunds
Date: Sat, 31 Aug 2019 12:00:09 +0200

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

dold pushed a commit to branch master
in repository wallet-core.

commit 5a7269b20db0371535669c0faa7f1814d967b5ca
Author: Florian Dold <address@hidden>
AuthorDate: Sat Aug 31 11:49:36 2019 +0200

    cli refunds
---
 src/headless/taler-wallet-cli.ts | 14 +++++++++++
 src/taleruri.ts                  | 53 ++++++++++++++++++++++++++++++++++++++++
 src/wallet.ts                    | 17 +++++++++----
 src/webex/pages/pay.tsx          | 13 +++++-----
 src/webex/pages/refund.tsx       |  8 ++++--
 src/webex/pages/tip.tsx          | 29 +++-------------------
 src/webex/renderHtml.tsx         | 25 +++++++++++++++++++
 src/webex/wxBackend.ts           |  2 +-
 8 files changed, 121 insertions(+), 40 deletions(-)

diff --git a/src/headless/taler-wallet-cli.ts b/src/headless/taler-wallet-cli.ts
index 86eaec64..bfa1ac4b 100644
--- a/src/headless/taler-wallet-cli.ts
+++ b/src/headless/taler-wallet-cli.ts
@@ -179,6 +179,20 @@ program
     wallet.stop();
   });
 
+
+
+  program
+  .command("refund-uri <refund-uri>")
+  .action(async (refundUri, cmdObj) => {
+    applyVerbose(program.verbose);
+    console.log("getting refund", refundUri);
+    const wallet = await getDefaultNodeWallet({
+      persistentStoragePath: walletDbPath,
+    });
+    await wallet.applyRefund(refundUri);
+    wallet.stop();
+  });
+
 program
   .command("pay-uri <pay-uri")
   .option("-y, --yes", "automatically answer yes to prompts")
diff --git a/src/taleruri.ts b/src/taleruri.ts
index f5fc7742..bd01abb6 100644
--- a/src/taleruri.ts
+++ b/src/taleruri.ts
@@ -26,6 +26,10 @@ export interface WithdrawUriResult {
   statusUrl: string;
 }
 
+export interface RefundUriResult {
+  refundUrl: string;
+}
+
 export interface TipUriResult {
   tipPickupUrl: string;
   tipId: string;
@@ -155,3 +159,52 @@ export function parseTipUri(s: string): TipUriResult | 
undefined {
     merchantOrigin: new URI(tipPickupUrl).origin(),
   };
 }
+
+export function parseRefundUri(s: string): RefundUriResult | undefined {
+  const parsedUri = new URI(s);
+  if (parsedUri.scheme() != "taler") {
+    return undefined;
+  }
+  if (parsedUri.authority() != "refund") {
+    return undefined;
+  }
+
+  let [
+    _,
+    host,
+    maybePath,
+    maybeInstance,
+    orderId,
+  ] = parsedUri.path().split("/");
+
+  if (!host) {
+    return undefined;
+  }
+
+  if (!maybePath) {
+    return undefined;
+  }
+
+  if (!orderId) {
+    return undefined;
+  }
+
+  if (maybePath === "-") {
+    maybePath = "public/refund";
+  } else {
+    maybePath = decodeURIComponent(maybePath);
+  }
+  if (maybeInstance === "-") {
+    maybeInstance = "default";
+  }
+
+  const refundUrl = new URI(
+    "https://"; + host + "/" + decodeURIComponent(maybePath),
+  )
+    .addQuery({ instance: maybeInstance, order_id: orderId })
+    .href();
+
+  return {
+    refundUrl,
+  };
+}
\ No newline at end of file
diff --git a/src/wallet.ts b/src/wallet.ts
index fd1be529..00a82f92 100644
--- a/src/wallet.ts
+++ b/src/wallet.ts
@@ -109,7 +109,7 @@ import {
   AcceptWithdrawalResponse,
 } from "./walletTypes";
 import { openPromise } from "./promiseUtils";
-import { parsePayUri, parseWithdrawUri, parseTipUri } from "./taleruri";
+import { parsePayUri, parseWithdrawUri, parseTipUri, parseRefundUri } from 
"./taleruri";
 
 interface SpeculativePayData {
   payCoinInfo: PayCoinInfo;
@@ -3109,7 +3109,7 @@ export class Wallet {
     }
   }
 
-  async acceptRefundResponse(
+  private async acceptRefundResponse(
     refundResponse: MerchantRefundResponse,
   ): Promise<string> {
     const refundPermissions = refundResponse.refund_permissions;
@@ -3149,8 +3149,7 @@ export class Wallet {
       .finish();
     this.notifier.notify();
 
-    // Start submitting it but don't wait for it here.
-    this.submitRefunds(hc);
+    await this.submitRefunds(hc);
 
     return hc;
   }
@@ -3159,7 +3158,15 @@ export class Wallet {
    * Accept a refund, return the contract hash for the contract
    * that was involved in the refund.
    */
-  async acceptRefund(refundUrl: string): Promise<string> {
+  async applyRefund(talerRefundUri: string): Promise<string> {
+    const parseResult = parseRefundUri(talerRefundUri);
+
+    if (!parseResult) {
+      throw Error("invalid refund URI");
+    }
+
+    const refundUrl = parseResult.refundUrl;
+
     Wallet.enableTracing && console.log("processing refund");
     let resp;
     try {
diff --git a/src/webex/pages/pay.tsx b/src/webex/pages/pay.tsx
index d929426c..1561dd95 100644
--- a/src/webex/pages/pay.tsx
+++ b/src/webex/pages/pay.tsx
@@ -30,7 +30,7 @@ import { ExchangeRecord, ProposalDownloadRecord } from 
"../../dbTypes";
 import { ContractTerms } from "../../talerTypes";
 import { CheckPayResult, PreparePayResult } from "../../walletTypes";
 
-import { renderAmount } from "../renderHtml";
+import { renderAmount, ProgressButton } from "../renderHtml";
 import * as wxApi from "../wxApi";
 
 import React, { useState, useEffect } from "react";
@@ -44,6 +44,7 @@ function TalerPayDialog({ talerPayUri }: { talerPayUri: 
string }) {
   const [payStatus, setPayStatus] = useState<PreparePayResult | undefined>();
   const [payErrMsg, setPayErrMsg] = useState<string | undefined>("");
   const [numTries, setNumTries] = useState(0);
+  const [loading, setLoading] = useState(false);
   let totalFees: Amounts.AmountJson | undefined = undefined;
 
   useEffect(() => {
@@ -99,6 +100,7 @@ function TalerPayDialog({ talerPayUri }: { talerPayUri: 
string }) {
   const doPayment = async () => {
     setNumTries(numTries + 1);
     try {
+      setLoading(true);
       const res = await wxApi.confirmPay(payStatus!.proposalId!, undefined);
       document.location.href = res.nextUrl;
     } catch (e) {
@@ -140,12 +142,11 @@ function TalerPayDialog({ talerPayUri }: { talerPayUri: 
string }) {
         </div>
       ) : (
         <div>
-          <button
-            className="pure-button button-success"
-            onClick={() => doPayment()}
-          >
+          <ProgressButton
+            loading={loading}
+            onClick={() => doPayment()}>
             {i18n.str`Confirm payment`}
-          </button>
+          </ProgressButton>
         </div>
       )}
     </div>
diff --git a/src/webex/pages/refund.tsx b/src/webex/pages/refund.tsx
index 6bc1a136..57d74048 100644
--- a/src/webex/pages/refund.tsx
+++ b/src/webex/pages/refund.tsx
@@ -188,8 +188,12 @@ async function main() {
     return;
   }
 
-  const contractTermsHash = query.contractTermsHash;
-  const refundUrl = query.refundUrl;
+  const talerRefundUri = query.talerRefundUri;
+  if (!talerRefundUri) {
+    console.error("taler refund URI requred");
+    return;
+  }
+
   ReactDOM.render(<RefundStatusView contractTermsHash={contractTermsHash} 
refundUrl={refundUrl} />, container);
 }
 
diff --git a/src/webex/pages/tip.tsx b/src/webex/pages/tip.tsx
index a3f5c38c..0a066053 100644
--- a/src/webex/pages/tip.tsx
+++ b/src/webex/pages/tip.tsx
@@ -29,35 +29,12 @@ import * as i18n from "../../i18n";
 
 import { acceptTip, getReserveCreationInfo, getTipStatus } from "../wxApi";
 
-import { WithdrawDetailView, renderAmount } from "../renderHtml";
+import { WithdrawDetailView, renderAmount, ProgressButton } from 
"../renderHtml";
 
 import * as Amounts from "../../amounts";
 import { useState, useEffect } from "react";
 import { TipStatus } from "../../walletTypes";
 
-interface LoadingButtonProps {
-  loading: boolean;
-}
-
-function LoadingButton(
-  props:
-    & React.PropsWithChildren<LoadingButtonProps>
-    & React.DetailedHTMLProps<
-        React.ButtonHTMLAttributes<HTMLButtonElement>,
-        HTMLButtonElement
-      >,
-) {
-  return (
-    <button
-      className="pure-button pure-button-primary"
-      type="button"
-      {...props}
-    >
-      {props.loading ? <span><object className="svg-icon svg-baseline" 
data="/img/spinner-bars.svg" /></span> : null}
-      {props.children}
-    </button>
-  );
-}
 
 function TipDisplay(props: { talerTipUri: string }) {
   const [tipStatus, setTipStatus] = useState<TipStatus | undefined>(undefined);
@@ -110,9 +87,9 @@ function TipDisplay(props: { talerTipUri: string }) {
         operation.
       </p>
       <form className="pure-form">
-        <LoadingButton loading={loading} onClick={() => accept()}>
+        <ProgressButton loading={loading} onClick={() => accept()}>
           AcceptTip
-        </LoadingButton>
+        </ProgressButton>
         {" "}
         <button className="pure-button" type="button" onClick={() => 
discard()}>
           Discard tip
diff --git a/src/webex/renderHtml.tsx b/src/webex/renderHtml.tsx
index e4686ade..867fb440 100644
--- a/src/webex/renderHtml.tsx
+++ b/src/webex/renderHtml.tsx
@@ -316,3 +316,28 @@ export class ExpanderText extends 
ImplicitStateComponent<ExpanderTextProps> {
   }
 }
 
+
+export interface LoadingButtonProps {
+  loading: boolean;
+}
+
+export function ProgressButton(
+  props:
+    & React.PropsWithChildren<LoadingButtonProps>
+    & React.DetailedHTMLProps<
+        React.ButtonHTMLAttributes<HTMLButtonElement>,
+        HTMLButtonElement
+      >,
+) {
+  return (
+    <button
+      className="pure-button pure-button-primary"
+      type="button"
+      {...props}
+    >
+      {props.loading ? <span><object className="svg-icon svg-baseline" 
data="/img/spinner-bars.svg" /></span> : null}
+      {" "}
+      {props.children}
+    </button>
+  );
+}
\ No newline at end of file
diff --git a/src/webex/wxBackend.ts b/src/webex/wxBackend.ts
index 5bff4fe0..70a7557e 100644
--- a/src/webex/wxBackend.ts
+++ b/src/webex/wxBackend.ts
@@ -292,7 +292,7 @@ function handleMessage(
     case "get-full-refund-fees":
       return needsWallet().getFullRefundFees(detail.refundPermissions);
     case "accept-refund":
-      return needsWallet().acceptRefund(detail.refundUrl);
+      return needsWallet().applyRefund(detail.refundUrl);
     case "get-tip-status": {
       return needsWallet().getTipStatus(detail.talerTipUri);
     }

-- 
To stop receiving notification emails like this one, please contact
address@hidden.



reply via email to

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