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

Commit

Permalink
[Settings] Edit THORNode's api/rpc endpoints (#2371)
Browse files Browse the repository at this point in the history
  • Loading branch information
veado authored Aug 22, 2022
1 parent 6a271fc commit 8de8fc3
Show file tree
Hide file tree
Showing 12 changed files with 167 additions and 23 deletions.
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$}
/>
)
}

0 comments on commit 8de8fc3

Please sign in to comment.