/*
This file is part of GNU Taler
(C) 2022 Taler Systems S.A.
GNU Taler is free software; you can redistribute it and/or modify it under the
terms of the GNU General Public License as published by the Free Software
Foundation; either version 3, or (at your option) any later version.
GNU Taler is distributed in the hope that it will be useful, but WITHOUT ANY
WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
A PARTICULAR PURPOSE. See the GNU General Public License for more details.
You should have received a copy of the GNU General Public License along with
GNU Taler; see the file COPYING. If not, see
*/
import {
Amounts,
CoinDumpJson,
ExchangeListItem,
NotificationType,
} from "@gnu-taler/taler-util";
import { PendingTaskInfo } from "@gnu-taler/taler-wallet-core";
import { format } from "date-fns";
import { Fragment, h, VNode } from "preact";
import { useEffect, useRef, useState } from "preact/hooks";
import { Diagnostics } from "../components/Diagnostics.js";
import { NotifyUpdateFadeOut } from "../components/styled/index.js";
import { Time } from "../components/Time.js";
import { useTranslationContext } from "../context/translation.js";
import { useAsyncAsHook } from "../hooks/useAsyncAsHook.js";
import { useDiagnostics } from "../hooks/useDiagnostics.js";
import { Button } from "../mui/Button.js";
import { Grid } from "../mui/Grid.js";
import { Paper } from "../mui/Paper.js";
import * as wxApi from "../wxApi.js";
export function DeveloperPage(): VNode {
const [status, timedOut] = useDiagnostics();
const listenAllEvents = Array.from({ length: 1 });
//FIXME: waiting for retry notification make a always increasing loop of notifications
listenAllEvents.includes = (e) => e !== "waiting-for-retry"; // includes every event
const response = useAsyncAsHook(async () => {
const op = await wxApi.getPendingOperations();
const c = await wxApi.dumpCoins();
const ex = await wxApi.listExchanges();
return {
operations: op.pendingOperations,
coins: c.coins,
exchanges: ex.exchanges,
};
});
useEffect(() => {
return wxApi.onUpdateNotification(listenAllEvents, () => {
response?.retry();
});
});
const nonResponse = { operations: [], coins: [], exchanges: [] };
const { operations, coins, exchanges } =
response === undefined
? nonResponse
: response.hasError
? nonResponse
: response.response;
return (
{
const db = await wxApi.exportDB();
return JSON.stringify(db);
}}
/>
);
}
type CoinsInfo = CoinDumpJson["coins"];
type CalculatedCoinfInfo = {
ageKeysCount: number | undefined;
denom_value: number;
remain_value: number;
status: string;
from_refresh: boolean;
id: string;
};
type SplitedCoinInfo = {
spent: CalculatedCoinfInfo[];
usable: CalculatedCoinfInfo[];
};
export interface Props {
status: any;
timedOut: boolean;
operations: PendingTaskInfo[];
coins: CoinsInfo;
exchanges: ExchangeListItem[];
onDownloadDatabase: () => Promise;
}
function hashObjectId(o: any): string {
return JSON.stringify(o);
}
export function View({
status,
timedOut,
operations,
coins,
onDownloadDatabase,
}: Props): VNode {
const { i18n } = useTranslationContext();
const [downloadedDatabase, setDownloadedDatabase] = useState<
{ time: Date; content: string } | undefined
>(undefined);
async function onExportDatabase(): Promise {
const content = await onDownloadDatabase();
setDownloadedDatabase({
time: new Date(),
content,
});
}
const fileRef = useRef(null);
async function onImportDatabase(str: string): Promise {
return wxApi.importDB(JSON.parse(str));
}
const currencies: { [ex: string]: string } = {};
const money_by_exchange = coins.reduce(
(prev, cur) => {
const denom = Amounts.parseOrThrow(cur.denom_value);
if (!prev[cur.exchange_base_url]) {
prev[cur.exchange_base_url] = [];
currencies[cur.exchange_base_url] = denom.currency;
}
prev[cur.exchange_base_url].push({
ageKeysCount: cur.ageCommitmentProof?.proof.privateKeys.length,
denom_value: parseFloat(Amounts.stringifyValue(denom)),
remain_value: parseFloat(
Amounts.stringifyValue(Amounts.parseOrThrow(cur.remaining_value)),
),
status: cur.coin_suspended ? "suspended" : "ok",
from_refresh: cur.refresh_parent_coin_pub !== undefined,
id: cur.coin_pub,
});
return prev;
},
{} as {
[exchange_name: string]: CalculatedCoinfInfo[];
},
);
return (