Skip to content
Merged
Show file tree
Hide file tree
Changes from 3 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
3 changes: 2 additions & 1 deletion sample-dapps/solana-staking-ui/.env.example
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
DEVNET_RPC_ENDPOINT=https://example.solana-devnet.quiknode.pro/12345/
MAINNET_RPC_ENDPOINT=https://example.solana-mainnet.quiknode.pro/12345/
NEXT_PUBLIC_NETWORK_ENV=mainnet
NEXT_PUBLIC_VALIDATOR_ADDRESS=5s3vajJvaAbabQvxFdiMfg14y23b2jvK6K2Mw4PYcYK
NEXT_PUBLIC_VALIDATOR_ADDRESS=5s3vajJvaAbabQvxFdiMfg14y23b2jvK6K2Mw4PYcYK
NEXT_PUBLIC_JUPITER_API_KEY=your_jupiter_api_key
3 changes: 3 additions & 0 deletions sample-dapps/solana-staking-ui/.gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,9 @@ yarn-error.log*

# env files (can opt-in for committing if needed)
.env
.env.*
# Re-include an example file to show required variables (optional)
!.env.example

# vercel
.vercel
Expand Down
20 changes: 12 additions & 8 deletions sample-dapps/solana-staking-ui/README.md
Original file line number Diff line number Diff line change
@@ -1,26 +1,28 @@
# QuickNode Solana Staking UI
# Quicknode Solana Staking UI

## Overview

This is a simple demo let's stand up a staking page to easily empower your users to stake to your validator. The demo will:

![Preview](public/preview.png)
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We can update the screenshot due to rebranding


The demo uses
The demo uses

- [Solana Kit](https://github.com/anza-xyz/kit)
- [Wallet Standard](https://www.npmjs.com/package/@wallet-standard/core)
- [Next.js 15](https://nextjs.org/) project bootstrapped with [`create-next-app`](https://github.com/vercel/next.js/tree/canary/packages/create-next-app).
- [Radix UI](https://www.radix-ui.com/)


## Getting Started

### Install Dependencies

Open the project dictory:
Open the project dictory:

```bash
cd sample-dapps/solana-staking-ui
```

Then, install the dependencies:

```bash
Expand All @@ -35,17 +37,19 @@ bun install

### Set Environment Variables

Make sure you have a QuickNode endpoint handy--you can get one free [here](https://www.quicknode.com/signup?utm_source=internal&utm_campaign=dapp-examples&utm_content=solana-staking-ui).
Make sure you have a Quicknode endpoint handy--you can [get one free](https://www.quicknode.com/signup?utm_source=internal&utm_campaign=dapp-examples&utm_content=solana-staking-ui).

- Rename `.env.example` to `.env` and update with your QuickNode Solana Node Endpoint.
- Rename `.env.example` to `.env` and update with your Quicknode Solana Node Endpoint.
- Specify which cluster you are using (mainnet-beta, devnet) (using `NEXT_PUBLIC_NETWORK_ENV`).
- Specify the validator vote address that your staker should stake to (using `NEXT_PUBLIC_VALIDATOR_ADDRESS`). The default value, `5s3vajJvaAbabQvxFdiMfg14y23b2jvK6K2Mw4PYcYK` is QuickNode's validator.
- Specify the validator vote address that your staker should stake to (using `NEXT_PUBLIC_VALIDATOR_ADDRESS`). The default value, `5s3vajJvaAbabQvxFdiMfg14y23b2jvK6K2Mw4PYcYK` is Quicknode's validator.
- Add your [Jupiter API key](https://dev.jup.ag/portal/setup) (using `NEXT_PUBLIC_JUPITER_API_KEY`) for fetching SOL price data.

```sh
DEVNET_RPC_ENDPOINT=https://example.solana-devnet.quiknode.pro/12345/
MAINNET_RPC_ENDPOINT=https://example.solana-mainnet.quiknode.pro/12345/
NEXT_PUBLIC_NETWORK_ENV=mainnet
NEXT_PUBLIC_VALIDATOR_ADDRESS=5s3vajJvaAbabQvxFdiMfg14y23b2jvK6K2Mw4PYcYK
NEXT_PUBLIC_JUPITER_API_KEY=your_jupiter_api_key_here
```

First, run the development server:
Expand Down Expand Up @@ -99,4 +103,4 @@ src/

## Deploy on Vercel

[![Deploy with Vercel](https://vercel.com/button)](https://vercel.com/new/clone?repository-url=https%3A%2F%2Fgithub.com%2Fquiknode-labs%2Fqn-guide-examples%2Fsample-dapps%2Fsolana-staking-ui&env=DEVNET_RPC_ENDPOINT,MAINNET_RPC_ENDPOINT,NEXT_PUBLIC_NETWORK_ENV,NEXT_PUBLIC_VALIDATOR_ADDRESS&envDescription=QuickNode%20Endpoint%20and%20Validator%20Address&envLink=https%3A%2F%2Fdashboard.quicknode.com%2F%3Fprompt%3Dsignup&project-name=quicknode-stake-ui&repository-name=quicknode-stake-ui&demo-title=QuickNode%20Stake%20%20Solana%20UI&demo-description=A%20landing%20page%20for%20staking%20Solana)
[![Deploy with Vercel](https://vercel.com/button)](https://vercel.com/new/clone?repository-url=https%3A%2F%2Fgithub.com%2Fquiknode-labs%2Fqn-guide-examples%2Fsample-dapps%2Fsolana-staking-ui&env=DEVNET_RPC_ENDPOINT,MAINNET_RPC_ENDPOINT,NEXT_PUBLIC_NETWORK_ENV,NEXT_PUBLIC_VALIDATOR_ADDRESS&envDescription=Quicknode%20Endpoint%20and%20Validator%20Address&envLink=https%3A%2F%2Fdashboard.quicknode.com%2F%3Fprompt%3Dsignup&project-name=quicknode-stake-ui&repository-name=quicknode-stake-ui&demo-title=Quicknode%20Stake%20%20Solana%20UI&demo-description=A%20landing%20page%20for%20staking%20Solana)
5 changes: 3 additions & 2 deletions sample-dapps/solana-staking-ui/app/layout.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -17,8 +17,8 @@ const geistMono = Geist_Mono({
});

export const metadata: Metadata = {
title: "Stake with QuickNode",
description: "Stake Smarter. Earn Faster. With QuickNode.",
title: "Stake with Quicknode",
description: "Stake Smarter. Earn Faster. With Quicknode.",
icons: [
{ rel: "icon", url: "/favicon.ico" },
{ rel: "icon", url: "/favicon.png", type: "image/png" }
Expand All @@ -34,6 +34,7 @@ export default function RootLayout({
<html lang="en">
<body
className={`${geistSans.variable} ${geistMono.variable} antialiased`}
suppressHydrationWarning
>
<Theme
appearance="dark"
Expand Down
2 changes: 1 addition & 1 deletion sample-dapps/solana-staking-ui/components/Title.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -45,7 +45,7 @@ export const Title = () => {
padding: "0 16px"
}}
>
Stake Smarter. Earn Faster. With QuickNode.
Stake Smarter. Earn Faster. With Quicknode.
</Text>
</Flex>
);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -70,7 +70,7 @@ function WalletConnectButton() {
<div style={{ margin: "0 auto", position: "relative" }}>
<Image
src="/quicknode.svg"
alt="QuickNode Logo"
alt="Quicknode Logo"
width={64}
height={64}
style={{
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ export function FeaturesList() {
return (
<Flex direction="column" gap="2">
<Text size="2" weight="bold">
Why stake with QuickNode:
Why stake with Quicknode:
</Text>
{FEATURES.map((feature) => (
<Flex align="center" gap="2" key={feature}>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -82,7 +82,7 @@ export function StakeAccountsTable({ stakeAccounts }: StakeAccountsTableProps) {
{account.voter === getValidatorAddress() ? (
<Image
src="/quicknode.svg"
alt="QuickNode Validator"
alt="Quicknode Validator"
width={20}
height={20}
style={{ margin: "0 auto" }}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -222,7 +222,7 @@ export function StakeButton({
>
<Image
src="/quicknode.svg"
alt="QuickNode Logo"
alt="Quicknode Logo"
width={48}
height={48}
style={{
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -48,7 +48,7 @@ export function StakeSuccessModal({
<div style={{ margin: "0 auto", position: "relative" }}>
<Image
src="/quicknode.svg"
alt="QuickNode Logo"
alt="Quicknode Logo"
width={64}
height={64}
style={{
Expand Down Expand Up @@ -160,7 +160,7 @@ export function StakeSuccessModal({
color: "#009fd1"
}}
>
QuickNode
Quicknode
<ExternalLinkIcon width={12} height={12} />
</Link>
</Flex>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -76,9 +76,9 @@ export function StakingForm() {
const fetchPrice = async () => {
try {
const priceData = await fetchSolanaPrice();
const price = priceData?.data?.[WRAPPED_SOL_ADDRESS]?.price;
const price = priceData?.[WRAPPED_SOL_ADDRESS]?.usdPrice;
if (price) {
setSolPrice(parseFloat(price));
setSolPrice(price);
} else {
console.error("Invalid price data structure:", priceData);
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -23,13 +23,13 @@ export function ValidatorInfo({ apy }: ValidatorInfoProps) {
<Flex align="center" gap="2">
<Image
src="/quicknode.svg"
alt="QuickNode Logo"
alt="Quicknode Logo"
width={40}
height={40}
style={{ borderRadius: "50%", padding: "2px" }}
/>
<Flex direction="column" gap="1">
<Text size="3">QuickNode</Text>
<Text size="3">Quicknode</Text>
<Link
size="1"
target="_blank"
Expand Down
Loading