Skip to content
This repository has been archived by the owner on Oct 10, 2023. It is now read-only.

[Settings] Edit THORNode's api/rpc endpoints #2371

Merged
merged 1 commit into from
Aug 22, 2022
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
16 changes: 16 additions & 0 deletions src/renderer/components/settings/AppSettings.stories.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,8 @@ type StoryArgs = {
goToReleasePage: (version: string) => void
changeLocale: (locale: Locale) => void
onChangeMidgardUrl: (url: string) => void
onChangeThornodeNodeUrl: (url: string) => void
onChangeThornodeRpcUrl: (url: string) => void
changeNetwork: ChangeNetworkHandler
collapsed: boolean
}
Expand All @@ -26,6 +28,8 @@ const Template = ({
checkForUpdates,
goToReleasePage,
onChangeMidgardUrl,
onChangeThornodeRpcUrl,
onChangeThornodeNodeUrl,
changeLocale,
collapsed
}: StoryArgs) => {
Expand All @@ -47,8 +51,14 @@ const Template = ({
collapsed={collapsed}
toggleCollapse={() => console.log('toggle')}
midgardUrl={RD.pending}
thornodeNodeUrl="thornode-node-url"
thornodeRpcUrl="thornode-rpc-url"
onChangeMidgardUrl={onChangeMidgardUrl}
onChangeThornodeRpcUrl={onChangeThornodeRpcUrl}
onChangeThornodeNodeUrl={onChangeThornodeNodeUrl}
checkMidgardUrl$={(url, _) => Rx.of(RD.success(url))}
checkThornodeNodeUrl$={(url, _) => Rx.of(RD.success(url))}
checkThornodeRpcUrl$={(url, _) => Rx.of(RD.success(url))}
/>
)
}
Expand Down Expand Up @@ -76,6 +86,12 @@ const meta: ComponentMeta<typeof Template> = {
},
onChangeMidgardUrl: {
action: 'onChangeMidgardUrl'
},
onChangeThornodeNodeUrl: {
action: 'onChangeThornodeNodeUrl'
},
onChangeThornodeRpcUrl: {
action: 'onChangeThornodeRpcUrl'
}
},
args: { onlineStatus: OnlineStatus.ON, updateDataRD: 'initial', collapsed: false }
Expand Down
54 changes: 44 additions & 10 deletions src/renderer/components/settings/AppSettings.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@ import { Locale } from '../../../shared/i18n/types'
import { LOCALES } from '../../i18n'
import { AVAILABLE_NETWORKS } from '../../services/const'
import { CheckMidgardUrlHandler, MidgardUrlRD } from '../../services/midgard/types'
import { CheckThornodeNodeUrlHandler, CheckThornodeRpcUrlHandler } from '../../services/thorchain/types'
import { DownIcon } from '../icons'
import { Menu } from '../shared/menu'
import { BorderButton, TextButton } from '../uielements/button'
Expand All @@ -34,6 +35,12 @@ export type Props = {
midgardUrl: MidgardUrlRD
onChangeMidgardUrl: (url: string) => void
checkMidgardUrl$: CheckMidgardUrlHandler
checkThornodeNodeUrl$: CheckThornodeNodeUrlHandler
onChangeThornodeNodeUrl: (url: string) => void
checkThornodeRpcUrl$: CheckThornodeRpcUrlHandler
thornodeRpcUrl: string
thornodeNodeUrl: string
onChangeThornodeRpcUrl: (url: string) => void
}

type SectionProps = {
Expand Down Expand Up @@ -63,7 +70,13 @@ export const AppSettings: React.FC<Props> = (props): JSX.Element => {
toggleCollapse,
midgardUrl: midgardUrlRD,
onChangeMidgardUrl,
checkMidgardUrl$
checkMidgardUrl$,
onChangeThornodeNodeUrl,
checkThornodeNodeUrl$,
checkThornodeRpcUrl$,
onChangeThornodeRpcUrl,
thornodeRpcUrl,
thornodeNodeUrl
} = props

const intl = useIntl()
Expand Down Expand Up @@ -244,15 +257,36 @@ export const AppSettings: React.FC<Props> = (props): JSX.Element => {
<SwitchButton className="ml-10px" active={advancedActive} />
</TextButton>
{advancedActive && (
<Section className="mt-20px" title="Midgard">
<EditableUrl
className="w-full xl:w-3/4"
url={midgardUrl}
onChange={onChangeMidgardUrl}
loading={RD.isPending(midgardUrlRD)}
checkUrl$={checkMidgardUrl$}
/>
</Section>
<>
<Section className="mt-20px" title="Midgard">
<EditableUrl
className="w-full xl:w-3/4"
url={midgardUrl}
onChange={onChangeMidgardUrl}
loading={RD.isPending(midgardUrlRD)}
checkUrl$={checkMidgardUrl$}
successMsg={intl.formatMessage({ id: 'midgard.url.valid' })}
/>
</Section>
<Section className="mt-10px" title="THORNode API">
<EditableUrl
className="w-full xl:w-3/4"
url={thornodeNodeUrl}
onChange={onChangeThornodeNodeUrl}
checkUrl$={checkThornodeNodeUrl$}
successMsg={intl.formatMessage({ id: 'setting.thornode.node.valid' })}
/>
</Section>
<Section className="mt-10px" title="THORNode RPC">
<EditableUrl
className="w-full xl:w-3/4"
url={thornodeRpcUrl}
onChange={onChangeThornodeRpcUrl}
checkUrl$={checkThornodeRpcUrl$}
successMsg={intl.formatMessage({ id: 'setting.thornode.rpc.valid' })}
/>
</Section>
</>
)}
</div>
</Collapse.Panel>
Expand Down
11 changes: 4 additions & 7 deletions src/renderer/components/settings/EditableUrl.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -23,13 +23,14 @@ type TestUrlHandler = (url: string, intl: IntlShape) => TestUrlLD
type Props = {
url: string
checkUrl$: TestUrlHandler
successMsg: string
loading?: boolean
onChange?: (url: string) => void
className?: string
}

const EditableUrl: React.FC<Props> = (props): JSX.Element => {
const { url: initialUrl, className, loading = false, onChange = FP.constVoid, checkUrl$ } = props
const { url: initialUrl, className, successMsg, loading = false, onChange = FP.constVoid, checkUrl$ } = props

const [editableUrl, setEditableUrl] = useState<O.Option<string>>(O.none)
const [url, setUrl] = useState<string>(initialUrl)
Expand Down Expand Up @@ -86,14 +87,10 @@ const EditableUrl: React.FC<Props> = (props): JSX.Element => {
{error?.message ?? error.toString()}
</p>
),
(_) => (
<p className={`mt-10px font-main text-[14px] uppercase text-turquoise`}>
{intl.formatMessage({ id: 'midgard.url.valid' })}
</p>
)
(_) => <p className={`mt-10px font-main text-[14px] uppercase text-turquoise`}>{successMsg}</p>
)
),
[intl, testUrlState]
[successMsg, testUrlState]
)

const renderUrl = useCallback(() => {
Expand Down
44 changes: 43 additions & 1 deletion src/renderer/hooks/useThorchainClientUrl.ts
Original file line number Diff line number Diff line change
@@ -1,19 +1,24 @@
import { useEffect } from 'react'

import * as RD from '@devexperts/remote-data-ts'
import { NodeUrl } from '@xchainjs/xchain-thorchain'
import * as FP from 'fp-ts/lib/function'
import { useObservableState } from 'observable-hooks'
import { useIntl } from 'react-intl'
import * as Rx from 'rxjs'
import * as RxAjax from 'rxjs/ajax'
import * as RxOp from 'rxjs/operators'

import { Network } from '../../shared/api/types'
import { useThorchainContext } from '../contexts/ThorchainContext'
import { INITIAL_CLIENT_URL } from '../services/thorchain/const'
import { Configuration, HealthApi } from '../types/generated/thornode'
import { useNetwork } from './useNetwork'

export const useThorchainClientUrl = () => {
const { clientUrl$, setClientUrl } = useThorchainContext()
const { network } = useNetwork()
const intl = useIntl()

const [nodeUrl, networkUpdated] = useObservableState<NodeUrl, Network>(
(network$) =>
Expand All @@ -32,5 +37,42 @@ export const useThorchainClientUrl = () => {
const setRpc = (url: string) => setClientUrl({ url, network, type: 'rpc' })
const setNode = (url: string) => setClientUrl({ url, network, type: 'node' })

return { rpc: nodeUrl.rpc, node: nodeUrl.node, setRpc, setNode }
const checkNode$ = (url: string) =>
FP.pipe(
// Check `ping` endpoint
new HealthApi(new Configuration({ basePath: url })).ping(),
RxOp.map((result) => {
const { ping } = result
if (ping) return RD.success(url)

return RD.failure(
Error(intl.formatMessage({ id: 'setting.thornode.node.error.unhealthy' }, { endpoint: '/ping' }))
)
}),
RxOp.catchError((_: Error) =>
Rx.of(RD.failure(Error(`${intl.formatMessage({ id: 'setting.thornode.node.error.url' })}`)))
)
)

const checkRpc$ = (url: string) =>
FP.pipe(
// Check `health` endpoint
// https://docs.tendermint.com/v0.34/rpc/#/Info/health
RxAjax.ajax(`${url}/health`),
RxOp.map(({ response }) => {
// Empty result object means no error
if (response.result && typeof response.result === 'object' && Object.keys(response.result).length === 0)
return RD.success(url)

return RD.failure(
Error(intl.formatMessage({ id: 'setting.thornode.rpc.error.unhealthy' }, { endpoint: '/ping' }))
)
}),

RxOp.catchError((_: Error) =>
Rx.of(RD.failure(Error(`${intl.formatMessage({ id: 'thornode.url.error.invalid' })}`)))
)
)

return { rpc: nodeUrl.rpc, node: nodeUrl.node, setRpc, setNode, checkNode$, checkRpc$ }
}
9 changes: 8 additions & 1 deletion src/renderer/i18n/de/settings.ts
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,14 @@ const settings: SettingMessages = {
'setting.wallet.index': 'Index',
'setting.wallet.index.info': 'Trage die Index Nummer der Ledger Addresse ein, die Du verwenden möchtest',
'setting.wallet.hdpath.legacy.info': 'Veralteter Derivation Pfad {path}',
'setting.wallet.hdpath.ledgerlive.info': 'Ledger Live Derivation Pfad {path}'
'setting.wallet.hdpath.ledgerlive.info': 'Ledger Live Derivation Pfad {path}',
'setting.thornode.node.error.unhealthy':
'THORNode API URL scheint "unhealthy" zu sein beim Überprüfen von "{endpoint}"',
'setting.thornode.node.error.url': 'Ungültige THORNode API URL. Bitte überprüfe diese und versuche es erneut.',
'setting.thornode.rpc.error.url': 'Ungültige THORNode RPC URL. Bitte überprüfe diese und versuche es erneut.',
'setting.thornode.rpc.error.unhealthy': 'THORNode RPC scheint "unhealthy" zu sein beim Überprüfen von "{endpoint"',
'setting.thornode.node.valid': 'Gültige THORNode API URL',
'setting.thornode.rpc.valid': 'Gültige THORNode RPC URL'
}

export default settings
8 changes: 7 additions & 1 deletion src/renderer/i18n/en/settings.ts
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,13 @@ const settings: SettingMessages = {
'setting.wallet.index': 'Index',
'setting.wallet.index.info': 'Enter the index number of the Ledger address you want to use',
'setting.wallet.hdpath.legacy.info': 'Legacy derivation path {path}',
'setting.wallet.hdpath.ledgerlive.info': 'Ledger Live derivation path {path}'
'setting.wallet.hdpath.ledgerlive.info': 'Ledger Live derivation path {path}',
'setting.thornode.node.error.unhealthy': 'THORNode API seems to be unhealthy by checking "{endpoint}"',
'setting.thornode.node.error.url': 'Invalid THORNode API URL. Please double check and try again',
'setting.thornode.rpc.error.url': 'Invalid THORNode RPC URL. Please double check and try again',
'setting.thornode.rpc.error.unhealthy': 'THORNode RPC seems to be unhealthy by checking "{endpoint}"',
'setting.thornode.node.valid': 'Valid THORNode API URL',
'setting.thornode.rpc.valid': 'Valid THORNode RPC URL'
}

export default settings
8 changes: 7 additions & 1 deletion src/renderer/i18n/fr/settings.ts
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,13 @@ const settings: SettingMessages = {
'setting.wallet.index': 'Index',
'setting.wallet.index.info': "Entrez le numéro d'index de l'adresse Ledger que vous souhaitez utiliser",
'setting.wallet.hdpath.legacy.info': 'Legacy derivation path {path} - FR',
'setting.wallet.hdpath.ledgerlive.info': 'Ledger Live derivation path {path} - FR'
'setting.wallet.hdpath.ledgerlive.info': 'Ledger Live derivation path {path} - FR',
'setting.thornode.node.error.unhealthy': 'THORNode API seems to be unhealthy by checking "{endpoint} - FR"',
'setting.thornode.node.error.url': 'Invalid THORNode API URL. Please double check and try again - FR',
'setting.thornode.rpc.error.url': 'Invalid THORNode RPC URL. Please double check and try again - FR',
'setting.thornode.rpc.error.unhealthy': 'THORNode RPC seems to be unhealthy by checking "{endpoint}" - FR',
'setting.thornode.node.valid': 'Valid THORNode API URL - FR',
'setting.thornode.rpc.valid': 'Valid THORNode RPC URL - FR'
}

export default settings
8 changes: 7 additions & 1 deletion src/renderer/i18n/ru/settings.ts
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,13 @@ const settings: SettingMessages = {
'setting.wallet.index': 'Индекс',
'setting.wallet.index.info': 'Введите индекс Ledger адреса, который вы хотите использовать',
'setting.wallet.hdpath.legacy.info': 'Устаревший путь деривации {path}',
'setting.wallet.hdpath.ledgerlive.info': 'Путь деривации Ledger Live {path}'
'setting.wallet.hdpath.ledgerlive.info': 'Путь деривации Ledger Live {path}',
'setting.thornode.node.error.unhealthy': 'THORNode API seems to be unhealthy by checking "{endpoint} - RU"',
'setting.thornode.node.error.url': 'Invalid THORNode API URL. Please double check and try again - RU',
'setting.thornode.rpc.error.url': 'Invalid THORNode RPC URL. Please double check and try again - RU',
'setting.thornode.rpc.error.unhealthy': 'THORNode RPC seems to be unhealthy by checking "{endpoint}" - RU',
'setting.thornode.node.valid': 'Valid THORNode API URL - RU',
'setting.thornode.rpc.valid': 'Valid THORNode RPC URL - RU'
}

export default settings
6 changes: 6 additions & 0 deletions src/renderer/i18n/types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -328,6 +328,12 @@ type SettingMessageKey =
| 'setting.wallet.index.info'
| 'setting.wallet.hdpath.legacy.info'
| 'setting.wallet.hdpath.ledgerlive.info'
| 'setting.thornode.node.error.url'
| 'setting.thornode.node.error.unhealthy'
| 'setting.thornode.rpc.error.url'
| 'setting.thornode.rpc.error.unhealthy'
| 'setting.thornode.node.valid'
| 'setting.thornode.rpc.valid'

export type SettingMessages = { [key in SettingMessageKey]: string }

Expand Down
2 changes: 1 addition & 1 deletion src/renderer/services/thorchain/common.ts
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@ const setClientUrl = ({ url, network, type }: { url: string; network: Network; t
// TODO(@veado) Store data persistent on disc
const current = getClientUrl()
const cNetwork = toClientNetwork(network)
_setClientUrl({ ...current, [cNetwork]: { ...[cNetwork], [type]: url } })
_setClientUrl({ ...current, [cNetwork]: { ...current[cNetwork], [type]: url } })
}

/**
Expand Down
8 changes: 8 additions & 0 deletions src/renderer/services/thorchain/types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ import { Asset, BaseAmount } from '@xchainjs/xchain-util'
import * as O from 'fp-ts/Option'
import * as t from 'io-ts'
import { optionFromNullable } from 'io-ts-types/lib/optionFromNullable'
import { IntlShape } from 'react-intl'
import * as Rx from 'rxjs'

import { assetIO } from '../../../shared/api/io'
Expand All @@ -29,9 +30,16 @@ export type NodeUrl$ = Rx.Observable<NodeUrl>
export type NodeUrlLD = LiveData<Error, NodeUrl>
export type NodeUrlRD = RD.RemoteData<Error, NodeUrl>

export type CheckThornodeNodeRpcHandler = (url: string, intl: IntlShape) => LiveData<Error, string>

type UrlRD = RD.RemoteData<Error, string>
type CheckUrlHandler = (url: string, intl: IntlShape) => LiveData<Error, string>

export type ThornodeNodeUrlRD = UrlRD
export type CheckThornodeNodeUrlHandler = CheckUrlHandler

export type ThornodeRpcUrlRD = UrlRD
export type CheckThornodeRpcUrlHandler = CheckUrlHandler

export type FeesService = C.FeesService

Expand Down
16 changes: 16 additions & 0 deletions src/renderer/views/app/AppSettingsView.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@ import { useMidgardContext } from '../../contexts/MidgardContext'
import { useAppUpdate } from '../../hooks/useAppUpdate'
import { useCollapsedSetting } from '../../hooks/useCollapsedSetting'
import { useNetwork } from '../../hooks/useNetwork'
import { useThorchainClientUrl } from '../../hooks/useThorchainClientUrl'

export const AppSettingsView: React.FC = (): JSX.Element => {
const { network, changeNetwork } = useNetwork()
Expand All @@ -23,6 +24,15 @@ export const AppSettingsView: React.FC = (): JSX.Element => {

const { collapsed, toggle: toggleCollapse } = useCollapsedSetting('app')

const {
node: thornodeNodeUrl,
rpc: thornodeRpcUrl,
setRpc: setThornodeRpcUrl,
setNode: setThornodeNodeUrl,
checkRpc$: checkThornodeRpcUrl$,
checkNode$: checkThornodeNodeUrl$
} = useThorchainClientUrl()

const { changeLocale, locale$ } = useI18nContext()
const currentLocale = useObservableState(locale$, DEFAULT_LOCALE)

Expand Down Expand Up @@ -52,7 +62,13 @@ export const AppSettingsView: React.FC = (): JSX.Element => {
toggleCollapse={toggleCollapse}
midgardUrl={midgardUrl}
onChangeMidgardUrl={updateMidgardUrlHandler}
onChangeThornodeNodeUrl={setThornodeNodeUrl}
onChangeThornodeRpcUrl={setThornodeRpcUrl}
checkMidgardUrl$={checkMidgardUrl$}
thornodeRpcUrl={thornodeRpcUrl}
thornodeNodeUrl={thornodeNodeUrl}
checkThornodeRpcUrl$={checkThornodeRpcUrl$}
checkThornodeNodeUrl$={checkThornodeNodeUrl$}
/>
)
}