diff --git a/packages/renderer/src/constants/lang/LangKeys.ts b/packages/renderer/src/constants/lang/LangKeys.ts index ce7c2a7..0128cf2 100644 --- a/packages/renderer/src/constants/lang/LangKeys.ts +++ b/packages/renderer/src/constants/lang/LangKeys.ts @@ -39,6 +39,10 @@ export enum LangKeys { AccountNodeFieldDeamonFlags = "account.nodeSecurity.deamonFlags", AccountNodeFieldPort = "account.nodeSecurity.port", AccountNodeStopDeamon = "account.nodeSecurity.stopDeamon", + AccountNodeStartDeamon = "account.nodeSecurity.startDeamon", + AccountNodeLocalSaveNotification = "account.nodeSecurity.saveNotification", + AccountNodeDeamonStoppedNotif = "account.nodeSecurity.stoppedNotification", + AccountNodeDeamonStartedNotif = "account.nodeSecurity.startedNotification", AccountSettingsAddNode = "account.settings.addNewNode", AccountSettingsCurrent = "account.settings.current", AccountSecurityFieldPassword = "account.security.field.password", diff --git a/packages/renderer/src/constants/lang/en.ts b/packages/renderer/src/constants/lang/en.ts index 8352d1a..6200293 100644 --- a/packages/renderer/src/constants/lang/en.ts +++ b/packages/renderer/src/constants/lang/en.ts @@ -43,6 +43,11 @@ const LangPackEN: { [key in LangKeys]: string } = { [LangKeys.AccountNodeFieldPort]: "Port", [LangKeys.AccountNodeFieldDeamonFlags]: "Deamon startup flags", [LangKeys.AccountNodeStopDeamon]: "Stop deamon", + [LangKeys.AccountNodeStartDeamon]: "Start deamon", + [LangKeys.AccountNodeLocalSaveNotification]: + "Local node settings updated successfully", + [LangKeys.AccountNodeDeamonStoppedNotif]: "Deamon stopped successfully", + [LangKeys.AccountNodeDeamonStartedNotif]: "Deamon started successfully", [LangKeys.AccountSettingsAddNode]: "Add a new node", [LangKeys.AccountSettingsCurrent]: "Current", [LangKeys.AccountSecurityFieldPassword]: "Update account password", diff --git a/packages/renderer/src/constants/lang/es.ts b/packages/renderer/src/constants/lang/es.ts index 1424e93..e068a66 100644 --- a/packages/renderer/src/constants/lang/es.ts +++ b/packages/renderer/src/constants/lang/es.ts @@ -44,6 +44,11 @@ const LangPackES: { [key in LangKeys]: string } = { [LangKeys.AccountNodeFieldPort]: "Puerto", [LangKeys.AccountNodeFieldDeamonFlags]: "Indicadores de inicio de daemon", [LangKeys.AccountNodeStopDeamon]: "Detener demonio", + [LangKeys.AccountNodeStartDeamon]: "Comienzo demonio", + [LangKeys.AccountNodeLocalSaveNotification]: + "La configuración del nodo local se actualizó correctamente.", + [LangKeys.AccountNodeDeamonStoppedNotif]: "Daemon se detuvo con éxito", + [LangKeys.AccountNodeDeamonStartedNotif]: "Daemon se inició con éxito", [LangKeys.AccountSettingsAddNode]: "Agregar un nuevo nodo", [LangKeys.AccountSettingsCurrent]: "Actual", [LangKeys.AccountSecurityFieldPassword]: "Clave", diff --git a/packages/renderer/src/constants/query-keys.ts b/packages/renderer/src/constants/query-keys.ts index bbcf488..4179029 100644 --- a/packages/renderer/src/constants/query-keys.ts +++ b/packages/renderer/src/constants/query-keys.ts @@ -18,6 +18,10 @@ export enum QueryKeys { HavenoVersion = "Haveno.Version", Balances = "Haveno.Balances", PaymentAccounts = "Haveno.PaymentAccounts", + MoneroNodeSettings = "Haveno.MoneroNodeSettings", + MoneroNodeIsRunning = "Haveno.MoneroNodeIsRunning", + MoneroRemoteNodes = "Haveno.MoneroRemoteNodes", + SyncStatus = "Haveno.SyncStatus", StorageAccountInfo = "Storage.AccountInfo", diff --git a/packages/renderer/src/hooks/haveno/useIsMoneroNodeRunning.ts b/packages/renderer/src/hooks/haveno/useIsMoneroNodeRunning.ts new file mode 100644 index 0000000..650ea9d --- /dev/null +++ b/packages/renderer/src/hooks/haveno/useIsMoneroNodeRunning.ts @@ -0,0 +1,27 @@ +// ============================================================================= +// Copyright 2022 Haveno +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +// ============================================================================= + +import { useQuery } from "react-query"; +import { QueryKeys } from "@constants/query-keys"; +import { useHavenoClient } from "./useHavenoClient"; + +export function useIsMoneroNodeRunning() { + const client = useHavenoClient(); + + return useQuery(QueryKeys.MoneroNodeIsRunning, () => + client.isMoneroNodeRunning() + ); +} diff --git a/packages/renderer/src/hooks/haveno/useMoneroNodeSettings.ts b/packages/renderer/src/hooks/haveno/useMoneroNodeSettings.ts new file mode 100644 index 0000000..c2d875b --- /dev/null +++ b/packages/renderer/src/hooks/haveno/useMoneroNodeSettings.ts @@ -0,0 +1,31 @@ +// ============================================================================= +// Copyright 2022 Haveno +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +// ============================================================================= + +import { QueryKeys } from "@constants/query-keys"; +import type { MoneroNodeSettings } from "haveno-ts"; +import { useQuery } from "react-query"; +import { useHavenoClient } from "./useHavenoClient"; + +export function useMoneroNodeSettings() { + const client = useHavenoClient(); + + return useQuery( + QueryKeys.MoneroNodeSettings, + async () => { + return client.getMoneroNodeSettings(); + } + ); +} diff --git a/packages/renderer/src/hooks/haveno/useMoneroRemoteNodes.ts b/packages/renderer/src/hooks/haveno/useMoneroRemoteNodes.ts new file mode 100644 index 0000000..b6d0bdd --- /dev/null +++ b/packages/renderer/src/hooks/haveno/useMoneroRemoteNodes.ts @@ -0,0 +1,39 @@ +// ============================================================================= +// Copyright 2022 Haveno +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +// ============================================================================= + +import { useQuery } from "react-query"; +import { QueryKeys } from "@constants/query-keys"; +// import { useHavenoClient } from "./useHavenoClient"; + +interface MoneroRemoteNodes { + title: string; + isActive: boolean; +} + +export function useMoneroRemoteNodes() { + // const client = useHavenoClient(); + + return useQuery( + QueryKeys.MoneroRemoteNodes, + async () => { + return Promise.resolve([ + { title: "node.moneroworldcom:18089", isActive: true }, + { title: "node.xmr.pt:18081", isActive: true }, + { title: "node.monero.net:18081", isActive: true }, + ]); + } + ); +} diff --git a/packages/renderer/src/hooks/haveno/useSetMoneroNodeSettings.ts b/packages/renderer/src/hooks/haveno/useSetMoneroNodeSettings.ts new file mode 100644 index 0000000..5262d1e --- /dev/null +++ b/packages/renderer/src/hooks/haveno/useSetMoneroNodeSettings.ts @@ -0,0 +1,46 @@ +// ============================================================================= +// Copyright 2022 Haveno +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +// ============================================================================= + +import { useMutation, useQueryClient } from "react-query"; +import { QueryKeys } from "@constants/query-keys"; +import { useHavenoClient } from "./useHavenoClient"; + +interface SetMeneroNodeSettingsVariables { + blockchainPath?: string; + bootstrapUrl?: string; + startupFlags?: Array; +} + +export function useSetMoneroNodeSettings() { + const queryClient = useQueryClient(); + const client = useHavenoClient(); + + return useMutation( + async (data: SetMeneroNodeSettingsVariables) => { + const nodeSettings = await client.getMoneroNodeSettings(); + + data.blockchainPath && + nodeSettings?.setBlockchainPath(data.blockchainPath); + data.startupFlags && nodeSettings?.setStartupFlagsList(data.startupFlags); + data.bootstrapUrl && nodeSettings?.setBootstrapUrl(data.bootstrapUrl); + }, + { + onSuccess: () => { + queryClient.invalidateQueries(QueryKeys.MoneroNodeSettings); + }, + } + ); +} diff --git a/packages/renderer/src/hooks/haveno/useStartMoneroNode.ts b/packages/renderer/src/hooks/haveno/useStartMoneroNode.ts new file mode 100644 index 0000000..593867d --- /dev/null +++ b/packages/renderer/src/hooks/haveno/useStartMoneroNode.ts @@ -0,0 +1,34 @@ +// ============================================================================= +// Copyright 2022 Haveno +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +// ============================================================================= + +import { QueryKeys } from "@constants/query-keys"; +import type { MoneroNodeSettings } from "haveno-ts"; +import { useMutation, useQueryClient } from "react-query"; +import { useHavenoClient } from "./useHavenoClient"; + +export function useStartMoneroNode() { + const client = useHavenoClient(); + const queryClient = useQueryClient(); + + return useMutation( + (data: MoneroNodeSettings) => client.startMoneroNode(data), + { + onSuccess: () => { + queryClient.invalidateQueries(QueryKeys.MoneroNodeIsRunning); + }, + } + ); +} diff --git a/packages/renderer/src/hooks/haveno/useStopMoneroNode.ts b/packages/renderer/src/hooks/haveno/useStopMoneroNode.ts new file mode 100644 index 0000000..5a838a9 --- /dev/null +++ b/packages/renderer/src/hooks/haveno/useStopMoneroNode.ts @@ -0,0 +1,30 @@ +// ============================================================================= +// Copyright 2022 Haveno +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +// ============================================================================= + +import { QueryKeys } from "@constants/query-keys"; +import { useMutation, useQueryClient } from "react-query"; +import { useHavenoClient } from "./useHavenoClient"; + +export function useStopMoneroNode() { + const queryClient = useQueryClient(); + const client = useHavenoClient(); + + return useMutation(() => client.stopMoneroNode(), { + onSuccess: () => { + queryClient.invalidateQueries(QueryKeys.MoneroNodeIsRunning); + }, + }); +} diff --git a/packages/renderer/src/pages/Account/NodeSettings/NodeLocalForm.tsx b/packages/renderer/src/pages/Account/NodeSettings/NodeLocalForm.tsx index 55d746b..04f7de1 100644 --- a/packages/renderer/src/pages/Account/NodeSettings/NodeLocalForm.tsx +++ b/packages/renderer/src/pages/Account/NodeSettings/NodeLocalForm.tsx @@ -14,28 +14,70 @@ // limitations under the License. // ============================================================================= -import { Box, Stack, Grid, createStyles } from "@mantine/core"; -import { useForm } from "@mantine/form"; +import { Box, Stack, Grid, Group } from "@mantine/core"; +import { joiResolver, useForm } from "@mantine/form"; +import { FormattedMessage, useIntl } from "react-intl"; +import { showNotification } from "@mantine/notifications"; import { Button } from "@atoms/Buttons"; -import { FormattedMessage } from "react-intl"; import { LangKeys } from "@constants/lang"; import { TextInput } from "@atoms/TextInput"; +import { useMoneroNodeSettings } from "@hooks/haveno/useMoneroNodeSettings"; +import { useSetMoneroNodeSettings } from "@hooks/haveno/useSetMoneroNodeSettings"; +import { NodeLocalStopDeamon } from "./NodeLocalStopDeamon"; +import type { NodeLocalFormValues } from "./_hooks"; +import { useNodeLocalFormValidation } from "./_hooks"; +import { transformSettingsRequestToForm } from "./_utils"; export function NodeLocalForm() { - const form = useForm({ + const { data: nodeSettings } = useMoneroNodeSettings(); + const { mutateAsync: updateNodeSettings } = useSetMoneroNodeSettings(); + const intl = useIntl(); + + const validation = useNodeLocalFormValidation(); + + const form = useForm({ initialValues: { blockchainLocation: "", startupFlags: "", deamonAddress: "", port: "", + ...(nodeSettings + ? transformSettingsRequestToForm(nodeSettings.toObject()) + : {}), }, + validate: joiResolver(validation), }); + const handleFormSubmit = (values: NodeLocalFormValues) => { + updateNodeSettings({ + blockchainPath: values.blockchainLocation, + startupFlags: values.startupFlags.split(", "), + bootstrapUrl: `${values.deamonAddress}:${values.port}`, + }) + .then(() => { + showNotification({ + color: "green", + message: intl.formatMessage({ + id: LangKeys.AccountNodeLocalSaveNotification, + defaultMessage: "Local node settings updated successfully", + }), + }); + }) + .catch((err) => { + console.dir(err); + showNotification({ + color: "red", + message: err.message, + title: "Something went wrong", + }); + }); + }; + return ( -
console.log(values))}> + } + required {...form.getInputProps("deamonAddress")} /> @@ -79,33 +122,19 @@ export function NodeLocalForm() { defaultMessage="Port" /> } + required {...form.getInputProps("port")} /> + + + +
); } - -function NodeLocalStopDeamon() { - const { classes } = useStyles(); - - return ( -
- -
- ); -} - -const useStyles = createStyles((theme) => ({ - actions: { - marginBottom: theme.spacing.xl, - }, -})); diff --git a/packages/renderer/src/pages/Account/NodeSettings/NodeLocalStopDeamon.tsx b/packages/renderer/src/pages/Account/NodeSettings/NodeLocalStopDeamon.tsx new file mode 100644 index 0000000..7440c73 --- /dev/null +++ b/packages/renderer/src/pages/Account/NodeSettings/NodeLocalStopDeamon.tsx @@ -0,0 +1,112 @@ +// ============================================================================= +// Copyright 2022 Haveno +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +// ============================================================================= + +import { FormattedMessage, useIntl } from "react-intl"; +import { createStyles } from "@mantine/core"; +import { showNotification } from "@mantine/notifications"; +import { Button } from "@atoms/Buttons"; +import { LangKeys } from "@constants/lang"; +import { useMoneroNodeSettings } from "@hooks/haveno/useMoneroNodeSettings"; +import { useStopMoneroNode } from "@hooks/haveno/useStopMoneroNode"; +import { useIsMoneroNodeRunning } from "@hooks/haveno/useIsMoneroNodeRunning"; +import { useStartMoneroNode } from "@hooks/haveno/useStartMoneroNode"; + +export function NodeLocalStopDeamon() { + const { classes } = useStyles(); + const intl = useIntl(); + + const { mutateAsync: stopMoneroNode } = useStopMoneroNode(); + const { data: isMoneroNodeRunning } = useIsMoneroNodeRunning(); + const { mutateAsync: startMoneroNode } = useStartMoneroNode(); + const { isLoading: isNodeSettingsLoading, data: nodeSettings } = + useMoneroNodeSettings(); + + // handle the stop button click. + const handleStopBtnClick = () => { + stopMoneroNode() + .then(() => { + showNotification({ + color: "green", + message: intl.formatMessage({ + id: LangKeys.AccountNodeDeamonStoppedNotif, + defaultMessage: "Deamon stopped successfully", + }), + }); + }) + .catch((err) => { + console.dir(err); + showNotification({ + color: "red", + message: err.message, + title: "Something went wrong", + }); + }); + }; + // Handle the start button click. + const handleStartBtnClick = () => { + if (!nodeSettings) { + return; + } + startMoneroNode(nodeSettings) + .then(() => { + showNotification({ + color: "green", + message: intl.formatMessage({ + id: LangKeys.AccountNodeDeamonStartedNotif, + defaultMessage: "Deamon started successfully", + }), + }); + }) + .catch((err) => { + console.dir(err); + showNotification({ + color: "red", + message: err.message, + title: "Something went wrong", + }); + }); + }; + + return ( +
+ {isMoneroNodeRunning ? ( + + ) : ( + + )} +
+ ); +} + +const useStyles = createStyles((theme) => ({ + actions: { + marginBottom: theme.spacing.xl, + }, +})); diff --git a/packages/renderer/src/pages/Account/NodeSettings/NodeRemoteStatus.tsx b/packages/renderer/src/pages/Account/NodeSettings/NodeRemoteStatus.tsx index 91c25dc..a4bc420 100644 --- a/packages/renderer/src/pages/Account/NodeSettings/NodeRemoteStatus.tsx +++ b/packages/renderer/src/pages/Account/NodeSettings/NodeRemoteStatus.tsx @@ -15,23 +15,26 @@ // ============================================================================= import { Stack, createStyles, Group } from "@mantine/core"; +import { FormattedMessage } from "react-intl"; import { Button } from "@atoms/Buttons"; import { NodeStatus, NodeStatusType } from "@atoms/NodeStatus"; -import { FormattedMessage } from "react-intl"; import { LangKeys } from "@constants/lang"; +import { useMoneroRemoteNodes } from "@hooks/haveno/useMoneroRemoteNodes"; export function NodeRemoteStatus() { + const { data: remoteNodes } = useMoneroRemoteNodes(); + return ( - - - + {remoteNodes?.map((node) => ( + + ))} diff --git a/packages/renderer/src/pages/Account/NodeSettings/NodeSettingsBoot.tsx b/packages/renderer/src/pages/Account/NodeSettings/NodeSettingsBoot.tsx new file mode 100644 index 0000000..716e0cf --- /dev/null +++ b/packages/renderer/src/pages/Account/NodeSettings/NodeSettingsBoot.tsx @@ -0,0 +1,52 @@ +// ============================================================================= +// Copyright 2022 Haveno +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +// ============================================================================= + +import type { ReactNode } from "react"; +import { BodyText } from "@atoms/Typography"; +import { useMoneroNodeSettings } from "@hooks/haveno/useMoneroNodeSettings"; +import { useIsMoneroNodeRunning } from "@hooks/haveno/useIsMoneroNodeRunning"; +import { useMoneroRemoteNodes } from "@hooks/haveno/useMoneroRemoteNodes"; + +interface NodeSettingsBootProps { + children: ReactNode; +} + +export function LocalNodeSettingsBoot({ children }: NodeSettingsBootProps) { + const { isLoading: isNodeSettingsLoading } = useMoneroNodeSettings(); + const { isLoading: isMoneroNodeIsLoading } = useIsMoneroNodeRunning(); + + return isNodeSettingsLoading || isMoneroNodeIsLoading ? ( + Loading settings... + ) : ( + <>{children} + ); +} + +interface RemoteNodeSettingsBootProps { + children: ReactNode; +} + +export function RemoteNodeSettingsBoot({ + children, +}: RemoteNodeSettingsBootProps) { + const { isLoading: isMoneroRemoteLoading } = useMoneroRemoteNodes(); + + return isMoneroRemoteLoading ? ( + Loading settings... + ) : ( + <>{children} + ); +} diff --git a/packages/renderer/src/pages/Account/NodeSettings/NodeSettingsSwitch.tsx b/packages/renderer/src/pages/Account/NodeSettings/NodeSettingsSwitch.tsx index 1e7c7d7..a400927 100644 --- a/packages/renderer/src/pages/Account/NodeSettings/NodeSettingsSwitch.tsx +++ b/packages/renderer/src/pages/Account/NodeSettings/NodeSettingsSwitch.tsx @@ -22,6 +22,10 @@ import { ReactComponent as CloudIcon } from "@assets/setting-cloud.svg"; import { ReactComponent as ServerIcon } from "@assets/setting-server.svg"; import { NodeLocalForm } from "./NodeLocalForm"; import { NodeRemoteStatus } from "./NodeRemoteStatus"; +import { + LocalNodeSettingsBoot, + RemoteNodeSettingsBoot, +} from "./NodeSettingsBoot"; export function NodeSettingsSwitch() { const { classes } = useStyles(); @@ -43,7 +47,9 @@ export function NodeSettingsSwitch() { } icon={} > - + + + } > - + + + ); diff --git a/packages/renderer/src/pages/Account/NodeSettings/_hooks.ts b/packages/renderer/src/pages/Account/NodeSettings/_hooks.ts new file mode 100644 index 0000000..d07576c --- /dev/null +++ b/packages/renderer/src/pages/Account/NodeSettings/_hooks.ts @@ -0,0 +1,33 @@ +// ============================================================================= +// Copyright 2022 Haveno +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +// ============================================================================= + +import * as Joi from "joi"; + +export interface NodeLocalFormValues { + blockchainLocation: string; + startupFlags: string; + deamonAddress: string; + port: string; +} + +export function useNodeLocalFormValidation() { + return Joi.object({ + blockchainLocation: Joi.string().empty("").uri({ relativeOnly: true }), + startupFlags: Joi.string().empty(""), + deamonAddress: Joi.string().uri({ allowRelative: false }), + port: Joi.number().port(), + }); +} diff --git a/packages/renderer/src/pages/Account/NodeSettings/_utils.ts b/packages/renderer/src/pages/Account/NodeSettings/_utils.ts new file mode 100644 index 0000000..17a43eb --- /dev/null +++ b/packages/renderer/src/pages/Account/NodeSettings/_utils.ts @@ -0,0 +1,55 @@ +// ============================================================================= +// Copyright 2022 Haveno +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +// ============================================================================= + +import type { MoneroNodeSettings } from "haveno-ts"; +import type { NodeLocalFormValues } from "./_hooks"; + +/** + * Transformes the settings request values to form. + * @param {MoneroNodeSettings.AsObject} nodeSettings + * @returns {NodeLocalFormValues} + */ +export function transformSettingsRequestToForm( + nodeSettings: MoneroNodeSettings.AsObject +): NodeLocalFormValues { + return { + blockchainLocation: nodeSettings?.blockchainPath || "", + startupFlags: nodeSettings?.startupFlagsList.join(", ") || "", + deamonAddress: transfromBootstrapUrl(nodeSettings?.bootstrapUrl || ""), + port: transformPort(nodeSettings?.bootstrapUrl || ""), + }; +} + +function transformPort(urlAsString: string) { + try { + const url = new URL(urlAsString); + return url.port; + } catch { + return ""; + } +} + +function transfromBootstrapUrl(urlAsString: string) { + try { + const url = new URL(urlAsString); + + // Remove the port from url. + url.port = ""; + return url.href; + } catch { + return ""; + } +}