diff --git a/.changeset/large-drinks-carry.md b/.changeset/large-drinks-carry.md
new file mode 100644
index 000000000..b023f3981
--- /dev/null
+++ b/.changeset/large-drinks-carry.md
@@ -0,0 +1,5 @@
+---
+'website': minor
+---
+
+Binary downloads are now the latest stable version.
diff --git a/.changeset/quick-cobras-cross.md b/.changeset/quick-cobras-cross.md
new file mode 100644
index 000000000..9652a510d
--- /dev/null
+++ b/.changeset/quick-cobras-cross.md
@@ -0,0 +1,5 @@
+---
+'explorer': minor
+---
+
+The explorer now shows average prices on the home page.
diff --git a/.changeset/witty-eggs-fail.md b/.changeset/witty-eggs-fail.md
index 6581572c3..f5508ee93 100644
--- a/.changeset/witty-eggs-fail.md
+++ b/.changeset/witty-eggs-fail.md
@@ -2,4 +2,4 @@
'explorer': minor
---
-The explorer has been revamped and not supports searching for and viewing hosts.
+The explorer has been revamped and now supports searching for and viewing hosts.
diff --git a/apps/explorer/app/host/[id]/opengraph-image.tsx b/apps/explorer/app/host/[id]/opengraph-image.tsx
index 4e315f7c4..da9873b6c 100644
--- a/apps/explorer/app/host/[id]/opengraph-image.tsx
+++ b/apps/explorer/app/host/[id]/opengraph-image.tsx
@@ -41,15 +41,24 @@ export default async function Image({ params }) {
const values = [
{
label: 'storage',
- value: getStorageCost({ host: h.host, rates: r.rates }),
+ value: getStorageCost({
+ price: h.host.settings.storage_price,
+ rates: r.rates,
+ }),
},
{
label: 'download',
- value: getDownloadCost({ host: h.host, rates: r.rates }),
+ value: getDownloadCost({
+ price: h.host.settings.download_price,
+ rates: r.rates,
+ }),
},
{
label: 'upload',
- value: getUploadCost({ host: h.host, rates: r.rates }),
+ value: getUploadCost({
+ price: h.host.settings.upload_price,
+ rates: r.rates,
+ }),
},
]
diff --git a/apps/explorer/app/layout.tsx b/apps/explorer/app/layout.tsx
index 49ebf1ae0..df195194d 100644
--- a/apps/explorer/app/layout.tsx
+++ b/apps/explorer/app/layout.tsx
@@ -2,6 +2,26 @@ import { Layout } from '../components/Layout'
import '../config/style.css'
import { NextAppSsrAppRouter } from '@siafoundation/design-system'
import { appLink } from '../config'
+import { IBM_Plex_Sans, IBM_Plex_Mono } from '@next/font/google'
+import { cx } from 'class-variance-authority'
+
+const sans = IBM_Plex_Sans({
+ weight: ['100', '200', '300', '400', '500', '600', '700'],
+ style: ['normal', 'italic'],
+ subsets: ['latin'],
+ variable: '--font-sans',
+ display: 'swap',
+ preload: true,
+})
+
+const mono = IBM_Plex_Mono({
+ weight: ['100', '200', '300', '400', '500', '600', '700'],
+ style: ['normal', 'italic'],
+ subsets: ['latin'],
+ variable: '--font-mono',
+ display: 'swap',
+ preload: true,
+})
export const metadata = {
title: 'Explorer',
@@ -19,7 +39,11 @@ export default function RootLayout({
children: React.ReactNode
}) {
return (
-
+
{children}
diff --git a/apps/explorer/app/page.tsx b/apps/explorer/app/page.tsx
index 8b763a521..180cac304 100644
--- a/apps/explorer/app/page.tsx
+++ b/apps/explorer/app/page.tsx
@@ -4,6 +4,7 @@ import { Home } from '../components/Home'
import {
getSiaCentralBlockLatest,
getSiaCentralBlocks,
+ getSiaCentralExchangeRates,
getSiaCentralHosts,
getSiaCentralHostsNetworkMetrics,
} from '@siafoundation/sia-central'
@@ -30,7 +31,7 @@ export function generateMetadata(): Metadata {
export const revalidate = 60
export default async function HomePage() {
- const [metrics, lastestBlock] = await Promise.all([
+ const [m, lb, r, h] = await Promise.all([
getSiaCentralHostsNetworkMetrics({
config: {
api: siaCentralApi,
@@ -41,9 +42,23 @@ export default async function HomePage() {
api: siaCentralApi,
},
}),
+ getSiaCentralExchangeRates({
+ config: {
+ api: siaCentralApi,
+ },
+ }),
+ getSiaCentralHosts({
+ params: {
+ limit: 5,
+ },
+ config: {
+ api: siaCentralApi,
+ },
+ }),
])
- const lastBlockHeight = lastestBlock?.block.height || 0
- const blocks = await getSiaCentralBlocks({
+
+ const lastBlockHeight = lb?.block.height || 0
+ const bs = await getSiaCentralBlocks({
payload: {
heights: range(lastBlockHeight - 5, lastBlockHeight),
},
@@ -51,20 +66,14 @@ export default async function HomePage() {
api: siaCentralApi,
},
})
- const hosts = await getSiaCentralHosts({
- params: {
- limit: 5,
- },
- config: {
- api: siaCentralApi,
- },
- })
+
return (
)
}
diff --git a/apps/explorer/components/Home/index.tsx b/apps/explorer/components/Home/index.tsx
index 755a4d718..8fc95f3c4 100644
--- a/apps/explorer/components/Home/index.tsx
+++ b/apps/explorer/components/Home/index.tsx
@@ -11,21 +11,25 @@ import { ContentLayout } from '../ContentLayout'
import { reverse, sortBy } from 'lodash'
import {
SiaCentralBlock,
+ SiaCentralExchangeRates,
SiaCentralHost,
SiaCentralHostsNetworkMetricsResponse,
} from '@siafoundation/sia-central'
import { hashToAvatar } from '../../lib/avatar'
+import { getDownloadCost, getStorageCost, getUploadCost } from '../../lib/host'
export function Home({
metrics,
blockHeight,
blocks,
hosts,
+ rates,
}: {
metrics: SiaCentralHostsNetworkMetricsResponse
blockHeight: number
blocks: SiaCentralBlock[]
hosts: SiaCentralHost[]
+ rates: SiaCentralExchangeRates
}) {
const values = useMemo(() => {
const list = [
@@ -120,9 +124,60 @@ export function Home({
),
},
+ {
+ label: 'Average storage price',
+ value: (
+
+
+ {getStorageCost({
+ price: metrics?.average.settings.storage_price,
+ rates,
+ })}
+
+
+ ),
+ },
+ {
+ label: 'Average download price',
+ value: (
+
+
+ {getDownloadCost({
+ price: metrics?.average.settings.download_price,
+ rates,
+ })}
+
+
+ ),
+ },
+ {
+ label: 'Average upload price',
+ value: (
+
+
+ {getUploadCost({
+ price: metrics?.average.settings.upload_price,
+ rates,
+ })}
+
+
+ ),
+ },
]
return list
- }, [metrics, blockHeight])
+ }, [metrics, blockHeight, rates])
return (
+
+
+
}
>
diff --git a/apps/explorer/components/Host/HostPricing.tsx b/apps/explorer/components/Host/HostPricing.tsx
index 2918c22e3..b0873b90d 100644
--- a/apps/explorer/components/Host/HostPricing.tsx
+++ b/apps/explorer/components/Host/HostPricing.tsx
@@ -20,17 +20,17 @@ type Props = {
export function HostPricing({ host, rates }: Props) {
const storageCost = useMemo(
- () => getStorageCost({ host, rates }),
+ () => getStorageCost({ price: host.settings.storage_price, rates }),
[rates, host]
)
const downloadCost = useMemo(
- () => getDownloadCost({ host, rates }),
+ () => getDownloadCost({ price: host.settings.download_price, rates }),
[rates, host]
)
const uploadCost = useMemo(
- () => getUploadCost({ host, rates }),
+ () => getUploadCost({ price: host.settings.upload_price, rates }),
[rates, host]
)
diff --git a/apps/explorer/lib/host.ts b/apps/explorer/lib/host.ts
index 172f4b9cf..b75b1c5fc 100644
--- a/apps/explorer/lib/host.ts
+++ b/apps/explorer/lib/host.ts
@@ -1,54 +1,47 @@
import { TBToBytes, monthsToBlocks } from '@siafoundation/design-system'
-import {
- SiaCentralExchangeRates,
- SiaCentralHost,
-} from '@siafoundation/sia-central'
+import { SiaCentralExchangeRates } from '@siafoundation/sia-central'
import BigNumber from 'bignumber.js'
import { humanSiacoin } from '@siafoundation/sia-js'
type Props = {
- host: SiaCentralHost
+ price: string
rates: SiaCentralExchangeRates
}
-export function getStorageCost({ host, rates }: Props) {
+export function getStorageCost({ price, rates }: Props) {
return rates
- ? `$${new BigNumber(host.settings.storage_price)
+ ? `$${new BigNumber(price)
.times(TBToBytes(1))
.times(monthsToBlocks(1))
.div(1e24)
.times(rates.sc.usd || 1)
.toFixed(2)}/TB`
: `${humanSiacoin(
- new BigNumber(host.settings.storage_price)
- .times(TBToBytes(1))
- .times(monthsToBlocks(1)),
+ new BigNumber(price).times(TBToBytes(1)).times(monthsToBlocks(1)),
{ fixed: 0 }
)}/TB`
}
-export function getDownloadCost({ host, rates }: Props) {
+export function getDownloadCost({ price, rates }: Props) {
return rates
- ? `$${new BigNumber(host.settings.download_price)
+ ? `$${new BigNumber(price)
.times(TBToBytes(1))
.div(1e24)
.times(rates.sc.usd || 1)
.toFixed(2)}/TB`
- : `${humanSiacoin(
- new BigNumber(host.settings.download_price).times(TBToBytes(1)),
- { fixed: 0 }
- )}/TB`
+ : `${humanSiacoin(new BigNumber(price).times(TBToBytes(1)), {
+ fixed: 0,
+ })}/TB`
}
-export function getUploadCost({ host, rates }: Props) {
+export function getUploadCost({ price, rates }: Props) {
return rates
- ? `$${new BigNumber(host.settings.upload_price)
+ ? `$${new BigNumber(price)
.times(TBToBytes(1))
.div(1e24)
.times(rates.sc.usd || 1)
.toFixed(2)}/TB`
- : `${humanSiacoin(
- new BigNumber(host.settings.upload_price).times(TBToBytes(1)),
- { fixed: 0 }
- )}/TB`
+ : `${humanSiacoin(new BigNumber(price).times(TBToBytes(1)), {
+ fixed: 0,
+ })}/TB`
}
diff --git a/apps/explorer/project.json b/apps/explorer/project.json
index 27090f690..0a0509307 100644
--- a/apps/explorer/project.json
+++ b/apps/explorer/project.json
@@ -10,7 +10,7 @@
"defaultConfiguration": "production",
"options": {
"outputPath": "dist/apps/explorer",
- "postcssConfig": "apps/website/postcss.config.js",
+ "postcssConfig": "apps/explorer/postcss.config.js",
"assets": [
{
"glob": "**/*",
diff --git a/apps/explorer/tailwind.config.js b/apps/explorer/tailwind.config.js
index f927defea..758f1d1a1 100644
--- a/apps/explorer/tailwind.config.js
+++ b/apps/explorer/tailwind.config.js
@@ -5,7 +5,7 @@ module.exports = {
content: [
join(
__dirname,
- '{src,pages,components}/**/*!(*.stories|*.spec).{ts,tsx,html}'
+ '{app,pages,components,config,hooks}/**/*!(*.stories|*.spec).{ts,tsx,html}'
),
...createGlobPatternsForDependencies(__dirname),
],
diff --git a/apps/website/components/DownloadWidgetSelect.tsx b/apps/website/components/DownloadWidgetSelect.tsx
index cfaf06dd9..2e7605ffd 100644
--- a/apps/website/components/DownloadWidgetSelect.tsx
+++ b/apps/website/components/DownloadWidgetSelect.tsx
@@ -7,7 +7,11 @@ import {
Download16,
} from '@siafoundation/design-system'
import { useState } from 'react'
-import { getLinks, getLinksRuntimeNetwork } from '../content/downloads'
+import {
+ getHostdDownloadLinks,
+ getRenterdDownloadLinks,
+ getWalletDownloadLinks,
+} from '../content/downloads'
type Daemon = 'renterd' | 'hostd' | 'walletd'
type Props = {
@@ -17,9 +21,12 @@ type Props = {
export function DownloadWidgetSelect({ daemon, version }: Props) {
const downloadLinks =
- daemon === 'walletd'
- ? getLinksRuntimeNetwork(daemon, version)
- : getLinks(daemon, version)
+ daemon === 'renterd'
+ ? getRenterdDownloadLinks(version)
+ : daemon === 'hostd'
+ ? getHostdDownloadLinks(version)
+ : getWalletDownloadLinks(version)
+
const [download, setDownload] = useState(downloadLinks[0])
const combined = downloadLinks.filter((i) => i.group === 'combined')
diff --git a/apps/website/components/HostMap/HostItem.tsx b/apps/website/components/HostMap/HostItem.tsx
index d5b79f9d4..77daf8171 100644
--- a/apps/website/components/HostMap/HostItem.tsx
+++ b/apps/website/components/HostMap/HostItem.tsx
@@ -141,7 +141,6 @@ export function HostItem({
{
}
export type GitHubRelease = {
+ name: string
tag_name: string
}
@@ -191,10 +192,10 @@ export async function getGitHubRenterdLatestRelease(): Promise {
try {
const response = await axios.get(
- 'https://api.github.com/repos/SiaFoundation/hostd/releases?per_page=1'
+ 'https://api.github.com/repos/SiaFoundation/hostd/releases/latest'
)
- if (response.data.length) {
- return response.data[0]
+ if (response.data) {
+ return response.data
} else {
return null
}
diff --git a/libs/design-system/src/app/AppAuthedLayout/SidenavItem.tsx b/libs/design-system/src/app/AppAuthedLayout/SidenavItem.tsx
index 9dd8c262d..9a23c5190 100644
--- a/libs/design-system/src/app/AppAuthedLayout/SidenavItem.tsx
+++ b/libs/design-system/src/app/AppAuthedLayout/SidenavItem.tsx
@@ -15,7 +15,7 @@ type Props = {
export function SidenavItem({ title, children, route, onClick }: Props) {
const pathname = usePathname()
const state =
- route && (route === '/' ? pathname === route : pathname.startsWith(route))
+ route && (route === '/' ? pathname === route : pathname?.startsWith(route))
if (!route) {
return (
diff --git a/libs/design-system/src/index.ts b/libs/design-system/src/index.ts
index b10e8b58b..468906f2f 100644
--- a/libs/design-system/src/index.ts
+++ b/libs/design-system/src/index.ts
@@ -131,7 +131,6 @@ export * from './site/PatternedPanel'
export * from './site/Callout'
export * from './site/Links'
export * from './site/SitePageHead'
-export * from './site/NextAppSsr'
export * from './site/NextAppSsrAppRouter'
export * from './site/NextAppCsr'
export * from './site/NextDocument'
@@ -200,3 +199,4 @@ export * from './lib/getOs'
export * from './lib/countryEmoji'
export { colors } from './config/colors'
+export * from './config/css'
diff --git a/libs/design-system/src/site/NextAppSsrAppRouter.tsx b/libs/design-system/src/site/NextAppSsrAppRouter.tsx
index cdb96fad5..3e43b485c 100644
--- a/libs/design-system/src/site/NextAppSsrAppRouter.tsx
+++ b/libs/design-system/src/site/NextAppSsrAppRouter.tsx
@@ -3,7 +3,6 @@
import { TooltipProvider } from '../hooks/tooltip'
import { Toaster } from '../lib/toast'
import { AppSettingsProvider, CoreProvider } from '@siafoundation/react-core'
-import { rootClasses } from '../config/css'
import { ThemeProvider } from 'next-themes'
export function NextAppSsrAppRouter({
@@ -16,7 +15,7 @@ export function NextAppSsrAppRouter({
-