diff options
Diffstat (limited to 'packages/taler-wallet-webextension/src/cta/InvoiceCreate/state.ts')
-rw-r--r-- | packages/taler-wallet-webextension/src/cta/InvoiceCreate/state.ts | 73 |
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, }; |