summaryrefslogtreecommitdiff
path: root/packages
diff options
context:
space:
mode:
authorSebastian <sebasjm@gmail.com>2024-03-22 09:16:23 -0300
committerSebastian <sebasjm@gmail.com>2024-03-22 09:16:23 -0300
commita9540de313506200105f8c75ac219ffeb7622d78 (patch)
tree94f98b62b7dc2e56a2980927c2a8054e9b0014b8 /packages
parent4cc76389a826a5a0c1f07a6cfd7602d12fc6acc5 (diff)
downloadwallet-core-a9540de313506200105f8c75ac219ffeb7622d78.tar.gz
wallet-core-a9540de313506200105f8c75ac219ffeb7622d78.tar.bz2
wallet-core-a9540de313506200105f8c75ac219ffeb7622d78.zip
revert c09caa5fd which removed minimum_age from contract terms
Diffstat (limited to 'packages')
-rw-r--r--packages/taler-util/src/MerchantApiClient.ts2
-rw-r--r--packages/taler-util/src/http-client/README.md31
-rw-r--r--packages/taler-util/src/http-client/merchant.ts80
-rw-r--r--packages/taler-util/src/http-client/types.ts153
-rw-r--r--packages/taler-util/src/http-client/utils.ts6
-rw-r--r--packages/taler-util/src/merchant-api-types.ts1
-rw-r--r--packages/taler-util/src/observability.ts2
-rw-r--r--packages/taler-util/src/taler-types.ts12
-rw-r--r--packages/taler-util/src/wallet-types.ts13
-rw-r--r--packages/taler-wallet-core/src/pay-merchant.ts9
10 files changed, 158 insertions, 151 deletions
diff --git a/packages/taler-util/src/MerchantApiClient.ts b/packages/taler-util/src/MerchantApiClient.ts
index 65827849d..fa9a00176 100644
--- a/packages/taler-util/src/MerchantApiClient.ts
+++ b/packages/taler-util/src/MerchantApiClient.ts
@@ -34,7 +34,7 @@ import {
MerchantPostOrderRequest,
MerchantPostOrderResponse,
MerchantTemplateAddDetails,
- codecForMerchantPostOrderResponse
+ codecForMerchantPostOrderResponse,
} from "./merchant-api-types.js";
import {
FailCasesByMethod,
diff --git a/packages/taler-util/src/http-client/README.md b/packages/taler-util/src/http-client/README.md
index 5af5d48a7..33d1a8645 100644
--- a/packages/taler-util/src/http-client/README.md
+++ b/packages/taler-util/src/http-client/README.md
@@ -1,24 +1,19 @@
-HTTP Cclients
--------------
+## HTTP Cclients
This folder contain class or function specifically designed to facilitate HTTP client
-interactions with a the core systems.
+interactions with a the core systems.
These API defines:
-1. **API Communication**: Handle communication with the component API,
-abstracting away the details of HTTP requests and responses.
-This includes making GET, POST, PUT, and DELETE requests to the servers.
-
-2. **Data Formatting**: Responsible for formatting requests to the API in a
-way that's expected by the servers (JSON) and parsing the responses back
-into formats usable by the client.
-
-3. **Authentication and Security**: Handling authentication with the server API,
-which could involve sending API keys, client credentials, or managing tokens.
-It might also implement security features to ensure data integrity and confidentiality during transit.
-
-4. **Error Handling**: Providing robust error handling and retry mechanisms
-for failed HTTP requests, including logging and potentially user notifications for critical failures.
-
+1. **API Communication**: Handle communication with the component API,
+ abstracting away the details of HTTP requests and responses.
+ This includes making GET, POST, PUT, and DELETE requests to the servers.
+2. **Data Formatting**: Responsible for formatting requests to the API in a
+ way that's expected by the servers (JSON) and parsing the responses back
+ into formats usable by the client.
+3. **Authentication and Security**: Handling authentication with the server API,
+ which could involve sending API keys, client credentials, or managing tokens.
+ It might also implement security features to ensure data integrity and confidentiality during transit.
+4. **Error Handling**: Providing robust error handling and retry mechanisms
+ for failed HTTP requests, including logging and potentially user notifications for critical failures.
5. **Data Validation**: Before sending requests, it could validate the data to ensure it meets the API's expected format, types, and value ranges, reducing the likelihood of errors and improving system reliability.
diff --git a/packages/taler-util/src/http-client/merchant.ts b/packages/taler-util/src/http-client/merchant.ts
index 1cc410191..0fe9973bb 100644
--- a/packages/taler-util/src/http-client/merchant.ts
+++ b/packages/taler-util/src/http-client/merchant.ts
@@ -53,7 +53,7 @@ import {
codecForWebhookSummaryResponse,
opEmptySuccess,
opKnownAlternativeFailure,
- opKnownHttpFailure
+ opKnownHttpFailure,
} from "@gnu-taler/taler-util";
import {
HttpRequestLibrary,
@@ -61,7 +61,11 @@ import {
createPlatformHttpLib,
} from "@gnu-taler/taler-util/http";
import { opSuccessFromHttp, opUnknownFailure } from "../operation.js";
-import { CacheEvictor, addMerchantPaginationParams, nullEvictor } from "./utils.js";
+import {
+ CacheEvictor,
+ addMerchantPaginationParams,
+ nullEvictor,
+} from "./utils.js";
export enum TalerMerchantCacheEviction {
CREATE_ORDER,
@@ -681,7 +685,7 @@ export class TalerMerchantInstanceHttpClient {
switch (resp.status) {
case HttpStatusCode.NoContent:
- return opEmptySuccess(resp)
+ return opEmptySuccess(resp);
case HttpStatusCode.NotFound:
return opKnownHttpFailure(resp.status, resp);
case HttpStatusCode.Gone:
@@ -703,7 +707,7 @@ export class TalerMerchantInstanceHttpClient {
switch (resp.status) {
case HttpStatusCode.NoContent:
- return opEmptySuccess(resp)
+ return opEmptySuccess(resp);
case HttpStatusCode.NotFound:
return opKnownHttpFailure(resp.status, resp);
case HttpStatusCode.Conflict:
@@ -727,19 +731,23 @@ export class TalerMerchantInstanceHttpClient {
method: "POST",
body,
});
- return TalerMerchantInstanceHttpClient.procesOrderCreationResponse(resp)
+ return TalerMerchantInstanceHttpClient.procesOrderCreationResponse(resp);
}
private static async procesOrderCreationResponse(resp: HttpResponse) {
switch (resp.status) {
case HttpStatusCode.Ok:
- return opSuccessFromHttp(resp, codecForPostOrderResponse())
+ return opSuccessFromHttp(resp, codecForPostOrderResponse());
case HttpStatusCode.NotFound:
return opKnownHttpFailure(resp.status, resp);
case HttpStatusCode.Conflict:
return opKnownHttpFailure(resp.status, resp);
case HttpStatusCode.Gone:
- return opKnownAlternativeFailure(resp, resp.status, codecForOutOfStockResponse());
+ return opKnownAlternativeFailure(
+ resp,
+ resp.status,
+ codecForOutOfStockResponse(),
+ );
default:
return opUnknownFailure(resp, await resp.text());
}
@@ -772,7 +780,7 @@ export class TalerMerchantInstanceHttpClient {
if (params.wired) {
url.searchParams.set("wired", "YES");
}
- addMerchantPaginationParams(url, params)
+ addMerchantPaginationParams(url, params);
const resp = await this.httpLib.fetch(url.href, {
method: "GET",
@@ -780,7 +788,7 @@ export class TalerMerchantInstanceHttpClient {
switch (resp.status) {
case HttpStatusCode.Ok:
- return opSuccessFromHttp(resp, codecForOrderHistory())
+ return opSuccessFromHttp(resp, codecForOrderHistory());
default:
return opUnknownFailure(resp, await resp.text());
}
@@ -811,17 +819,23 @@ export class TalerMerchantInstanceHttpClient {
switch (resp.status) {
case HttpStatusCode.Ok:
- return opSuccessFromHttp(resp, codecForMerchantOrderPrivateStatusResponse())
+ return opSuccessFromHttp(
+ resp,
+ codecForMerchantOrderPrivateStatusResponse(),
+ );
case HttpStatusCode.NotFound:
return opKnownHttpFailure(resp.status, resp);
case HttpStatusCode.BadGateway:
return opKnownHttpFailure(resp.status, resp);
case HttpStatusCode.GatewayTimeout:
- return opKnownAlternativeFailure(resp, resp.status, codecForOutOfStockResponse());
+ return opKnownAlternativeFailure(
+ resp,
+ resp.status,
+ codecForOutOfStockResponse(),
+ );
default:
return opUnknownFailure(resp, await resp.text());
}
-
}
/**
@@ -837,9 +851,9 @@ export class TalerMerchantInstanceHttpClient {
switch (resp.status) {
case HttpStatusCode.Ok:
- return opEmptySuccess(resp)
+ return opEmptySuccess(resp);
case HttpStatusCode.NoContent:
- return opEmptySuccess(resp)
+ return opEmptySuccess(resp);
case HttpStatusCode.BadRequest:
return opKnownHttpFailure(resp.status, resp);
case HttpStatusCode.NotFound:
@@ -863,7 +877,7 @@ export class TalerMerchantInstanceHttpClient {
switch (resp.status) {
case HttpStatusCode.NoContent:
- return opEmptySuccess(resp)
+ return opEmptySuccess(resp);
case HttpStatusCode.NotFound:
return opKnownHttpFailure(resp.status, resp);
case HttpStatusCode.Conflict:
@@ -890,7 +904,7 @@ export class TalerMerchantInstanceHttpClient {
switch (resp.status) {
case HttpStatusCode.Ok:
- return opSuccessFromHttp(resp, codecForMerchantRefundResponse())
+ return opSuccessFromHttp(resp, codecForMerchantRefundResponse());
case HttpStatusCode.Forbidden:
return opKnownHttpFailure(resp.status, resp);
case HttpStatusCode.NotFound:
@@ -921,7 +935,7 @@ export class TalerMerchantInstanceHttpClient {
switch (resp.status) {
case HttpStatusCode.NoContent:
- return opEmptySuccess(resp)
+ return opEmptySuccess(resp);
case HttpStatusCode.NotFound:
return opKnownHttpFailure(resp.status, resp);
case HttpStatusCode.Conflict:
@@ -951,7 +965,7 @@ export class TalerMerchantInstanceHttpClient {
if (params.verified) {
url.searchParams.set("verified", "YES");
}
- addMerchantPaginationParams(url, params)
+ addMerchantPaginationParams(url, params);
const resp = await this.httpLib.fetch(url.href, {
method: "GET",
@@ -959,7 +973,7 @@ export class TalerMerchantInstanceHttpClient {
switch (resp.status) {
case HttpStatusCode.Ok:
- return opSuccessFromHttp(resp, codecForTansferList())
+ return opSuccessFromHttp(resp, codecForTansferList());
default:
return opUnknownFailure(resp, await resp.text());
}
@@ -977,7 +991,7 @@ export class TalerMerchantInstanceHttpClient {
switch (resp.status) {
case HttpStatusCode.NoContent:
- return opEmptySuccess(resp)
+ return opEmptySuccess(resp);
case HttpStatusCode.NotFound:
return opKnownHttpFailure(resp.status, resp);
case HttpStatusCode.Conflict:
@@ -1004,7 +1018,7 @@ export class TalerMerchantInstanceHttpClient {
switch (resp.status) {
case HttpStatusCode.NoContent:
- return opEmptySuccess(resp)
+ return opEmptySuccess(resp);
case HttpStatusCode.NotFound:
return opKnownHttpFailure(resp.status, resp);
default:
@@ -1027,7 +1041,7 @@ export class TalerMerchantInstanceHttpClient {
});
switch (resp.status) {
case HttpStatusCode.NoContent:
- return opEmptySuccess(resp)
+ return opEmptySuccess(resp);
case HttpStatusCode.NotFound:
return opKnownHttpFailure(resp.status, resp);
case HttpStatusCode.Conflict:
@@ -1048,7 +1062,7 @@ export class TalerMerchantInstanceHttpClient {
});
switch (resp.status) {
case HttpStatusCode.Ok:
- return opSuccessFromHttp(resp, codecForOtpDeviceSummaryResponse())
+ return opSuccessFromHttp(resp, codecForOtpDeviceSummaryResponse());
case HttpStatusCode.NotFound:
return opKnownHttpFailure(resp.status, resp);
default:
@@ -1077,7 +1091,7 @@ export class TalerMerchantInstanceHttpClient {
switch (resp.status) {
case HttpStatusCode.Ok:
- return opSuccessFromHttp(resp, codecForOtpDeviceDetails())
+ return opSuccessFromHttp(resp, codecForOtpDeviceDetails());
case HttpStatusCode.NotFound:
return opKnownHttpFailure(resp.status, resp);
default:
@@ -1243,7 +1257,7 @@ export class TalerMerchantInstanceHttpClient {
body,
});
- return TalerMerchantInstanceHttpClient.procesOrderCreationResponse(resp)
+ return TalerMerchantInstanceHttpClient.procesOrderCreationResponse(resp);
}
//
@@ -1263,13 +1277,12 @@ export class TalerMerchantInstanceHttpClient {
switch (resp.status) {
case HttpStatusCode.NoContent:
- return opEmptySuccess(resp)
+ return opEmptySuccess(resp);
case HttpStatusCode.NotFound:
return opKnownHttpFailure(resp.status, resp);
default:
return opUnknownFailure(resp, await resp.text());
}
-
}
/**
@@ -1288,7 +1301,7 @@ export class TalerMerchantInstanceHttpClient {
switch (resp.status) {
case HttpStatusCode.NoContent:
- return opEmptySuccess(resp)
+ return opEmptySuccess(resp);
case HttpStatusCode.NotFound:
return opKnownHttpFailure(resp.status, resp);
case HttpStatusCode.Conflict:
@@ -1296,7 +1309,6 @@ export class TalerMerchantInstanceHttpClient {
default:
return opUnknownFailure(resp, await resp.text());
}
-
}
/**
@@ -1311,13 +1323,12 @@ export class TalerMerchantInstanceHttpClient {
switch (resp.status) {
case HttpStatusCode.NoContent:
- return opSuccessFromHttp(resp, codecForWebhookSummaryResponse())
+ return opSuccessFromHttp(resp, codecForWebhookSummaryResponse());
case HttpStatusCode.NotFound:
return opKnownHttpFailure(resp.status, resp);
default:
return opUnknownFailure(resp, await resp.text());
}
-
}
/**
@@ -1331,7 +1342,7 @@ export class TalerMerchantInstanceHttpClient {
});
switch (resp.status) {
case HttpStatusCode.NoContent:
- return opSuccessFromHttp(resp, codecForWebhookDetails())
+ return opSuccessFromHttp(resp, codecForWebhookDetails());
case HttpStatusCode.NotFound:
return opKnownHttpFailure(resp.status, resp);
default:
@@ -1356,7 +1367,6 @@ export class TalerMerchantInstanceHttpClient {
default:
return opUnknownFailure(resp, await resp.text());
}
-
}
//
@@ -1563,7 +1573,7 @@ export class TalerMerchantManagementHttpClient extends TalerMerchantInstanceHttp
switch (resp.status) {
case HttpStatusCode.Ok:
- return opSuccessFromHttp(resp, codecForInstancesResponse())
+ return opSuccessFromHttp(resp, codecForInstancesResponse());
default:
return opUnknownFailure(resp, await resp.text());
}
@@ -1582,7 +1592,7 @@ export class TalerMerchantManagementHttpClient extends TalerMerchantInstanceHttp
switch (resp.status) {
case HttpStatusCode.Ok:
- return opSuccessFromHttp(resp, codecForQueryInstancesResponse())
+ return opSuccessFromHttp(resp, codecForQueryInstancesResponse());
default:
return opUnknownFailure(resp, await resp.text());
}
diff --git a/packages/taler-util/src/http-client/types.ts b/packages/taler-util/src/http-client/types.ts
index 5fa3d0e7a..e3d25b888 100644
--- a/packages/taler-util/src/http-client/types.ts
+++ b/packages/taler-util/src/http-client/types.ts
@@ -572,11 +572,10 @@ export const codecForOutOfStockResponse =
.property("restock_expected", codecForTimestamp)
.build("TalerMerchantApi.OutOfStockResponse");
-export const codecForOrderHistory =
- (): Codec<TalerMerchantApi.OrderHistory> =>
- buildCodecForObject<TalerMerchantApi.OrderHistory>()
- .property("orders", codecForList(codecForOrderHistoryEntry()))
- .build("TalerMerchantApi.OrderHistory");
+export const codecForOrderHistory = (): Codec<TalerMerchantApi.OrderHistory> =>
+ buildCodecForObject<TalerMerchantApi.OrderHistory>()
+ .property("orders", codecForList(codecForOrderHistoryEntry()))
+ .build("TalerMerchantApi.OrderHistory");
export const codecForOrderHistoryEntry =
(): Codec<TalerMerchantApi.OrderHistoryEntry> =>
@@ -590,7 +589,6 @@ export const codecForOrderHistoryEntry =
.property("paid", codecForBoolean())
.build("TalerMerchantApi.OrderHistoryEntry");
-
export const codecForMerchant = (): Codec<TalerMerchantApi.Merchant> =>
buildCodecForObject<TalerMerchantApi.Merchant>()
.property("name", codecForString())
@@ -608,36 +606,40 @@ export const codecForExchange = (): Codec<TalerMerchantApi.Exchange> =>
.property("url", codecForString())
.build("TalerMerchantApi.Exchange");
-export const codecForContractTerms = (): Codec<TalerMerchantApi.ContractTerms> =>
- buildCodecForObject<TalerMerchantApi.ContractTerms>()
- .property("order_id", codecForString())
- .property("fulfillment_url", codecOptional(codecForString()))
- .property("fulfillment_message", codecOptional(codecForString()))
- .property(
- "fulfillment_message_i18n",
- codecOptional(codecForInternationalizedString()),
- )
- .property("merchant_base_url", codecForString())
- .property("h_wire", codecForString())
- .property("auto_refund", codecOptional(codecForDuration))
- .property("wire_method", codecForString())
- .property("summary", codecForString())
- .property("summary_i18n", codecOptional(codecForInternationalizedString()))
- .property("nonce", codecForString())
- .property("amount", codecForAmountString())
- .property("pay_deadline", codecForTimestamp)
- .property("refund_deadline", codecForTimestamp)
- .property("wire_transfer_deadline", codecForTimestamp)
- .property("timestamp", codecForTimestamp)
- .property("delivery_location", codecOptional(codecForLocation()))
- .property("delivery_date", codecOptional(codecForTimestamp))
- .property("max_fee", codecForAmountString())
- .property("merchant", codecForMerchant())
- .property("merchant_pub", codecForString())
- .property("exchanges", codecForList(codecForExchange()))
- .property("products", codecForList(codecForProduct()))
- .property("extra", codecForAny())
- .build("TalerMerchantApi.ContractTerms");
+export const codecForContractTerms =
+ (): Codec<TalerMerchantApi.ContractTerms> =>
+ buildCodecForObject<TalerMerchantApi.ContractTerms>()
+ .property("order_id", codecForString())
+ .property("fulfillment_url", codecOptional(codecForString()))
+ .property("fulfillment_message", codecOptional(codecForString()))
+ .property(
+ "fulfillment_message_i18n",
+ codecOptional(codecForInternationalizedString()),
+ )
+ .property("merchant_base_url", codecForString())
+ .property("h_wire", codecForString())
+ .property("auto_refund", codecOptional(codecForDuration))
+ .property("wire_method", codecForString())
+ .property("summary", codecForString())
+ .property(
+ "summary_i18n",
+ codecOptional(codecForInternationalizedString()),
+ )
+ .property("nonce", codecForString())
+ .property("amount", codecForAmountString())
+ .property("pay_deadline", codecForTimestamp)
+ .property("refund_deadline", codecForTimestamp)
+ .property("wire_transfer_deadline", codecForTimestamp)
+ .property("timestamp", codecForTimestamp)
+ .property("delivery_location", codecOptional(codecForLocation()))
+ .property("delivery_date", codecOptional(codecForTimestamp))
+ .property("max_fee", codecForAmountString())
+ .property("merchant", codecForMerchant())
+ .property("merchant_pub", codecForString())
+ .property("exchanges", codecForList(codecForExchange()))
+ .property("products", codecForList(codecForProduct()))
+ .property("extra", codecForAny())
+ .build("TalerMerchantApi.ContractTerms");
export const codecForProduct = (): Codec<TalerMerchantApi.Product> =>
buildCodecForObject<TalerMerchantApi.Product>()
@@ -655,8 +657,6 @@ export const codecForProduct = (): Codec<TalerMerchantApi.Product> =>
.property("delivery_date", codecOptional(codecForTimestamp))
.build("TalerMerchantApi.Product");
-
-
export const codecForCheckPaymentPaidResponse =
(): Codec<TalerMerchantApi.CheckPaymentPaidResponse> =>
buildCodecForObject<TalerMerchantApi.CheckPaymentPaidResponse>()
@@ -704,8 +704,6 @@ export const codecForMerchantOrderPrivateStatusResponse =
.alternative("claimed", codecForCheckPaymentClaimedResponse())
.build("TalerMerchantApi.MerchantOrderStatusResponse");
-
-
export const codecForRefundDetails =
(): Codec<TalerMerchantApi.RefundDetails> =>
buildCodecForObject<TalerMerchantApi.RefundDetails>()
@@ -742,11 +740,10 @@ export const codecForMerchantRefundResponse =
.property("h_contract", codecForString())
.build("TalerMerchantApi.MerchantRefundResponse");
-export const codecForTansferList =
- (): Codec<TalerMerchantApi.TransferList> =>
- buildCodecForObject<TalerMerchantApi.TransferList>()
- .property("transfers", codecForList(codecForTransferDetails()))
- .build("TalerMerchantApi.TransferList");
+export const codecForTansferList = (): Codec<TalerMerchantApi.TransferList> =>
+ buildCodecForObject<TalerMerchantApi.TransferList>()
+ .property("transfers", codecForList(codecForTransferDetails()))
+ .build("TalerMerchantApi.TransferList");
export const codecForTransferDetails =
(): Codec<TalerMerchantApi.TransferDetails> =>
@@ -784,7 +781,6 @@ export const codecForOtpDeviceDetails =
.property("otp_code", codecOptional(codecForString()))
.build("TalerMerchantApi.OtpDeviceDetails");
-
export const codecForTemplateSummaryResponse =
(): Codec<TalerMerchantApi.TemplateSummaryResponse> =>
buildCodecForObject<TalerMerchantApi.TemplateSummaryResponse>()
@@ -822,19 +818,17 @@ export const codecForWalletTemplateDetails =
.property("template_contract", codecForTemplateContractDetails())
.build("TalerMerchantApi.WalletTemplateDetails");
-
export const codecForWebhookSummaryResponse =
(): Codec<TalerMerchantApi.WebhookSummaryResponse> =>
buildCodecForObject<TalerMerchantApi.WebhookSummaryResponse>()
.property("webhooks", codecForList(codecForWebhookEntry()))
.build("TalerMerchantApi.WebhookSummaryResponse");
-export const codecForWebhookEntry =
- (): Codec<TalerMerchantApi.WebhookEntry> =>
- buildCodecForObject<TalerMerchantApi.WebhookEntry>()
- .property("webhook_id", codecForString())
- .property("event_type", codecForString())
- .build("TalerMerchantApi.WebhookEntry");
+export const codecForWebhookEntry = (): Codec<TalerMerchantApi.WebhookEntry> =>
+ buildCodecForObject<TalerMerchantApi.WebhookEntry>()
+ .property("webhook_id", codecForString())
+ .property("event_type", codecForString())
+ .build("TalerMerchantApi.WebhookEntry");
export const codecForWebhookDetails =
(): Codec<TalerMerchantApi.WebhookDetails> =>
@@ -851,21 +845,20 @@ export const codecForTokenFamilyKind =
codecForEither(
codecForConstString("discount"),
codecForConstString("subscription"),
- ) as any //FIXME: create a codecForEnum
- ;
+ ) as any; //FIXME: create a codecForEnum
export const codecForTokenFamilyDetails =
(): Codec<TalerMerchantApi.TokenFamilyDetails> =>
buildCodecForObject<TalerMerchantApi.TokenFamilyDetails>()
.property("slug", codecForString())
.property("name", codecForString())
.property("description", codecForString())
- .property("description_i18n", (codecForInternationalizedString()))
- .property("valid_after", (codecForTimestamp))
- .property("valid_before", (codecForTimestamp))
- .property("duration", (codecForDuration))
+ .property("description_i18n", codecForInternationalizedString())
+ .property("valid_after", codecForTimestamp)
+ .property("valid_before", codecForTimestamp)
+ .property("duration", codecForDuration)
.property("kind", codecForTokenFamilyKind())
- .property("issued", (codecForNumber()))
- .property("redeemed", (codecForNumber()))
+ .property("issued", codecForNumber())
+ .property("redeemed", codecForNumber())
.build("TalerMerchantApi.TokenFamilyDetails");
export const codecForTokenFamiliesList =
@@ -884,25 +877,23 @@ export const codecForTokenFamilySummary =
.property("kind", codecForTokenFamilyKind())
.build("TalerMerchantApi.TokenFamilySummary");
-
export const codecForInstancesResponse =
(): Codec<TalerMerchantApi.InstancesResponse> =>
buildCodecForObject<TalerMerchantApi.InstancesResponse>()
.property("instances", codecForList(codecForInstance()))
.build("TalerMerchantApi.InstancesResponse");
-export const codecForInstance =
- (): Codec<TalerMerchantApi.Instance> =>
- buildCodecForObject<TalerMerchantApi.Instance>()
- .property("name", codecForString())
- .property("user_type", codecForString())
- .property("website", codecOptional(codecForString()))
- .property("logo", codecOptional(codecForString()))
- .property("id", codecForString())
- .property("merchant_pub", codecForString())
- .property("payment_targets", codecForList(codecForString()))
- .property("deleted", codecForBoolean())
- .build("TalerMerchantApi.Instance");
+export const codecForInstance = (): Codec<TalerMerchantApi.Instance> =>
+ buildCodecForObject<TalerMerchantApi.Instance>()
+ .property("name", codecForString())
+ .property("user_type", codecForString())
+ .property("website", codecOptional(codecForString()))
+ .property("logo", codecOptional(codecForString()))
+ .property("id", codecForString())
+ .property("merchant_pub", codecForString())
+ .property("payment_targets", codecForList(codecForString()))
+ .property("deleted", codecForBoolean())
+ .build("TalerMerchantApi.Instance");
export const codecForExchangeConfig =
(): Codec<TalerExchangeApi.ExchangeVersionResponse> =>
@@ -3177,15 +3168,15 @@ export namespace TalerMerchantApi {
// use “all”) to see all orders regardless of wire transfer
// status.
wired?: boolean;
- // At most return the given number of results. Negative
- // for descending by row ID, positive for ascending by
+ // At most return the given number of results. Negative
+ // for descending by row ID, positive for ascending by
// row ID. Default is 20. Since protocol v12.
limit?: number;
// Non-negative date in seconds after the UNIX Epoc, see delta
// for its interpretation. If not specified, we default to the
// oldest or most recent entry, depending on delta.
date?: AbsoluteTime;
- // Starting product_serial_id for an iteration.
+ // Starting product_serial_id for an iteration.
// Since protocol v12.
offset?: string;
// Timeout in milliseconds to wait for additional orders if the
@@ -4610,7 +4601,6 @@ export namespace TalerMerchantApi {
}
export interface WalletTemplateDetails {
-
// Hard-coded information about the contrac terms
// for this template.
template_contract: TemplateContractDetails;
@@ -4931,6 +4921,13 @@ export namespace TalerMerchantApi {
// Useful when the merchant needs to store extra information on a
// contract without storing it separately in their database.
extra?: any;
+
+ // Minimum age the buyer must have (in years). Default is 0.
+ // This value is at least as large as the maximum over all
+ // mimimum age requirements of the products in this contract.
+ // It might also be set independent of any product, due to
+ // legal requirements.
+ minimum_age?: Integer;
}
export interface Product {
diff --git a/packages/taler-util/src/http-client/utils.ts b/packages/taler-util/src/http-client/utils.ts
index dbfe64796..d6623cf00 100644
--- a/packages/taler-util/src/http-client/utils.ts
+++ b/packages/taler-util/src/http-client/utils.ts
@@ -59,7 +59,10 @@ export function addPaginationParams(url: URL, pagination?: PaginationParams) {
url.searchParams.set("delta", String(order * limit));
}
-export function addMerchantPaginationParams(url: URL, pagination?: PaginationParams) {
+export function addMerchantPaginationParams(
+ url: URL,
+ pagination?: PaginationParams,
+) {
if (!pagination) return;
if (pagination.offset) {
url.searchParams.set("offset", pagination.offset);
@@ -73,7 +76,6 @@ export function addMerchantPaginationParams(url: URL, pagination?: PaginationPar
url.searchParams.set("limit", String(order * limit));
}
-
export function addLongPollingParam(url: URL, param?: LongPollParams) {
if (!param) return;
if (param.timeoutMs) {
diff --git a/packages/taler-util/src/merchant-api-types.ts b/packages/taler-util/src/merchant-api-types.ts
index 6d5570b61..639ae8d13 100644
--- a/packages/taler-util/src/merchant-api-types.ts
+++ b/packages/taler-util/src/merchant-api-types.ts
@@ -114,7 +114,6 @@ export const codecForMerchantCheckPaymentPaidResponse =
.property("refund_details", codecForAny())
.build("CheckPaymentPaidResponse");
-
export type MerchantOrderPrivateStatusResponse =
| MerchantCheckPaymentPaidResponse
| CheckPaymentUnpaidResponse
diff --git a/packages/taler-util/src/observability.ts b/packages/taler-util/src/observability.ts
index 70391cbcd..0171142c8 100644
--- a/packages/taler-util/src/observability.ts
+++ b/packages/taler-util/src/observability.ts
@@ -92,7 +92,7 @@ export class ObservableHttpClientLibrary implements HttpRequestLibrary {
});
throw e;
} finally {
- this.cancelatorById.delete(id)
+ this.cancelatorById.delete(id);
}
}
}
diff --git a/packages/taler-util/src/taler-types.ts b/packages/taler-util/src/taler-types.ts
index bad9186dc..419aeb159 100644
--- a/packages/taler-util/src/taler-types.ts
+++ b/packages/taler-util/src/taler-types.ts
@@ -564,6 +564,13 @@ export interface MerchantContractTerms {
// contract without storing it separately in their database.
// Must really be an Object (not a string, integer, float or array).
extra?: any;
+
+ // Minimum age the buyer must have (in years). Default is 0.
+ // This value is at least as large as the maximum over all
+ // mimimum age requirements of the products in this contract.
+ // It might also be set independent of any product, due to
+ // legal requirements.
+ minimum_age?: Integer;
}
/**
@@ -617,7 +624,6 @@ export interface MerchantAbortPayRefundDetails {
exchange_http_status: number;
}
-
/**
* Planchet detail sent to the merchant.
*/
@@ -1394,11 +1400,9 @@ export const codecForMerchantInfo = (): Codec<MerchantInfo> =>
.property("jurisdiction", codecOptional(codecForLocation()))
.build("MerchantInfo");
-
export const codecForInternationalizedString =
(): Codec<InternationalizedString> => codecForMap(codecForString());
-
export const codecForMerchantContractTerms = (): Codec<MerchantContractTerms> =>
buildCodecForObject<MerchantContractTerms>()
.property("order_id", codecForString())
@@ -1615,7 +1619,6 @@ export const codecForMerchantOrderStatusPaid =
.property("refunded", codecForBoolean())
.build("MerchantOrderStatusPaid");
-
export const codecForMerchantOrderStatusUnpaid =
(): Codec<MerchantOrderStatusUnpaid> =>
buildCodecForObject<MerchantOrderStatusUnpaid>()
@@ -1653,7 +1656,6 @@ export interface AbortResponse {
refunds: MerchantAbortPayRefundStatus[];
}
-
export type MerchantAbortPayRefundStatus =
| MerchantAbortPayRefundSuccessStatus
| MerchantAbortPayRefundFailureStatus;
diff --git a/packages/taler-util/src/wallet-types.ts b/packages/taler-util/src/wallet-types.ts
index 61b9e1b59..92a902eca 100644
--- a/packages/taler-util/src/wallet-types.ts
+++ b/packages/taler-util/src/wallet-types.ts
@@ -628,11 +628,11 @@ export interface CoinDumpJson {
withdrawal_reserve_pub: string | undefined;
coin_status: CoinStatus;
spend_allocation:
- | {
- id: string;
- amount: AmountString;
- }
- | undefined;
+ | {
+ id: string;
+ amount: AmountString;
+ }
+ | undefined;
/**
* Information about the age restriction
*/
@@ -831,7 +831,7 @@ export const codecForPreparePayResultPaymentPossible =
)
.build("PreparePayResultPaymentPossible");
-export interface BalanceDetails { }
+export interface BalanceDetails {}
/**
* Detailed reason for why the wallet's balance is insufficient.
@@ -2954,6 +2954,7 @@ export interface WalletContractData {
wireMethod: string;
wireInfoHash: string;
maxDepositFee: AmountString;
+ minimumAge?: number;
}
export interface TestingWaitTransactionRequest {
diff --git a/packages/taler-wallet-core/src/pay-merchant.ts b/packages/taler-wallet-core/src/pay-merchant.ts
index e473566b0..562cee4a6 100644
--- a/packages/taler-wallet-core/src/pay-merchant.ts
+++ b/packages/taler-wallet-core/src/pay-merchant.ts
@@ -590,6 +590,7 @@ export function extractContractData(
maxDepositFee: Amounts.stringify(parsedContractTerms.max_fee),
merchant: parsedContractTerms.merchant,
summaryI18n: parsedContractTerms.summary_i18n,
+ minimumAge: parsedContractTerms.minimum_age,
};
}
@@ -1147,7 +1148,7 @@ async function handleInsufficientFunds(
depositFeeLimit: Amounts.parseOrThrow(contractData.maxDepositFee),
wireFeeAmortization: 1, // FIXME #8653
prevPayCoins,
- requiredMinimumAge: undefined, // FIXME #8653
+ requiredMinimumAge: contractData.minimumAge,
});
if (res.type !== "success") {
@@ -1276,7 +1277,7 @@ async function checkPaymentByProposalId(
depositFeeLimit: Amounts.parseOrThrow(contractData.maxDepositFee),
wireFeeAmortization: 1, // FIXME #8653
prevPayCoins: [],
- requiredMinimumAge: undefined, // FIXME #8653
+ requiredMinimumAge: contractData.minimumAge,
restrictWireMethod: contractData.wireMethod,
});
@@ -1630,7 +1631,7 @@ export async function generateDepositPermissions(
timestamp: contractData.timestamp,
wireInfoHash,
ageCommitmentProof: coin.ageCommitmentProof,
- requiredMinimumAge: undefined,// FIXME #8653
+ requiredMinimumAge: contractData.minimumAge,
});
depositPermissions.push(dp);
}
@@ -1815,7 +1816,7 @@ export async function confirmPay(
depositFeeLimit: Amounts.parseOrThrow(contractData.maxDepositFee),
wireFeeAmortization: 1, // FIXME #8653
prevPayCoins: [],
- requiredMinimumAge: undefined, // FIXME #8653
+ requiredMinimumAge: contractData.minimumAge,
forcedSelection: forcedCoinSel,
});