summaryrefslogtreecommitdiff
path: root/packages/taler-wallet-webextension/src/cta/InvoiceCreate/state.ts
diff options
context:
space:
mode:
Diffstat (limited to 'packages/taler-wallet-webextension/src/cta/InvoiceCreate/state.ts')
-rw-r--r--packages/taler-wallet-webextension/src/cta/InvoiceCreate/state.ts73
1 files changed, 64 insertions, 9 deletions
diff --git a/packages/taler-wallet-webextension/src/cta/InvoiceCreate/state.ts b/packages/taler-wallet-webextension/src/cta/InvoiceCreate/state.ts
index d845e121a..27f05ce03 100644
--- a/packages/taler-wallet-webextension/src/cta/InvoiceCreate/state.ts
+++ b/packages/taler-wallet-webextension/src/cta/InvoiceCreate/state.ts
@@ -15,8 +15,9 @@
*/
/* eslint-disable react-hooks/rules-of-hooks */
-import { Amounts, TalerErrorDetail } from "@gnu-taler/taler-util";
+import { Amounts, TalerErrorDetail, TalerProtocolTimestamp } from "@gnu-taler/taler-util";
import { TalerError, WalletApiOperation } from "@gnu-taler/taler-wallet-core";
+import { isFuture, parse } from "date-fns";
import { useState } from "preact/hooks";
import { useAsyncAsHook } from "../../hooks/useAsyncAsHook.js";
import { useSelectedExchange } from "../../hooks/useSelectedExchange.js";
@@ -49,7 +50,8 @@ export function useComponentState(
const exchangeList = hook.response.exchanges;
return () => {
- const [subject, setSubject] = useState("");
+ const [subject, setSubject] = useState<string | undefined>();
+ const [timestamp, setTimestamp] = useState<string | undefined>()
const [operationError, setOperationError] = useState<
TalerErrorDetail | undefined
@@ -67,13 +69,59 @@ export function useComponentState(
const exchange = selectedExchange.selected;
+ const hook = useAsyncAsHook(async () => {
+ const resp = await api.wallet.call(WalletApiOperation.PreparePeerPullPayment, {
+ amount: amountStr,
+ exchangeBaseUrl: exchange.exchangeBaseUrl,
+ })
+ return resp
+ })
+
+ if (!hook) {
+ return {
+ status: "loading",
+ error: undefined
+ }
+ }
+ if (hook.hasError) {
+ return {
+ status: "loading-uri",
+ error: hook
+ }
+ }
+
+ const { amountEffective, amountRaw } = hook.response
+ const requestAmount = Amounts.parseOrThrow(amountRaw)
+ const toBeReceived = Amounts.parseOrThrow(amountEffective)
+
+ let purse_expiration: TalerProtocolTimestamp | undefined = undefined
+ let timestampError: string | undefined = undefined;
+
+ const t = timestamp === undefined ? undefined : parse(timestamp, "dd/MM/yyyy", new Date())
+
+ if (t !== undefined) {
+ if (Number.isNaN(t.getTime())) {
+ timestampError = 'Should have the format "dd/MM/yyyy"'
+ } else {
+ if (!isFuture(t)) {
+ timestampError = 'Should be in the future'
+ } else {
+ purse_expiration = {
+ t_s: t.getTime() / 1000
+ }
+ }
+ }
+ }
+
async function accept(): Promise<void> {
+ if (!subject || !purse_expiration) return;
try {
const resp = await api.wallet.call(WalletApiOperation.InitiatePeerPullPayment, {
- amount: Amounts.stringify(amount),
exchangeBaseUrl: exchange.exchangeBaseUrl,
partialContractTerms: {
+ amount: Amounts.stringify(amount),
summary: subject,
+ purse_expiration
},
});
@@ -86,25 +134,32 @@ export function useComponentState(
throw Error("error trying to accept");
}
}
+ const unableToCreate = !subject || Amounts.isZero(amount) || !purse_expiration
return {
status: "ready",
subject: {
- error: !subject ? "cant be empty" : undefined,
- value: subject,
+ error: subject === undefined ? undefined : !subject ? "Can't be empty" : undefined,
+ value: subject ?? "",
onInput: async (e) => setSubject(e),
},
+ expiration: {
+ error: timestampError,
+ value: timestamp === undefined ? "" : timestamp,
+ onInput: async (e) => {
+ setTimestamp(e)
+ }
+ },
doSelectExchange: selectedExchange.doSelect,
- invalid: !subject || Amounts.isZero(amount),
exchangeUrl: exchange.exchangeBaseUrl,
create: {
- onClick: accept,
+ onClick: unableToCreate ? undefined : accept,
},
cancel: {
onClick: onClose,
},
- chosenAmount: amount,
- toBeReceived: amount,
+ requestAmount,
+ toBeReceived,
error: undefined,
operationError,
};