gnunet-svn
[Top][All Lists]
Advanced

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

[taler-wallet-core] 01/03: introducing getBalanceDetail for getting all


From: gnunet
Subject: [taler-wallet-core] 01/03: introducing getBalanceDetail for getting all depositable/transferable amount for a currency
Date: Fri, 20 Jan 2023 19:45:15 +0100

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

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

commit 7ea8321ddd2d56f43dceaa18340f1d1c39a83e76
Author: Sebastian <sebasjm@gmail.com>
AuthorDate: Fri Jan 20 15:41:08 2023 -0300

    introducing getBalanceDetail for getting all depositable/transferable 
amount for a currency
---
 packages/taler-util/src/wallet-types.ts            | 21 ++++++---
 .../taler-wallet-core/src/operations/balance.ts    | 50 ++++++++++++++++++----
 .../taler-wallet-core/src/operations/deposits.ts   |  1 -
 packages/taler-wallet-core/src/wallet-api-types.ts | 21 ++++++---
 packages/taler-wallet-core/src/wallet.ts           | 21 ++++++---
 .../src/wallet/DestinationSelection/index.ts       |  1 +
 .../src/wallet/DestinationSelection/state.ts       | 20 +++++++++
 .../src/wallet/DestinationSelection/stories.tsx    |  2 +
 .../src/wallet/DestinationSelection/test.ts        | 10 +++++
 .../src/wallet/DestinationSelection/views.tsx      | 11 ++++-
 .../src/wallet/History.tsx                         |  4 +-
 packages/taler-wallet-webextension/src/wxApi.ts    |  4 +-
 .../taler-wallet-webextension/src/wxBackend.ts     | 14 ++++--
 13 files changed, 146 insertions(+), 34 deletions(-)

diff --git a/packages/taler-util/src/wallet-types.ts 
b/packages/taler-util/src/wallet-types.ts
index fc383acb0..50cb50f30 100644
--- a/packages/taler-util/src/wallet-types.ts
+++ b/packages/taler-util/src/wallet-types.ts
@@ -105,6 +105,16 @@ export class CreateReserveResponse {
   reservePub: string;
 }
 
+export interface GetBalanceDetailRequest {
+  currency: string;
+}
+
+export const codecForGetBalanceDetailRequest = (): 
Codec<GetBalanceDetailRequest> =>
+  buildCodecForObject<GetBalanceDetailRequest>()
+    .property("currency", codecForString())
+    .build("GetBalanceDetailRequest");
+
+
 export interface Balance {
   available: AmountString;
   pendingIncoming: AmountString;
@@ -215,11 +225,11 @@ export interface CoinDumpJson {
     withdrawal_reserve_pub: string | undefined;
     coin_status: CoinStatus;
     spend_allocation:
-      | {
-          id: string;
-          amount: string;
-        }
-      | undefined;
+    | {
+      id: string;
+      amount: string;
+    }
+    | undefined;
     /**
      * Information about the age restriction
      */
@@ -1792,6 +1802,7 @@ export const codecForUserAttentionsRequest = (): 
Codec<UserAttentionsRequest> =>
     )
     .build("UserAttentionsRequest");
 
+
 export interface UserAttentionsRequest {
   priority?: AttentionPriority;
 }
diff --git a/packages/taler-wallet-core/src/operations/balance.ts 
b/packages/taler-wallet-core/src/operations/balance.ts
index 27b801804..50613d0aa 100644
--- a/packages/taler-wallet-core/src/operations/balance.ts
+++ b/packages/taler-wallet-core/src/operations/balance.ts
@@ -48,14 +48,12 @@
  */
 import {
   AmountJson,
-  BalancesResponse,
   Amounts,
-  Logger,
-  AuditorHandle,
-  ExchangeHandle,
+  BalancesResponse,
   canonicalizeBaseUrl,
+  GetBalanceDetailRequest,
+  Logger,
   parsePaytoUri,
-  TalerErrorCode,
 } from "@gnu-taler/taler-util";
 import {
   AllowedAuditorInfo,
@@ -63,11 +61,10 @@ import {
   RefreshGroupRecord,
   WalletStoresV1,
 } from "../db.js";
-import { GetReadOnlyAccess } from "../util/query.js";
 import { InternalWalletState } from "../internal-wallet-state.js";
-import { getExchangeDetails } from "./exchanges.js";
 import { checkLogicInvariant } from "../util/invariants.js";
-import { TalerError } from "../errors.js";
+import { GetReadOnlyAccess } from "../util/query.js";
+import { getExchangeDetails } from "./exchanges.js";
 
 /**
  * Logger.
@@ -429,6 +426,43 @@ export async function getMerchantPaymentBalanceDetails(
   return d;
 }
 
+export async function getBalanceDetail(
+  ws: InternalWalletState,
+  req: GetBalanceDetailRequest,
+): Promise<MerchantPaymentBalanceDetails> {
+  const exchanges: { exchangeBaseUrl: string; exchangePub: string }[] = [];
+  const wires = new Array<string>();
+  await ws.db
+    .mktx((x) => [x.exchanges, x.exchangeDetails])
+    .runReadOnly(async (tx) => {
+      const allExchanges = await tx.exchanges.iter().toArray();
+      for (const e of allExchanges) {
+        const details = await getExchangeDetails(tx, e.baseUrl);
+        if (!details || req.currency !== details.currency) {
+          continue;
+        }
+        details.wireInfo.accounts.forEach((a) => {
+          const payto = parsePaytoUri(a.payto_uri);
+          if (payto && !wires.includes(payto.targetType)) {
+            wires.push(payto.targetType);
+          }
+        });
+        exchanges.push({
+          exchangePub: details.masterPublicKey,
+          exchangeBaseUrl: e.baseUrl,
+        });
+      }
+    });
+
+  return await getMerchantPaymentBalanceDetails(ws, {
+    currency: req.currency,
+    acceptedAuditors: [],
+    acceptedExchanges: exchanges,
+    acceptedWireMethods: wires,
+    minAge: 0,
+  });
+}
+
 export interface PeerPaymentRestrictionsForBalance {
   currency: string;
   restrictExchangeTo?: string;
diff --git a/packages/taler-wallet-core/src/operations/deposits.ts 
b/packages/taler-wallet-core/src/operations/deposits.ts
index f3ec81686..e97738b55 100644
--- a/packages/taler-wallet-core/src/operations/deposits.ts
+++ b/packages/taler-wallet-core/src/operations/deposits.ts
@@ -457,7 +457,6 @@ export async function prepareDepositGroup(
   };
 }
 
-
 export async function createDepositGroup(
   ws: InternalWalletState,
   req: CreateDepositGroupRequest,
diff --git a/packages/taler-wallet-core/src/wallet-api-types.ts 
b/packages/taler-wallet-core/src/wallet-api-types.ts
index 88ae3a5c1..f14018401 100644
--- a/packages/taler-wallet-core/src/wallet-api-types.ts
+++ b/packages/taler-wallet-core/src/wallet-api-types.ts
@@ -24,7 +24,7 @@
  * Imports.
  */
 import {
-  AbortTransactionRequest as AbortTransactionRequest,
+  AbortTransactionRequest,
   AcceptBankIntegratedWithdrawalRequest,
   AcceptExchangeTosRequest,
   AcceptManualWithdrawalRequest,
@@ -56,6 +56,7 @@ import {
   ExchangesListResponse,
   ForceRefreshRequest,
   ForgetKnownBankAccountsRequest,
+  GetBalanceDetailRequest,
   GetContractTermsDetailsRequest,
   GetExchangeTosRequest,
   GetExchangeTosResult,
@@ -66,14 +67,12 @@ import {
   InitiatePeerPullPaymentResponse,
   InitiatePeerPushPaymentRequest,
   InitiatePeerPushPaymentResponse,
+  InitRequest,
   InitResponse,
   IntegrationTestArgs,
   KnownBankAccounts,
   ListKnownBankAccountsRequest,
   ManualWithdrawalDetails,
-  UserAttentionsCountResponse,
-  UserAttentionsRequest,
-  UserAttentionsResponse,
   PrepareDepositRequest,
   PrepareDepositResponse,
   PreparePayRequest,
@@ -99,14 +98,16 @@ import {
   TransactionByIdRequest,
   TransactionsRequest,
   TransactionsResponse,
+  UserAttentionByIdRequest,
+  UserAttentionsCountResponse,
+  UserAttentionsRequest,
+  UserAttentionsResponse,
   WalletBackupContentV1,
   WalletCoreVersion,
   WalletCurrencyInfo,
   WithdrawFakebankRequest,
   WithdrawTestBalanceRequest,
   WithdrawUriInfoResponse,
-  UserAttentionByIdRequest,
-  InitRequest,
 } from "@gnu-taler/taler-util";
 import { WalletContractData } from "./db.js";
 import {
@@ -116,6 +117,7 @@ import {
   RemoveBackupProviderRequest,
   RunBackupCycleRequest,
 } from "./operations/backup/index.js";
+import { MerchantPaymentBalanceDetails } from "./operations/balance.js";
 import { PendingOperationsResponse as PendingTasksResponse } from 
"./pending-types.js";
 
 export enum WalletApiOperation {
@@ -138,6 +140,7 @@ export enum WalletApiOperation {
   GetWithdrawalDetailsForAmount = "getWithdrawalDetailsForAmount",
   AcceptManualWithdrawal = "acceptManualWithdrawal",
   GetBalances = "getBalances",
+  GetBalanceDetail = "getBalanceDetail",
   GetUserAttentionRequests = "getUserAttentionRequests",
   GetUserAttentionUnreadCount = "getUserAttentionUnreadCount",
   MarkAttentionRequestAsRead = "markAttentionRequestAsRead",
@@ -221,6 +224,11 @@ export type GetBalancesOp = {
   request: EmptyObject;
   response: BalancesResponse;
 };
+export type GetBalancesDetailOp = {
+  op: WalletApiOperation.GetBalanceDetail;
+  request: GetBalanceDetailRequest;
+  response: MerchantPaymentBalanceDetails;
+};
 
 // group: Managing Transactions
 
@@ -831,6 +839,7 @@ export type WalletOperations = {
   [WalletApiOperation.ConfirmPay]: ConfirmPayOp;
   [WalletApiOperation.AbortTransaction]: AbortTransactionOp;
   [WalletApiOperation.GetBalances]: GetBalancesOp;
+  [WalletApiOperation.GetBalanceDetail]: GetBalancesDetailOp;
   [WalletApiOperation.GetTransactions]: GetTransactionsOp;
   [WalletApiOperation.GetTransactionById]: GetTransactionByIdOp;
   [WalletApiOperation.RetryPendingNow]: RetryPendingNowOp;
diff --git a/packages/taler-wallet-core/src/wallet.ts 
b/packages/taler-wallet-core/src/wallet.ts
index 24c7f7b9e..f1ed592bd 100644
--- a/packages/taler-wallet-core/src/wallet.ts
+++ b/packages/taler-wallet-core/src/wallet.ts
@@ -45,6 +45,7 @@ import {
   codecForDeleteTransactionRequest,
   codecForForceRefreshRequest,
   codecForForgetKnownBankAccounts,
+  codecForGetBalanceDetailRequest,
   codecForGetContractTermsDetails,
   codecForGetExchangeTosRequest,
   codecForGetFeeForDeposit,
@@ -87,6 +88,7 @@ import {
   ExchangesListResponse,
   ExchangeTosStatusDetails,
   FeeDescription,
+  GetBalanceDetailRequest,
   GetExchangeTosResult,
   InitResponse,
   j2s,
@@ -154,7 +156,11 @@ import {
   runBackupCycle,
 } from "./operations/backup/index.js";
 import { setWalletDeviceId } from "./operations/backup/state.js";
-import { getBalances } from "./operations/balance.js";
+import {
+  getBalanceDetail,
+  getBalances,
+  getMerchantPaymentBalanceDetails,
+} from "./operations/balance.js";
 import {
   getExchangeTosStatus,
   makeExchangeListItem,
@@ -948,9 +954,9 @@ async function dumpCoins(ws: InternalWalletState): 
Promise<CoinDumpJson> {
           ageCommitmentProof: c.ageCommitmentProof,
           spend_allocation: c.spendAllocation
             ? {
-              amount: c.spendAllocation.amount,
-              id: c.spendAllocation.id,
-            }
+                amount: c.spendAllocation.amount,
+                id: c.spendAllocation.id,
+              }
             : undefined,
         });
       }
@@ -1111,6 +1117,10 @@ async function dispatchRequestInternal<Op extends 
WalletApiOperation>(
     case WalletApiOperation.GetBalances: {
       return await getBalances(ws);
     }
+    case WalletApiOperation.GetBalanceDetail: {
+      const req = codecForGetBalanceDetailRequest().decode(payload);
+      return await getBalanceDetail(ws, req);
+    }
     case WalletApiOperation.GetUserAttentionRequests: {
       const req = codecForUserAttentionsRequest().decode(payload);
       return await getUserAttentions(ws, req);
@@ -1350,7 +1360,8 @@ async function dispatchRequestInternal<Op extends 
WalletApiOperation>(
         {
           amount: Amounts.stringify(amount),
           reserve_pub: wres.reservePub,
-          debit_account: 
"payto://x-taler-bank/localhost/testdebtor?receiver-name=Foo",
+          debit_account:
+            "payto://x-taler-bank/localhost/testdebtor?receiver-name=Foo",
         },
       );
       const fbResp = await readSuccessResponseJsonOrThrow(fbReq, 
codecForAny());
diff --git 
a/packages/taler-wallet-webextension/src/wallet/DestinationSelection/index.ts 
b/packages/taler-wallet-webextension/src/wallet/DestinationSelection/index.ts
index bd6b32e78..9a0ba1d88 100644
--- 
a/packages/taler-wallet-webextension/src/wallet/DestinationSelection/index.ts
+++ 
b/packages/taler-wallet-webextension/src/wallet/DestinationSelection/index.ts
@@ -66,6 +66,7 @@ export namespace State {
     error: undefined;
     type: Props["type"];
     selectCurrency: ButtonHandler;
+    sendAll: ButtonHandler;
     previous: Contact[];
     goToBank: ButtonHandler;
     goToWallet: ButtonHandler;
diff --git 
a/packages/taler-wallet-webextension/src/wallet/DestinationSelection/state.ts 
b/packages/taler-wallet-webextension/src/wallet/DestinationSelection/state.ts
index d5015ae1d..a921d32cb 100644
--- 
a/packages/taler-wallet-webextension/src/wallet/DestinationSelection/state.ts
+++ 
b/packages/taler-wallet-webextension/src/wallet/DestinationSelection/state.ts
@@ -27,10 +27,21 @@ import { Contact, Props, State } from "./index.js";
 export function useComponentState(props: Props): RecursiveState<State> {
   const api = useBackendContext();
   const { pushAlertOnError } = useAlertContext();
+
   const parsedInitialAmount = !props.amount
     ? undefined
     : Amounts.parse(props.amount);
 
+  const hook = useAsyncAsHook(async () => {
+    if (!parsedInitialAmount) return undefined;
+    const resp = await api.wallet.call(WalletApiOperation.GetBalanceDetail, {
+      currency: parsedInitialAmount.currency,
+    });
+    return resp;
+  });
+
+  const total = hook && !hook.hasError ? hook.response : undefined;
+
   // const initialCurrency = parsedInitialAmount?.currency;
 
   const [amount, setAmount] = useState(
@@ -120,6 +131,14 @@ export function useComponentState(props: Props): 
RecursiveState<State> {
                 props.goToWalletBankDeposit(currencyAndAmount);
               }),
         },
+        sendAll: {
+          onClick:
+            total === undefined
+              ? undefined
+              : pushAlertOnError(async () => {
+                  setAmount(total.balanceMerchantDepositable);
+                }),
+        },
         goToWallet: {
           onClick: invalid
             ? undefined
@@ -143,6 +162,7 @@ export function useComponentState(props: Props): 
RecursiveState<State> {
             setAmount(undefined);
           }),
         },
+        sendAll: {},
         goToBank: {
           onClick: invalid
             ? undefined
diff --git 
a/packages/taler-wallet-webextension/src/wallet/DestinationSelection/stories.tsx
 
b/packages/taler-wallet-webextension/src/wallet/DestinationSelection/stories.tsx
index 111f47776..247affec6 100644
--- 
a/packages/taler-wallet-webextension/src/wallet/DestinationSelection/stories.tsx
+++ 
b/packages/taler-wallet-webextension/src/wallet/DestinationSelection/stories.tsx
@@ -35,6 +35,7 @@ export const GetCash = tests.createExample(ReadyView, {
     },
   },
   goToBank: {},
+  sendAll: {},
   goToWallet: {},
   previous: [],
   selectCurrency: {},
@@ -49,6 +50,7 @@ export const SendCash = tests.createExample(ReadyView, {
     },
   },
   goToBank: {},
+  sendAll: {},
   goToWallet: {},
   previous: [],
   selectCurrency: {},
diff --git 
a/packages/taler-wallet-webextension/src/wallet/DestinationSelection/test.ts 
b/packages/taler-wallet-webextension/src/wallet/DestinationSelection/test.ts
index b079ef0e8..c6a57270b 100644
--- a/packages/taler-wallet-webextension/src/wallet/DestinationSelection/test.ts
+++ b/packages/taler-wallet-webextension/src/wallet/DestinationSelection/test.ts
@@ -118,6 +118,16 @@ describe("Destination selection states", () => {
           expect(state.goToBank.onClick).not.eq(undefined);
           expect(state.goToWallet.onClick).not.eq(undefined);
 
+          expect(state.amountHandler.value).deep.eq(
+            Amounts.parseOrThrow("ARS:2"),
+          );
+        },
+        (state) => {
+          if (state.status !== "ready") expect.fail();
+          if (state.error) expect.fail();
+          expect(state.goToBank.onClick).not.eq(undefined);
+          expect(state.goToWallet.onClick).not.eq(undefined);
+
           expect(state.amountHandler.value).deep.eq(
             Amounts.parseOrThrow("ARS:2"),
           );
diff --git 
a/packages/taler-wallet-webextension/src/wallet/DestinationSelection/views.tsx 
b/packages/taler-wallet-webextension/src/wallet/DestinationSelection/views.tsx
index 8a7a1fa97..0649fd12f 100644
--- 
a/packages/taler-wallet-webextension/src/wallet/DestinationSelection/views.tsx
+++ 
b/packages/taler-wallet-webextension/src/wallet/DestinationSelection/views.tsx
@@ -17,6 +17,7 @@
 import { styled } from "@linaria/react";
 import { Fragment, h, VNode } from "preact";
 import { AmountField } from "../../components/AmountField.js";
+import { JustInDevMode } from "../../components/JustInDevMode.js";
 import { SelectList } from "../../components/SelectList.js";
 import {
   Input,
@@ -283,6 +284,7 @@ export function ReadySendView({
   goToBank,
   goToWallet,
   previous,
+  sendAll,
 }: State.Ready): VNode {
   const { i18n } = useTranslationContext();
 
@@ -292,13 +294,18 @@ export function ReadySendView({
         <i18n.Translate>Specify the amount and the destination</i18n.Translate>
       </h1>
 
-      <div>
+      <Grid container columns={2} justifyContent="space-between">
         <AmountField
           label={i18n.str`Amount`}
           required
           handler={amountHandler}
         />
-      </div>
+        <JustInDevMode>
+          <Button onClick={sendAll.onClick}>
+            <i18n.Translate>Send all</i18n.Translate>
+          </Button>
+        </JustInDevMode>
+      </Grid>
 
       <Grid container spacing={1} columns={1}>
         {previous.length > 0 ? (
diff --git a/packages/taler-wallet-webextension/src/wallet/History.tsx 
b/packages/taler-wallet-webextension/src/wallet/History.tsx
index 1d51f835a..f2a239f83 100644
--- a/packages/taler-wallet-webextension/src/wallet/History.tsx
+++ b/packages/taler-wallet-webextension/src/wallet/History.tsx
@@ -111,8 +111,10 @@ export function HistoryView({
   balances: Balance[];
 }): VNode {
   const { i18n } = useTranslationContext();
-  const currencies = balances.map((b) => b.available.split(":")[0]);
   const { pushAlertOnError } = useAlertContext();
+  const currencies = balances
+    .filter((b) => Amounts.isNonZero(b.available))
+    .map((b) => b.available.split(":")[0]);
 
   const defaultCurrencyIndex = currencies.findIndex(
     (c) => c === defaultCurrency,
diff --git a/packages/taler-wallet-webextension/src/wxApi.ts 
b/packages/taler-wallet-webextension/src/wxApi.ts
index 001f77934..c064d7111 100644
--- a/packages/taler-wallet-webextension/src/wxApi.ts
+++ b/packages/taler-wallet-webextension/src/wxApi.ts
@@ -88,8 +88,8 @@ export interface BackgroundOperations {
   };
   setLoggingLevel: {
     request: {
-      tag?: string,
-      level: LogLevel
+      tag?: string;
+      level: LogLevel;
     };
     response: void;
   };
diff --git a/packages/taler-wallet-webextension/src/wxBackend.ts 
b/packages/taler-wallet-webextension/src/wxBackend.ts
index 1bfee1064..2055953e3 100644
--- a/packages/taler-wallet-webextension/src/wxBackend.ts
+++ b/packages/taler-wallet-webextension/src/wxBackend.ts
@@ -186,12 +186,18 @@ const backendHandlers: BackendHandlerType = {
   setLoggingLevel,
 };
 
-async function setLoggingLevel({ tag, level }: { tag?: string, level: LogLevel 
}): Promise<void> {
-  logger.info(`setting ${tag} to ${level}`)
+async function setLoggingLevel({
+  tag,
+  level,
+}: {
+  tag?: string;
+  level: LogLevel;
+}): Promise<void> {
+  logger.info(`setting ${tag} to ${level}`);
   if (!tag) {
-    setGlobalLogLevelFromString(level)
+    setGlobalLogLevelFromString(level);
   } else {
-    setLogLevelFromString(tag, level)
+    setLogLevelFromString(tag, level);
   }
 }
 

-- 
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]