diff --git a/apps/hostd/components/Contracts/ContractContextMenu.tsx b/apps/hostd/components/Contracts/ContractContextMenu.tsx index 6854c2959..9d4b80fc4 100644 --- a/apps/hostd/components/Contracts/ContractContextMenu.tsx +++ b/apps/hostd/components/Contracts/ContractContextMenu.tsx @@ -12,10 +12,8 @@ import { Text, } from '@siafoundation/design-system' import { CaretDown16, DataCheck16 } from '@siafoundation/react-icons' -import { - ContractStatus, - useContractsIntegrityCheck, -} from '@siafoundation/hostd-react' +import { ContractStatus } from '@siafoundation/hostd-types' +import { useContractsIntegrityCheck } from '@siafoundation/hostd-react' import { useDialog } from '../../contexts/dialog' import { useCallback } from 'react' diff --git a/apps/hostd/components/DirectorySelectMenu/DirectorySelectCmd/index.tsx b/apps/hostd/components/DirectorySelectMenu/DirectorySelectCmd/index.tsx index 4aa33257a..bd486571f 100644 --- a/apps/hostd/components/DirectorySelectMenu/DirectorySelectCmd/index.tsx +++ b/apps/hostd/components/DirectorySelectMenu/DirectorySelectCmd/index.tsx @@ -3,7 +3,7 @@ import { Page } from '../../CmdRoot/types' import { Text } from '@siafoundation/design-system' import { FolderIcon } from '@siafoundation/react-icons' import { DirectorySelectEmpty } from './DirectorySelectEmpty' -import { SystemDirResponse } from '@siafoundation/hostd-react' +import { SystemDirectoryResponse } from '@siafoundation/hostd-types' import { useHostOSPathSeparator } from '../../../hooks/useHostOSPathSeparator' import { getChildDirectoryPath } from '../../../lib/system' import { DirectorySelectError } from './DirectorySelectError' @@ -27,7 +27,7 @@ export function DirectorySelectCmd({ afterSelect, }: { path: string - dir: SWRResponse + dir: SWRResponse setPath: (path: string) => void currentPage?: Page beforeSelect?: () => void diff --git a/apps/hostd/components/DirectorySelectMenu/index.tsx b/apps/hostd/components/DirectorySelectMenu/index.tsx index 74316a22e..e87a42c3f 100644 --- a/apps/hostd/components/DirectorySelectMenu/index.tsx +++ b/apps/hostd/components/DirectorySelectMenu/index.tsx @@ -1,6 +1,6 @@ import { Panel, ScrollArea } from '@siafoundation/design-system' import { SWRError } from '@siafoundation/react-core' -import { SystemDirResponse } from '@siafoundation/hostd-react' +import { SystemDirectoryResponse } from '@siafoundation/hostd-types' import { Command } from 'cmdk' import { SWRResponse } from 'swr' import { @@ -10,7 +10,7 @@ import { type Props = { path: string - dir: SWRResponse + dir: SWRResponse onChange: (path: string) => void } diff --git a/apps/hostd/components/Volumes/VolumeContextMenu.tsx b/apps/hostd/components/Volumes/VolumeContextMenu.tsx index a80faba2f..2d8a5c215 100644 --- a/apps/hostd/components/Volumes/VolumeContextMenu.tsx +++ b/apps/hostd/components/Volumes/VolumeContextMenu.tsx @@ -17,8 +17,8 @@ import { Edit16, Close16, } from '@siafoundation/react-icons' +import { VolumeStatus } from '@siafoundation/hostd-types' import { - VolumeStatus, useVolume, useVolumeCancel, useVolumeUpdate, diff --git a/apps/hostd/contexts/config/resources.ts b/apps/hostd/contexts/config/resources.ts index a737b199f..3dfde3703 100644 --- a/apps/hostd/contexts/config/resources.ts +++ b/apps/hostd/contexts/config/resources.ts @@ -1,5 +1,5 @@ import { SWRError } from '@siafoundation/react-core' -import { HostSettings } from '@siafoundation/hostd-react' +import { HostSettings } from '@siafoundation/hostd-types' export type Resources = { settings: { diff --git a/apps/hostd/contexts/config/transform.ts b/apps/hostd/contexts/config/transform.ts index faa585051..be93f01bd 100644 --- a/apps/hostd/contexts/config/transform.ts +++ b/apps/hostd/contexts/config/transform.ts @@ -4,7 +4,7 @@ import { DNSDuckDNSOptions, DNSNoIPOptions, HostSettings, -} from '@siafoundation/hostd-react' +} from '@siafoundation/hostd-types' import { bytesToMB, MBToBytes, diff --git a/apps/hostd/contexts/config/types.ts b/apps/hostd/contexts/config/types.ts index e8e7a3eb2..db8040a29 100644 --- a/apps/hostd/contexts/config/types.ts +++ b/apps/hostd/contexts/config/types.ts @@ -1,4 +1,4 @@ -import { DNSProvider } from '@siafoundation/hostd-react' +import { DNSProvider } from '@siafoundation/hostd-types' import BigNumber from 'bignumber.js' export const scDecimalPlaces = 6 diff --git a/apps/hostd/contexts/contracts/columns.tsx b/apps/hostd/contexts/contracts/columns.tsx index d3228de29..2caf7a2f9 100644 --- a/apps/hostd/contexts/contracts/columns.tsx +++ b/apps/hostd/contexts/contracts/columns.tsx @@ -14,7 +14,7 @@ import { ArrowDownRight16, Money16, } from '@siafoundation/react-icons' -import { ContractStatus } from '@siafoundation/hostd-react' +import { ContractStatus } from '@siafoundation/hostd-types' import { blockHeightToTime, humanBytes, humanDate } from '@siafoundation/units' import { ContractContextMenu } from '../../components/Contracts/ContractContextMenu' import { ContractData, TableColumnId } from './types' diff --git a/apps/hostd/contexts/contracts/dataset.ts b/apps/hostd/contexts/contracts/dataset.ts index db1acba9d..d7b72ab0c 100644 --- a/apps/hostd/contexts/contracts/dataset.ts +++ b/apps/hostd/contexts/contracts/dataset.ts @@ -1,5 +1,6 @@ import { useMemo } from 'react' -import { Contract, useContracts } from '@siafoundation/hostd-react' +import { Contract } from '@siafoundation/hostd-types' +import { useContracts } from '@siafoundation/hostd-react' import { ContractData } from './types' import BigNumber from 'bignumber.js' diff --git a/apps/hostd/contexts/contracts/index.tsx b/apps/hostd/contexts/contracts/index.tsx index e30761045..eee424d10 100644 --- a/apps/hostd/contexts/contracts/index.tsx +++ b/apps/hostd/contexts/contracts/index.tsx @@ -5,10 +5,8 @@ import { getContractsTimeRangeBlockHeight, } from '@siafoundation/design-system' import { useRouter } from 'next/router' -import { - ContractStatus, - useContracts as useContractsData, -} from '@siafoundation/hostd-react' +import { ContractStatus } from '@siafoundation/hostd-types' +import { useContracts as useContractsData } from '@siafoundation/hostd-react' import { createContext, useContext, useMemo } from 'react' import { columnsDefaultVisible, diff --git a/apps/hostd/contexts/contracts/types.ts b/apps/hostd/contexts/contracts/types.ts index 7f257de07..3e6c5fd42 100644 --- a/apps/hostd/contexts/contracts/types.ts +++ b/apps/hostd/contexts/contracts/types.ts @@ -8,7 +8,7 @@ import { import { ContractFilterSortField, ContractStatus, -} from '@siafoundation/hostd-react' +} from '@siafoundation/hostd-types' import BigNumber from 'bignumber.js' export type ContractData = { diff --git a/apps/hostd/contexts/volumes/dataset.ts b/apps/hostd/contexts/volumes/dataset.ts index ae9305a17..7481f9ed6 100644 --- a/apps/hostd/contexts/volumes/dataset.ts +++ b/apps/hostd/contexts/volumes/dataset.ts @@ -1,5 +1,6 @@ import { useMemo } from 'react' -import { useVolumes, VolumeMeta } from '@siafoundation/hostd-react' +import { VolumeMeta } from '@siafoundation/hostd-types' +import { useVolumes } from '@siafoundation/hostd-react' import { VolumeData } from './types' import BigNumber from 'bignumber.js' import { MiBToBytes } from '@siafoundation/units' diff --git a/apps/hostd/contexts/volumes/index.tsx b/apps/hostd/contexts/volumes/index.tsx index aa162aad2..185c7140b 100644 --- a/apps/hostd/contexts/volumes/index.tsx +++ b/apps/hostd/contexts/volumes/index.tsx @@ -3,10 +3,8 @@ import { useDatasetEmptyState, secondsInMilliseconds, } from '@siafoundation/design-system' -import { - VolumeMeta, - useVolumes as useVolumesData, -} from '@siafoundation/hostd-react' +import { VolumeMeta } from '@siafoundation/hostd-types' +import { useVolumes as useVolumesData } from '@siafoundation/hostd-react' import { createContext, useContext, useMemo } from 'react' import { columnsDefaultVisible, TableColumnId } from './types' import { columns } from './columns' diff --git a/apps/hostd/contexts/volumes/types.ts b/apps/hostd/contexts/volumes/types.ts index abf017910..94f52f09a 100644 --- a/apps/hostd/contexts/volumes/types.ts +++ b/apps/hostd/contexts/volumes/types.ts @@ -1,4 +1,4 @@ -import { VolumeStatus } from '@siafoundation/hostd-react' +import { VolumeStatus } from '@siafoundation/hostd-types' import BigNumber from 'bignumber.js' export type VolumeData = { diff --git a/apps/hostd/dialogs/AlertsDialog.tsx b/apps/hostd/dialogs/AlertsDialog.tsx index 5e66a9e7f..142752e95 100644 --- a/apps/hostd/dialogs/AlertsDialog.tsx +++ b/apps/hostd/dialogs/AlertsDialog.tsx @@ -5,11 +5,8 @@ import { triggerSuccessToast, ValueCopyable, } from '@siafoundation/design-system' -import { - AlertSeverity, - useAlerts, - useAlertsDismiss, -} from '@siafoundation/hostd-react' +import { AlertSeverity } from '@siafoundation/hostd-types' +import { useAlerts, useAlertsDismiss } from '@siafoundation/hostd-react' import { humanTime } from '@siafoundation/units' import { useCallback } from 'react' import { defaultDatasetRefreshInterval } from '../config/swr' diff --git a/libs/hostd-react/package.json b/libs/hostd-react/package.json index 9b41bf7fc..4ff4162e7 100644 --- a/libs/hostd-react/package.json +++ b/libs/hostd-react/package.json @@ -1,12 +1,12 @@ { "name": "@siafoundation/hostd-react", - "description": " React hooks for interacting with `hostd`.", + "description": "React hooks for interacting with `hostd`.", "version": "4.0.0", "license": "MIT", - "peerDependencies": { + "dependencies": { "swr": "^2.1.1", "@siafoundation/react-core": "^1.1.0", - "@siafoundation/types": "^0.2.0" + "@siafoundation/hostd-types": "0.0.0" }, "types": "./src/index.d.ts" } diff --git a/libs/hostd-react/src/api.ts b/libs/hostd-react/src/api.ts index f3f239005..78cd50035 100644 --- a/libs/hostd-react/src/api.ts +++ b/libs/hostd-react/src/api.ts @@ -13,53 +13,102 @@ import { delay, usePatchFunc, } from '@siafoundation/react-core' -import { - FileContractID, - PublicKey, - Currency, - TransactionID, - ChainIndex, -} from '@siafoundation/types' import useSWR from 'swr' -import { Contract, ContractStatus, WalletTransaction } from './siaTypes' +import { + AlertsDismissParams, + AlertsDismissPayload, + AlertsDismissResponse, + AlertsParams, + AlertsResponse, + ContractsIntegrityCheckParams, + ContractsIntegrityCheckPaylaod, + ContractsIntegrityCheckResponse, + ContractsParams, + ContractsPayload, + ContractsResponse, + LogsSearchParams, + LogsSearchPayload, + LogsSearchResponse, + MetricsParams, + MetricsPeriodParams, + MetricsPeriodResponse, + MetricsResponse, + SettingsAnnounceParams, + SettingsAnnouncePayload, + SettingsAnnounceResponse, + SettingsDdnsParams, + SettingsDdnsPayload, + SettingsDdnsResponse, + SettingsDdnsUpdateParams, + SettingsDdnsUpdatePayload, + SettingsDdnsUpdateResponse, + SettingsParams, + SettingsResponse, + SettingsUpdateParams, + SettingsUpdatePayload, + SettingsUpdateResponse, + StateConsensusParams, + StateConsensusResponse, + StateHostParams, + StateHostResponse, + SyncerConnectParams, + SyncerConnectPayload, + SyncerConnectResponse, + SyncerPeersParams, + SyncerPeersResponse, + SystemDirectoryCreateParams, + SystemDirectoryCreatePayload, + SystemDirectoryCreateResponse, + SystemDirectoryParams, + SystemDirectoryResponse, + TxPoolFeeParams, + TxPoolFeeResponse, + VolumeCancelParams, + VolumeCancelPayload, + VolumeCancelResponse, + VolumeCreateParams, + VolumeCreatePayload, + VolumeCreateResponse, + VolumeDeleteParams, + VolumeDeletePayload, + VolumeDeleteResponse, + VolumeParams, + VolumeResizeParams, + VolumeResizePayload, + VolumeResizeResponse, + VolumeResponse, + VolumeUpdateParams, + VolumeUpdatePayload, + VolumeUpdateResponse, + VolumesParams, + VolumesResponse, + WalletParams, + WalletPendingParams, + WalletPendingResponse, + WalletResponse, + WalletSendParams, + WalletSendPayload, + WalletSendResponse, + WalletTransactionsParams, + WalletTransactionsResponse, +} from '@siafoundation/hostd-types' // state -export type StateHost = { - name?: string - publicKey: string - walletAddress: string - network: 'Mainnet' | 'Zen Testnet' - version: string - commit: string - os: string - startTime: string - buildTime: string - lastAnnouncement?: { - index: ChainIndex - publicKey: string - address: string - } -} - export const stateHostKey = '/state/host' -export function useStateHost(args?: HookArgsSwr) { +export function useStateHost( + args?: HookArgsSwr +) { return useGetSwr({ ...args, route: stateHostKey, }) } -export type StateConsensus = { - chainIndex: { - height: number - id: string - } - synced: boolean -} - -export function useStateConsensus(args?: HookArgsSwr) { +export function useStateConsensus( + args?: HookArgsSwr +) { return useGetSwr({ ...args, route: '/state/consensus', @@ -92,14 +141,11 @@ export function useEstimatedNetworkBlockHeight(): number { // syncer -type Peer = { - address: string - version: string -} - const syncerPeers = '/syncer/peers' -export function useSyncerPeers(args?: HookArgsSwr) { +export function useSyncerPeers( + args?: HookArgsSwr +) { return useGetSwr({ ...args, route: syncerPeers, @@ -107,7 +153,11 @@ export function useSyncerPeers(args?: HookArgsSwr) { } export function useSyncerConnect( - args?: HookArgsCallback + args?: HookArgsCallback< + SyncerConnectParams, + SyncerConnectPayload, + SyncerConnectResponse + > ) { return usePutFunc( { @@ -122,15 +172,7 @@ export function useSyncerConnect( // wallet -type WalletResponse = { - scanHeight: number - address: string - spendable: string - confirmed: string - unconfirmed: string -} - -export function useWallet(args?: HookArgsSwr) { +export function useWallet(args?: HookArgsSwr) { return useGetSwr({ ...args, route: '/wallet', @@ -138,7 +180,7 @@ export function useWallet(args?: HookArgsSwr) { } export function useWalletTransactions( - args?: HookArgsSwr<{ limit?: number; offset?: number }, WalletTransaction[]> + args?: HookArgsSwr ) { return useGetSwr({ ...args, @@ -148,7 +190,7 @@ export function useWalletTransactions( const walletPendingRoute = '/wallet/pending' export function useWalletPending( - args?: HookArgsSwr + args?: HookArgsSwr ) { return useGetSwr({ ...args, @@ -156,13 +198,12 @@ export function useWalletPending( }) } -type WalletSendRequest = { - amount: string - address: string -} - export function useWalletSend( - args?: HookArgsCallback + args?: HookArgsCallback< + WalletSendParams, + WalletSendPayload, + WalletSendResponse + > ) { return usePostFunc({ ...args, route: '/wallet/send' }, async (mutate) => { await delay(2_000) @@ -177,7 +218,9 @@ export function useWalletSend( // txpool -export function useTxPoolFee(args?: HookArgsSwr) { +export function useTxPoolFee( + args?: HookArgsSwr +) { return useGetSwr({ ...args, route: '/tpool/fee', @@ -186,45 +229,12 @@ export function useTxPoolFee(args?: HookArgsSwr) { // contracts -export type ContractFilterSortField = - | 'status' - | 'negotiationHeight' - | 'expirationHeight' - -export type ContractFilterRequest = { - // filters - statuses?: ContractStatus[] - contractIDs?: FileContractID[] - renewedFrom?: FileContractID[] - renewedTo?: FileContractID[] - renterKey?: PublicKey[] - - minNegotiationHeight?: number - maxNegotiationHeight?: number - - minExpirationHeight?: number - maxExpirationHeight?: number - - // pagination - limit?: number - offset?: number - - // sorting - sortField?: ContractFilterSortField - sortDesc?: boolean -} - -export type ContractFilterResponse = { - contracts: Contract[] - count: number -} - const contractsRoute = '/contracts' export function useContracts( args: HookArgsWithPayloadSwr< - void, - ContractFilterRequest, - ContractFilterResponse + ContractsParams, + ContractsPayload, + ContractsResponse > ) { return usePostSwr({ @@ -234,117 +244,28 @@ export function useContracts( } export function useContractsIntegrityCheck( - args?: HookArgsCallback<{ id: string }, void, void> + args?: HookArgsCallback< + ContractsIntegrityCheckParams, + ContractsIntegrityCheckPaylaod, + ContractsIntegrityCheckResponse + > ) { return usePutFunc({ ...args, route: '/contracts/:id/integrity' }) } // metrics -// Revenue is a collection of metrics related to revenue. -type Revenue = { - rpc: string - storage: string - ingress: string - egress: string - registryRead: string - registryWrite: string -} - -// Data is a collection of metrics related to data usage. -type Data = { - // Ingress returns the number of bytes received by the host. - ingress: number - // Egress returns the number of bytes sent by the host. - egress: number -} - -// Contracts is a collection of metrics related to contracts. -type Contracts = { - pending: number - active: number - rejected: number - failed: number - successful: number - lockedCollateral: string - riskedCollateral: string -} - -// Pricing is a collection of metrics related to the host's pricing settings. -type Pricing = { - contractPrice: string - ingressPrice: string - egressPrice: string - baseRPCPrice: string - sectorAccessPrice: string - storagePrice: string - collateralMultiplier: number -} - -// Registry is a collection of metrics related to the host's registry. -type Registry = { - entries: number - maxEntries: number - - reads: number - writes: number -} - -// Storage is a collection of metrics related to storage. -type Storage = { - totalSectors: number - physicalSectors: number - contractSectors: number - tempSectors: number - reads: number - writes: number -} - -// RevenueMetrics is a collection of metrics related to revenue. -type RevenueMetrics = { - potential: Revenue - earned: Revenue -} - -// DataMetrics is a collection of metrics related to data usage. -type DataMetrics = { - rhp: Data -} - -type Metrics = { - revenue: RevenueMetrics - pricing: Pricing - contracts: Contracts - storage: Storage - registry: Registry - data: DataMetrics - balance: string - timestamp: string -} - const metricsRoute = '/metrics' -export function useMetrics(args?: HookArgsSwr<{ timestamp: string }, Metrics>) { +export function useMetrics(args?: HookArgsSwr) { return useGetSwr({ ...args, route: metricsRoute, }) } -type Interval = - | '5m' - | '15m' - | 'hourly' - | 'daily' - | 'weekly' - | 'monthly' - | 'yearly' - const metricsPeriodRoute = '/metrics/:interval' export function useMetricsPeriod( - args?: HookArgsSwr< - { interval: Interval; start: string; periods?: number }, - Metrics[] - > + args?: HookArgsSwr ) { return useGetSwr({ ...args, @@ -354,79 +275,10 @@ export function useMetricsPeriod( // settings -// DuckDNS -export type DNSDuckDNSOptions = { - token: string -} - -// No-IP -export type DNSNoIPOptions = { - email: string - password: string -} - -// AWS -export type DNSAWSOptions = { - id: string - secret: string - zoneID: string -} - -// Cloudflare -export type DNSCloudflareOptions = { - token: string - zoneID: string -} - -export type DNSProvider = '' | 'route53' | 'noip' | 'duckdns' | 'cloudflare' - -type DNSSettings = { - provider: DNSProvider - ipv4: boolean - ipv6: boolean - options: - | DNSDuckDNSOptions - | DNSNoIPOptions - | DNSAWSOptions - | DNSCloudflareOptions -} - -export type HostSettings = { - // Host settings - acceptingContracts: boolean - netAddress: string - maxContractDuration: number - - // Pricing - contractPrice: Currency - baseRPCPrice: Currency - sectorAccessPrice: Currency - - collateralMultiplier: number - maxCollateral: Currency - - storagePrice: Currency - egressPrice: Currency - ingressPrice: Currency - - priceTableValidity: number - - // RHP3 settings - accountExpiry: number - maxAccountBalance: Currency - - // Bandwidth limiter settings - ingressLimit: number - egressLimit: number - - // DNS settings - ddns: DNSSettings - - revision: number -} - const settingsRoute = '/settings' -export function useSettings(args?: HookArgsSwr) { +export function useSettings( + args?: HookArgsSwr +) { return useGetSwr({ ...args, route: settingsRoute, @@ -434,7 +286,11 @@ export function useSettings(args?: HookArgsSwr) { } export function useSettingsUpdate( - args?: HookArgsCallback, HostSettings> + args?: HookArgsCallback< + SettingsUpdateParams, + SettingsUpdatePayload, + SettingsUpdateResponse + > ) { return usePatchFunc({ ...args, route: '/settings' }, async (mutate) => { await mutate((key) => { @@ -443,65 +299,52 @@ export function useSettingsUpdate( }) } -export function useSettingsAnnounce(args?: HookArgsCallback) { +export function useSettingsAnnounce( + args?: HookArgsCallback< + SettingsAnnounceParams, + SettingsAnnouncePayload, + SettingsAnnounceResponse + > +) { return usePostFunc({ ...args, route: '/settings/announce' }) } export function useSettingsDdnsUpdate( - args?: HookArgsCallback + args?: HookArgsCallback< + SettingsDdnsUpdateParams, + SettingsDdnsUpdatePayload, + SettingsDdnsUpdateResponse + > ) { return usePutFunc({ ...args, route: '/settings/ddns/update' }) } export function useSettingsDdns( - args?: HookArgsWithPayloadSwr + args?: HookArgsWithPayloadSwr< + SettingsDdnsParams, + SettingsDdnsPayload, + SettingsDdnsResponse + > ) { return usePutSwr({ ...args, payload: {}, route: '/settings/ddns/update' }) } // volumes -export type Volume = { - id: number - localPath: string - usedSectors: number - totalSectors: number - readOnly: boolean - available: boolean -} - -export type VolumeStatus = - | 'unavailable' - | 'creating' - | 'resizing' - | 'removing' - | 'ready' - -export type VolumeStats = { - failedReads: number - failedWrites: number - successfulReads: number - successfulWrites: number - status: VolumeStatus - errors: string[] -} - -export type VolumeMeta = Volume & VolumeStats - -export function useVolumes(args?: HookArgsSwr) { +export function useVolumes(args?: HookArgsSwr) { return useGetSwr({ ...args, route: '/volumes' }) } -export function useVolume(args?: HookArgsSwr<{ id: string }, VolumeMeta>) { +export function useVolume(args?: HookArgsSwr) { return useGetSwr({ ...args, route: '/volumes/:id' }) } const volumesRoute = '/volumes' export function useVolumeCreate( args?: HookArgsCallback< - void, - { localPath: string; maxSectors: number }, - Volume + VolumeCreateParams, + VolumeCreatePayload, + VolumeCreateResponse > ) { return usePostFunc({ ...args, route: volumesRoute }, async (mutate) => { @@ -512,7 +355,11 @@ export function useVolumeCreate( } export function useVolumeUpdate( - args?: HookArgsCallback<{ id: number }, { readOnly: boolean }, void> + args?: HookArgsCallback< + VolumeUpdateParams, + VolumeUpdatePayload, + VolumeUpdateResponse + > ) { return usePutFunc({ ...args, route: '/volumes/:id' }, async (mutate) => { mutate((key) => { @@ -522,7 +369,11 @@ export function useVolumeUpdate( } export function useVolumeDelete( - args?: HookArgsCallback<{ id: number; force?: boolean }, void, void> + args?: HookArgsCallback< + VolumeDeleteParams, + VolumeDeletePayload, + VolumeDeleteResponse + > ) { return useDeleteFunc({ ...args, route: '/volumes/:id' }, async (mutate) => { mutate((key) => { @@ -532,7 +383,11 @@ export function useVolumeDelete( } export function useVolumeResize( - args?: HookArgsCallback<{ id: number }, { maxSectors: number }, void> + args?: HookArgsCallback< + VolumeResizeParams, + VolumeResizePayload, + VolumeResizeResponse + > ) { return usePutFunc( { ...args, route: '/volumes/:id/resize' }, @@ -546,7 +401,11 @@ export function useVolumeResize( } export function useVolumeCancel( - args?: HookArgsCallback<{ id: number }, void, void> + args?: HookArgsCallback< + VolumeCancelParams, + VolumeCancelPayload, + VolumeCancelResponse + > ) { return useDeleteFunc( { ...args, route: '/volumes/:id/cancel' }, @@ -559,49 +418,29 @@ export function useVolumeCancel( ) } -export type SystemDirResponse = { - path: string - totalBytes: number - freeBytes: number - directories: string[] -} - export function useSystemDirectory( - args: HookArgsSwr<{ path: string }, SystemDirResponse> + args: HookArgsSwr ) { return useGetSwr({ ...args, route: '/system/dir' }) } export function useSystemDirectoryCreate( - args?: HookArgsCallback + args?: HookArgsCallback< + SystemDirectoryCreateParams, + SystemDirectoryCreatePayload, + SystemDirectoryCreateResponse + > ) { return usePutFunc({ ...args, route: '/system/dir' }) } // logs -type LogEntry = { - timestamp: string - level: string - name: string - caller: string - message: string - fields: Record -} - export function useLogsSearch( args: HookArgsWithPayloadSwr< - void, - { - names?: string[] - callers?: string[] - levels?: string[] - before?: string - after?: string - limit?: number - offset?: number - }, - { count: number; entries: LogEntry[] } + LogsSearchParams, + LogsSearchPayload, + LogsSearchResponse > ) { return usePostSwr({ ...args, route: '/log/entries' }) @@ -609,48 +448,18 @@ export function useLogsSearch( // alerts -export type AlertSeverity = 'info' | 'warning' | 'error' | 'critical' - -export type Alert = { - id: string - severity: AlertSeverity - message: string - data: { - contractID?: number - blockHeight?: number - resolution?: string - volume?: string - volumeID?: number - - elapsed?: number - error?: string - - checked?: number - missing?: number - corrupt?: number - total?: number - - oldSectors?: number - currentSectors?: number - targetSectors?: number - migratedSectors?: number - - migrated?: number - target?: number - - force?: boolean - } - timestamp: string -} - const alertsRoute = '/alerts' -export function useAlerts(args?: HookArgsSwr) { +export function useAlerts(args?: HookArgsSwr) { return useGetSwr({ ...args, route: alertsRoute }) } export function useAlertsDismiss( - args?: HookArgsCallback + args?: HookArgsCallback< + AlertsDismissParams, + AlertsDismissPayload, + AlertsDismissResponse + > ) { return usePostFunc({ ...args, route: '/alerts/dismiss' }, async (mutate) => { mutate((key) => { diff --git a/libs/hostd-react/src/index.ts b/libs/hostd-react/src/index.ts index 74b0328a1..3318fdbc9 100644 --- a/libs/hostd-react/src/index.ts +++ b/libs/hostd-react/src/index.ts @@ -1,2 +1 @@ export * from './api' -export * from './siaTypes' diff --git a/libs/hostd-types/.babelrc b/libs/hostd-types/.babelrc new file mode 100644 index 000000000..1ea870ead --- /dev/null +++ b/libs/hostd-types/.babelrc @@ -0,0 +1,12 @@ +{ + "presets": [ + [ + "@nx/react/babel", + { + "runtime": "automatic", + "useBuiltIns": "usage" + } + ] + ], + "plugins": [] +} diff --git a/libs/hostd-types/.eslintrc.json b/libs/hostd-types/.eslintrc.json new file mode 100644 index 000000000..2008618ec --- /dev/null +++ b/libs/hostd-types/.eslintrc.json @@ -0,0 +1,21 @@ +{ + "extends": ["plugin:@nx/react", "../../.eslintrc.json"], + "ignorePatterns": ["!**/*"], + "rules": { + "@nx/dependency-checks": [ + "error", + { + "ignoredFiles": ["libs/hostd-types/rollup.config.js"] + } + ] + }, + "overrides": [ + { + "files": ["*.json"], + "parser": "jsonc-eslint-parser", + "rules": { + "@nx/dependency-checks": "error" + } + } + ] +} diff --git a/libs/hostd-types/README.md b/libs/hostd-types/README.md new file mode 100644 index 000000000..38933f693 --- /dev/null +++ b/libs/hostd-types/README.md @@ -0,0 +1,3 @@ +# hostd-types + +Types for `hostd`. diff --git a/libs/hostd-types/jest.config.ts b/libs/hostd-types/jest.config.ts new file mode 100644 index 000000000..b3d22dc64 --- /dev/null +++ b/libs/hostd-types/jest.config.ts @@ -0,0 +1,17 @@ +/* eslint-disable */ +export default { + displayName: 'hostd-types', + preset: '../../jest.preset.js', + transform: { + '^(?!.*\\.(js|jsx|ts|tsx|css|json)$)': '@nx/react/plugins/jest', + '^.+\\.[tj]sx?$': [ + 'babel-jest', + { + presets: ['@nx/next/babel'], + plugins: ['@babel/plugin-transform-private-methods'], + }, + ], + }, + moduleFileExtensions: ['ts', 'tsx', 'js', 'jsx'], + coverageDirectory: '../../coverage/libs/hostd-types', +} diff --git a/libs/hostd-types/package.json b/libs/hostd-types/package.json new file mode 100644 index 000000000..7446942b3 --- /dev/null +++ b/libs/hostd-types/package.json @@ -0,0 +1,10 @@ +{ + "name": "@siafoundation/hostd-types", + "description": "Types for `hostd`.", + "version": "0.0.0", + "license": "MIT", + "dependencies": { + "@siafoundation/types": "^0.2.0" + }, + "types": "./src/index.d.ts" +} diff --git a/libs/hostd-types/project.json b/libs/hostd-types/project.json new file mode 100644 index 000000000..0772332a3 --- /dev/null +++ b/libs/hostd-types/project.json @@ -0,0 +1,42 @@ +{ + "name": "hostd-types", + "$schema": "../../node_modules/nx/schemas/project-schema.json", + "sourceRoot": "libs/hostd-types/src", + "projectType": "library", + "tags": [], + "targets": { + "build": { + "executor": "@nx/rollup:rollup", + "outputs": ["{options.outputPath}"], + "options": { + "outputPath": "dist/libs/hostd-types", + "tsConfig": "libs/hostd-types/tsconfig.lib.json", + "project": "libs/hostd-types/package.json", + "entryFile": "libs/hostd-types/src/index.ts", + "external": ["react/jsx-runtime"], + "compiler": "tsc", + "outputFileName": "index.js", + "rollupConfig": "libs/hostd-types/rollup.config.js", + "assets": [ + { + "glob": "libs/hostd-types/*.md", + "input": ".", + "output": "." + } + ] + }, + "configurations": {} + }, + "lint": { + "executor": "@nx/eslint:lint", + "outputs": ["{options.outputFile}"] + }, + "test": { + "executor": "@nx/jest:jest", + "outputs": ["{workspaceRoot}/coverage/libs/hostd-types"], + "options": { + "jestConfig": "libs/hostd-types/jest.config.ts" + } + } + } +} diff --git a/libs/hostd-types/rollup.config.js b/libs/hostd-types/rollup.config.js new file mode 100644 index 000000000..3f5e4e997 --- /dev/null +++ b/libs/hostd-types/rollup.config.js @@ -0,0 +1,18 @@ +// eslint-disable-next-line @typescript-eslint/no-var-requires +const preserveDirectives = require('rollup-plugin-preserve-directives') + +// https://github.com/rollup/rollup/issues/4699#issuecomment-1465302665 +function getRollupOptions(options) { + return { + ...options, + output: { + ...options.output, + preserveModules: true, + format: 'esm', + sourcemap: true, + }, + plugins: options.plugins.concat(preserveDirectives.default()), + } +} + +module.exports = getRollupOptions diff --git a/libs/hostd-types/src/api.ts b/libs/hostd-types/src/api.ts new file mode 100644 index 000000000..5bb2980f4 --- /dev/null +++ b/libs/hostd-types/src/api.ts @@ -0,0 +1,449 @@ +import { + FileContractID, + PublicKey, + Currency, + TransactionID, + ChainIndex, +} from '@siafoundation/types' +import { Contract, ContractStatus, WalletTransaction } from './types' + +// state + +export type StateHostParams = void +export type StateHostResponse = { + name?: string + publicKey: string + walletAddress: string + network: 'Mainnet' | 'Zen Testnet' + version: string + commit: string + os: string + startTime: string + buildTime: string + lastAnnouncement?: { + index: ChainIndex + publicKey: string + address: string + } +} + +export type StateConsensusParams = void +export type StateConsensusResponse = { + chainIndex: { + height: number + id: string + } + synced: boolean +} + +// syncer + +type Peer = { + address: string + version: string +} + +export type SyncerPeersParams = void +export type SyncerPeersResponse = Peer[] + +export type SyncerConnectParams = void +export type SyncerConnectPayload = { address: string } +export type SyncerConnectResponse = never + +// wallet + +export type WalletParams = void +export type WalletResponse = { + scanHeight: number + address: string + spendable: string + confirmed: string + unconfirmed: string +} + +export type WalletTransactionsParams = { limit?: number; offset?: number } +export type WalletTransactionsResponse = WalletTransaction[] + +export type WalletPendingParams = void +export type WalletPendingResponse = WalletTransaction[] + +export type WalletSendParams = void +export type WalletSendPayload = { + amount: string + address: string +} +export type WalletSendResponse = TransactionID + +// txpool + +export type TxPoolFeeParams = void +export type TxPoolFeeResponse = Currency + +// contracts + +export type ContractFilterSortField = + | 'status' + | 'negotiationHeight' + | 'expirationHeight' + +export type ContractsParams = void +export type ContractsPayload = { + // filters + statuses?: ContractStatus[] + contractIDs?: FileContractID[] + renewedFrom?: FileContractID[] + renewedTo?: FileContractID[] + renterKey?: PublicKey[] + + minNegotiationHeight?: number + maxNegotiationHeight?: number + + minExpirationHeight?: number + maxExpirationHeight?: number + + // pagination + limit?: number + offset?: number + + // sorting + sortField?: ContractFilterSortField + sortDesc?: boolean +} + +export type ContractsResponse = { + contracts: Contract[] + count: number +} + +export type ContractsIntegrityCheckParams = { id: string } +export type ContractsIntegrityCheckPaylaod = void +export type ContractsIntegrityCheckResponse = void + +// metrics + +// Revenue is a collection of metrics related to revenue. +type Revenue = { + rpc: string + storage: string + ingress: string + egress: string + registryRead: string + registryWrite: string +} + +// Data is a collection of metrics related to data usage. +type Data = { + // Ingress returns the number of bytes received by the host. + ingress: number + // Egress returns the number of bytes sent by the host. + egress: number +} + +// Contracts is a collection of metrics related to contracts. +type Contracts = { + pending: number + active: number + rejected: number + failed: number + successful: number + lockedCollateral: string + riskedCollateral: string +} + +// Pricing is a collection of metrics related to the host's pricing settings. +type Pricing = { + contractPrice: string + ingressPrice: string + egressPrice: string + baseRPCPrice: string + sectorAccessPrice: string + storagePrice: string + collateralMultiplier: number +} + +// Registry is a collection of metrics related to the host's registry. +type Registry = { + entries: number + maxEntries: number + + reads: number + writes: number +} + +// Storage is a collection of metrics related to storage. +type Storage = { + totalSectors: number + physicalSectors: number + contractSectors: number + tempSectors: number + reads: number + writes: number +} + +// RevenueMetrics is a collection of metrics related to revenue. +type RevenueMetrics = { + potential: Revenue + earned: Revenue +} + +// DataMetrics is a collection of metrics related to data usage. +type DataMetrics = { + rhp: Data +} + +export type Metrics = { + revenue: RevenueMetrics + pricing: Pricing + contracts: Contracts + storage: Storage + registry: Registry + data: DataMetrics + balance: string + timestamp: string +} + +export type MetricsParams = { timestamp: string } +export type MetricsResponse = Metrics + +type Interval = + | '5m' + | '15m' + | 'hourly' + | 'daily' + | 'weekly' + | 'monthly' + | 'yearly' + +export type MetricsPeriodParams = { + interval: Interval + start: string + periods?: number +} +export type MetricsPeriodResponse = Metrics[] + +// settings + +// DuckDNS +export type DNSDuckDNSOptions = { + token: string +} + +// No-IP +export type DNSNoIPOptions = { + email: string + password: string +} + +// AWS +export type DNSAWSOptions = { + id: string + secret: string + zoneID: string +} + +// Cloudflare +export type DNSCloudflareOptions = { + token: string + zoneID: string +} + +export type DNSProvider = '' | 'route53' | 'noip' | 'duckdns' | 'cloudflare' + +type DNSSettings = { + provider: DNSProvider + ipv4: boolean + ipv6: boolean + options: + | DNSDuckDNSOptions + | DNSNoIPOptions + | DNSAWSOptions + | DNSCloudflareOptions +} + +export type HostSettings = { + // Host settings + acceptingContracts: boolean + netAddress: string + maxContractDuration: number + + // Pricing + contractPrice: Currency + baseRPCPrice: Currency + sectorAccessPrice: Currency + + collateralMultiplier: number + maxCollateral: Currency + + storagePrice: Currency + egressPrice: Currency + ingressPrice: Currency + + priceTableValidity: number + + // RHP3 settings + accountExpiry: number + maxAccountBalance: Currency + + // Bandwidth limiter settings + ingressLimit: number + egressLimit: number + + // DNS settings + ddns: DNSSettings + + revision: number +} + +export type SettingsParams = void +export type SettingsResponse = HostSettings + +export type SettingsUpdateParams = void +export type SettingsUpdatePayload = Partial +export type SettingsUpdateResponse = HostSettings + +export type SettingsAnnounceParams = void +export type SettingsAnnouncePayload = void +export type SettingsAnnounceResponse = void + +export type SettingsDdnsUpdateParams = void +export type SettingsDdnsUpdatePayload = void +export type SettingsDdnsUpdateResponse = void + +export type SettingsDdnsParams = void +export type SettingsDdnsPayload = void +export type SettingsDdnsResponse = void + +// volumes + +export type Volume = { + id: number + localPath: string + usedSectors: number + totalSectors: number + readOnly: boolean + available: boolean +} + +export type VolumeStatus = + | 'unavailable' + | 'creating' + | 'resizing' + | 'removing' + | 'ready' + +export type VolumeStats = { + failedReads: number + failedWrites: number + successfulReads: number + successfulWrites: number + status: VolumeStatus + errors: string[] +} + +export type VolumeMeta = Volume & VolumeStats + +export type VolumesParams = void +export type VolumesResponse = VolumeMeta[] + +export type VolumeParams = { id: string } +export type VolumeResponse = VolumeMeta + +export type VolumeCreateParams = void +export type VolumeCreatePayload = { localPath: string; maxSectors: number } +export type VolumeCreateResponse = Volume + +export type VolumeUpdateParams = { id: number } +export type VolumeUpdatePayload = { readOnly: boolean } +export type VolumeUpdateResponse = void + +export type VolumeDeleteParams = { id: number; force?: boolean } +export type VolumeDeletePayload = void +export type VolumeDeleteResponse = void + +export type VolumeResizeParams = { id: number } +export type VolumeResizePayload = { maxSectors: number } +export type VolumeResizeResponse = void + +export type VolumeCancelParams = { id: number } +export type VolumeCancelPayload = void +export type VolumeCancelResponse = void + +export type SystemDirectoryParams = { + path: string +} +export type SystemDirectoryResponse = { + path: string + totalBytes: number + freeBytes: number + directories: string[] +} + +export type SystemDirectoryCreateParams = void +export type SystemDirectoryCreatePayload = { path: string } +export type SystemDirectoryCreateResponse = void + +// logs + +type LogEntry = { + timestamp: string + level: string + name: string + caller: string + message: string + fields: Record +} + +export type LogsSearchParams = void +export type LogsSearchPayload = { + names?: string[] + callers?: string[] + levels?: string[] + before?: string + after?: string + limit?: number + offset?: number +} +export type LogsSearchResponse = { count: number; entries: LogEntry[] } + +// alerts + +export type AlertSeverity = 'info' | 'warning' | 'error' | 'critical' + +export type Alert = { + id: string + severity: AlertSeverity + message: string + data: { + contractID?: number + blockHeight?: number + resolution?: string + volume?: string + volumeID?: number + + elapsed?: number + error?: string + + checked?: number + missing?: number + corrupt?: number + total?: number + + oldSectors?: number + currentSectors?: number + targetSectors?: number + migratedSectors?: number + + migrated?: number + target?: number + + force?: boolean + } + timestamp: string +} + +export type AlertsParams = void +export type AlertsResponse = Alert[] + +export type AlertsDismissParams = void +export type AlertsDismissPayload = string[] +export type AlertsDismissResponse = void diff --git a/libs/hostd-types/src/index.ts b/libs/hostd-types/src/index.ts new file mode 100644 index 000000000..39a2c95ba --- /dev/null +++ b/libs/hostd-types/src/index.ts @@ -0,0 +1,2 @@ +export * from './api' +export * from './types' diff --git a/libs/hostd-react/src/siaTypes.ts b/libs/hostd-types/src/types.ts similarity index 100% rename from libs/hostd-react/src/siaTypes.ts rename to libs/hostd-types/src/types.ts diff --git a/libs/hostd-types/tsconfig.json b/libs/hostd-types/tsconfig.json new file mode 100644 index 000000000..4c089585e --- /dev/null +++ b/libs/hostd-types/tsconfig.json @@ -0,0 +1,25 @@ +{ + "extends": "../../tsconfig.base.json", + "compilerOptions": { + "jsx": "react-jsx", + "allowJs": true, + "esModuleInterop": true, + "allowSyntheticDefaultImports": true, + "forceConsistentCasingInFileNames": true, + "strict": true, + "noImplicitOverride": true, + "noPropertyAccessFromIndexSignature": true, + "noImplicitReturns": true, + "noFallthroughCasesInSwitch": true + }, + "files": [], + "include": [], + "references": [ + { + "path": "./tsconfig.lib.json" + }, + { + "path": "./tsconfig.spec.json" + } + ] +} diff --git a/libs/hostd-types/tsconfig.lib.json b/libs/hostd-types/tsconfig.lib.json new file mode 100644 index 000000000..d73537814 --- /dev/null +++ b/libs/hostd-types/tsconfig.lib.json @@ -0,0 +1,22 @@ +{ + "extends": "./tsconfig.json", + "compilerOptions": { + "outDir": "../../dist/out-tsc", + "types": [ + "node", + "@nx/react/typings/cssmodule.d.ts", + "@nx/react/typings/image.d.ts" + ] + }, + "exclude": [ + "**/*.spec.ts", + "**/*.test.ts", + "**/*.spec.tsx", + "**/*.test.tsx", + "**/*.spec.js", + "**/*.test.js", + "**/*.spec.jsx", + "**/*.test.jsx" + ], + "include": ["src/**/*.js", "src/**/*.jsx", "src/**/*.ts", "src/**/*.tsx"] +} diff --git a/libs/hostd-types/tsconfig.spec.json b/libs/hostd-types/tsconfig.spec.json new file mode 100644 index 000000000..503e9a83d --- /dev/null +++ b/libs/hostd-types/tsconfig.spec.json @@ -0,0 +1,19 @@ +{ + "extends": "./tsconfig.json", + "compilerOptions": { + "outDir": "../../dist/out-tsc", + "module": "commonjs", + "types": ["jest", "node"] + }, + "include": [ + "src/**/*.test.ts", + "src/**/*.spec.ts", + "src/**/*.test.tsx", + "src/**/*.spec.tsx", + "src/**/*.test.js", + "src/**/*.spec.js", + "src/**/*.test.jsx", + "src/**/*.spec.jsx", + "src/**/*.d.ts" + ] +} diff --git a/libs/renterd-react/package.json b/libs/renterd-react/package.json index 6482aba66..d0f8892a4 100644 --- a/libs/renterd-react/package.json +++ b/libs/renterd-react/package.json @@ -1,6 +1,6 @@ { "name": "@siafoundation/renterd-react", - "description": " React hooks for interacting with `renterd`.", + "description": "React hooks for interacting with `renterd`.", "version": "4.0.0", "license": "MIT", "dependencies": { diff --git a/libs/walletd-react/package.json b/libs/walletd-react/package.json index bbb02a3f3..145c8dc9f 100644 --- a/libs/walletd-react/package.json +++ b/libs/walletd-react/package.json @@ -1,6 +1,6 @@ { "name": "@siafoundation/walletd-react", - "description": " React hooks for interacting with `walletd`.", + "description": "React hooks for interacting with `walletd`.", "version": "4.0.0", "license": "MIT", "peerDependencies": { diff --git a/tsconfig.base.json b/tsconfig.base.json index 4283de66c..5aa0fc619 100644 --- a/tsconfig.base.json +++ b/tsconfig.base.json @@ -20,10 +20,11 @@ "@siafoundation/fonts": ["libs/fonts/src/index.ts"], "@siafoundation/next": ["libs/next/src/index.ts"], "@siafoundation/react-core": ["libs/react-core/src/index.ts"], + "@siafoundation/hostd-types": ["libs/hostd-types/src/index.ts"], "@siafoundation/hostd-react": ["libs/hostd-react/src/index.ts"], "@siafoundation/react-icons": ["libs/react-icons/src/index.ts"], - "@siafoundation/renterd-react": ["libs/renterd-react/src/index.ts"], "@siafoundation/renterd-types": ["libs/renterd-types/src/index.ts"], + "@siafoundation/renterd-react": ["libs/renterd-react/src/index.ts"], "@siafoundation/sia-central-react": [ "libs/sia-central-react/src/index.ts" ],