├── src
├── App.css
├── index.css
├── main.jsx
├── ShowSolBalance.jsx
├── RequestAirdrop.jsx
├── SendTokens.jsx
├── SignMessage.jsx
├── App.jsx
└── assets
│ └── react.svg
├── vite.config.js
├── .gitignore
├── index.html
├── README.md
├── eslint.config.js
├── package.json
└── public
└── vite.svg
/src/App.css:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/src/index.css:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/vite.config.js:
--------------------------------------------------------------------------------
1 | import { defineConfig } from 'vite'
2 | import react from '@vitejs/plugin-react'
3 | import { nodePolyfills } from 'vite-plugin-node-polyfills'
4 |
5 | // https://vitejs.dev/config/
6 | export default defineConfig({
7 | plugins: [react(), nodePolyfills()],
8 | })
--------------------------------------------------------------------------------
/src/main.jsx:
--------------------------------------------------------------------------------
1 | import { StrictMode } from 'react'
2 | import { createRoot } from 'react-dom/client'
3 | import App from './App.jsx'
4 | import './index.css'
5 |
6 | createRoot(document.getElementById('root')).render(
7 |
8 |
9 | ,
10 | )
11 |
--------------------------------------------------------------------------------
/.gitignore:
--------------------------------------------------------------------------------
1 | # Logs
2 | logs
3 | *.log
4 | npm-debug.log*
5 | yarn-debug.log*
6 | yarn-error.log*
7 | pnpm-debug.log*
8 | lerna-debug.log*
9 |
10 | node_modules
11 | dist
12 | dist-ssr
13 | *.local
14 |
15 | # Editor directories and files
16 | .vscode/*
17 | !.vscode/extensions.json
18 | .idea
19 | .DS_Store
20 | *.suo
21 | *.ntvs*
22 | *.njsproj
23 | *.sln
24 | *.sw?
25 |
--------------------------------------------------------------------------------
/index.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 | Vite + React
8 |
9 |
10 |
11 |
12 |
13 |
14 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | # React + Vite
2 |
3 | This template provides a minimal setup to get React working in Vite with HMR and some ESLint rules.
4 |
5 | Currently, two official plugins are available:
6 |
7 | - [@vitejs/plugin-react](https://github.com/vitejs/vite-plugin-react/blob/main/packages/plugin-react/README.md) uses [Babel](https://babeljs.io/) for Fast Refresh
8 | - [@vitejs/plugin-react-swc](https://github.com/vitejs/vite-plugin-react-swc) uses [SWC](https://swc.rs/) for Fast Refresh
9 |
--------------------------------------------------------------------------------
/src/ShowSolBalance.jsx:
--------------------------------------------------------------------------------
1 | import { useConnection, useWallet } from "@solana/wallet-adapter-react";
2 | import { LAMPORTS_PER_SOL } from "@solana/web3.js";
3 |
4 | export function ShowSolBalance() {
5 | const { connection } = useConnection();
6 | const wallet = useWallet();
7 |
8 | async function getBalance() {
9 | if (wallet.publicKey) {
10 |
11 | const balance = await connection.getBalance(wallet.publicKey);
12 | document.getElementById("balance").innerHTML = balance / LAMPORTS_PER_SOL;
13 | }
14 | }
15 |
16 | getBalance();
17 | return
20 | }
--------------------------------------------------------------------------------
/src/RequestAirdrop.jsx:
--------------------------------------------------------------------------------
1 | import { useWallet } from "@solana/wallet-adapter-react";
2 | import { useConnection } from "@solana/wallet-adapter-react";
3 | import { LAMPORTS_PER_SOL } from "@solana/web3.js";
4 |
5 | export function RequestAirdrop() {
6 | const wallet = useWallet();
7 | const { connection } = useConnection();
8 |
9 | async function requestAirdrop() {
10 | let amount = document.getElementById("amount").value;
11 | await connection.requestAirdrop(wallet.publicKey, amount * LAMPORTS_PER_SOL);
12 | alert("Airdropped " + amount + " SOL to " + wallet.publicKey.toBase58());
13 | }
14 |
15 | return
16 |
17 |
18 |
19 |
20 | }
--------------------------------------------------------------------------------
/src/SendTokens.jsx:
--------------------------------------------------------------------------------
1 | import { useConnection, useWallet } from "@solana/wallet-adapter-react"
2 | import { LAMPORTS_PER_SOL, PublicKey, SystemProgram, Transaction} from "@solana/web3.js";
3 |
4 |
5 | export function SendTokens() {
6 | const wallet = useWallet();
7 | const {connection} = useConnection();
8 |
9 | async function sendTokens() {
10 | let to = document.getElementById("to").value;
11 | let amount = document.getElementById("amount").value;
12 | const transaction = new Transaction();
13 | transaction.add(SystemProgram.transfer({
14 | fromPubkey: wallet.publicKey,
15 | toPubkey: new PublicKey(to),
16 | lamports: amount * LAMPORTS_PER_SOL,
17 | }));
18 |
19 | await wallet.sendTransaction(transaction, connection);
20 | alert("Sent " + amount + " SOL to " + to);
21 | }
22 |
23 | return
24 |
25 |
26 |
27 |
28 | }
--------------------------------------------------------------------------------
/src/SignMessage.jsx:
--------------------------------------------------------------------------------
1 | import { ed25519 } from '@noble/curves/ed25519';
2 | import { useWallet } from '@solana/wallet-adapter-react';
3 | import bs58 from 'bs58';
4 | import React from 'react';
5 |
6 | export function SignMessage() {
7 | const { publicKey, signMessage } = useWallet();
8 |
9 | async function onClick() {
10 | if (!publicKey) throw new Error('Wallet not connected!');
11 | if (!signMessage) throw new Error('Wallet does not support message signing!');
12 |
13 | const message = document.getElementById("message").value;
14 | const encodedMessage = new TextEncoder().encode(message);
15 | const signature = await signMessage(encodedMessage);
16 |
17 | if (!ed25519.verify(signature, encodedMessage, publicKey.toBytes())) throw new Error('Message signature invalid!');
18 | alert('success', `Message signature: ${bs58.encode(signature)}`);
19 | };
20 |
21 | return (
22 |
23 |
24 |
27 |
28 | );
29 | };
--------------------------------------------------------------------------------
/eslint.config.js:
--------------------------------------------------------------------------------
1 | import js from '@eslint/js'
2 | import globals from 'globals'
3 | import react from 'eslint-plugin-react'
4 | import reactHooks from 'eslint-plugin-react-hooks'
5 | import reactRefresh from 'eslint-plugin-react-refresh'
6 |
7 | export default [
8 | { ignores: ['dist'] },
9 | {
10 | files: ['**/*.{js,jsx}'],
11 | languageOptions: {
12 | ecmaVersion: 2020,
13 | globals: globals.browser,
14 | parserOptions: {
15 | ecmaVersion: 'latest',
16 | ecmaFeatures: { jsx: true },
17 | sourceType: 'module',
18 | },
19 | },
20 | settings: { react: { version: '18.3' } },
21 | plugins: {
22 | react,
23 | 'react-hooks': reactHooks,
24 | 'react-refresh': reactRefresh,
25 | },
26 | rules: {
27 | ...js.configs.recommended.rules,
28 | ...react.configs.recommended.rules,
29 | ...react.configs['jsx-runtime'].rules,
30 | ...reactHooks.configs.recommended.rules,
31 | 'react/jsx-no-target-blank': 'off',
32 | 'react-refresh/only-export-components': [
33 | 'warn',
34 | { allowConstantExport: true },
35 | ],
36 | },
37 | },
38 | ]
39 |
--------------------------------------------------------------------------------
/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "react-week-5",
3 | "private": true,
4 | "version": "0.0.0",
5 | "type": "module",
6 | "scripts": {
7 | "dev": "vite",
8 | "build": "vite build",
9 | "lint": "eslint .",
10 | "preview": "vite preview"
11 | },
12 | "dependencies": {
13 | "@noble/curves": "^1.5.0",
14 | "@solana/spl-token": "^0.4.8",
15 | "@solana/wallet-adapter-base": "^0.9.23",
16 | "@solana/wallet-adapter-react": "^0.15.35",
17 | "@solana/wallet-adapter-react-ui": "^0.9.35",
18 | "@solana/wallet-adapter-wallets": "^0.19.32",
19 | "@solana/web3.js": "^1.95.3",
20 | "buffer": "^6.0.3",
21 | "react": "^18.3.1",
22 | "react-dom": "^18.3.1",
23 | "vite-plugin-node-polyfills": "^0.22.0"
24 | },
25 | "devDependencies": {
26 | "@eslint/js": "^9.9.0",
27 | "@types/react": "^18.3.3",
28 | "@types/react-dom": "^18.3.0",
29 | "@vitejs/plugin-react": "^4.3.1",
30 | "eslint": "^9.9.0",
31 | "eslint-plugin-react": "^7.35.0",
32 | "eslint-plugin-react-hooks": "^5.1.0-rc.0",
33 | "eslint-plugin-react-refresh": "^0.4.9",
34 | "globals": "^15.9.0",
35 | "vite": "^5.4.1"
36 | }
37 | }
38 |
--------------------------------------------------------------------------------
/src/App.jsx:
--------------------------------------------------------------------------------
1 | import React, { useMemo } from 'react';
2 | import { ConnectionProvider, WalletProvider } from '@solana/wallet-adapter-react';
3 | import { WalletAdapterNetwork } from '@solana/wallet-adapter-base';
4 | import {
5 | WalletModalProvider,
6 | WalletDisconnectButton,
7 | WalletMultiButton
8 | } from '@solana/wallet-adapter-react-ui';
9 | import { clusterApiUrl } from '@solana/web3.js';
10 |
11 | import '@solana/wallet-adapter-react-ui/styles.css';
12 | import { SendTokens } from './SendTokens';
13 | import { SignMessage } from './SignMessage';
14 |
15 | function App() {
16 | const network = WalletAdapterNetwork.Devnet;
17 |
18 | const endpoint = useMemo(() => clusterApiUrl(network), [network]);
19 |
20 | return (
21 |
22 |
23 |
24 |
25 |
26 |
27 |
28 | {/*
29 | */}
30 | {/* */}
31 |
32 |
33 |
34 |
35 |
36 | );
37 | }
38 |
39 | export default App
40 |
--------------------------------------------------------------------------------
/public/vite.svg:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/src/assets/react.svg:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------