gnunet-svn
[Top][All Lists]
Advanced

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

[taler-wallet-core] branch master updated: wallet-core: exposed KYC limi


From: gnunet
Subject: [taler-wallet-core] branch master updated: wallet-core: exposed KYC limits WIP
Date: Wed, 11 Sep 2024 14:37:42 +0200

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

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

The following commit(s) were added to refs/heads/master by this push:
     new e308a6a83 wallet-core: exposed KYC limits WIP
e308a6a83 is described below

commit e308a6a83a95735481134452bc4d4240783eec53
Author: Florian Dold <florian@dold.me>
AuthorDate: Wed Sep 11 14:37:36 2024 +0200

    wallet-core: exposed KYC limits WIP
---
 .../test-kyc-threshold-withdrawal.ts               | 25 ++++++++--
 packages/taler-util/src/types-taler-exchange.ts    | 56 +++++++++++++++++-----
 packages/taler-util/src/types-taler-wallet.ts      | 56 +++++++++++-----------
 packages/taler-wallet-core/src/db.ts               |  6 +++
 packages/taler-wallet-core/src/denomSelection.ts   |  6 ---
 packages/taler-wallet-core/src/exchanges.ts        | 10 ++++
 packages/taler-wallet-core/src/withdraw.ts         | 25 +++-------
 7 files changed, 115 insertions(+), 69 deletions(-)

diff --git 
a/packages/taler-harness/src/integrationtests/test-kyc-threshold-withdrawal.ts 
b/packages/taler-harness/src/integrationtests/test-kyc-threshold-withdrawal.ts
index 7861fae97..bf3c2dbb2 100644
--- 
a/packages/taler-harness/src/integrationtests/test-kyc-threshold-withdrawal.ts
+++ 
b/packages/taler-harness/src/integrationtests/test-kyc-threshold-withdrawal.ts
@@ -18,8 +18,6 @@
  * Imports.
  */
 import {
-  encodeCrock,
-  hashPaytoUri,
   NotificationType,
   TalerCorebankApiClient,
   TransactionMajorState,
@@ -145,6 +143,14 @@ async function createKycTestkudosEnvironment(
     config.setString("KYC-RULE-R1", "timeframe", "1d");
     config.setString("KYC-RULE-R1", "next_measures", "M1");
 
+    config.setString("KYC-RULE-R1", "operation_type", "withdraw");
+    config.setString("KYC-RULE-R1", "enabled", "yes");
+    config.setString("KYC-RULE-R1", "exposed", "yes");
+    config.setString("KYC-RULE-R1", "is_and_combinator", "yes");
+    config.setString("KYC-RULE-R1", "threshold", "TESTKUDOS:300");
+    config.setString("KYC-RULE-R1", "timeframe", "1d");
+    config.setString("KYC-RULE-R1", "next_measures", "verboten");
+
     config.setString("KYC-MEASURE-M1", "check_name", "C1");
     config.setString("KYC-MEASURE-M1", "context", "{}");
     config.setString("KYC-MEASURE-M1", "program", "P1");
@@ -226,13 +232,24 @@ export async function runKycThresholdWithdrawalTest(t: 
GlobalTestState) {
 
   // Hand it to the wallet
 
-  await walletClient.client.call(
+  const withdrawalUrlInfo = await walletClient.client.call(
     WalletApiOperation.GetWithdrawalDetailsForUri,
     {
       talerWithdrawUri: wop.taler_withdraw_uri,
     },
   );
 
+  const withdrawalAmountInfo = await walletClient.call(
+    WalletApiOperation.GetWithdrawalDetailsForAmount,
+    {
+      amount: withdrawalUrlInfo.amount!,
+      exchangeBaseUrl: withdrawalUrlInfo.possibleExchanges[0].exchangeBaseUrl,
+    },
+  );
+
+  // t.assertTrue(!!withdrawalAmountInfo.kycHardLimit);
+  // t.assertAmountEquals(withdrawalAmountInfo.kycHardLimit, "TESTKUDOS:300");
+
   // Withdraw
 
   const acceptResp = await walletClient.client.call(
@@ -265,7 +282,6 @@ export async function runKycThresholdWithdrawalTest(t: 
GlobalTestState) {
 
   await kycNotificationCond;
 
-
   const txDet = await walletClient.call(WalletApiOperation.GetTransactionById, 
{
     transactionId: withdrawalTxId,
   });
@@ -275,7 +291,6 @@ export async function runKycThresholdWithdrawalTest(t: 
GlobalTestState) {
   const kycPaytoHash = txDet.kycPaytoHash;
   t.assertTrue(!!kycPaytoHash);
 
-
   await postAmlDecisionNoRules(t, {
     amlPriv: amlKeypair.priv,
     amlPub: amlKeypair.pub,
diff --git a/packages/taler-util/src/types-taler-exchange.ts 
b/packages/taler-util/src/types-taler-exchange.ts
index 678b0b6c8..7c879b52e 100644
--- a/packages/taler-util/src/types-taler-exchange.ts
+++ b/packages/taler-util/src/types-taler-exchange.ts
@@ -454,6 +454,21 @@ export interface ExchangeKeysJson {
   // Optional option, if not given there is no limit.
   // Currency must match currency.
   wallet_balance_limit_without_kyc?: AmountString[];
+
+  // Array of limits that apply to all accounts.
+  // All of the given limits will be hard limits.
+  // Wallets and merchants are expected to obey them
+  // and not even allow the user to cross them.
+  // Since protocol **v21**.
+  hard_limits?: AccountLimit[];
+
+  // Array of limits with a soft threshold of zero
+  // that apply to all accounts without KYC.
+  // Wallets and merchants are expected to trigger
+  // a KYC process before attempting any zero-limited
+  // operations.
+  // Since protocol **v21**.
+  zero_limits?: ZeroLimitedOperation[];
 }
 
 export interface ExchangeMeltRequest {
@@ -877,6 +892,8 @@ export const codecForExchangeKeysJson = (): 
Codec<ExchangeKeysJson> =>
     .property("global_fees", codecForList(codecForGlobalFees()))
     .property("accounts", codecForList(codecForExchangeWireAccount()))
     .property("wire_fees", codecForMap(codecForList(codecForWireFeesJson())))
+    .property("zero_limits", 
codecOptional(codecForList(codecForZeroLimitedOperation())))
+    .property("hard_limits", 
codecOptional(codecForList(codecForAccountLimit())))
     .property("denominations", codecForList(codecForNgDenominations))
     .property(
       "wallet_balance_limit_without_kyc",
@@ -1687,11 +1704,12 @@ export interface AccountKycStatus {
   // request that would cause it to exceed hard limits).
   limits?: AccountLimit[];
 }
+
+export type LimitOperationType = "WITHDRAW" | "DEPOSIT" | "MERGE" | 
"AGGREGATE" | "BALANCE" | "REFUND" | "CLOSE" | "TRANSACTION";
+
 export interface AccountLimit {
   // Operation that is limited.
-  // Must be one of "WITHDRAW", "DEPOSIT", "P2P-RECEIVE"
-  // or "WALLET-BALANCE".
-  operation_type: "WITHDRAW" | "DEPOSIT" | "P2P-RECEIVE" | "WALLET-BALANCE";
+  operation_type: LimitOperationType;
 
   // Timeframe during which the limit applies.
   timeframe: RelativeTime;
@@ -2104,8 +2122,7 @@ export interface ExchangeKeysResponse {
   extensions_sig?: EddsaSignature;
 }
 
-interface ZeroLimitedOperation {
-
+export interface ZeroLimitedOperation {
   // Operation that is limited to an amount of
   // zero until the client has passed some KYC check.
   // Must be one of "WITHDRAW", "DEPOSIT",
@@ -2113,7 +2130,6 @@ interface ZeroLimitedOperation {
   // (reserve) "CLOSE", "AGGREGATE",
   // "TRANSACTION" or "REFUND".
   operation_type: string;
-
 }
 
 interface ExtensionManifest {
@@ -2486,7 +2502,7 @@ export const codecForLegitimizationNeededResponse =
       .property("hint", codecOptional(codecForString()))
       .property("h_payto", codecForString())
       .property("account_pub", codecOptional(codecForString()))
-      .property("requirement_row", (codecForNumber()))
+      .property("requirement_row", codecForNumber())
       .property("bad_kyc_auth", codecOptional(codecForBoolean()))
       .build("TalerExchangeApi.LegitimizationNeededResponse");
 
@@ -2497,22 +2513,36 @@ export const codecForAccountKycStatus = (): 
Codec<AccountKycStatus> =>
     .property("limits", codecOptional(codecForList(codecForAccountLimit())))
     .build("TalerExchangeApi.AccountKycStatus");
 
+export const codecForOperationType = codecForEither(
+  codecForConstString("WITHDRAW"),
+  codecForConstString("DEPOSIT"),
+  codecForConstString("MERGE"),
+  codecForConstString("BALANCE"),
+  codecForConstString("CLOSE"),
+  codecForConstString("AGGREGATE"),
+  codecForConstString("TRANSACTION"),
+  codecForConstString("REFUND"),
+);
+
 export const codecForAccountLimit = (): Codec<AccountLimit> =>
   buildCodecForObject<AccountLimit>()
     .property(
       "operation_type",
-      codecForEither(
-        codecForConstString("WITHDRAW"),
-        codecForConstString("DEPOSIT"),
-        codecForConstString("P2P-RECEIVE"),
-        codecForConstString("WALLET-BALANCE"),
-      ),
+      codecForOperationType,
     )
     .property("timeframe", codecForDuration)
     .property("threshold", codecForAmountString())
     .property("soft_limit", codecOptional(codecForBoolean()))
     .build("TalerExchangeApi.AccountLimit");
 
+export const codecForZeroLimitedOperation = (): Codec<ZeroLimitedOperation> =>
+  buildCodecForObject<ZeroLimitedOperation>()
+    .property(
+      "operation_type",
+      codecForOperationType
+    )
+    .build("TalerExchangeApi.ZeroLimitedOperation");
+
 export const codecForKycCheckPublicInformation =
   (): Codec<KycCheckPublicInformation> =>
     buildCodecForObject<KycCheckPublicInformation>()
diff --git a/packages/taler-util/src/types-taler-wallet.ts 
b/packages/taler-util/src/types-taler-wallet.ts
index 798197834..0461b74f9 100644
--- a/packages/taler-util/src/types-taler-wallet.ts
+++ b/packages/taler-util/src/types-taler-wallet.ts
@@ -57,7 +57,6 @@ import {
   WithdrawalOperationStatus,
   canonicalizeBaseUrl,
 } from "./index.js";
-import { VersionMatchResult } from "./libtool-version.js";
 import { PaytoString, PaytoUri, codecForPaytoString } from "./payto.js";
 import { QrCodeSpec } from "./qr.js";
 import { AgeCommitmentProof } from "./taler-crypto.js";
@@ -1507,6 +1506,20 @@ export interface WithdrawalDetailsForAmount {
    * Scope info of the currency withdrawn.
    */
   scopeInfo: ScopeInfo;
+
+  /**
+   * KYC soft limit.
+   *
+   * Withdrawals over that amount will require KYC.
+   */
+  kycSoftLimit?: AmountString;
+
+  /**
+   * KYC soft limits.
+   *
+   * Withdrawals over that amount will be denied.
+   */
+  kycHardLimit?: AmountString;
 }
 
 export interface DenomSelItem {
@@ -1520,13 +1533,12 @@ export interface DenomSelItem {
 }
 
 /**
- * Selected denominations withn some extra info.
+ * Selected denominations with some extra info.
  */
 export interface DenomSelectionState {
   totalCoinValue: AmountString;
   totalWithdrawCost: AmountString;
   selectedDenoms: DenomSelItem[];
-  earliestDepositExpiration: TalerProtocolTimestamp;
   hasDenomWithAgeRestriction: boolean;
 }
 
@@ -1555,30 +1567,6 @@ export interface ExchangeWithdrawalDetails {
    */
   termsOfServiceAccepted: boolean;
 
-  /**
-   * The earliest deposit expiration of the selected coins.
-   */
-  earliestDepositExpiration: TalerProtocolTimestamp;
-
-  /**
-   * Result of checking the wallet's version
-   * against the exchange's version.
-   *
-   * Older exchanges don't return version information.
-   */
-  versionMatch: VersionMatchResult | undefined;
-
-  /**
-   * Libtool-style version string for the exchange or "unknown"
-   * for older exchanges.
-   */
-  exchangeVersion: string;
-
-  /**
-   * Libtool-style version string for the wallet.
-   */
-  walletVersion: string;
-
   /**
    * Amount that will be subtracted from the reserve's balance.
    */
@@ -1597,6 +1585,20 @@ export interface ExchangeWithdrawalDetails {
   ageRestrictionOptions?: number[];
 
   scopeInfo: ScopeInfo;
+
+  /**
+   * KYC soft limit.
+   *
+   * Withdrawals over that amount will require KYC.
+   */
+  kycSoftLimit?: AmountString;
+
+  /**
+   * KYC soft limits.
+   *
+   * Withdrawals over that amount will be denied.
+   */
+  kycHardLimit?: AmountString;
 }
 
 export interface GetExchangeTosResult {
diff --git a/packages/taler-wallet-core/src/db.ts 
b/packages/taler-wallet-core/src/db.ts
index a42548bb3..7f3b24250 100644
--- a/packages/taler-wallet-core/src/db.ts
+++ b/packages/taler-wallet-core/src/db.ts
@@ -29,6 +29,7 @@ import {
 } from "@gnu-taler/idb-bridge";
 import {
   AbsoluteTime,
+  AccountLimit,
   AgeCommitmentProof,
   AmountString,
   Amounts,
@@ -61,6 +62,7 @@ import {
   UnblindedSignature,
   WireInfo,
   WithdrawalExchangeAccountDetails,
+  ZeroLimitedOperation,
   codecForAny,
   j2s,
   stringifyScopeInfo,
@@ -624,6 +626,10 @@ export interface ExchangeDetailsRecord {
   ageMask?: number;
 
   walletBalanceLimits?: AmountString[];
+
+  hardLimits?: AccountLimit[];
+
+  zeroLimits?: ZeroLimitedOperation[];
 }
 
 export interface ExchangeDetailsPointer {
diff --git a/packages/taler-wallet-core/src/denomSelection.ts 
b/packages/taler-wallet-core/src/denomSelection.ts
index ecc1fa881..9e62857bf 100644
--- a/packages/taler-wallet-core/src/denomSelection.ts
+++ b/packages/taler-wallet-core/src/denomSelection.ts
@@ -123,9 +123,6 @@ export function selectWithdrawalDenominations(
     selectedDenoms,
     totalCoinValue: Amounts.stringify(totalCoinValue),
     totalWithdrawCost: Amounts.stringify(totalWithdrawCost),
-    earliestDepositExpiration: AbsoluteTime.toProtocolTimestamp(
-      earliestDepositExpiration,
-    ),
     hasDenomWithAgeRestriction,
   };
 }
@@ -191,9 +188,6 @@ export function selectForcedWithdrawalDenominations(
     selectedDenoms,
     totalCoinValue: Amounts.stringify(totalCoinValue),
     totalWithdrawCost: Amounts.stringify(totalWithdrawCost),
-    earliestDepositExpiration: AbsoluteTime.toProtocolTimestamp(
-      earliestDepositExpiration,
-    ),
     hasDenomWithAgeRestriction,
   };
 }
diff --git a/packages/taler-wallet-core/src/exchanges.ts 
b/packages/taler-wallet-core/src/exchanges.ts
index 2c0386d0c..4c2677482 100644
--- a/packages/taler-wallet-core/src/exchanges.ts
+++ b/packages/taler-wallet-core/src/exchanges.ts
@@ -26,6 +26,7 @@
 import {
   AbsoluteTime,
   AccountKycStatus,
+  AccountLimit,
   AgeRestriction,
   Amount,
   AmountLike,
@@ -91,6 +92,7 @@ import {
   WireFeeMap,
   WireFeesJson,
   WireInfo,
+  ZeroLimitedOperation,
   assertUnreachable,
   checkDbInvariant,
   checkLogicInvariant,
@@ -854,6 +856,8 @@ export interface ExchangeKeysDownloadResult {
   wireFees: { [methodName: string]: WireFeesJson[] };
   currencySpecification?: CurrencySpecification;
   walletBalanceLimits: AmountString[] | undefined;
+  hardLimits: AccountLimit[] | undefined;
+  zeroLimits: ZeroLimitedOperation[] | undefined;
 }
 
 /**
@@ -1019,6 +1023,8 @@ async function downloadExchangeKeysInfo(
     currencySpecification: exchangeKeysJsonUnchecked.currency_specification,
     walletBalanceLimits:
       exchangeKeysJsonUnchecked.wallet_balance_limit_without_kyc,
+    hardLimits: exchangeKeysJsonUnchecked.hard_limits,
+    zeroLimits: exchangeKeysJsonUnchecked.zero_limits,
   };
 }
 
@@ -1259,6 +1265,8 @@ export interface ReadyExchangeSummary {
   protocolVersionRange: string;
   tosAcceptedTimestamp: TalerPreciseTimestamp | undefined;
   scopeInfo: ScopeInfo;
+  zeroLimits: ZeroLimitedOperation[];
+  hardLimits: AccountLimit[];
 }
 
 /**
@@ -1423,6 +1431,8 @@ async function waitReadyExchange(
           exchange.tosAcceptedTimestamp,
         ),
         scopeInfo,
+        hardLimits: exchangeDetails.hardLimits ?? [],
+        zeroLimits: exchangeDetails.zeroLimits ?? [],
       };
 
       if (options.expectedMasterPub) {
diff --git a/packages/taler-wallet-core/src/withdraw.ts 
b/packages/taler-wallet-core/src/withdraw.ts
index c98c16f65..5cc0f228f 100644
--- a/packages/taler-wallet-core/src/withdraw.ts
+++ b/packages/taler-wallet-core/src/withdraw.ts
@@ -2190,14 +2190,6 @@ async function redenominateWithdrawal(
           .toString(),
         hasDenomWithAgeRestriction:
           prevHasDenomWithAgeRestriction || newSel.hasDenomWithAgeRestriction,
-        earliestDepositExpiration: AbsoluteTime.toProtocolTimestamp(
-          AbsoluteTime.min(
-            prevEarliestDepositExpiration,
-            AbsoluteTime.fromProtocolTimestamp(
-              newSel.earliestDepositExpiration,
-            ),
-          ),
-        ),
       };
       wg.denomsSel = mergedSel;
       if (logger.shouldLogTrace()) {
@@ -2574,14 +2566,10 @@ export async function getExchangeWithdrawalInfo(
   }
 
   const ret: ExchangeWithdrawalDetails = {
-    earliestDepositExpiration: selectedDenoms.earliestDepositExpiration,
     exchangePaytoUris: paytoUris,
     exchangeWireAccounts,
     exchangeCreditAccountDetails: withdrawalAccountsList,
-    exchangeVersion: exchange.protocolVersionRange || "unknown",
     selectedDenoms,
-    versionMatch,
-    walletVersion: WALLET_EXCHANGE_PROTOCOL_VERSION,
     termsOfServiceAccepted: tosAccepted,
     withdrawalAmountEffective: 
Amounts.stringify(selectedDenoms.totalCoinValue),
     withdrawalAmountRaw: Amounts.stringify(instructedAmount),
@@ -2595,11 +2583,6 @@ export async function getExchangeWithdrawalInfo(
   return ret;
 }
 
-export interface GetWithdrawalDetailsForUriOpts {
-  restrictAge?: number;
-  notifyChangeFromPendingTimeoutMs?: number;
-}
-
 async function getWithdrawalDetailsForBankInfo(
   wex: WalletExecutionContext,
   info: BankWithdrawDetails,
@@ -2629,6 +2612,12 @@ async function getWithdrawalDetailsForBankInfo(
   } else {
     const listExchangesResp = await listExchanges(wex);
 
+    for (const exchange of listExchangesResp.exchanges) {
+      if (exchange.currency !== currency) {
+        continue;
+      }
+    }
+
     possibleExchanges = listExchangesResp.exchanges.filter((x) => {
       return (
         x.currency === currency &&
@@ -3993,7 +3982,7 @@ export async function getWithdrawalDetailsForAmount(
   );
 }
 
-async function internalGetWithdrawalDetailsForAmount(
+export async function internalGetWithdrawalDetailsForAmount(
   wex: WalletExecutionContext,
   req: GetWithdrawalDetailsForAmountRequest,
 ): Promise<WithdrawalDetailsForAmount> {

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