From de5a5b71bb3dbd02d70c70fd4ba3fb1661c4d844 Mon Sep 17 00:00:00 2001 From: Noah Prince Date: Fri, 3 May 2024 10:03:04 -0500 Subject: [PATCH 01/41] WIP: About to change to proxy assignment rename --- README.md | 124 ++++++++++ next.config.mjs | 80 +++++-- package.json | 17 +- src/app/[network]/proxies/[wallet]/page.tsx | 47 ++++ src/app/[network]/proxies/page.tsx | 28 +++ src/components/AssignProxyModal.tsx | 252 ++++++++++++++++++++ src/components/Header.tsx | 6 +- src/components/Proposal.tsx | 10 +- src/components/Proxies.tsx | 128 ++++++++++ src/components/ProxyButton.tsx | 42 ++++ src/components/ProxyProfile.tsx | 151 ++++++++++++ src/components/RevokeProxyButton.tsx | 49 ++++ src/components/RevokeProxyModal.tsx | 129 ++++++++++ src/components/SubNav.tsx | 101 ++++++++ src/components/VeTokensCallout.tsx | 2 +- src/components/ViewPositionsButton.tsx | 23 -- src/components/VoteBreakdown.tsx | 10 +- src/components/VoteHistory.tsx | 117 +++++++++ src/components/ui/dropdown-menu.tsx | 200 ++++++++++++++++ src/components/ui/toggle-group.tsx | 61 +++++ src/components/ui/toggle.tsx | 45 ++++ src/hooks/useMetaplexMetadata.ts | 131 ++++++++++ src/hooks/useNetwork.ts | 31 +++ src/lib/constants.ts | 9 + src/lib/dateTools.ts | 70 ++++++ src/lib/utils.ts | 8 + src/providers/GovernanceProvider.tsx | 5 +- tailwind.config.ts | 1 + yarn.lock | 246 ++++++++++++++----- 29 files changed, 1996 insertions(+), 127 deletions(-) create mode 100644 src/app/[network]/proxies/[wallet]/page.tsx create mode 100644 src/app/[network]/proxies/page.tsx create mode 100644 src/components/AssignProxyModal.tsx create mode 100644 src/components/Proxies.tsx create mode 100644 src/components/ProxyButton.tsx create mode 100644 src/components/ProxyProfile.tsx create mode 100644 src/components/RevokeProxyButton.tsx create mode 100644 src/components/RevokeProxyModal.tsx create mode 100644 src/components/SubNav.tsx delete mode 100644 src/components/ViewPositionsButton.tsx create mode 100644 src/components/VoteHistory.tsx create mode 100644 src/components/ui/dropdown-menu.tsx create mode 100644 src/components/ui/toggle-group.tsx create mode 100644 src/components/ui/toggle.tsx create mode 100644 src/hooks/useMetaplexMetadata.ts create mode 100644 src/hooks/useNetwork.ts create mode 100644 src/lib/dateTools.ts diff --git a/README.md b/README.md index 3048acf..50905ac 100644 --- a/README.md +++ b/README.md @@ -9,3 +9,127 @@ A straw poll website that enables a simple straw-poll for Helium related initiat * A block height deadline is set for the tally to be taken. * Votes are tallied by the HNT voting "power" of the account. One HNT = 1 Vote. * DCs sent to an outcome address will be flushed from the system after voting is complete. + +## Developing Locally (with proxies) + +### 1. Localnet from helium-program-library + +Clone helium-program-library. Run + +``` +anchor localnet +``` + +Then run + +``` +./scripts/bootstrap.sh +``` + +This will create a bunch of keypairs in packages/helium-admin-cli/keypairs. You will need to get the addresses of the HNT, IOT, and MOBILE tokens it created. Then update constants.js in `spl-utils`. + +### 2. Make sure modgov idls deployed + +Clone modular-governance. + +``` +./scripts/upgrade-idls.sh +``` + +### 3. Bootstrap the Helium DAO + +In this repo + +``` +./bin/helium-vote.ts bootstrap --name Helium --mint APqAVo5q9erS8GaXcbJuy3Gx4ikuSzXjzY4SnyppPUm1 --authority $(solana address) +``` + +### 4. Create a proposal + +``` +./bin/helium-vote.ts create-proposal --name HIP 110: Proxy Voting --proposalUri https://gist.githubusercontent.com/hiptron/4404ea1e78ed8c92ba5001df45740386/raw/88adb21a40475dd7b6673e816492357fb425c72a/HIP-110-HNT-Vote-Summary.md --orgName Helium +``` + +### 5. Run the account-postgres-sink for helium-vote-service + +Make sure you have a postgres running. I just have a script to run it via docker: + +``` +#!/bin/bash + +docker volume create -o size=10GB pgdata +docker run --shm-size=1g -it --rm -p 5432:5432 --name postgres -e POSTGRES_PASSWORD=postgres -d -v pgdata:/var/lib/postgresql/data postgres:latest + +docker logs -f postgres +``` + +In helium-program-library, cd `packages/account-postgres-sink-service` + +Update the `.env` to the following: + +``` +SOLANA_URL=http://localhost:8899 +PGUSER=postgres +PGPASSWORD=postgres +USE_SUBSTREAMS=false +PHOTON_URL=https://photon.komoot.io +USE_KAFKA=false +PROGRAM_ACCOUNT_CONFIGS=/path/to/helium-program-library/packages/account-postgres-sink-service/vote_service_example.json + +``` + +Making sure to update the path to the `vote_service_example.json` + +Run + +``` +yarn dev +``` + +Then, navigate to `localhost:3000/refresh-accounts` + +Every time you make a change to proxies, you will need to re-hit-this endpoint. + +### 6. Run the helium-vote service. + +cd into helium-program-library/packages/helium-vote-service + +Update the .env to: + +``` +PGDATABASE=postgres +PGUSER=postgres +PGPASSWORD=postgres +``` + +Then: + +``` +yarn dev +``` + +### 7. Run helium-vote on port 3001 + +In this repo, + +``` +env PORT=3001 yarn dev +``` + +Note that if you're using yalc, it's useful to just run: + +``` +yalc update && rm -rf .next/cache && env PORT=3001 yarn dev +``` + + +### 8. Fund any wallets you're using for testing + +``` +solana transfer -u http://localhost:8899 exmrL4U6vk6VFoh3Q7fkrPbjpNLHPYFf1J8bqGypuiK 10 --allow-unfunded-recipient +``` + +Make sure to transfer some fake HNT to whatever wallet you plan to stake with. +``` +spl-token transfer -u http://localhost:8899 100 --allow-unfunded-recipient --fund-recipient +``` diff --git a/next.config.mjs b/next.config.mjs index 3a456fa..f6b2ce7 100644 --- a/next.config.mjs +++ b/next.config.mjs @@ -15,6 +15,14 @@ const nextConfig = { port: "", pathname: "/**/**", }, + ...(process.env.NODE_ENV === "development" && [ + { + protocol: "http", + hostname: "localhost", + port: "8081", + pathname: "/**/**", + }, + ]), ], }, logging: { @@ -1272,122 +1280,146 @@ const nextConfig = { }, { source: "/147pXvGVcLKU76D7Hdi7iTTLvLw9qX8jXsCgNkKSHqo3rnfzkby", - destination: "/legacy/147pXvGVcLKU76D7Hdi7iTTLvLw9qX8jXsCgNkKSHqo3rnfzkby", + destination: + "/legacy/147pXvGVcLKU76D7Hdi7iTTLvLw9qX8jXsCgNkKSHqo3rnfzkby", permanent: true, }, { source: "/14rmHKjpZhsnrA2j24KiGzg8teA1zAMRhVGcWVUdmTAomTrJJQf", - destination: "/legacy/14rmHKjpZhsnrA2j24KiGzg8teA1zAMRhVGcWVUdmTAomTrJJQf", + destination: + "/legacy/14rmHKjpZhsnrA2j24KiGzg8teA1zAMRhVGcWVUdmTAomTrJJQf", permanent: true, }, { source: "/146pksPcH7C3Wz8hN5NxL544k1VVq6Z4W2iB14e1yJ1HFJ3Wtf3", - destination: "/legacy/146pksPcH7C3Wz8hN5NxL544k1VVq6Z4W2iB14e1yJ1HFJ3Wtf3", + destination: + "/legacy/146pksPcH7C3Wz8hN5NxL544k1VVq6Z4W2iB14e1yJ1HFJ3Wtf3", permanent: true, }, { source: "/144wSVHr4cuVSjxEC62X1bHuLsc5Hcpq6XBhfSY8BQwiyMborFZ", - destination: "/legacy/144wSVHr4cuVSjxEC62X1bHuLsc5Hcpq6XBhfSY8BQwiyMborFZ", + destination: + "/legacy/144wSVHr4cuVSjxEC62X1bHuLsc5Hcpq6XBhfSY8BQwiyMborFZ", permanent: true, }, { source: "/143vgVpLgC3LcXLZCyXYZiHCFcsH9UNz3vR8CL6SDxTLPL5tWtr", - destination: "/legacy/143vgVpLgC3LcXLZCyXYZiHCFcsH9UNz3vR8CL6SDxTLPL5tWtr", + destination: + "/legacy/143vgVpLgC3LcXLZCyXYZiHCFcsH9UNz3vR8CL6SDxTLPL5tWtr", permanent: true, }, { source: "/14jH67zhctwb3B5NmwiAjaXQuyF7jZMZCAnfyBYhSpRS3L22sQE", - destination: "/legacy/14jH67zhctwb3B5NmwiAjaXQuyF7jZMZCAnfyBYhSpRS3L22sQE", + destination: + "/legacy/14jH67zhctwb3B5NmwiAjaXQuyF7jZMZCAnfyBYhSpRS3L22sQE", permanent: true, }, { source: "/13Z3p82AX8H1EUQF74cP2qq7RmmhbKBAiGWWsyA7WLxQ9NENTVW", - destination: "/legacy/13Z3p82AX8H1EUQF74cP2qq7RmmhbKBAiGWWsyA7WLxQ9NENTVW", + destination: + "/legacy/13Z3p82AX8H1EUQF74cP2qq7RmmhbKBAiGWWsyA7WLxQ9NENTVW", permanent: true, }, { source: "/13Y79HnMVt4Epug2rbLYivMPvrcpC2wYUNbZK5Dga3tw3VBpBjk", - destination: "/legacy/13Y79HnMVt4Epug2rbLYivMPvrcpC2wYUNbZK5Dga3tw3VBpBjk", + destination: + "/legacy/13Y79HnMVt4Epug2rbLYivMPvrcpC2wYUNbZK5Dga3tw3VBpBjk", permanent: true, }, { source: "/13Y79HnMVt4Epug2rbLYivMPvrcpC2wYUNbZK5Dga3tw3VBpBjk", - destination: "/legacy/13Y79HnMVt4Epug2rbLYivMPvrcpC2wYUNbZK5Dga3tw3VBpBjk", + destination: + "/legacy/13Y79HnMVt4Epug2rbLYivMPvrcpC2wYUNbZK5Dga3tw3VBpBjk", permanent: true, }, { source: "/13KaGoC2ED8kEh2sXLZ7eGWrqDUMyFH5k48VQ3LLjU5QoQidMV4", - destination: "/legacy/13KaGoC2ED8kEh2sXLZ7eGWrqDUMyFH5k48VQ3LLjU5QoQidMV4", + destination: + "/legacy/13KaGoC2ED8kEh2sXLZ7eGWrqDUMyFH5k48VQ3LLjU5QoQidMV4", permanent: true, }, { source: "/13rA4AXq5ME5s9FEyZrE4BMjxiAF9W3kU2tnmUH8FkFGsV97jEp", - destination: "/legacy/13rA4AXq5ME5s9FEyZrE4BMjxiAF9W3kU2tnmUH8FkFGsV97jEp", + destination: + "/legacy/13rA4AXq5ME5s9FEyZrE4BMjxiAF9W3kU2tnmUH8FkFGsV97jEp", permanent: true, }, { source: "/14cXnMdXYcS7WKNh33dYUaPeo8bZmRFn5AoPA78AZtAgfFXu9jf", - destination: "/legacy/14cXnMdXYcS7WKNh33dYUaPeo8bZmRFn5AoPA78AZtAgfFXu9jf", + destination: + "/legacy/14cXnMdXYcS7WKNh33dYUaPeo8bZmRFn5AoPA78AZtAgfFXu9jf", permanent: true, }, { source: "/14KhDJUdvAXNVVP5m5cqEaLGNC859sXvpHtxWX9r999pZKC8xAs", - destination: "/legacy/14KhDJUdvAXNVVP5m5cqEaLGNC859sXvpHtxWX9r999pZKC8xAs", + destination: + "/legacy/14KhDJUdvAXNVVP5m5cqEaLGNC859sXvpHtxWX9r999pZKC8xAs", permanent: true, }, { source: "/13UrtNApGd3NbeP3NyyTejqNEPAv3NGxkGjvtwTVdaRs24NT7Wy", - destination: "/legacy/13UrtNApGd3NbeP3NyyTejqNEPAv3NGxkGjvtwTVdaRs24NT7Wy", + destination: + "/legacy/13UrtNApGd3NbeP3NyyTejqNEPAv3NGxkGjvtwTVdaRs24NT7Wy", permanent: true, }, { source: "/14Rjhhz1DXLVmSRdzappqWgD6rfgu6XYxmdaSCvWLyLH8ZWbciK", - destination: "/legacy/14Rjhhz1DXLVmSRdzappqWgD6rfgu6XYxmdaSCvWLyLH8ZWbciK", + destination: + "/legacy/14Rjhhz1DXLVmSRdzappqWgD6rfgu6XYxmdaSCvWLyLH8ZWbciK", permanent: true, }, { source: "/14me3X7jpEmn3eeFfnAkMvUoFU3cN6GAS3CDomqCikr7VQfHWrU", - destination: "/legacy/14me3X7jpEmn3eeFfnAkMvUoFU3cN6GAS3CDomqCikr7VQfHWrU", + destination: + "/legacy/14me3X7jpEmn3eeFfnAkMvUoFU3cN6GAS3CDomqCikr7VQfHWrU", permanent: true, }, { source: "/14hfi6Vs9YmwYLwVHKygqyEqwTERRrx5kfQkVoX1uqMTxiE5EgJ", - destination: "/legacy/14hfi6Vs9YmwYLwVHKygqyEqwTERRrx5kfQkVoX1uqMTxiE5EgJ", + destination: + "/legacy/14hfi6Vs9YmwYLwVHKygqyEqwTERRrx5kfQkVoX1uqMTxiE5EgJ", permanent: true, }, { source: "/14XDEkg1t398kvqvgxMMKH8qzVGNBb1mgHhTjNmc5KkC3XJxu8p", - destination: "/legacy/14XDEkg1t398kvqvgxMMKH8qzVGNBb1mgHhTjNmc5KkC3XJxu8p", + destination: + "/legacy/14XDEkg1t398kvqvgxMMKH8qzVGNBb1mgHhTjNmc5KkC3XJxu8p", permanent: true, }, { source: "/14rifUhocpzdwsrWaG5PDbdREDkzyesKe1hXuWzibv8h9DdqKLe", - destination: "/legacy/14rifUhocpzdwsrWaG5PDbdREDkzyesKe1hXuWzibv8h9DdqKLe", + destination: + "/legacy/14rifUhocpzdwsrWaG5PDbdREDkzyesKe1hXuWzibv8h9DdqKLe", permanent: true, }, { source: "/13NyqFtVKsifrh6HQ7DjSBKXRDi7qLHDoATHogoSgvBh56oZJv8", - destination: "/legacy/13NyqFtVKsifrh6HQ7DjSBKXRDi7qLHDoATHogoSgvBh56oZJv8", + destination: + "/legacy/13NyqFtVKsifrh6HQ7DjSBKXRDi7qLHDoATHogoSgvBh56oZJv8", permanent: true, }, { source: "/14MnuexopPfDg3bmq8JdCm7LMDkUBoqhqanD9QzLrUURLZxFHBx", - destination: "/legacy/14MnuexopPfDg3bmq8JdCm7LMDkUBoqhqanD9QzLrUURLZxFHBx", + destination: + "/legacy/14MnuexopPfDg3bmq8JdCm7LMDkUBoqhqanD9QzLrUURLZxFHBx", permanent: true, }, { source: "/13wCuq7XGnc4xgxPAc9n9ragKsRfmH9t9jB3c1smfKPZWSikZkd", - destination: "/legacy/13wCuq7XGnc4xgxPAc9n9ragKsRfmH9t9jB3c1smfKPZWSikZkd", + destination: + "/legacy/13wCuq7XGnc4xgxPAc9n9ragKsRfmH9t9jB3c1smfKPZWSikZkd", permanent: true, }, { source: "/14iwaexUYUe5taFgb5hx2BZw74z3TSyonRLYyZU1RbddV4bJest", - destination: "/legacy/14iwaexUYUe5taFgb5hx2BZw74z3TSyonRLYyZU1RbddV4bJest", + destination: + "/legacy/14iwaexUYUe5taFgb5hx2BZw74z3TSyonRLYyZU1RbddV4bJest", permanent: true, }, { source: "/13F5AWLhxwTjhDMnZ6ww4oJWgRkBoW9ji4JnDzwQXjsQhiT2kcX", - destination: "/legacy/13F5AWLhxwTjhDMnZ6ww4oJWgRkBoW9ji4JnDzwQXjsQhiT2kcX", + destination: + "/legacy/13F5AWLhxwTjhDMnZ6ww4oJWgRkBoW9ji4JnDzwQXjsQhiT2kcX", permanent: true, }, ]; diff --git a/package.json b/package.json index ad60053..7aae9f6 100644 --- a/package.json +++ b/package.json @@ -16,20 +16,23 @@ "@helium/modular-governance-hooks": "^0.0.8", "@helium/modular-governance-idls": "^0.0.8-next", "@helium/organization-sdk": "^0.0.8", - "@helium/spl-utils": "^0.7.11", + "@helium/spl-utils": "file:.yalc/@helium/spl-utils", "@helium/state-controller-sdk": "^0.0.8", - "@helium/voter-stake-registry-hooks": "^0.7.11", - "@helium/voter-stake-registry-sdk": "^0.7.11", + "@helium/voter-stake-registry-hooks": "file:.yalc/@helium/voter-stake-registry-hooks", + "@helium/voter-stake-registry-sdk": "file:.yalc/@helium/voter-stake-registry-sdk", "@hookform/resolvers": "^3.3.4", "@metaplex-foundation/mpl-token-metadata": "2.10.0", "@project-serum/anchor": "^0.26.0", "@radix-ui/react-avatar": "^1.0.4", "@radix-ui/react-checkbox": "^1.0.4", "@radix-ui/react-dialog": "^1.0.5", + "@radix-ui/react-dropdown-menu": "^2.0.6", "@radix-ui/react-hover-card": "^1.0.7", "@radix-ui/react-progress": "^1.0.3", "@radix-ui/react-separator": "^1.0.3", "@radix-ui/react-slot": "^1.0.2", + "@radix-ui/react-toggle": "^1.0.3", + "@radix-ui/react-toggle-group": "^1.0.4", "@solana/spl-token": "^0.4.0", "@solana/wallet-adapter-base": "^0.9.23", "@solana/wallet-adapter-react": "^0.15.35", @@ -53,6 +56,7 @@ "react-countdown": "^2.3.5", "react-dom": "^18", "react-icons": "^5.0.1", + "react-infinite-scroll-component": "^6.1.0", "react-markdown": "^9.0.1", "sonner": "^1.4.0", "tailwind-merge": "^2.2.1", @@ -65,10 +69,11 @@ "@helium/account-fetch-cache": "^0.7.11", "@helium/account-fetch-cache-hooks": "^0.7.11", "@helium/helium-react-hooks": "^0.7.11", - "@helium/voter-stake-registry-hooks": "^0.7.11", - "@helium/spl-utils": "^0.7.11", + "@helium/voter-stake-registry-hooks": "file:.yalc/@helium/voter-stake-registry-hooks", + "@helium/spl-utils": "file:.yalc/@helium/spl-utils", "@helium/modular-governance-hooks": "^0.0.8", - "@solana/wallet-adapter-react": "^0.15.35" + "@solana/wallet-adapter-react": "^0.15.35", + "@helium/voter-stake-registry-sdk": "file:.yalc/@helium/voter-stake-registry-sdk" }, "devDependencies": { "@tailwindcss/typography": "^0.5.10", diff --git a/src/app/[network]/proxies/[wallet]/page.tsx b/src/app/[network]/proxies/[wallet]/page.tsx new file mode 100644 index 0000000..d2774a8 --- /dev/null +++ b/src/app/[network]/proxies/[wallet]/page.tsx @@ -0,0 +1,47 @@ +import { Header } from "@/components/Header"; +import { ProxyProfile } from "@/components/ProxyProfile"; +import { WalletBoundary } from "@/components/WalletBoundary"; +import { networksToMint } from "@/lib/constants"; +import { VoteService, getRegistrarKey } from "@helium/voter-stake-registry-sdk"; +import { PublicKey } from "@solana/web3.js"; + +export default async function ProxyPage({ + params: { wallet, network }, +}: { + params: { wallet: string; network: string }; +}) { + const mint = networksToMint[network]; + const { proxy, detail, image } = await getData( + new PublicKey(wallet as string), + mint + ); + + return ( + <> +
+ + + ); +} + +export async function getData(wallet: PublicKey, mint: PublicKey) { + const registrar = getRegistrarKey(mint); + + const voteService = new VoteService({ + baseURL: process.env.NEXT_PUBLIC_HELIUM_VOTE_URI, + registrar, + }); + const proxy = await voteService.getProxy(wallet.toBase58()); + let detail = null; + if (proxy.detail) { + const res = await fetch(proxy.detail); + detail = await res.text(); + } + + return { + proxy, + detail, + image: proxy.image ? proxy.image : null, + // revalidate: 10 * 60, + }; +} diff --git a/src/app/[network]/proxies/page.tsx b/src/app/[network]/proxies/page.tsx new file mode 100644 index 0000000..e3899b4 --- /dev/null +++ b/src/app/[network]/proxies/page.tsx @@ -0,0 +1,28 @@ +import { Header } from "@/components/Header"; +import { Proxies } from "@/components/Proxies"; +import { formMetaTags } from "@/lib/utils"; + +export interface VotersPageParams { + params: { + network: string; + }; + searchParams: Record | null | undefined; +} + +export const generateMetadata = async ({ params }: VotersPageParams) => { + const { network } = params; + + return formMetaTags({ + title: `${network.toUpperCase()} Positions`, + url: `https://heliumvote.com/${network}/voters`, + }); +}; + +export default async function PositionsPage() { + return ( + <> +
+ + + ); +} diff --git a/src/components/AssignProxyModal.tsx b/src/components/AssignProxyModal.tsx new file mode 100644 index 0000000..80e4b89 --- /dev/null +++ b/src/components/AssignProxyModal.tsx @@ -0,0 +1,252 @@ +import { useMint } from "@helium/helium-react-hooks"; +import { + PositionWithMeta, + useHeliumVsrState, +} from "@helium/voter-stake-registry-hooks"; +import { PublicKey } from "@solana/web3.js"; +import BN from "bn.js"; +import React, { useEffect, useMemo, useState } from "react"; +import { getMinDurationFmt, getTimeLeftFromNowFmt } from "@/lib/dateTools"; +import { toast } from "sonner"; +import { Dialog, DialogContent, DialogTrigger } from "./ui/dialog"; +import { Loader2 } from "lucide-react"; +import { useMetaplexMetadata } from "@/hooks/useMetaplexMetadata"; +import { humanReadable } from "@/lib/utils"; +import { Button } from "./ui/button"; + +interface AssignProxyModalProps { + onSubmit: (args: { + positions: PositionWithMeta[]; + recipient: PublicKey; + expirationTime: BN; + }) => Promise; + wallet?: PublicKey; +} + +export const AssignProxyModal: React.FC< + React.PropsWithChildren +> = ({ onSubmit, wallet, children }) => { + const [open, setOpen] = useState(false); + + const { loading, positions, mint } = useHeliumVsrState(); + const [selectedPositions, setSelectedPositions] = useState>( + new Set() + ); + const [isSubmitting, setIsSubmitting] = useState(false); + const unproxiedPositions = useMemo( + () => + positions?.filter( + (p) => !p.proxy || p.proxy.nextOwner.equals(PublicKey.default) + ) || [], + [positions] + ); + const today = new Date(); + const augustFirst = Date.UTC( + today.getMonth() > 7 ? today.getFullYear() + 1 : today.getFullYear(), + 7, + 1 + ); + const maxDate = Math.min( + augustFirst - 1000, + ...unproxiedPositions + .filter((p) => selectedPositions.has(p.pubkey.toBase58()) && p.proxy) + // @ts-ignore + .map((p) => p.proxy.expirationTime.toNumber() * 1000) + ); + const maxDays = Math.floor( + (maxDate - today.getTime()) / (1000 * 60 * 60 * 24) + ); + const [selectedDays, setSelectedDays] = useState(maxDays); + const [recipient, setRecipient] = useState(wallet?.toBase58() || ""); + const expirationTime = useMemo( + () => + selectedDays === maxDays + ? maxDate.valueOf() / 1000 + : new Date().valueOf() / 1000 + selectedDays * (24 * 60 * 60), + [selectedDays, maxDays, maxDate] + ); + useEffect(() => { + if (selectedDays > maxDays) { + setSelectedDays(maxDays); + } + }, [maxDays]); + + const changeRecipient = (e: any) => { + setRecipient(e.target.value); + }; + + const handleOnSubmit = async () => { + try { + const positionsByKey = positions?.reduce((acc, p) => { + acc[p.pubkey.toString()] = p; + return acc; + }, {} as Record); + setIsSubmitting(true); + + if (positionsByKey) { + await onSubmit({ + positions: Array.from(selectedPositions).map( + (p) => positionsByKey[p] + ), + recipient: new PublicKey(recipient), + expirationTime: new BN( + Math.min(expirationTime, maxDate.valueOf() / 1000) + ), + }); + setOpen(false); + } + } catch (e: any) { + setIsSubmitting(false); + toast(e.message || "Unable to assign proxy"); + } + }; + const handleOpenChange = () => { + setIsSubmitting(false); + setOpen(!open); + }; + + return ( + + {children} + +

+ Assign Voting Proxy +

+ {loading ? ( + <> +
+
Fetching Positions available to Proxy
+
+
+ +
+ + ) : ( +
+
+
+ Once you assign this wallet as your proxy, it will be able to + use your positions to vote on HIPs. You can override these votes + or revoke the proxy at any point. The proxy will expire at the + set expiration date. +
+
+
+ Proxy assignments are reset August 1st yearly. +
+
+
+

Expiration Time

+ { + setSelectedDays(parseInt(e.target.value)); + }} + /> +
+ {selectedDays} days ( + {new Date(expirationTime * 1000).toLocaleString()}) +
+
+
+

Positions to Assign

+ + {unproxiedPositions?.map((position) => { + return ( + { + setSelectedPositions((sel) => { + const key = position.pubkey.toBase58(); + const newS = new Set(sel); + if (sel.has(key)) { + newS.delete(key); + return newS; + } else { + newS.add(key); + return newS; + } + }); + }} + /> + ); + })} +
+ {!wallet && ( +
+

Wallet to Assign

+ +
+ )} +
+ )} +
+ + +
+
+
+ ); +}; + +export const PositionItem = ({ + position, + isSelected, + onClick, + mint, +}: { + position: PositionWithMeta; + isSelected: boolean; + mint: PublicKey; + onClick: () => void; +}) => { + const { info: mintAcc } = useMint(mint); + const { symbol } = useMetaplexMetadata(mint); + const { lockup } = position; + const lockupKind = Object.keys(lockup.kind)[0] as string; + const isConstant = lockupKind === "constant"; + const lockedTokens = + mintAcc && humanReadable(position.amountDepositedNative, mintAcc.decimals); + const lockupTime = isConstant + ? getMinDurationFmt(position.lockup.startTs, position.lockup.endTs) + : getTimeLeftFromNowFmt(position.lockup.endTs); + const lockupLabel = isConstant ? "duration" : "time left"; + const fullLabel = `${lockedTokens} ${symbol} locked with ${lockupTime} ${lockupLabel}`; + + return ( +
+ {fullLabel} +
+ ); +}; diff --git a/src/components/Header.tsx b/src/components/Header.tsx index 0ae01b0..1bacb75 100644 --- a/src/components/Header.tsx +++ b/src/components/Header.tsx @@ -1,11 +1,11 @@ import Image from "next/image"; import Link from "next/link"; -import React, { FC } from "react"; +import { FC } from "react"; import { ContentSection } from "./ContentSection"; import { CreatePositionButton } from "./CreatePositionButton"; import { NetworkTabs } from "./NetworkTabs"; +import { SubNav } from "./SubNav"; import { VeTokensCallout } from "./VeTokensCallout"; -import { ViewPositionsButton } from "./ViewPositionsButton"; import { WalletConnectButton } from "./WalletConnectButton"; export const Header: FC<{ @@ -82,7 +82,7 @@ export const Header: FC<{ ) : ( - + )} diff --git a/src/components/Proposal.tsx b/src/components/Proposal.tsx index 55d47f8..97d0bf3 100644 --- a/src/components/Proposal.tsx +++ b/src/components/Proposal.tsx @@ -197,7 +197,13 @@ export const Proposal: FC<{ const { connected, connecting } = useWallet(); const markdownRef = useRef(null); const [markdownExpanded, setMarkdownExpanded] = useState(false); - const { loading: loadingGov, amountLocked, network } = useGovernance(); + const { + loading: loadingGov, + amountLocked, + amountProxyLocked, + network, + } = useGovernance(); + const totalLocked = amountLocked?.add(amountProxyLocked || new BN(0)); const pKey = useMemo(() => new PublicKey(proposalKey), [proposalKey]); const { loading: loadingProposal, info: proposal } = useProposal(pKey); const { loading: loadingVote, voteWeights } = useVote(pKey); @@ -254,7 +260,7 @@ export const Proposal: FC<{ [connecting, loadingGov, loadingProposal, proposal] ); const timeExpired = endTs && endTs.toNumber() <= Date.now().valueOf() / 1000; - const noVotingPower = !isLoading && (!amountLocked || amountLocked.isZero()); + const noVotingPower = !isLoading && (!totalLocked || totalLocked.isZero()); const isActive = derivedState === "active"; const isCancelled = derivedState === "cancelled"; const isFailed = derivedState === "failed"; diff --git a/src/components/Proxies.tsx b/src/components/Proxies.tsx new file mode 100644 index 0000000..6a05c43 --- /dev/null +++ b/src/components/Proxies.tsx @@ -0,0 +1,128 @@ +"use client"; + +import { useHeliumVsrState } from "@helium/voter-stake-registry-hooks"; +import InfiniteScroll from "react-infinite-scroll-component"; +import { useEffect, useState } from "react"; +import { useMint } from "@helium/helium-react-hooks"; +import BN from "bn.js"; +import Link from "next/link"; +import { useNetwork } from "@/hooks/useNetwork"; +import { ellipsisMiddle, humanReadable } from "@/lib/utils"; +import { EnhancedProxy } from "@helium/voter-stake-registry-sdk"; +import { ContentSection } from "./ContentSection"; +import { Card } from "./ui/card"; +import { Avatar, AvatarFallback, AvatarImage } from "./ui/avatar"; +import { useAsyncCallback } from "react-async-hook"; +import { usePathname } from "next/navigation"; + +function CardDetail({ title, value }: { title: string; value: string }) { + return ( +
+ + {title} + + {value} +
+ ); +} + +export function Proxies() { + const { voteService, mint } = useHeliumVsrState(); + const { info: mintAcc } = useMint(mint); + const decimals = mintAcc?.decimals; + const [proxies, setProxies] = useState([]); + const [hasMore, setHasMore] = useState(false); + const [page, setPage] = useState(1); + const path = usePathname(); + + const { execute: fetchMoreData, loading } = useAsyncCallback(async () => { + if (voteService) { + const newProxies = await voteService.getProxies({ + page: page, + limit: 100, + }); + setPage((p) => p + 1); + if (newProxies.length == 100) { + setHasMore(true); + } + setProxies((prevProxies) => [...prevProxies, ...newProxies]); + } + }); + + useEffect(() => { + if (voteService) { + setProxies([]); + setPage(1); + fetchMoreData(); + } + }, [voteService?.registrar.toBase58()]); + + return ( + +
+

Browse Proxies

+ Loading...} + endMessage={ +

+ No More Proxies +

+ } + > +
+ {proxies.map((proxy, index) => ( + + +
+ Assigned {proxy.numAssignments} positions +
+
+
+ + + {proxy.name} + +
+

{proxy.name}

+ {ellipsisMiddle(proxy.wallet)} +
+
+ +
+ + + +
+
+
+ + ))} +
+
+
+
+ ); +} diff --git a/src/components/ProxyButton.tsx b/src/components/ProxyButton.tsx new file mode 100644 index 0000000..e602cab --- /dev/null +++ b/src/components/ProxyButton.tsx @@ -0,0 +1,42 @@ +import React, { useMemo } from "react"; +import { useWallet } from "@solana/wallet-adapter-react"; +import { useHeliumVsrState } from "@helium/voter-stake-registry-hooks"; +import { PublicKey } from "@solana/web3.js"; +import { Button } from "./ui/button"; +import { Loader2 } from "lucide-react"; + +export const ProxyButton: React.FC<{ + className?: string; + onClick: () => void; + isLoading?: boolean; +}> = ({ className = "", onClick, isLoading = false }) => { + const { connected } = useWallet(); + const { loading, positions } = useHeliumVsrState(); + + const unproxiedPositions = useMemo( + () => + positions?.filter( + (p) => !p.proxy || p.proxy.nextOwner.equals(PublicKey.default) + ), + [positions] + ); + + const tooltipContent = !connected + ? "Connect your wallet to claim" + : !unproxiedPositions?.length + ? "You don't have any positions available to proxy." + : ""; + + return ( + + ); +}; diff --git a/src/components/ProxyProfile.tsx b/src/components/ProxyProfile.tsx new file mode 100644 index 0000000..2779511 --- /dev/null +++ b/src/components/ProxyProfile.tsx @@ -0,0 +1,151 @@ +"use client"; + +import { ellipsisMiddle, humanReadable } from "@/lib/utils"; +import { useMint } from "@helium/helium-react-hooks"; +import { + useAssignProxies, + useHeliumVsrState, + useProxiedTo, + useUnassignProxies, +} from "@helium/voter-stake-registry-hooks"; +import { EnhancedProxy, WithRank } from "@helium/voter-stake-registry-sdk"; +import { PublicKey } from "@solana/web3.js"; +import BN from "bn.js"; +import Image from "next/image"; +import { useMemo, useState } from "react"; +import ReactMarkdown from "react-markdown"; +import { AssignProxyModal } from "./AssignProxyModal"; +import { ProxyButton } from "./ProxyButton"; +import { RevokeProxyButton } from "./RevokeProxyButton"; +import { RevokeProxyModal } from "./RevokeProxyModal"; +import VoteHistory from "./VoteHistory"; +import { ContentSection } from "./ContentSection"; +import { Card, CardContent, CardHeader } from "./ui/card"; +import { FaArrowLeft } from "react-icons/fa6"; +import Link from "next/link"; +import { useNetwork } from "@/hooks/useNetwork"; +import { useGovernance } from "@/providers/GovernanceProvider"; + +export function ProxyProfile({ + proxy, + detail, + image, +}: { + proxy: EnhancedProxy & WithRank; + detail: string; + image: string; +}) { + const { mint } = useHeliumVsrState(); + const { info: mintAcc } = useMint(mint); + const decimals = mintAcc?.decimals; + const [revokeProxyModalVisible, setRevokeProxyModalVisible] = useState(false); + const handleSetRevokeProxy = () => { + setRevokeProxyModalVisible(true); + }; + const { assignProxies } = useAssignProxies(); + const { unassignProxies } = useUnassignProxies(); + const wallet = useMemo(() => new PublicKey(proxy.wallet), [proxy.wallet]); + const { votingPower } = useProxiedTo(wallet); + const { network } = useGovernance(); + + return ( + + + + + + Back to Proxies + +
+
+ Profile +
+

{proxy.name}

+ {ellipsisMiddle(proxy.wallet)} +
+
+
+
+
+ Current Rank + + #{proxy.rank} of {proxy.numProxies} + +
+
+ Last Voted + {proxy.lastVotedAt?.toDateString() || "Never"} +
+
+
+ + + + {votingPower && ( +
+ My Delegations: + {humanReadable(votingPower, decimals)} +
+ )} + + + + {}} + isLoading={false} + /> + + {revokeProxyModalVisible && ( + setRevokeProxyModalVisible(false)} + onSubmit={unassignProxies} + wallet={wallet} + /> + )} +
+
+ Wallet: + {proxy.wallet} +
+
+ Num Delegations: + {proxy.numDelegations} +
+
+ Delegated Tokens: + + {proxy.delegatedVeTokens + ? humanReadable(new BN(proxy.delegatedVeTokens), decimals) + : "0"} + +
+
+ Percent: + {Number(proxy.percent).toFixed(2)} +
+
+
+ {detail} +
+ +
+ + + ); +} diff --git a/src/components/RevokeProxyButton.tsx b/src/components/RevokeProxyButton.tsx new file mode 100644 index 0000000..e628dd2 --- /dev/null +++ b/src/components/RevokeProxyButton.tsx @@ -0,0 +1,49 @@ +import React, { useMemo } from "react"; +import { useWallet } from "@solana/wallet-adapter-react"; +import { useHeliumVsrState } from "@helium/voter-stake-registry-hooks"; +import { PublicKey } from "@solana/web3.js"; +import { Button } from "./ui/button"; +import { Loader2 } from "lucide-react"; + +export const RevokeProxyButton: React.FC<{ + className?: string; + onClick: () => void; + isLoading?: boolean; + wallet?: PublicKey; +}> = ({ wallet, className = "", onClick, isLoading = false }) => { + const { connected } = useWallet(); + const { loading, positions } = useHeliumVsrState(); + + const proxiedPositions = useMemo( + () => + positions?.filter( + (p) => + p.proxy && + !p.proxy.nextOwner.equals(PublicKey.default) && + (!wallet || p.proxy.nextOwner.equals(wallet)) + ), + [positions] + ); + + const tooltipContent = !connected + ? "Connect your wallet to claim" + : !proxiedPositions?.length + ? "You don't have any positions available to revoke proxy." + : ""; + + const disabled = !connected || loading || !proxiedPositions?.length; + + return ( + + ); +}; diff --git a/src/components/RevokeProxyModal.tsx b/src/components/RevokeProxyModal.tsx new file mode 100644 index 0000000..6871ff0 --- /dev/null +++ b/src/components/RevokeProxyModal.tsx @@ -0,0 +1,129 @@ +import { + PositionWithMeta, + useHeliumVsrState, +} from "@helium/voter-stake-registry-hooks"; +import { DialogContent } from "@radix-ui/react-dialog"; +import { PublicKey } from "@solana/web3.js"; +import { Loader2 } from "lucide-react"; +import React, { useMemo, useState } from "react"; +import { toast } from "sonner"; +import { PositionItem } from "./AssignProxyModal"; +import { Button } from "./ui/button"; +import { Dialog } from "./ui/dialog"; + +interface RevokeProxyModalProps { + isOpen: boolean; + onClose: () => void; + onSubmit: (args: { positions: PositionWithMeta[] }) => Promise; + wallet?: PublicKey; +} + +export const RevokeProxyModal: React.FC = ({ + isOpen, + onClose, + onSubmit, + wallet, +}) => { + const { loading, positions, mint } = useHeliumVsrState(); + const [selectedPositions, setSelectedPositions] = useState>( + new Set() + ); + const [isSubmitting, setIsSubmitting] = useState(false); + const proxiedPositions = useMemo( + () => + positions?.filter( + (p) => + p.proxy && + !p.proxy.nextOwner.equals(PublicKey.default) && + (!wallet || p.proxy.nextOwner.equals(wallet)) + ), + [positions, wallet] + ); + + const handleOnSubmit = async () => { + try { + const positionsByKey = positions?.reduce((acc, p) => { + acc[p.pubkey.toString()] = p; + return acc; + }, {} as Record); + setIsSubmitting(true); + if (positionsByKey) { + await onSubmit({ + positions: Array.from(selectedPositions).map( + (p) => positionsByKey[p] + ), + }); + } + + onClose(); + } catch (e: any) { + setIsSubmitting(false); + toast(e.message || "Unable to Revoke proxy") + } + }; + + return ( + + +

+ Revoke Voting Proxy +

+ {loading ? ( + <> +
+
Fetching Positions available to Revoke Proxy
+
+
+ +
+ + ) : ( +
+
+

Positions to Revoke

+ + {proxiedPositions?.map((position) => { + return ( + { + setSelectedPositions((sel) => { + const key = position.pubkey.toBase58(); + const newS = new Set(sel); + if (sel.has(key)) { + newS.delete(key); + return newS; + } else { + newS.add(key); + return newS; + } + }); + }} + /> + ); + })} +
+
+ )} +
+ + +
+
+
+ ); +}; diff --git a/src/components/SubNav.tsx b/src/components/SubNav.tsx new file mode 100644 index 0000000..c19dbbf --- /dev/null +++ b/src/components/SubNav.tsx @@ -0,0 +1,101 @@ +"use client"; + +import React from "react"; +import { ToggleGroup, ToggleGroupItem } from "./ui/toggle-group"; +import Link from "next/link"; +import { usePathname } from "next/navigation"; +import { FaBolt } from "react-icons/fa6"; +import { IoPerson } from "react-icons/io5"; +import { LuScrollText } from "react-icons/lu"; +import { + DropdownMenu, + DropdownMenuContent, + DropdownMenuTrigger, +} from "./ui/dropdown-menu"; +import { Button } from "./ui/button"; +import { DropdownMenuLabel } from "@radix-ui/react-dropdown-menu"; +import { IconType } from "react-icons"; + +const icons: { [key: string]: IconType } = { + proposals: LuScrollText, + proxies: IoPerson, + positions: FaBolt, +}; + +export const SubNav: React.FC = () => { + const path = usePathname(); + const basePath = path.split("/").slice(0, 2).join("/"); + const currentPath = path.split("/")[2] || "proposals"; + const Icon = icons[currentPath]; + + return ( +
+
+ + + + + Proposals + + + + + + Proxies + + + + + + Positions + + + +
+
+ + + + + + + + + Proposals + + + + + + Proxies + + + + + + Positions + + + + +
+
+ ); +}; diff --git a/src/components/VeTokensCallout.tsx b/src/components/VeTokensCallout.tsx index 1a7b80b..ac413d9 100644 --- a/src/components/VeTokensCallout.tsx +++ b/src/components/VeTokensCallout.tsx @@ -11,10 +11,10 @@ import { HNT_MINT, IOT_MINT, MOBILE_MINT, toNumber } from "@helium/spl-utils"; import { calcPositionVotingPower, getPositionKeys, - getRegistrarKey, usePositions, useRegistrar, } from "@helium/voter-stake-registry-hooks"; +import { getRegistrarKey } from "@helium/voter-stake-registry-sdk"; import { PublicKey } from "@solana/web3.js"; import BN from "bn.js"; import Image from "next/image"; diff --git a/src/components/ViewPositionsButton.tsx b/src/components/ViewPositionsButton.tsx deleted file mode 100644 index a87da2c..0000000 --- a/src/components/ViewPositionsButton.tsx +++ /dev/null @@ -1,23 +0,0 @@ -"use client"; - -import { FaBolt } from "react-icons/fa6"; -import Link from "next/link"; -import React, { FC } from "react"; -import { Button } from "./ui/button"; -import { usePathname } from "next/navigation"; -import classNames from "classnames"; - -export const ViewPositionsButton: FC<{ className: string }> = ({ - className = "", -}) => { - const path = usePathname(); - - return ( - - - - ); -}; diff --git a/src/components/VoteBreakdown.tsx b/src/components/VoteBreakdown.tsx index 36a3f5c..45a74c8 100644 --- a/src/components/VoteBreakdown.tsx +++ b/src/components/VoteBreakdown.tsx @@ -1,5 +1,5 @@ import React, { FC, useMemo, useState } from "react"; -import { humanReadable } from "@/lib/utils"; +import { ellipsisMiddle, humanReadable } from "@/lib/utils"; import { PublicKey } from "@solana/web3.js"; import { useProposal, @@ -24,14 +24,6 @@ import { FaChevronDown } from "react-icons/fa6"; import classNames from "classnames"; import Link from "next/link"; -const ellipsisMiddle = (wallet: string): string => { - const length = wallet.length; - const start = wallet.slice(0, 5); - const end = wallet.slice(length - 5, length); - const middle = "..."; - return start + middle + end; -}; - export const VoteBreakdown: FC<{ proposalKey: PublicKey; }> = ({ proposalKey }) => { diff --git a/src/components/VoteHistory.tsx b/src/components/VoteHistory.tsx new file mode 100644 index 0000000..4bf20e4 --- /dev/null +++ b/src/components/VoteHistory.tsx @@ -0,0 +1,117 @@ +import { humanReadable } from "@/lib/utils"; +import { useMint } from "@helium/helium-react-hooks"; +import { useHeliumVsrState } from "@helium/voter-stake-registry-hooks"; +import { ProposalWithVotes } from "@helium/voter-stake-registry-sdk"; +import { PublicKey } from "@solana/web3.js"; +import BN from "bn.js"; +import { useEffect, useState } from "react"; +import InfiniteScroll from "react-infinite-scroll-component"; + +export default function VoteHistory({ wallet }: { wallet: PublicKey }) { + const { voteService, mint } = useHeliumVsrState(); + const { info: mintAcc } = useMint(mint); + const decimals = mintAcc?.decimals; + const [voteHistories, setVoteHistory] = useState([]); + const [hasMore, setHasMore] = useState(true); + const [page, setPage] = useState(1); + + const fetchMoreData = async () => { + if (voteService) { + const newVoteHistory = await voteService.getVotesForWallet({ + wallet: wallet, + page: page, + limit: 10, + }); + setPage((p) => p + 1); + if (newVoteHistory.length < 10) { + setHasMore(false); + } + setVoteHistory((prevVoteHistory) => [ + ...prevVoteHistory, + ...newVoteHistory, + ]); + } + }; + + useEffect(() => { + if (voteService) { + setPage(1); + setHasMore(true); + fetchMoreData(); + } + }, [voteService]); + + return ( +
+ Loading...} + endMessage={ +

+ End of vote history +

+ } + > + + + + + + + + + + + + {voteHistories.map((voteHistory, index) => { + const totalWeight = voteHistory.choices.reduce((acc, c) => { + return acc.add(new BN(c.weight)); + }, new BN(0)); + console.log(totalWeight.toNumber()); + const percent = voteHistory.votes[0] + ? (100 * Number(voteHistory.votes[0].weight)) / + totalWeight.toNumber() + : 0; + + return ( + + + + + + + + ); + })} + +
+ Proposal + + State + + Weight + + Choices + + Percent +
+ {voteHistory.name} + + {Object.keys(voteHistory.state)[0]} + + {voteHistory.votes[0]?.weight && + humanReadable( + new BN(voteHistory.votes[0].weight), + decimals + )} + + {voteHistory.votes.map((v) => v.choiceName).join(", ")} + + {percent.toFixed(2)} +
+
+
+ ); +} diff --git a/src/components/ui/dropdown-menu.tsx b/src/components/ui/dropdown-menu.tsx new file mode 100644 index 0000000..f69a0d6 --- /dev/null +++ b/src/components/ui/dropdown-menu.tsx @@ -0,0 +1,200 @@ +"use client" + +import * as React from "react" +import * as DropdownMenuPrimitive from "@radix-ui/react-dropdown-menu" +import { Check, ChevronRight, Circle } from "lucide-react" + +import { cn } from "@/lib/utils" + +const DropdownMenu = DropdownMenuPrimitive.Root + +const DropdownMenuTrigger = DropdownMenuPrimitive.Trigger + +const DropdownMenuGroup = DropdownMenuPrimitive.Group + +const DropdownMenuPortal = DropdownMenuPrimitive.Portal + +const DropdownMenuSub = DropdownMenuPrimitive.Sub + +const DropdownMenuRadioGroup = DropdownMenuPrimitive.RadioGroup + +const DropdownMenuSubTrigger = React.forwardRef< + React.ElementRef, + React.ComponentPropsWithoutRef & { + inset?: boolean + } +>(({ className, inset, children, ...props }, ref) => ( + + {children} + + +)) +DropdownMenuSubTrigger.displayName = + DropdownMenuPrimitive.SubTrigger.displayName + +const DropdownMenuSubContent = React.forwardRef< + React.ElementRef, + React.ComponentPropsWithoutRef +>(({ className, ...props }, ref) => ( + +)) +DropdownMenuSubContent.displayName = + DropdownMenuPrimitive.SubContent.displayName + +const DropdownMenuContent = React.forwardRef< + React.ElementRef, + React.ComponentPropsWithoutRef +>(({ className, sideOffset = 4, ...props }, ref) => ( + + + +)) +DropdownMenuContent.displayName = DropdownMenuPrimitive.Content.displayName + +const DropdownMenuItem = React.forwardRef< + React.ElementRef, + React.ComponentPropsWithoutRef & { + inset?: boolean + } +>(({ className, inset, ...props }, ref) => ( + +)) +DropdownMenuItem.displayName = DropdownMenuPrimitive.Item.displayName + +const DropdownMenuCheckboxItem = React.forwardRef< + React.ElementRef, + React.ComponentPropsWithoutRef +>(({ className, children, checked, ...props }, ref) => ( + + + + + + + {children} + +)) +DropdownMenuCheckboxItem.displayName = + DropdownMenuPrimitive.CheckboxItem.displayName + +const DropdownMenuRadioItem = React.forwardRef< + React.ElementRef, + React.ComponentPropsWithoutRef +>(({ className, children, ...props }, ref) => ( + + + + + + + {children} + +)) +DropdownMenuRadioItem.displayName = DropdownMenuPrimitive.RadioItem.displayName + +const DropdownMenuLabel = React.forwardRef< + React.ElementRef, + React.ComponentPropsWithoutRef & { + inset?: boolean + } +>(({ className, inset, ...props }, ref) => ( + +)) +DropdownMenuLabel.displayName = DropdownMenuPrimitive.Label.displayName + +const DropdownMenuSeparator = React.forwardRef< + React.ElementRef, + React.ComponentPropsWithoutRef +>(({ className, ...props }, ref) => ( + +)) +DropdownMenuSeparator.displayName = DropdownMenuPrimitive.Separator.displayName + +const DropdownMenuShortcut = ({ + className, + ...props +}: React.HTMLAttributes) => { + return ( + + ) +} +DropdownMenuShortcut.displayName = "DropdownMenuShortcut" + +export { + DropdownMenu, + DropdownMenuTrigger, + DropdownMenuContent, + DropdownMenuItem, + DropdownMenuCheckboxItem, + DropdownMenuRadioItem, + DropdownMenuLabel, + DropdownMenuSeparator, + DropdownMenuShortcut, + DropdownMenuGroup, + DropdownMenuPortal, + DropdownMenuSub, + DropdownMenuSubContent, + DropdownMenuSubTrigger, + DropdownMenuRadioGroup, +} diff --git a/src/components/ui/toggle-group.tsx b/src/components/ui/toggle-group.tsx new file mode 100644 index 0000000..6cadb52 --- /dev/null +++ b/src/components/ui/toggle-group.tsx @@ -0,0 +1,61 @@ +"use client" + +import * as React from "react" +import * as ToggleGroupPrimitive from "@radix-ui/react-toggle-group" +import { VariantProps } from "class-variance-authority" + +import { cn } from "@/lib/utils" +import { toggleVariants } from "@/components/ui/toggle" + +const ToggleGroupContext = React.createContext< + VariantProps +>({ + size: "default", + variant: "default", +}) + +const ToggleGroup = React.forwardRef< + React.ElementRef, + React.ComponentPropsWithoutRef & + VariantProps +>(({ className, variant, size, children, ...props }, ref) => ( + + + {children} + + +)) + +ToggleGroup.displayName = ToggleGroupPrimitive.Root.displayName + +const ToggleGroupItem = React.forwardRef< + React.ElementRef, + React.ComponentPropsWithoutRef & + VariantProps +>(({ className, children, variant, size, ...props }, ref) => { + const context = React.useContext(ToggleGroupContext) + + return ( + + {children} + + ) +}) + +ToggleGroupItem.displayName = ToggleGroupPrimitive.Item.displayName + +export { ToggleGroup, ToggleGroupItem } diff --git a/src/components/ui/toggle.tsx b/src/components/ui/toggle.tsx new file mode 100644 index 0000000..1adebf9 --- /dev/null +++ b/src/components/ui/toggle.tsx @@ -0,0 +1,45 @@ +"use client" + +import * as React from "react" +import * as TogglePrimitive from "@radix-ui/react-toggle" +import { cva, type VariantProps } from "class-variance-authority" + +import { cn } from "@/lib/utils" + +const toggleVariants = cva( + "inline-flex items-center justify-center rounded-md text-sm rounded-full py-0 px-4 font-medium ring-offset-background transition-colors hover:bg-muted hover:text-muted-foreground focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring focus-visible:ring-offset-2 disabled:pointer-events-none disabled:opacity-50 data-[state=on]:bg-black/30 data-[state=on]:text-accent-foreground", + { + variants: { + variant: { + default: "bg-transparent", + outline: + "border border-input bg-transparent hover:bg-accent hover:text-accent-foreground", + }, + size: { + default: "h-10 px-3", + sm: "h-9 px-2.5", + lg: "h-11 px-5", + }, + }, + defaultVariants: { + variant: "default", + size: "default", + }, + } +) + +const Toggle = React.forwardRef< + React.ElementRef, + React.ComponentPropsWithoutRef & + VariantProps +>(({ className, variant, size, ...props }, ref) => ( + +)) + +Toggle.displayName = TogglePrimitive.Root.displayName + +export { Toggle, toggleVariants } diff --git a/src/hooks/useMetaplexMetadata.ts b/src/hooks/useMetaplexMetadata.ts new file mode 100644 index 0000000..60fa1f4 --- /dev/null +++ b/src/hooks/useMetaplexMetadata.ts @@ -0,0 +1,131 @@ +import { TypedAccountParser } from "@helium/account-fetch-cache"; +import { + PROGRAM_ID as MPL_PID, + Metadata, +} from "@metaplex-foundation/mpl-token-metadata"; +import { NATIVE_MINT } from "@solana/spl-token"; +import { AccountInfo, PublicKey } from "@solana/web3.js"; +import axios from "axios"; +import { useMemo } from "react"; +import { useAsync } from "react-async-hook"; +import { useAccount } from "@helium/account-fetch-cache-hooks"; + +const cache: Record> = {}; +export function getMetadata( + uriIn: string | undefined +): Promise { + const uri = uriIn?.replace(/\0/g, ""); + if (uri) { + if (!cache[uri]) { + cache[uri] = axios + .get(uri.replace(/\0/g, ""), { + timeout: 3000, + }) + .then((res) => res.data) + .catch((err: any) => { + console.error(`Error at uri ${uri}`, err); + }); + } + return cache[uri]; + } + return Promise.resolve(undefined); +} + +export const METADATA_PARSER: TypedAccountParser = ( + _: PublicKey, + account: AccountInfo +) => { + return Metadata.fromAccountInfo(account)[0]; +}; + +export function getMetadataId(mint: PublicKey): PublicKey { + return PublicKey.findProgramAddressSync( + [Buffer.from("metadata", "utf-8"), MPL_PID.toBuffer(), mint.toBuffer()], + MPL_PID + )[0]; +} + +type TokenInfo = { + name: string; + symbol: string; + logoURI: string; +}; + +export const tokenInfoToMetadata = ( + tokenInfo: TokenInfo | null | undefined +): any | undefined => { + if (!tokenInfo) return undefined; + + return { + json: { + name: tokenInfo.name, + symbol: tokenInfo.symbol, + image: tokenInfo.logoURI, + }, + symbol: tokenInfo.symbol, + name: tokenInfo.name, + }; +}; + +const USDC = new PublicKey("EPjFWdd5AufqSSqeM2qN1xzybapC8G4wEGGkZwyTDt1v"); +export function useMetaplexMetadata(mint: PublicKey | undefined): { + loading: boolean; + metadata: Metadata | undefined; + json: any | undefined; + symbol: string | undefined; + name: string | undefined; +} { + const metadataAddr = useMemo(() => { + if (mint) { + return getMetadataId(mint); + } + // eslint-disable-next-line react-hooks/exhaustive-deps + }, [mint?.toBase58()]); + + const { info: metadataAcc, loading } = useAccount( + metadataAddr, + METADATA_PARSER + ); + + const { result: json, loading: jsonLoading } = useAsync(getMetadata, [ + metadataAcc?.data.uri.trim(), + ]); + + if (mint?.equals(NATIVE_MINT)) { + return { + metadata: undefined, + loading: false, + json: { + name: "SOL", + symbol: "SOL", + image: + "https://github.com/solana-labs/token-list/blob/main/assets/mainnet/So11111111111111111111111111111111111111112/logo.png?raw=true", + }, + symbol: "SOL", + name: "SOL", + }; + } + + if (mint?.equals(USDC)) { + return { + metadata: undefined, + loading: false, + json: { + name: "USDC", + symbol: "USDC", + image: + "https://github.com/solana-labs/token-list/blob/main/assets/mainnet/EPjFWdd5AufqSSqeM2qN1xzybapC8G4wEGGkZwyTDt1v/logo.png?raw=true", + }, + symbol: "USDC", + name: "USDC", + }; + } + + return { + loading: jsonLoading || loading, + json, + metadata: metadataAcc, + symbol: json?.symbol || metadataAcc?.data?.symbol, + name: json?.name || metadataAcc?.data?.name, + }; +} diff --git a/src/hooks/useNetwork.ts b/src/hooks/useNetwork.ts new file mode 100644 index 0000000..a6470a8 --- /dev/null +++ b/src/hooks/useNetwork.ts @@ -0,0 +1,31 @@ +import { networksToMint } from "@/lib/constants"; +import { PublicKey } from "@solana/web3.js"; +import { usePathname } from "next/navigation"; +import { useRouter } from "next/router"; +import { useCallback } from "react"; + +export function useNetwork() { + const path = usePathname(); + const network = path.split("/")[0]; + const router = useRouter(); + const mint = networksToMint[network || ""]; + + const setMint = useCallback( + (mint: PublicKey) => { + const newNetwork = Object.entries(networksToMint).find(([_, m]) => + mint.equals(m) + )?.[0]; + // Construct new path + const newPath = router.asPath.replace(network, newNetwork || network); + + router.push(newPath); + }, + [network, router] + ); + + return { + network, + mint, + setMint, + }; +} diff --git a/src/lib/constants.ts b/src/lib/constants.ts index b1d8313..839c337 100644 --- a/src/lib/constants.ts +++ b/src/lib/constants.ts @@ -1,2 +1,11 @@ +import { HNT_MINT, IOT_MINT, MOBILE_MINT } from "@helium/spl-utils"; +import { PublicKey } from "@solana/web3.js"; + // Make a smaller batch for the sake of ledger. export const MAX_TRANSACTIONS_PER_SIGNATURE_BATCH = 5; + +export const networksToMint: { [key: string]: PublicKey } = { + hnt: HNT_MINT, + mobile: MOBILE_MINT, + iot: IOT_MINT, +}; diff --git a/src/lib/dateTools.ts b/src/lib/dateTools.ts new file mode 100644 index 0000000..b7dd524 --- /dev/null +++ b/src/lib/dateTools.ts @@ -0,0 +1,70 @@ +import { BN } from "@coral-xyz/anchor"; + +export const DAYS_PER_YEAR = 365; +export const SECS_PER_DAY = 86400; +export const DAYS_PER_MONTH = DAYS_PER_YEAR / 12; +export const HOURS_PER_DAY = 24; +export const MINS_PER_HOUR = 60; + +export function getFormattedStringFromDays( + numberOfDays: number, + fullFormat = false +) { + const years = Math.floor(numberOfDays / DAYS_PER_YEAR); + const months = Math.floor((numberOfDays % DAYS_PER_YEAR) / DAYS_PER_MONTH); + const days = Math.floor((numberOfDays % DAYS_PER_YEAR) % DAYS_PER_MONTH); + const hours = (numberOfDays - Math.floor(numberOfDays)) * HOURS_PER_DAY; + const hoursInt = Math.floor(hours); + const minutes = Math.floor((hours - hoursInt) * MINS_PER_HOUR); + const yearSuffix = years > 1 ? " years" : " year"; + const monthSuffix = months > 1 ? " months" : " month"; + const daysSuffix = days > 1 ? " days" : " day"; + const yearsDisplay = + years > 0 ? years + `${fullFormat ? yearSuffix : "y"}` : null; + const monthsDisplay = + months > 0 ? months + `${fullFormat ? monthSuffix : "m"}` : null; + const daysDisplay = + days > 0 ? days + `${fullFormat ? daysSuffix : "d"}` : null; + const hoursDisplay = hours > 0 ? `${hoursInt}h ${minutes}min` : null; + const text = + !years && !months && days <= 1 + ? [daysDisplay, hoursDisplay].filter(Boolean).join(" ") + : [yearsDisplay, monthsDisplay, daysDisplay].filter(Boolean).join(" "); + return text ? text : 0; +} + +export const yearsToDays = (years: number) => { + return DAYS_PER_YEAR * years; +}; +export const daysToYear = (days: number) => { + return days / DAYS_PER_YEAR; +}; +export const yearsToSecs = (years: number) => { + return DAYS_PER_YEAR * years * SECS_PER_DAY; +}; + +export const daysToSecs = (days: number) => { + return days * SECS_PER_DAY; +}; + +export const secsToDays = (secs: number) => { + return secs / SECS_PER_DAY; +}; + +export const daysToMonths = (days: number) => { + return days / DAYS_PER_MONTH; +}; + +export const getMinDurationFmt = (startTs: BN, endTs: BN) => { + return getFormattedStringFromDays(getMinDurationInDays(startTs, endTs)); +}; +export const getTimeLeftFromNowFmt = (ts: BN) => { + const dateNowSecTimeStampBN = new BN(new Date().getTime() / 1000); + return getFormattedStringFromDays( + ts.sub(dateNowSecTimeStampBN).toNumber() / SECS_PER_DAY + ); +}; + +export const getMinDurationInDays = (startTs: BN, endTs: BN) => { + return endTs.sub(startTs).toNumber() / SECS_PER_DAY; +}; diff --git a/src/lib/utils.ts b/src/lib/utils.ts index 3b48304..d7ea43b 100644 --- a/src/lib/utils.ts +++ b/src/lib/utils.ts @@ -36,6 +36,14 @@ export function cn(...inputs: ClassValue[]) { return twMerge(clsx(inputs)); } +export const ellipsisMiddle = (wallet: string): string => { + const length = wallet.length; + const start = wallet.slice(0, 5); + const end = wallet.slice(length - 5, length); + const middle = "..."; + return start + middle + end; +}; + export const formMetaTags = (args?: { title?: string; description?: string; diff --git a/src/providers/GovernanceProvider.tsx b/src/providers/GovernanceProvider.tsx index 983e523..f00ed0b 100644 --- a/src/providers/GovernanceProvider.tsx +++ b/src/providers/GovernanceProvider.tsx @@ -6,15 +6,15 @@ import { organizationKey } from "@helium/organization-sdk"; import { HNT_MINT, IOT_MINT, MOBILE_MINT } from "@helium/spl-utils"; import { HeliumVsrStateProvider, - getRegistrarKey, getSubDaos, useHeliumVsrState, useRegistrar, useSubDaos, } from "@helium/voter-stake-registry-hooks"; +import { getRegistrarKey } from "@helium/voter-stake-registry-sdk"; import { PublicKey } from "@solana/web3.js"; import { useParams } from "next/navigation"; -import React, { +import { FC, ReactNode, createContext, @@ -110,6 +110,7 @@ const GovernanceProvider: FC<{ children: ReactNode }> = ({ children }) => { mint={mint} wallet={anchorProvider?.wallet as Wallet} connection={anchorProvider?.connection} + heliumVoteUri="http://localhost:8081" > {children} diff --git a/tailwind.config.ts b/tailwind.config.ts index a543f34..0718ff6 100644 --- a/tailwind.config.ts +++ b/tailwind.config.ts @@ -113,6 +113,7 @@ const config = { card: { DEFAULT: "hsl(var(--card))", foreground: "hsl(var(--card-foreground))", + muted: "#28303B", }, }, borderRadius: { diff --git a/yarn.lock b/yarn.lock index dc36782..d734c3b 100644 --- a/yarn.lock +++ b/yarn.lock @@ -171,7 +171,7 @@ resolved "https://registry.yarnpkg.com/@floating-ui/utils/-/utils-0.2.1.tgz#16308cea045f0fc777b6ff20a9f25474dd8293d2" integrity sha512-9TANp6GPoMtYzQdt54kfAyMmz1+osLlXdg2ENroU7zzrtflTLrrC/lgrIfaSe+Wu0b89GKccT7vxXA0MoAIO+Q== -"@helium/account-fetch-cache-hooks@^0.5.0", "@helium/account-fetch-cache-hooks@^0.7.11": +"@helium/account-fetch-cache-hooks@^0.5.0", "@helium/account-fetch-cache-hooks@^0.7.11", "@helium/account-fetch-cache-hooks@^0.7.6": version "0.7.11" resolved "https://registry.yarnpkg.com/@helium/account-fetch-cache-hooks/-/account-fetch-cache-hooks-0.7.11.tgz#cc36cc403958de9b9f230bdd1adf2730b9dfd287" integrity sha512-YoUacY5cQJStezTIw3sbmxxsuyH+P0VNtVVGnQ7jA3g+Y20BISWs/NOxf5w3cyAPscadUzTnqwGFiQ2isd9UTg== @@ -180,7 +180,7 @@ "@solana/web3.js" "^1.78.8" react-async-hook "^4.0.0" -"@helium/account-fetch-cache@^0.5.0", "@helium/account-fetch-cache@^0.7.11": +"@helium/account-fetch-cache@^0.5.0", "@helium/account-fetch-cache@^0.7.11", "@helium/account-fetch-cache@^0.7.6": version "0.7.11" resolved "https://registry.yarnpkg.com/@helium/account-fetch-cache/-/account-fetch-cache-0.7.11.tgz#5813509464214cbfbbe42040eb5a48a386e1eefd" integrity sha512-5HPecniIyU/rcUc+Na7gqPRr352Dw8egrfgOzc24PdquVWvbJzrVwfcjrFL2PGEr858uTx0uIzbICrfsaMvEaQ== @@ -196,6 +196,14 @@ js-sha256 "^0.9.0" multiformats "^9.6.4" +"@helium/anchor-resolvers@^0.2.17": + version "0.2.21" + resolved "https://registry.yarnpkg.com/@helium/anchor-resolvers/-/anchor-resolvers-0.2.21.tgz#8cd13bca3e7af83ffff3ab754dcf9f788d26e57e" + integrity sha512-rz3GJaULGmokjrq63v4sy683PMUkL31jrK5wVX01tzCYbI1woC9vISoPd3oSSuauZqQXdBhhQ49GKrpzi49JbA== + dependencies: + "@solana/spl-token" "^0.3.6" + "@solana/web3.js" "^1.43.4" + "@helium/anchor-resolvers@^0.5.0": version "0.5.0" resolved "https://registry.yarnpkg.com/@helium/anchor-resolvers/-/anchor-resolvers-0.5.0.tgz#499fbcd82411d07b148d7015a1e6432020a3f82d" @@ -204,26 +212,26 @@ "@solana/spl-token" "^0.3.8" "@solana/web3.js" "^1.78.4" -"@helium/anchor-resolvers@^0.7.11": - version "0.7.11" - resolved "https://registry.yarnpkg.com/@helium/anchor-resolvers/-/anchor-resolvers-0.7.11.tgz#8e0612644129c4497dfa796c51e4db556aa43872" - integrity sha512-npHweI0lEO00bjLmOanCZXJkfC+cPn+JPNARsF5r42eJk0QL9HLxJJBaAwihpD3Q2xpyXhk1N306MMEgXRdTOQ== +"@helium/anchor-resolvers@^0.7.12", "@helium/anchor-resolvers@^0.7.6": + version "0.7.12" + resolved "https://registry.yarnpkg.com/@helium/anchor-resolvers/-/anchor-resolvers-0.7.12.tgz#bb6921d252c7ae4c2788569ddbf68fb57a3f2adc" + integrity sha512-KphCkH4IHRMxWq/SSaWRxDVV8b1w8L0tY1qFOvvH/bY+Mr1E8CiVHZCCpdi1c5k/idLDz/wHvHCUSXppFPxdDQ== dependencies: "@solana/spl-token" "^0.3.8" "@solana/web3.js" "^1.78.8" -"@helium/circuit-breaker-sdk@^0.7.11": - version "0.7.11" - resolved "https://registry.yarnpkg.com/@helium/circuit-breaker-sdk/-/circuit-breaker-sdk-0.7.11.tgz#032c4697bd7205423bc946371792c085cea5e31b" - integrity sha512-t7iNkNLKBL0uPkqK+gcrAzOLnL+w1gjbpcWQ4jVfRwmzQApmhwu15WKlO1NW+av/neZeCYtvD+bOqR69ASruVA== +"@helium/circuit-breaker-sdk@^0.7.12", "@helium/circuit-breaker-sdk@^0.7.6": + version "0.7.12" + resolved "https://registry.yarnpkg.com/@helium/circuit-breaker-sdk/-/circuit-breaker-sdk-0.7.12.tgz#400d28228f473edc80dc8b0a81ef76cf6a3f3bcd" + integrity sha512-4qhoYuW0Aeo9+gg1/z9Fp+IjtS4+v2Wz88imKSHYmpINJ3BNNh7q7zfuYsX/t1utQyaYxhFSejlIIP1yVdlmsw== dependencies: "@coral-xyz/anchor" "^0.28.0" - "@helium/anchor-resolvers" "^0.7.11" - "@helium/idls" "^0.7.11" + "@helium/anchor-resolvers" "^0.7.12" + "@helium/idls" "^0.7.12" bn.js "^5.2.0" bs58 "^4.0.1" -"@helium/helium-react-hooks@^0.5.0", "@helium/helium-react-hooks@^0.7.11": +"@helium/helium-react-hooks@^0.5.0", "@helium/helium-react-hooks@^0.7.11", "@helium/helium-react-hooks@^0.7.6": version "0.7.11" resolved "https://registry.yarnpkg.com/@helium/helium-react-hooks/-/helium-react-hooks-0.7.11.tgz#1d67bf58906f9c8d02ee9e7cb064ba6fb1668f3b" integrity sha512-BD3cjdxn+98h+Cm1Dy5duwAk2RmmxqMkLoRQKZTiXK7X91d80bS3bHep6XbPMGlvHFokyrCcITiWp/ivHRHLLw== @@ -237,23 +245,23 @@ pako "^2.0.3" react-async-hook "^4.0.0" -"@helium/helium-sub-daos-sdk@^0.7.11": - version "0.7.11" - resolved "https://registry.yarnpkg.com/@helium/helium-sub-daos-sdk/-/helium-sub-daos-sdk-0.7.11.tgz#eb59678610f9b5b8cdf7c4c7671ed23347acd517" - integrity sha512-37is9bYr0W/+4rqTInkaErYKQB72Fa53csXtZCYwRsDqhYWCXT/UvTyepr+Cyg/cHc70HcL/Cmrt/UFg1brH0w== +"@helium/helium-sub-daos-sdk@^0.7.6": + version "0.7.12" + resolved "https://registry.yarnpkg.com/@helium/helium-sub-daos-sdk/-/helium-sub-daos-sdk-0.7.12.tgz#7b38a582e8f195c82f307225e48f3f8dedc24e95" + integrity sha512-ziVwT9mo8OK7lWHBXmqy6M9b9UltvphNFNtysdGIWjgnZYYWrZbK6t0PKKciCBg/W9D3SHQzWiiSHfQhHCwCFA== dependencies: "@coral-xyz/anchor" "^0.28.0" - "@helium/anchor-resolvers" "^0.7.11" - "@helium/circuit-breaker-sdk" "^0.7.11" - "@helium/treasury-management-sdk" "^0.7.11" - "@helium/voter-stake-registry-sdk" "^0.7.11" + "@helium/anchor-resolvers" "^0.7.12" + "@helium/circuit-breaker-sdk" "^0.7.12" + "@helium/treasury-management-sdk" "^0.7.12" + "@helium/voter-stake-registry-sdk" "^0.7.12" bn.js "^5.2.0" bs58 "^4.0.1" -"@helium/idls@^0.7.11": - version "0.7.11" - resolved "https://registry.yarnpkg.com/@helium/idls/-/idls-0.7.11.tgz#90e73f3878f1326067784ae208ee753f2fce90c6" - integrity sha512-bZYDJpPMsDmB+Zm6ZmcHsuLkNOEw2Nf4xtQ8SWPglSoKwsXa8VB6P6cEtNavRVBfU1RBn3XQbGHuevvW5Yuq2g== +"@helium/idls@^0.7.12", "@helium/idls@^0.7.6": + version "0.7.12" + resolved "https://registry.yarnpkg.com/@helium/idls/-/idls-0.7.12.tgz#6940c0e4750e8201994e1420b6053e3aefff75d0" + integrity sha512-ZcAw904YsbyUqGuejhGq7YaE+S5RZfNTSkV43T/KA/HwEtxCyWRrz8oiKEVEbYXk+XX/InQX5feW/X+3g/w+5g== dependencies: "@coral-xyz/anchor" "^0.28.0" "@solana/web3.js" "^1.78.8" @@ -274,7 +282,15 @@ "@helium/organization-sdk" "^0.0.8" "@solana/web3.js" "^1.78.4" -"@helium/modular-governance-idls@^0.0.8", "@helium/modular-governance-idls@^0.0.8-next": +"@helium/modular-governance-idls@0.0.8-next.17+7ff2115": + version "0.0.8-next.17" + resolved "https://registry.yarnpkg.com/@helium/modular-governance-idls/-/modular-governance-idls-0.0.8-next.17.tgz#066c639879dec20cb71d727bec38500bc39e79da" + integrity sha512-lFQs2V8kPozwI+wSAHxv0l2QRdia2Dy8HJLF71rabeCHVRIBlyoYkveI9wYopEX1XxAAPtGtGvVeLR4SafLe/w== + dependencies: + "@coral-xyz/anchor" "^0.28.0" + "@solana/web3.js" "^1.78.4" + +"@helium/modular-governance-idls@^0.0.8", "@helium/modular-governance-idls@^0.0.8-next", "@helium/modular-governance-idls@^0.0.8-next.17+7ff2115": version "0.0.8" resolved "https://registry.yarnpkg.com/@helium/modular-governance-idls/-/modular-governance-idls-0.0.8.tgz#b913b28790ff80359c7470d9d6665468f5f1b435" integrity sha512-vmBw9dRUsYKX5ZXiMJaCoKYv5yNBLHpXKb5LI/5cIq0KrGNC4quzMuoMzeehXGgDkIIM9VLnk8YP1Bz8CvUzqA== @@ -282,6 +298,16 @@ "@coral-xyz/anchor" "^0.28.0" "@solana/web3.js" "^1.78.4" +"@helium/nft-proxy-sdk@0.0.8-next.17+7ff2115": + version "0.0.8-next.17" + resolved "https://registry.yarnpkg.com/@helium/nft-proxy-sdk/-/nft-proxy-sdk-0.0.8-next.17.tgz#50ea6f3a9f8253035527b0a4cecdc2cd78c4ce81" + integrity sha512-Uphw4HorYpAJmQ/Kf3ggR85/Vqe1ueZpzA8oRtMiwQpo+67pcAHplIVuwQEVkHZ5S23XwL5dNGDIZyBA9Khg0w== + dependencies: + "@coral-xyz/anchor" "^0.28.0" + "@helium/anchor-resolvers" "^0.2.17" + "@helium/modular-governance-idls" "^0.0.8-next.17+7ff2115" + "@solana/spl-token" "^0.3.8" + "@helium/organization-sdk@^0.0.8": version "0.0.8" resolved "https://registry.yarnpkg.com/@helium/organization-sdk/-/organization-sdk-0.0.8.tgz#4738619a929999af6529f21e80e79ab766472322" @@ -301,15 +327,13 @@ "@helium/anchor-resolvers" "^0.5.0" "@helium/modular-governance-idls" "^0.0.8" -"@helium/spl-utils@^0.7.11": - version "0.7.11" - resolved "https://registry.yarnpkg.com/@helium/spl-utils/-/spl-utils-0.7.11.tgz#c217d6ec106ce8d2559f6b1a90cba9184223a7e6" - integrity sha512-4JsmePhEF+3ZO1NQx4Cev+G3pXUyfeW0GUeYArjUV524zpzlc5HvpU28BJg5OD1rNaQ2ZY8Vd+upy31hofrj8g== +"@helium/spl-utils@^0.7.6", "@helium/spl-utils@file:.yalc/@helium/spl-utils": + version "0.7.6" dependencies: "@coral-xyz/anchor" "^0.28.0" - "@helium/account-fetch-cache" "^0.7.11" + "@helium/account-fetch-cache" "^0.7.6" "@helium/address" "^4.10.2" - "@helium/anchor-resolvers" "^0.7.11" + "@helium/anchor-resolvers" "^0.7.6" "@metaplex-foundation/mpl-token-metadata" "^2.10.0" "@solana/spl-account-compression" "^0.1.7" "@solana/spl-token" "^0.3.8" @@ -328,32 +352,31 @@ "@helium/anchor-resolvers" "^0.5.0" "@helium/modular-governance-idls" "^0.0.8" -"@helium/treasury-management-sdk@^0.7.11": - version "0.7.11" - resolved "https://registry.yarnpkg.com/@helium/treasury-management-sdk/-/treasury-management-sdk-0.7.11.tgz#1f2a86b6590f633a2908304bce7bdfde4a0d972b" - integrity sha512-LvUJIPhJSEoJTNcsq8vOIYRSMVlrNte3hFPib9d5ur48PTehKHfUdNG9YAOX3UhbD8xSsIFgwe+ZgcZOFHYJbw== +"@helium/treasury-management-sdk@^0.7.12": + version "0.7.12" + resolved "https://registry.yarnpkg.com/@helium/treasury-management-sdk/-/treasury-management-sdk-0.7.12.tgz#4d9a4f3f04e92c082eacbf38f9ff6f928863bfad" + integrity sha512-Dv+J/Dr6gd9K5drVlUbaBYAI0FISaxhftY55BrofUDhYhsA8drciu+Y97MXt2BGKstAWAlJCHq3HbbwQbmjsmQ== dependencies: "@coral-xyz/anchor" "^0.28.0" - "@helium/anchor-resolvers" "^0.7.11" - "@helium/circuit-breaker-sdk" "^0.7.11" - "@helium/idls" "^0.7.11" + "@helium/anchor-resolvers" "^0.7.12" + "@helium/circuit-breaker-sdk" "^0.7.12" + "@helium/idls" "^0.7.12" bn.js "^5.2.0" bs58 "^4.0.1" -"@helium/voter-stake-registry-hooks@^0.7.11": - version "0.7.11" - resolved "https://registry.yarnpkg.com/@helium/voter-stake-registry-hooks/-/voter-stake-registry-hooks-0.7.11.tgz#57c8ed321db235c756f3ccd59cc1dd259e05409a" - integrity sha512-rsI6ATu7VMjDnaBhaD51BuEbx3ADhQjtlxJzvPdrYK41DwGDMEPbt54qDYfB6+v5EhKAmdWIryOO6bCPt6G6rg== +"@helium/voter-stake-registry-hooks@file:.yalc/@helium/voter-stake-registry-hooks": + version "0.7.6" dependencies: "@coral-xyz/anchor" "^0.28.0" - "@helium/account-fetch-cache" "^0.7.11" - "@helium/account-fetch-cache-hooks" "^0.7.11" - "@helium/circuit-breaker-sdk" "^0.7.11" - "@helium/helium-react-hooks" "^0.7.11" - "@helium/helium-sub-daos-sdk" "^0.7.11" + "@helium/account-fetch-cache" "^0.7.6" + "@helium/account-fetch-cache-hooks" "^0.7.6" + "@helium/circuit-breaker-sdk" "^0.7.6" + "@helium/helium-react-hooks" "^0.7.6" + "@helium/helium-sub-daos-sdk" "^0.7.6" "@helium/modular-governance-hooks" "^0.0.8" - "@helium/spl-utils" "^0.7.11" - "@helium/voter-stake-registry-sdk" "^0.7.11" + "@helium/modular-governance-idls" "0.0.8-next.17+7ff2115" + "@helium/spl-utils" "^0.7.6" + "@helium/voter-stake-registry-sdk" "^0.7.6" "@solana/wallet-adapter-base" "^0.9.22" "@solana/wallet-adapter-react" "^0.15.32" "@solana/web3.js" "^1.78.8" @@ -361,14 +384,14 @@ bs58 "^4.0.1" react-async-hook "^4.0.0" -"@helium/voter-stake-registry-sdk@^0.7.11": - version "0.7.11" - resolved "https://registry.yarnpkg.com/@helium/voter-stake-registry-sdk/-/voter-stake-registry-sdk-0.7.11.tgz#70f75d7407dfac089266b902129a9f748db7fd13" - integrity sha512-1YqH/yYibFE5dTbn8/M8eaHdiP/oYDfU6WLBJg7mmlXsxxyxRaS2t33LTdTAVv8SUwC6pBxm/0LHg4ZRXCdrDw== +"@helium/voter-stake-registry-sdk@^0.7.12", "@helium/voter-stake-registry-sdk@^0.7.6", "@helium/voter-stake-registry-sdk@file:.yalc/@helium/voter-stake-registry-sdk": + version "0.7.6" dependencies: "@coral-xyz/anchor" "^0.28.0" - "@helium/anchor-resolvers" "^0.7.11" - "@helium/idls" "^0.7.11" + "@helium/anchor-resolvers" "^0.7.6" + "@helium/idls" "^0.7.6" + "@helium/nft-proxy-sdk" "0.0.8-next.17+7ff2115" + "@helium/spl-utils" "^0.7.6" "@metaplex-foundation/mpl-token-metadata" "^2.10.0" "@solana/spl-token" "^0.3.8" bn.js "^5.2.0" @@ -658,6 +681,17 @@ "@radix-ui/react-use-previous" "1.0.1" "@radix-ui/react-use-size" "1.0.1" +"@radix-ui/react-collection@1.0.3": + version "1.0.3" + resolved "https://registry.yarnpkg.com/@radix-ui/react-collection/-/react-collection-1.0.3.tgz#9595a66e09026187524a36c6e7e9c7d286469159" + integrity sha512-3SzW+0PW7yBBoQlT8wNcGtaxaD0XSu0uLUFgrtHY08Acx05TaHaOmVLR73c0j/cqpDy53KBMO7s0dx2wmOIDIA== + dependencies: + "@babel/runtime" "^7.13.10" + "@radix-ui/react-compose-refs" "1.0.1" + "@radix-ui/react-context" "1.0.1" + "@radix-ui/react-primitive" "1.0.3" + "@radix-ui/react-slot" "1.0.2" + "@radix-ui/react-compose-refs@1.0.1": version "1.0.1" resolved "https://registry.yarnpkg.com/@radix-ui/react-compose-refs/-/react-compose-refs-1.0.1.tgz#7ed868b66946aa6030e580b1ffca386dd4d21989" @@ -693,6 +727,13 @@ aria-hidden "^1.1.1" react-remove-scroll "2.5.5" +"@radix-ui/react-direction@1.0.1": + version "1.0.1" + resolved "https://registry.yarnpkg.com/@radix-ui/react-direction/-/react-direction-1.0.1.tgz#9cb61bf2ccf568f3421422d182637b7f47596c9b" + integrity sha512-RXcvnXgyvYvBEOhCBuddKecVkoMiI10Jcm5cTI7abJRAHYfFxeu+FBQs/DvdxSYucxR5mna0dNsL6QFlds5TMA== + dependencies: + "@babel/runtime" "^7.13.10" + "@radix-ui/react-dismissable-layer@1.0.5": version "1.0.5" resolved "https://registry.yarnpkg.com/@radix-ui/react-dismissable-layer/-/react-dismissable-layer-1.0.5.tgz#3f98425b82b9068dfbab5db5fff3df6ebf48b9d4" @@ -705,6 +746,20 @@ "@radix-ui/react-use-callback-ref" "1.0.1" "@radix-ui/react-use-escape-keydown" "1.0.3" +"@radix-ui/react-dropdown-menu@^2.0.6": + version "2.0.6" + resolved "https://registry.yarnpkg.com/@radix-ui/react-dropdown-menu/-/react-dropdown-menu-2.0.6.tgz#cdf13c956c5e263afe4e5f3587b3071a25755b63" + integrity sha512-i6TuFOoWmLWq+M/eCLGd/bQ2HfAX1RJgvrBQ6AQLmzfvsLdefxbWu8G9zczcPFfcSPehz9GcpF6K9QYreFV8hA== + dependencies: + "@babel/runtime" "^7.13.10" + "@radix-ui/primitive" "1.0.1" + "@radix-ui/react-compose-refs" "1.0.1" + "@radix-ui/react-context" "1.0.1" + "@radix-ui/react-id" "1.0.1" + "@radix-ui/react-menu" "2.0.6" + "@radix-ui/react-primitive" "1.0.3" + "@radix-ui/react-use-controllable-state" "1.0.1" + "@radix-ui/react-focus-guards@1.0.1": version "1.0.1" resolved "https://registry.yarnpkg.com/@radix-ui/react-focus-guards/-/react-focus-guards-1.0.1.tgz#1ea7e32092216b946397866199d892f71f7f98ad" @@ -746,6 +801,31 @@ "@babel/runtime" "^7.13.10" "@radix-ui/react-use-layout-effect" "1.0.1" +"@radix-ui/react-menu@2.0.6": + version "2.0.6" + resolved "https://registry.yarnpkg.com/@radix-ui/react-menu/-/react-menu-2.0.6.tgz#2c9e093c1a5d5daa87304b2a2f884e32288ae79e" + integrity sha512-BVkFLS+bUC8HcImkRKPSiVumA1VPOOEC5WBMiT+QAVsPzW1FJzI9KnqgGxVDPBcql5xXrHkD3JOVoXWEXD8SYA== + dependencies: + "@babel/runtime" "^7.13.10" + "@radix-ui/primitive" "1.0.1" + "@radix-ui/react-collection" "1.0.3" + "@radix-ui/react-compose-refs" "1.0.1" + "@radix-ui/react-context" "1.0.1" + "@radix-ui/react-direction" "1.0.1" + "@radix-ui/react-dismissable-layer" "1.0.5" + "@radix-ui/react-focus-guards" "1.0.1" + "@radix-ui/react-focus-scope" "1.0.4" + "@radix-ui/react-id" "1.0.1" + "@radix-ui/react-popper" "1.1.3" + "@radix-ui/react-portal" "1.0.4" + "@radix-ui/react-presence" "1.0.1" + "@radix-ui/react-primitive" "1.0.3" + "@radix-ui/react-roving-focus" "1.0.4" + "@radix-ui/react-slot" "1.0.2" + "@radix-ui/react-use-callback-ref" "1.0.1" + aria-hidden "^1.1.1" + react-remove-scroll "2.5.5" + "@radix-ui/react-popper@1.1.3": version "1.1.3" resolved "https://registry.yarnpkg.com/@radix-ui/react-popper/-/react-popper-1.1.3.tgz#24c03f527e7ac348fabf18c89795d85d21b00b42" @@ -797,6 +877,22 @@ "@radix-ui/react-context" "1.0.1" "@radix-ui/react-primitive" "1.0.3" +"@radix-ui/react-roving-focus@1.0.4": + version "1.0.4" + resolved "https://registry.yarnpkg.com/@radix-ui/react-roving-focus/-/react-roving-focus-1.0.4.tgz#e90c4a6a5f6ac09d3b8c1f5b5e81aab2f0db1974" + integrity sha512-2mUg5Mgcu001VkGy+FfzZyzbmuUWzgWkj3rvv4yu+mLw03+mTzbxZHvfcGyFp2b8EkQeMkpRQ5FiA2Vr2O6TeQ== + dependencies: + "@babel/runtime" "^7.13.10" + "@radix-ui/primitive" "1.0.1" + "@radix-ui/react-collection" "1.0.3" + "@radix-ui/react-compose-refs" "1.0.1" + "@radix-ui/react-context" "1.0.1" + "@radix-ui/react-direction" "1.0.1" + "@radix-ui/react-id" "1.0.1" + "@radix-ui/react-primitive" "1.0.3" + "@radix-ui/react-use-callback-ref" "1.0.1" + "@radix-ui/react-use-controllable-state" "1.0.1" + "@radix-ui/react-separator@^1.0.3": version "1.0.3" resolved "https://registry.yarnpkg.com/@radix-ui/react-separator/-/react-separator-1.0.3.tgz#be5a931a543d5726336b112f465f58585c04c8aa" @@ -813,6 +909,30 @@ "@babel/runtime" "^7.13.10" "@radix-ui/react-compose-refs" "1.0.1" +"@radix-ui/react-toggle-group@^1.0.4": + version "1.0.4" + resolved "https://registry.yarnpkg.com/@radix-ui/react-toggle-group/-/react-toggle-group-1.0.4.tgz#f5b5c8c477831b013bec3580c55e20a68179d6ec" + integrity sha512-Uaj/M/cMyiyT9Bx6fOZO0SAG4Cls0GptBWiBmBxofmDbNVnYYoyRWj/2M/6VCi/7qcXFWnHhRUfdfZFvvkuu8A== + dependencies: + "@babel/runtime" "^7.13.10" + "@radix-ui/primitive" "1.0.1" + "@radix-ui/react-context" "1.0.1" + "@radix-ui/react-direction" "1.0.1" + "@radix-ui/react-primitive" "1.0.3" + "@radix-ui/react-roving-focus" "1.0.4" + "@radix-ui/react-toggle" "1.0.3" + "@radix-ui/react-use-controllable-state" "1.0.1" + +"@radix-ui/react-toggle@1.0.3", "@radix-ui/react-toggle@^1.0.3": + version "1.0.3" + resolved "https://registry.yarnpkg.com/@radix-ui/react-toggle/-/react-toggle-1.0.3.tgz#aecb2945630d1dc5c512997556c57aba894e539e" + integrity sha512-Pkqg3+Bc98ftZGsl60CLANXQBBQ4W3mTFS9EJvNxKMZ7magklKV69/id1mlAlOFDDfHvlCms0fx8fA4CMKDJHg== + dependencies: + "@babel/runtime" "^7.13.10" + "@radix-ui/primitive" "1.0.1" + "@radix-ui/react-primitive" "1.0.3" + "@radix-ui/react-use-controllable-state" "1.0.1" + "@radix-ui/react-use-callback-ref@1.0.1": version "1.0.1" resolved "https://registry.yarnpkg.com/@radix-ui/react-use-callback-ref/-/react-use-callback-ref-1.0.1.tgz#f4bb1f27f2023c984e6534317ebc411fc181107a" @@ -1138,7 +1258,7 @@ "@solana/wallet-standard-core" "^1.1.1" "@solana/wallet-standard-wallet-adapter" "^1.1.2" -"@solana/web3.js@^1.32.0", "@solana/web3.js@^1.56.2", "@solana/web3.js@^1.66.2", "@solana/web3.js@^1.68.0", "@solana/web3.js@^1.73.2", "@solana/web3.js@^1.78.4", "@solana/web3.js@^1.78.8", "@solana/web3.js@^1.90.0": +"@solana/web3.js@^1.32.0", "@solana/web3.js@^1.43.4", "@solana/web3.js@^1.56.2", "@solana/web3.js@^1.66.2", "@solana/web3.js@^1.68.0", "@solana/web3.js@^1.73.2", "@solana/web3.js@^1.78.4", "@solana/web3.js@^1.78.8", "@solana/web3.js@^1.90.0": version "1.91.0" resolved "https://registry.yarnpkg.com/@solana/web3.js/-/web3.js-1.91.0.tgz#a763b0fcca0fa005adce3d02f3a4b6d1b84eccb7" integrity sha512-iqOL9RjNra0TM9BbQWxBRUcZUiNmCJJO+vXLp0GiELUJhbNAoE/K6OV6s+gNEsC13dslvKtfA4mmzRnZNWXtIQ== @@ -4293,6 +4413,13 @@ react-icons@^5.0.1: resolved "https://registry.yarnpkg.com/react-icons/-/react-icons-5.0.1.tgz#1694e11bfa2a2888cab47dcc30154ce90485feee" integrity sha512-WqLZJ4bLzlhmsvme6iFdgO8gfZP17rfjYEJ2m9RsZjZ+cc4k1hTzknEz63YS1MeT50kVzoa1Nz36f4BEx+Wigw== +react-infinite-scroll-component@^6.1.0: + version "6.1.0" + resolved "https://registry.yarnpkg.com/react-infinite-scroll-component/-/react-infinite-scroll-component-6.1.0.tgz#7e511e7aa0f728ac3e51f64a38a6079ac522407f" + integrity sha512-SQu5nCqy8DxQWpnUVLx7V7b7LcA37aM7tvoWjTLZp1dk6EJibM5/4EJKzOnl07/BsM1Y40sKLuqjCwwH/xV0TQ== + dependencies: + throttle-debounce "^2.1.0" + react-is@^16.13.1: version "16.13.1" resolved "https://registry.yarnpkg.com/react-is/-/react-is-16.13.1.tgz#789729a4dc36de2999dc156dd6c1d9c18cea56a4" @@ -4812,6 +4939,11 @@ thenify-all@^1.0.0: dependencies: any-promise "^1.0.0" +throttle-debounce@^2.1.0: + version "2.3.0" + resolved "https://registry.yarnpkg.com/throttle-debounce/-/throttle-debounce-2.3.0.tgz#fd31865e66502071e411817e241465b3e9c372e2" + integrity sha512-H7oLPV0P7+jgvrk+6mwwwBDmxTaxnu9HMXmloNLXwnNO0ZxZ31Orah2n8lU1eMPvsaowP2CX+USCgyovXfdOFQ== + "through@>=2.2.7 <3": version "2.3.8" resolved "https://registry.yarnpkg.com/through/-/through-2.3.8.tgz#0dd4c9ffaabc357960b1b724115d7e0e86a2e1f5" From dde599b8d0a3ff38421c9bf8556697776ac7c260 Mon Sep 17 00:00:00 2001 From: Noah Prince Date: Fri, 3 May 2024 16:13:36 -0500 Subject: [PATCH 02/41] Finish refactor to proxy assignments --- package.json | 2 +- src/components/VoteOptions.tsx | 4 +- src/lib/utils.ts | 4 +- yarn.lock | 72 +++++++++++++++++----------------- 4 files changed, 41 insertions(+), 41 deletions(-) diff --git a/package.json b/package.json index 7aae9f6..be7e9d3 100644 --- a/package.json +++ b/package.json @@ -14,7 +14,7 @@ "@helium/account-fetch-cache-hooks": "^0.7.11", "@helium/helium-react-hooks": "^0.7.11", "@helium/modular-governance-hooks": "^0.0.8", - "@helium/modular-governance-idls": "^0.0.8-next", + "@helium/modular-governance-idls": "^0.0.8-next.19+4fa4c6b", "@helium/organization-sdk": "^0.0.8", "@helium/spl-utils": "file:.yalc/@helium/spl-utils", "@helium/state-controller-sdk": "^0.0.8", diff --git a/src/components/VoteOptions.tsx b/src/components/VoteOptions.tsx index 44b730f..edf2af7 100644 --- a/src/components/VoteOptions.tsx +++ b/src/components/VoteOptions.tsx @@ -1,7 +1,7 @@ "use client"; import { VoteChoiceWithMeta } from "@/lib/types"; -import { useRelinquishVote, useVote } from "@helium/voter-stake-registry-hooks"; +import { useHeliumVsrState, useRelinquishVote, useVote } from "@helium/voter-stake-registry-hooks"; import { PublicKey } from "@solana/web3.js"; import React, { FC, useState } from "react"; import { VoteOption } from "./VoteOption"; @@ -17,6 +17,8 @@ export const VoteOptions: FC<{ }> = ({ choices = [], maxChoicesPerVoter, proposalKey }) => { const [currVote, setCurrVote] = useState(0); const { voteWeights, canVote, vote, loading: voting } = useVote(proposalKey); + const { positions } = useHeliumVsrState() + console.log(positions) const { canRelinquishVote, diff --git a/src/lib/utils.ts b/src/lib/utils.ts index d7ea43b..20c20fe 100644 --- a/src/lib/utils.ts +++ b/src/lib/utils.ts @@ -4,10 +4,9 @@ import { HELIUM_COMMON_LUT, HELIUM_COMMON_LUT_DEVNET, batchInstructionsToTxsWithPriorityFee, - batchParallelInstructionsWithPriorityFee, bulkSendTransactions, sendAndConfirmWithRetry, - toVersionedTx, + toVersionedTx } from "@helium/spl-utils"; import { PositionWithMeta } from "@helium/voter-stake-registry-hooks"; import { Mint } from "@solana/spl-token"; @@ -347,7 +346,6 @@ export const onInstructions = ], } ); - console.log("hehe") await bulkSendTransactions( provider, diff --git a/yarn.lock b/yarn.lock index d734c3b..fc8d49b 100644 --- a/yarn.lock +++ b/yarn.lock @@ -171,7 +171,7 @@ resolved "https://registry.yarnpkg.com/@floating-ui/utils/-/utils-0.2.1.tgz#16308cea045f0fc777b6ff20a9f25474dd8293d2" integrity sha512-9TANp6GPoMtYzQdt54kfAyMmz1+osLlXdg2ENroU7zzrtflTLrrC/lgrIfaSe+Wu0b89GKccT7vxXA0MoAIO+Q== -"@helium/account-fetch-cache-hooks@^0.5.0", "@helium/account-fetch-cache-hooks@^0.7.11", "@helium/account-fetch-cache-hooks@^0.7.6": +"@helium/account-fetch-cache-hooks@^0.5.0", "@helium/account-fetch-cache-hooks@^0.7.11", "@helium/account-fetch-cache-hooks@^0.7.12": version "0.7.11" resolved "https://registry.yarnpkg.com/@helium/account-fetch-cache-hooks/-/account-fetch-cache-hooks-0.7.11.tgz#cc36cc403958de9b9f230bdd1adf2730b9dfd287" integrity sha512-YoUacY5cQJStezTIw3sbmxxsuyH+P0VNtVVGnQ7jA3g+Y20BISWs/NOxf5w3cyAPscadUzTnqwGFiQ2isd9UTg== @@ -180,7 +180,7 @@ "@solana/web3.js" "^1.78.8" react-async-hook "^4.0.0" -"@helium/account-fetch-cache@^0.5.0", "@helium/account-fetch-cache@^0.7.11", "@helium/account-fetch-cache@^0.7.6": +"@helium/account-fetch-cache@^0.5.0", "@helium/account-fetch-cache@^0.7.11", "@helium/account-fetch-cache@^0.7.12": version "0.7.11" resolved "https://registry.yarnpkg.com/@helium/account-fetch-cache/-/account-fetch-cache-0.7.11.tgz#5813509464214cbfbbe42040eb5a48a386e1eefd" integrity sha512-5HPecniIyU/rcUc+Na7gqPRr352Dw8egrfgOzc24PdquVWvbJzrVwfcjrFL2PGEr858uTx0uIzbICrfsaMvEaQ== @@ -212,7 +212,7 @@ "@solana/spl-token" "^0.3.8" "@solana/web3.js" "^1.78.4" -"@helium/anchor-resolvers@^0.7.12", "@helium/anchor-resolvers@^0.7.6": +"@helium/anchor-resolvers@^0.7.12": version "0.7.12" resolved "https://registry.yarnpkg.com/@helium/anchor-resolvers/-/anchor-resolvers-0.7.12.tgz#bb6921d252c7ae4c2788569ddbf68fb57a3f2adc" integrity sha512-KphCkH4IHRMxWq/SSaWRxDVV8b1w8L0tY1qFOvvH/bY+Mr1E8CiVHZCCpdi1c5k/idLDz/wHvHCUSXppFPxdDQ== @@ -220,7 +220,7 @@ "@solana/spl-token" "^0.3.8" "@solana/web3.js" "^1.78.8" -"@helium/circuit-breaker-sdk@^0.7.12", "@helium/circuit-breaker-sdk@^0.7.6": +"@helium/circuit-breaker-sdk@^0.7.12": version "0.7.12" resolved "https://registry.yarnpkg.com/@helium/circuit-breaker-sdk/-/circuit-breaker-sdk-0.7.12.tgz#400d28228f473edc80dc8b0a81ef76cf6a3f3bcd" integrity sha512-4qhoYuW0Aeo9+gg1/z9Fp+IjtS4+v2Wz88imKSHYmpINJ3BNNh7q7zfuYsX/t1utQyaYxhFSejlIIP1yVdlmsw== @@ -231,7 +231,7 @@ bn.js "^5.2.0" bs58 "^4.0.1" -"@helium/helium-react-hooks@^0.5.0", "@helium/helium-react-hooks@^0.7.11", "@helium/helium-react-hooks@^0.7.6": +"@helium/helium-react-hooks@^0.5.0", "@helium/helium-react-hooks@^0.7.11", "@helium/helium-react-hooks@^0.7.12": version "0.7.11" resolved "https://registry.yarnpkg.com/@helium/helium-react-hooks/-/helium-react-hooks-0.7.11.tgz#1d67bf58906f9c8d02ee9e7cb064ba6fb1668f3b" integrity sha512-BD3cjdxn+98h+Cm1Dy5duwAk2RmmxqMkLoRQKZTiXK7X91d80bS3bHep6XbPMGlvHFokyrCcITiWp/ivHRHLLw== @@ -245,7 +245,7 @@ pako "^2.0.3" react-async-hook "^4.0.0" -"@helium/helium-sub-daos-sdk@^0.7.6": +"@helium/helium-sub-daos-sdk@^0.7.12": version "0.7.12" resolved "https://registry.yarnpkg.com/@helium/helium-sub-daos-sdk/-/helium-sub-daos-sdk-0.7.12.tgz#7b38a582e8f195c82f307225e48f3f8dedc24e95" integrity sha512-ziVwT9mo8OK7lWHBXmqy6M9b9UltvphNFNtysdGIWjgnZYYWrZbK6t0PKKciCBg/W9D3SHQzWiiSHfQhHCwCFA== @@ -258,7 +258,7 @@ bn.js "^5.2.0" bs58 "^4.0.1" -"@helium/idls@^0.7.12", "@helium/idls@^0.7.6": +"@helium/idls@^0.7.12": version "0.7.12" resolved "https://registry.yarnpkg.com/@helium/idls/-/idls-0.7.12.tgz#6940c0e4750e8201994e1420b6053e3aefff75d0" integrity sha512-ZcAw904YsbyUqGuejhGq7YaE+S5RZfNTSkV43T/KA/HwEtxCyWRrz8oiKEVEbYXk+XX/InQX5feW/X+3g/w+5g== @@ -282,15 +282,15 @@ "@helium/organization-sdk" "^0.0.8" "@solana/web3.js" "^1.78.4" -"@helium/modular-governance-idls@0.0.8-next.17+7ff2115": - version "0.0.8-next.17" - resolved "https://registry.yarnpkg.com/@helium/modular-governance-idls/-/modular-governance-idls-0.0.8-next.17.tgz#066c639879dec20cb71d727bec38500bc39e79da" - integrity sha512-lFQs2V8kPozwI+wSAHxv0l2QRdia2Dy8HJLF71rabeCHVRIBlyoYkveI9wYopEX1XxAAPtGtGvVeLR4SafLe/w== +"@helium/modular-governance-idls@0.0.8-next.19+4fa4c6b": + version "0.0.8-next.19" + resolved "https://registry.yarnpkg.com/@helium/modular-governance-idls/-/modular-governance-idls-0.0.8-next.19.tgz#517c8b99e0dcd077a6257abff9f8dadf2761fa41" + integrity sha512-vvrqRO58zYSRlDU0SIL6W3eUkHQFfNq4R1hTP+Q8V1Ksik+mGBIidj5jux1+Lxj/wsGKwVxsE+zQ2CYS1K13lg== dependencies: "@coral-xyz/anchor" "^0.28.0" "@solana/web3.js" "^1.78.4" -"@helium/modular-governance-idls@^0.0.8", "@helium/modular-governance-idls@^0.0.8-next", "@helium/modular-governance-idls@^0.0.8-next.17+7ff2115": +"@helium/modular-governance-idls@^0.0.8", "@helium/modular-governance-idls@^0.0.8-next.19+4fa4c6b": version "0.0.8" resolved "https://registry.yarnpkg.com/@helium/modular-governance-idls/-/modular-governance-idls-0.0.8.tgz#b913b28790ff80359c7470d9d6665468f5f1b435" integrity sha512-vmBw9dRUsYKX5ZXiMJaCoKYv5yNBLHpXKb5LI/5cIq0KrGNC4quzMuoMzeehXGgDkIIM9VLnk8YP1Bz8CvUzqA== @@ -298,14 +298,14 @@ "@coral-xyz/anchor" "^0.28.0" "@solana/web3.js" "^1.78.4" -"@helium/nft-proxy-sdk@0.0.8-next.17+7ff2115": - version "0.0.8-next.17" - resolved "https://registry.yarnpkg.com/@helium/nft-proxy-sdk/-/nft-proxy-sdk-0.0.8-next.17.tgz#50ea6f3a9f8253035527b0a4cecdc2cd78c4ce81" - integrity sha512-Uphw4HorYpAJmQ/Kf3ggR85/Vqe1ueZpzA8oRtMiwQpo+67pcAHplIVuwQEVkHZ5S23XwL5dNGDIZyBA9Khg0w== +"@helium/nft-proxy-sdk@0.0.8-next.19+4fa4c6b": + version "0.0.8-next.19" + resolved "https://registry.yarnpkg.com/@helium/nft-proxy-sdk/-/nft-proxy-sdk-0.0.8-next.19.tgz#9e3d0ecc069e50ed6710fe9540e800d5ba264920" + integrity sha512-uwcE8GVAvScGIZtdG+M08Ck+wxYkS+KSnqun9tW2MiXS0IvbXLAiDxvYKiPswOYiaHKn+XGhEkhyyqtU1fbLDA== dependencies: "@coral-xyz/anchor" "^0.28.0" "@helium/anchor-resolvers" "^0.2.17" - "@helium/modular-governance-idls" "^0.0.8-next.17+7ff2115" + "@helium/modular-governance-idls" "^0.0.8-next.19+4fa4c6b" "@solana/spl-token" "^0.3.8" "@helium/organization-sdk@^0.0.8": @@ -327,13 +327,13 @@ "@helium/anchor-resolvers" "^0.5.0" "@helium/modular-governance-idls" "^0.0.8" -"@helium/spl-utils@^0.7.6", "@helium/spl-utils@file:.yalc/@helium/spl-utils": - version "0.7.6" +"@helium/spl-utils@^0.7.12", "@helium/spl-utils@file:.yalc/@helium/spl-utils": + version "0.7.12" dependencies: "@coral-xyz/anchor" "^0.28.0" - "@helium/account-fetch-cache" "^0.7.6" + "@helium/account-fetch-cache" "^0.7.12" "@helium/address" "^4.10.2" - "@helium/anchor-resolvers" "^0.7.6" + "@helium/anchor-resolvers" "^0.7.12" "@metaplex-foundation/mpl-token-metadata" "^2.10.0" "@solana/spl-account-compression" "^0.1.7" "@solana/spl-token" "^0.3.8" @@ -365,18 +365,18 @@ bs58 "^4.0.1" "@helium/voter-stake-registry-hooks@file:.yalc/@helium/voter-stake-registry-hooks": - version "0.7.6" + version "0.7.12" dependencies: "@coral-xyz/anchor" "^0.28.0" - "@helium/account-fetch-cache" "^0.7.6" - "@helium/account-fetch-cache-hooks" "^0.7.6" - "@helium/circuit-breaker-sdk" "^0.7.6" - "@helium/helium-react-hooks" "^0.7.6" - "@helium/helium-sub-daos-sdk" "^0.7.6" + "@helium/account-fetch-cache" "^0.7.12" + "@helium/account-fetch-cache-hooks" "^0.7.12" + "@helium/circuit-breaker-sdk" "^0.7.12" + "@helium/helium-react-hooks" "^0.7.12" + "@helium/helium-sub-daos-sdk" "^0.7.12" "@helium/modular-governance-hooks" "^0.0.8" - "@helium/modular-governance-idls" "0.0.8-next.17+7ff2115" - "@helium/spl-utils" "^0.7.6" - "@helium/voter-stake-registry-sdk" "^0.7.6" + "@helium/modular-governance-idls" "0.0.8-next.19+4fa4c6b" + "@helium/spl-utils" "^0.7.12" + "@helium/voter-stake-registry-sdk" "^0.7.12" "@solana/wallet-adapter-base" "^0.9.22" "@solana/wallet-adapter-react" "^0.15.32" "@solana/web3.js" "^1.78.8" @@ -384,14 +384,14 @@ bs58 "^4.0.1" react-async-hook "^4.0.0" -"@helium/voter-stake-registry-sdk@^0.7.12", "@helium/voter-stake-registry-sdk@^0.7.6", "@helium/voter-stake-registry-sdk@file:.yalc/@helium/voter-stake-registry-sdk": - version "0.7.6" +"@helium/voter-stake-registry-sdk@^0.7.12", "@helium/voter-stake-registry-sdk@file:.yalc/@helium/voter-stake-registry-sdk": + version "0.7.12" dependencies: "@coral-xyz/anchor" "^0.28.0" - "@helium/anchor-resolvers" "^0.7.6" - "@helium/idls" "^0.7.6" - "@helium/nft-proxy-sdk" "0.0.8-next.17+7ff2115" - "@helium/spl-utils" "^0.7.6" + "@helium/anchor-resolvers" "^0.7.12" + "@helium/idls" "^0.7.12" + "@helium/nft-proxy-sdk" "0.0.8-next.19+4fa4c6b" + "@helium/spl-utils" "^0.7.12" "@metaplex-foundation/mpl-token-metadata" "^2.10.0" "@solana/spl-token" "^0.3.8" bn.js "^5.2.0" From 29da73b9dd7ae42cb6994991567c0ad0710a7f23 Mon Sep 17 00:00:00 2001 From: bry Date: Mon, 13 May 2024 09:55:43 -0500 Subject: [PATCH 03/41] Remove instances of useHeliumVsr for useGovernance --- bin/helium-vote.ts | 2 +- .../proposals/realm/[proposalKey]/page.tsx | 1 - src/app/[network]/proxies/page.tsx | 4 +- src/components/AssignProxyModal.tsx | 8 +-- src/components/Proposal.tsx | 2 +- src/components/Proxies.tsx | 55 +++++++++++++++---- src/components/ProxyButton.tsx | 4 +- src/components/ProxyProfile.tsx | 14 ++--- src/components/RevokeProxyButton.tsx | 8 +-- src/components/RevokeProxyModal.tsx | 10 ++-- src/components/VoteHistory.tsx | 5 +- src/components/VoteOptions.tsx | 4 +- src/providers/GovernanceProvider.tsx | 8 +-- 13 files changed, 70 insertions(+), 55 deletions(-) diff --git a/bin/helium-vote.ts b/bin/helium-vote.ts index 4638214..882aa03 100755 --- a/bin/helium-vote.ts +++ b/bin/helium-vote.ts @@ -1,4 +1,4 @@ -#!/usr/bin/env ts-node +#!/usr/bin/env npx ts-node const { hideBin } = require("yargs/helpers"); diff --git a/src/app/[network]/proposals/realm/[proposalKey]/page.tsx b/src/app/[network]/proposals/realm/[proposalKey]/page.tsx index 21df4cd..a3cb455 100644 --- a/src/app/[network]/proposals/realm/[proposalKey]/page.tsx +++ b/src/app/[network]/proposals/realm/[proposalKey]/page.tsx @@ -36,7 +36,6 @@ const RealmProposalPage = async ({ const proposal: IRealmProposal = fetchRealmProposal(proposalKey); const content = await getContent(proposal.gist); - console.log(content); return ( <>
diff --git a/src/app/[network]/proxies/page.tsx b/src/app/[network]/proxies/page.tsx index e3899b4..e55ddfa 100644 --- a/src/app/[network]/proxies/page.tsx +++ b/src/app/[network]/proxies/page.tsx @@ -14,14 +14,14 @@ export const generateMetadata = async ({ params }: VotersPageParams) => { return formMetaTags({ title: `${network.toUpperCase()} Positions`, - url: `https://heliumvote.com/${network}/voters`, + url: `https://heliumvote.com/${network}/proxies`, }); }; export default async function PositionsPage() { return ( <> -
+
); diff --git a/src/components/AssignProxyModal.tsx b/src/components/AssignProxyModal.tsx index 80e4b89..70e115d 100644 --- a/src/components/AssignProxyModal.tsx +++ b/src/components/AssignProxyModal.tsx @@ -1,8 +1,5 @@ import { useMint } from "@helium/helium-react-hooks"; -import { - PositionWithMeta, - useHeliumVsrState, -} from "@helium/voter-stake-registry-hooks"; +import { PositionWithMeta } from "@helium/voter-stake-registry-hooks"; import { PublicKey } from "@solana/web3.js"; import BN from "bn.js"; import React, { useEffect, useMemo, useState } from "react"; @@ -13,6 +10,7 @@ import { Loader2 } from "lucide-react"; import { useMetaplexMetadata } from "@/hooks/useMetaplexMetadata"; import { humanReadable } from "@/lib/utils"; import { Button } from "./ui/button"; +import { useGovernance } from "@/providers/GovernanceProvider"; interface AssignProxyModalProps { onSubmit: (args: { @@ -28,7 +26,7 @@ export const AssignProxyModal: React.FC< > = ({ onSubmit, wallet, children }) => { const [open, setOpen] = useState(false); - const { loading, positions, mint } = useHeliumVsrState(); + const { loading, positions, mint } = useGovernance(); const [selectedPositions, setSelectedPositions] = useState>( new Set() ); diff --git a/src/components/Proposal.tsx b/src/components/Proposal.tsx index 97d0bf3..e883135 100644 --- a/src/components/Proposal.tsx +++ b/src/components/Proposal.tsx @@ -323,7 +323,7 @@ export const Proposal: FC<{ : "Voting has been Cancelled"}

- + ([]); @@ -57,10 +61,35 @@ export function Proxies() { } }, [voteService?.registrar.toBase58()]); + const handleBrowseProxies = () => { + // TODO: Implement + }; + return (
-

Browse Proxies

+
+

Browse Proxies

+
+
+ + +
+ +
+

{proxy.name}

- {ellipsisMiddle(proxy.wallet)} + + {ellipsisMiddle(proxy.wallet)} +
diff --git a/src/components/ProxyButton.tsx b/src/components/ProxyButton.tsx index e602cab..38e71cf 100644 --- a/src/components/ProxyButton.tsx +++ b/src/components/ProxyButton.tsx @@ -1,9 +1,9 @@ import React, { useMemo } from "react"; import { useWallet } from "@solana/wallet-adapter-react"; -import { useHeliumVsrState } from "@helium/voter-stake-registry-hooks"; import { PublicKey } from "@solana/web3.js"; import { Button } from "./ui/button"; import { Loader2 } from "lucide-react"; +import { useGovernance } from "@/providers/GovernanceProvider"; export const ProxyButton: React.FC<{ className?: string; @@ -11,7 +11,7 @@ export const ProxyButton: React.FC<{ isLoading?: boolean; }> = ({ className = "", onClick, isLoading = false }) => { const { connected } = useWallet(); - const { loading, positions } = useHeliumVsrState(); + const { loading, positions } = useGovernance(); const unproxiedPositions = useMemo( () => diff --git a/src/components/ProxyProfile.tsx b/src/components/ProxyProfile.tsx index 2779511..35c090a 100644 --- a/src/components/ProxyProfile.tsx +++ b/src/components/ProxyProfile.tsx @@ -1,10 +1,10 @@ "use client"; import { ellipsisMiddle, humanReadable } from "@/lib/utils"; +import { useGovernance } from "@/providers/GovernanceProvider"; import { useMint } from "@helium/helium-react-hooks"; import { useAssignProxies, - useHeliumVsrState, useProxiedTo, useUnassignProxies, } from "@helium/voter-stake-registry-hooks"; @@ -12,19 +12,17 @@ import { EnhancedProxy, WithRank } from "@helium/voter-stake-registry-sdk"; import { PublicKey } from "@solana/web3.js"; import BN from "bn.js"; import Image from "next/image"; +import Link from "next/link"; import { useMemo, useState } from "react"; +import { FaArrowLeft } from "react-icons/fa6"; import ReactMarkdown from "react-markdown"; import { AssignProxyModal } from "./AssignProxyModal"; +import { ContentSection } from "./ContentSection"; import { ProxyButton } from "./ProxyButton"; import { RevokeProxyButton } from "./RevokeProxyButton"; import { RevokeProxyModal } from "./RevokeProxyModal"; -import VoteHistory from "./VoteHistory"; -import { ContentSection } from "./ContentSection"; import { Card, CardContent, CardHeader } from "./ui/card"; -import { FaArrowLeft } from "react-icons/fa6"; -import Link from "next/link"; -import { useNetwork } from "@/hooks/useNetwork"; -import { useGovernance } from "@/providers/GovernanceProvider"; +import VoteHistory from "./VoteHistory"; export function ProxyProfile({ proxy, @@ -35,7 +33,7 @@ export function ProxyProfile({ detail: string; image: string; }) { - const { mint } = useHeliumVsrState(); + const { mint } = useGovernance(); const { info: mintAcc } = useMint(mint); const decimals = mintAcc?.decimals; const [revokeProxyModalVisible, setRevokeProxyModalVisible] = useState(false); diff --git a/src/components/RevokeProxyButton.tsx b/src/components/RevokeProxyButton.tsx index e628dd2..a982207 100644 --- a/src/components/RevokeProxyButton.tsx +++ b/src/components/RevokeProxyButton.tsx @@ -1,9 +1,9 @@ -import React, { useMemo } from "react"; +import { useGovernance } from "@/providers/GovernanceProvider"; import { useWallet } from "@solana/wallet-adapter-react"; -import { useHeliumVsrState } from "@helium/voter-stake-registry-hooks"; import { PublicKey } from "@solana/web3.js"; -import { Button } from "./ui/button"; import { Loader2 } from "lucide-react"; +import React, { useMemo } from "react"; +import { Button } from "./ui/button"; export const RevokeProxyButton: React.FC<{ className?: string; @@ -12,7 +12,7 @@ export const RevokeProxyButton: React.FC<{ wallet?: PublicKey; }> = ({ wallet, className = "", onClick, isLoading = false }) => { const { connected } = useWallet(); - const { loading, positions } = useHeliumVsrState(); + const { loading, positions } = useGovernance(); const proxiedPositions = useMemo( () => diff --git a/src/components/RevokeProxyModal.tsx b/src/components/RevokeProxyModal.tsx index 6871ff0..b92e5fc 100644 --- a/src/components/RevokeProxyModal.tsx +++ b/src/components/RevokeProxyModal.tsx @@ -1,7 +1,5 @@ -import { - PositionWithMeta, - useHeliumVsrState, -} from "@helium/voter-stake-registry-hooks"; +import { useGovernance } from "@/providers/GovernanceProvider"; +import { PositionWithMeta } from "@helium/voter-stake-registry-hooks"; import { DialogContent } from "@radix-ui/react-dialog"; import { PublicKey } from "@solana/web3.js"; import { Loader2 } from "lucide-react"; @@ -24,7 +22,7 @@ export const RevokeProxyModal: React.FC = ({ onSubmit, wallet, }) => { - const { loading, positions, mint } = useHeliumVsrState(); + const { loading, positions, mint } = useGovernance(); const [selectedPositions, setSelectedPositions] = useState>( new Set() ); @@ -58,7 +56,7 @@ export const RevokeProxyModal: React.FC = ({ onClose(); } catch (e: any) { setIsSubmitting(false); - toast(e.message || "Unable to Revoke proxy") + toast(e.message || "Unable to Revoke proxy"); } }; diff --git a/src/components/VoteHistory.tsx b/src/components/VoteHistory.tsx index 4bf20e4..9419809 100644 --- a/src/components/VoteHistory.tsx +++ b/src/components/VoteHistory.tsx @@ -1,6 +1,6 @@ import { humanReadable } from "@/lib/utils"; +import { useGovernance } from "@/providers/GovernanceProvider"; import { useMint } from "@helium/helium-react-hooks"; -import { useHeliumVsrState } from "@helium/voter-stake-registry-hooks"; import { ProposalWithVotes } from "@helium/voter-stake-registry-sdk"; import { PublicKey } from "@solana/web3.js"; import BN from "bn.js"; @@ -8,7 +8,7 @@ import { useEffect, useState } from "react"; import InfiniteScroll from "react-infinite-scroll-component"; export default function VoteHistory({ wallet }: { wallet: PublicKey }) { - const { voteService, mint } = useHeliumVsrState(); + const { voteService, mint } = useGovernance(); const { info: mintAcc } = useMint(mint); const decimals = mintAcc?.decimals; const [voteHistories, setVoteHistory] = useState([]); @@ -79,7 +79,6 @@ export default function VoteHistory({ wallet }: { wallet: PublicKey }) { const totalWeight = voteHistory.choices.reduce((acc, c) => { return acc.add(new BN(c.weight)); }, new BN(0)); - console.log(totalWeight.toNumber()); const percent = voteHistory.votes[0] ? (100 * Number(voteHistory.votes[0].weight)) / totalWeight.toNumber() diff --git a/src/components/VoteOptions.tsx b/src/components/VoteOptions.tsx index edf2af7..44b730f 100644 --- a/src/components/VoteOptions.tsx +++ b/src/components/VoteOptions.tsx @@ -1,7 +1,7 @@ "use client"; import { VoteChoiceWithMeta } from "@/lib/types"; -import { useHeliumVsrState, useRelinquishVote, useVote } from "@helium/voter-stake-registry-hooks"; +import { useRelinquishVote, useVote } from "@helium/voter-stake-registry-hooks"; import { PublicKey } from "@solana/web3.js"; import React, { FC, useState } from "react"; import { VoteOption } from "./VoteOption"; @@ -17,8 +17,6 @@ export const VoteOptions: FC<{ }> = ({ choices = [], maxChoicesPerVoter, proposalKey }) => { const [currVote, setCurrVote] = useState(0); const { voteWeights, canVote, vote, loading: voting } = useVote(proposalKey); - const { positions } = useHeliumVsrState() - console.log(positions) const { canRelinquishVote, diff --git a/src/providers/GovernanceProvider.tsx b/src/providers/GovernanceProvider.tsx index f00ed0b..9b08aad 100644 --- a/src/providers/GovernanceProvider.tsx +++ b/src/providers/GovernanceProvider.tsx @@ -14,13 +14,7 @@ import { import { getRegistrarKey } from "@helium/voter-stake-registry-sdk"; import { PublicKey } from "@solana/web3.js"; import { useParams } from "next/navigation"; -import { - FC, - ReactNode, - createContext, - useContext, - useMemo, -} from "react"; +import { FC, ReactNode, createContext, useContext, useMemo } from "react"; import { useAsync } from "react-async-hook"; type GovNetwork = "hnt" | "mobile" | "iot"; From 02d2503137ff48a86c5b59f0e6f9dc59600690b1 Mon Sep 17 00:00:00 2001 From: bry Date: Mon, 13 May 2024 09:59:45 -0500 Subject: [PATCH 04/41] Propposal takes 100% width on small screens now --- src/components/Proposal.tsx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/components/Proposal.tsx b/src/components/Proposal.tsx index e883135..b80b49f 100644 --- a/src/components/Proposal.tsx +++ b/src/components/Proposal.tsx @@ -323,7 +323,7 @@ export const Proposal: FC<{ : "Voting has been Cancelled"}

- + Date: Mon, 13 May 2024 11:04:55 -0500 Subject: [PATCH 05/41] rework some styles on proxies and nuke hard coded color value --- src/app/globals.css | 2 +- src/components/Header.tsx | 136 ++++++++++++++++------------------- src/components/Positions.tsx | 33 +++++---- src/components/Proxies.tsx | 81 ++++++++++----------- src/components/SubNav.tsx | 71 ++++++++++-------- src/components/ui/toggle.tsx | 19 ++--- tailwind.config.ts | 1 - 7 files changed, 170 insertions(+), 173 deletions(-) diff --git a/src/app/globals.css b/src/app/globals.css index 1370407..287f217 100644 --- a/src/app/globals.css +++ b/src/app/globals.css @@ -46,7 +46,7 @@ --secondary: 213 19% 32%; --secondary-foreground: 210 40% 98%; --muted: 217.2 32.6% 17.5%; - --muted-foreground: 215 20.2% 65.1%; + --muted-foreground: 213 19% 56%; --accent: 217.2 32.6% 17.5%; --accent-foreground: 210 40% 98%; --destructive: 0 62.8% 30.6%; diff --git a/src/components/Header.tsx b/src/components/Header.tsx index 1bacb75..b20e664 100644 --- a/src/components/Header.tsx +++ b/src/components/Header.tsx @@ -12,81 +12,71 @@ export const Header: FC<{ hideHero?: boolean; hideNav?: boolean; route?: string; -}> = ({ hideHero = false, hideNav = false, route = undefined }) => { - const isOnPositions = route?.includes("/positions"); - - return ( -
-
- - -
- Helium Governance Logo -
-
- Helium Governance Logo -
- -
- - +}> = ({ hideHero = false, hideNav = false, route = undefined }) => ( +
+
+ + +
+ Helium Governance Logo
-
-
- {!hideHero && ( - -
-
-
-

- Helium -
- Governance -

-

- Where the community comes together to make decisions on - the network. -

-
+
+ Helium Governance Logo +
+ +
+ + +
+ +
+ {!hideHero && ( + +
+
+
+

+ Helium +
+ Governance +

+

+ Where the community comes together to make decisions on + the network. +

+
-
- {/* eslint-disable-next-line @next/next/no-img-element */} - hero-image -
+
+ {/* eslint-disable-next-line @next/next/no-img-element */} + hero-image
- - )} - {!hideNav && ( -
- - - {isOnPositions ? ( -
- -
- ) : ( - - )} -
- )} -
- ); -}; + + )} + {!hideNav && ( +
+ + + + +
+ )} +
+); diff --git a/src/components/Positions.tsx b/src/components/Positions.tsx index d627025..1819dc6 100644 --- a/src/components/Positions.tsx +++ b/src/components/Positions.tsx @@ -132,21 +132,24 @@ export const Positions: FC = () => {

All Positions

- {network === "hnt" && ( - - )} +
+ + {network === "hnt" && ( + + )} +
{!notDecayedPositions?.length && !decayedPositions?.length && ( diff --git a/src/components/Proxies.tsx b/src/components/Proxies.tsx index a8bc184..8743319 100644 --- a/src/components/Proxies.tsx +++ b/src/components/Proxies.tsx @@ -22,7 +22,7 @@ import { useGovernance } from "@/providers/GovernanceProvider"; function CardDetail({ title, value }: { title: string; value: string }) { return (
- + {title} {value} @@ -85,7 +85,7 @@ export function Proxies() { disabled={!proxies.length} onClick={handleBrowseProxies} > - + Browse
@@ -104,49 +104,44 @@ export function Proxies() {
{proxies.map((proxy, index) => ( - -
- Assigned {proxy.numAssignments} positions -
-
-
- - - {proxy.name} - -
-

{proxy.name}

- - {ellipsisMiddle(proxy.wallet)} - -
+ +
+ + + {proxy.name} + +
+

{proxy.name}

+ + {ellipsisMiddle(proxy.wallet)} +
+
-
- - - -
+
+ + +
diff --git a/src/components/SubNav.tsx b/src/components/SubNav.tsx index c19dbbf..5b890ba 100644 --- a/src/components/SubNav.tsx +++ b/src/components/SubNav.tsx @@ -10,6 +10,8 @@ import { LuScrollText } from "react-icons/lu"; import { DropdownMenu, DropdownMenuContent, + DropdownMenuGroup, + DropdownMenuItem, DropdownMenuTrigger, } from "./ui/dropdown-menu"; import { Button } from "./ui/button"; @@ -31,7 +33,12 @@ export const SubNav: React.FC = () => { return (
- + @@ -60,39 +67,41 @@ export const SubNav: React.FC = () => {
- - - - - - - Proposals - - - - - - Proxies - - - - - - Positions - - + + + + + + Proposals + + + + + + Proxies + + + + + + Positions + + +
diff --git a/src/components/ui/toggle.tsx b/src/components/ui/toggle.tsx index 1adebf9..5895834 100644 --- a/src/components/ui/toggle.tsx +++ b/src/components/ui/toggle.tsx @@ -1,10 +1,10 @@ -"use client" +"use client"; -import * as React from "react" -import * as TogglePrimitive from "@radix-ui/react-toggle" -import { cva, type VariantProps } from "class-variance-authority" +import * as React from "react"; +import * as TogglePrimitive from "@radix-ui/react-toggle"; +import { cva, type VariantProps } from "class-variance-authority"; -import { cn } from "@/lib/utils" +import { cn } from "@/lib/utils"; const toggleVariants = cva( "inline-flex items-center justify-center rounded-md text-sm rounded-full py-0 px-4 font-medium ring-offset-background transition-colors hover:bg-muted hover:text-muted-foreground focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring focus-visible:ring-offset-2 disabled:pointer-events-none disabled:opacity-50 data-[state=on]:bg-black/30 data-[state=on]:text-accent-foreground", @@ -12,6 +12,7 @@ const toggleVariants = cva( variants: { variant: { default: "bg-transparent", + subNav: "bg-transparent hover:text-muted-foreground hover:bg-black/15", outline: "border border-input bg-transparent hover:bg-accent hover:text-accent-foreground", }, @@ -26,7 +27,7 @@ const toggleVariants = cva( size: "default", }, } -) +); const Toggle = React.forwardRef< React.ElementRef, @@ -38,8 +39,8 @@ const Toggle = React.forwardRef< className={cn(toggleVariants({ variant, size, className }))} {...props} /> -)) +)); -Toggle.displayName = TogglePrimitive.Root.displayName +Toggle.displayName = TogglePrimitive.Root.displayName; -export { Toggle, toggleVariants } +export { Toggle, toggleVariants }; diff --git a/tailwind.config.ts b/tailwind.config.ts index 0718ff6..a543f34 100644 --- a/tailwind.config.ts +++ b/tailwind.config.ts @@ -113,7 +113,6 @@ const config = { card: { DEFAULT: "hsl(var(--card))", foreground: "hsl(var(--card-foreground))", - muted: "#28303B", }, }, borderRadius: { From 7da543b3738fc2b5d2e41a52420db7a94e3754f2 Mon Sep 17 00:00:00 2001 From: bry Date: Tue, 14 May 2024 12:53:18 -0500 Subject: [PATCH 06/41] change tab title --- src/app/[network]/proxies/page.tsx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/app/[network]/proxies/page.tsx b/src/app/[network]/proxies/page.tsx index e55ddfa..717dcb0 100644 --- a/src/app/[network]/proxies/page.tsx +++ b/src/app/[network]/proxies/page.tsx @@ -13,7 +13,7 @@ export const generateMetadata = async ({ params }: VotersPageParams) => { const { network } = params; return formMetaTags({ - title: `${network.toUpperCase()} Positions`, + title: `${network.toUpperCase()} Proxies`, url: `https://heliumvote.com/${network}/proxies`, }); }; From da79de1b0d85bb8d595dfc27004e817de7252138 Mon Sep 17 00:00:00 2001 From: Noah Prince Date: Fri, 24 May 2024 15:11:54 -0700 Subject: [PATCH 07/41] WIP --- package.json | 4 + public/images/hntWhite.svg | 5 + public/images/iotWhite.svg | 3 + public/images/mobileWhite.svg | 3 + src/app/[network]/proxies/[wallet]/page.tsx | 2 +- src/components/AssignProxyModal.tsx | 155 ++++++++++-------- src/components/CreatePositionModal.tsx | 76 +++------ src/components/Markdown.tsx | 65 ++++++++ src/components/NetworkSelect.tsx | 46 ++++++ src/components/PositionPreview.tsx | 69 ++++++++ src/components/Proposal.tsx | 64 +------- src/components/Proxies.tsx | 123 +++++++------- src/components/ProxyButton.tsx | 26 +-- src/components/ProxyProfile.tsx | 43 ++--- src/components/ProxySearch.tsx | 88 ++++++++++ src/components/RevokeProxyButton.tsx | 30 ++-- src/components/RevokeProxyModal.tsx | 61 +++---- src/components/SubNav.tsx | 17 +- src/components/VoteHistory.tsx | 65 +++++++- src/components/ui/autocomplete.tsx | 168 ++++++++++++++++++++ src/components/ui/button.tsx | 5 +- src/components/ui/command.tsx | 155 ++++++++++++++++++ src/components/ui/dropdown-menu.tsx | 74 ++++----- src/components/ui/popover.tsx | 31 ++++ src/components/ui/select.tsx | 160 +++++++++++++++++++ src/components/ui/slider.tsx | 28 ++++ yarn.lock | 93 ++++++++++- 27 files changed, 1287 insertions(+), 372 deletions(-) create mode 100644 public/images/hntWhite.svg create mode 100644 public/images/iotWhite.svg create mode 100644 public/images/mobileWhite.svg create mode 100644 src/components/Markdown.tsx create mode 100644 src/components/NetworkSelect.tsx create mode 100644 src/components/PositionPreview.tsx create mode 100644 src/components/ProxySearch.tsx create mode 100644 src/components/ui/autocomplete.tsx create mode 100644 src/components/ui/command.tsx create mode 100644 src/components/ui/popover.tsx create mode 100644 src/components/ui/select.tsx create mode 100644 src/components/ui/slider.tsx diff --git a/package.json b/package.json index be7e9d3..46ff12c 100644 --- a/package.json +++ b/package.json @@ -28,8 +28,11 @@ "@radix-ui/react-dialog": "^1.0.5", "@radix-ui/react-dropdown-menu": "^2.0.6", "@radix-ui/react-hover-card": "^1.0.7", + "@radix-ui/react-popover": "^1.0.7", "@radix-ui/react-progress": "^1.0.3", + "@radix-ui/react-select": "^2.0.0", "@radix-ui/react-separator": "^1.0.3", + "@radix-ui/react-slider": "^1.1.2", "@radix-ui/react-slot": "^1.0.2", "@radix-ui/react-toggle": "^1.0.3", "@radix-ui/react-toggle-group": "^1.0.4", @@ -45,6 +48,7 @@ "class-variance-authority": "^0.7.0", "classnames": "^2.5.1", "clsx": "^2.1.0", + "cmdk": "^1.0.0", "date-fns": "^3.3.1", "lucide-react": "^0.323.0", "markdown-it": "^14.0.0", diff --git a/public/images/hntWhite.svg b/public/images/hntWhite.svg new file mode 100644 index 0000000..cddf61f --- /dev/null +++ b/public/images/hntWhite.svg @@ -0,0 +1,5 @@ + + + + + diff --git a/public/images/iotWhite.svg b/public/images/iotWhite.svg new file mode 100644 index 0000000..f9cea50 --- /dev/null +++ b/public/images/iotWhite.svg @@ -0,0 +1,3 @@ + + + diff --git a/public/images/mobileWhite.svg b/public/images/mobileWhite.svg new file mode 100644 index 0000000..0e24e8b --- /dev/null +++ b/public/images/mobileWhite.svg @@ -0,0 +1,3 @@ + + + \ No newline at end of file diff --git a/src/app/[network]/proxies/[wallet]/page.tsx b/src/app/[network]/proxies/[wallet]/page.tsx index d2774a8..4fc93b5 100644 --- a/src/app/[network]/proxies/[wallet]/page.tsx +++ b/src/app/[network]/proxies/[wallet]/page.tsx @@ -18,7 +18,7 @@ export default async function ProxyPage({ return ( <> -
+
); diff --git a/src/components/AssignProxyModal.tsx b/src/components/AssignProxyModal.tsx index 70e115d..0c0ce09 100644 --- a/src/components/AssignProxyModal.tsx +++ b/src/components/AssignProxyModal.tsx @@ -1,16 +1,16 @@ -import { useMint } from "@helium/helium-react-hooks"; +import { useGovernance } from "@/providers/GovernanceProvider"; import { PositionWithMeta } from "@helium/voter-stake-registry-hooks"; import { PublicKey } from "@solana/web3.js"; import BN from "bn.js"; +import { Loader2 } from "lucide-react"; import React, { useEffect, useMemo, useState } from "react"; -import { getMinDurationFmt, getTimeLeftFromNowFmt } from "@/lib/dateTools"; import { toast } from "sonner"; -import { Dialog, DialogContent, DialogTrigger } from "./ui/dialog"; -import { Loader2 } from "lucide-react"; -import { useMetaplexMetadata } from "@/hooks/useMetaplexMetadata"; -import { humanReadable } from "@/lib/utils"; +import { NetworkSelect } from "./NetworkSelect"; +import { PositionPreview } from "./PositionPreview"; +import { ProxySearch } from "./ProxySearch"; import { Button } from "./ui/button"; -import { useGovernance } from "@/providers/GovernanceProvider"; +import { Dialog, DialogContent, DialogTrigger } from "./ui/dialog"; +import { Slider } from "./ui/slider"; interface AssignProxyModalProps { onSubmit: (args: { @@ -25,8 +25,10 @@ export const AssignProxyModal: React.FC< React.PropsWithChildren > = ({ onSubmit, wallet, children }) => { const [open, setOpen] = useState(false); + const { network: networkDefault } = useGovernance(); + const [network, setNetwork] = useState(networkDefault); - const { loading, positions, mint } = useGovernance(); + const { loading, positions } = useGovernance(); const [selectedPositions, setSelectedPositions] = useState>( new Set() ); @@ -34,7 +36,7 @@ export const AssignProxyModal: React.FC< const unproxiedPositions = useMemo( () => positions?.filter( - (p) => !p.proxy || p.proxy.nextOwner.equals(PublicKey.default) + (p) => !p.proxy || p.proxy.nextVoter.equals(PublicKey.default) ) || [], [positions] ); @@ -103,13 +105,31 @@ export const AssignProxyModal: React.FC< setOpen(!open); }; + const selectedAll = unproxiedPositions.length === selectedPositions.size; + return ( {children} -

- Assign Voting Proxy -

+
+

+ Assign Proxy +

+
+ Enter the amount of voting power and cycle period you’d like to + assign the selected voter +
+
+ + + setNetwork(network as "hnt" | "mobile" | "iot") + } + /> + + + {loading ? ( <>
@@ -120,39 +140,29 @@ export const AssignProxyModal: React.FC<
) : ( -
-
-
- Once you assign this wallet as your proxy, it will be able to - use your positions to vote on HIPs. You can override these votes - or revoke the proxy at any point. The proxy will expire at the - set expiration date. -
-
-
- Proxy assignments are reset August 1st yearly. +
+
+
+
Assign Positions
+
-
-
-

Expiration Time

- { - setSelectedDays(parseInt(e.target.value)); - }} - /> -
- {selectedDays} days ( - {new Date(expirationTime * 1000).toLocaleString()}) -
-
-
-

Positions to Assign

{unproxiedPositions?.map((position) => { return ( @@ -162,7 +172,6 @@ export const AssignProxyModal: React.FC< position.pubkey.toBase58() )} position={position} - mint={mint!} onClick={() => { setSelectedPositions((sel) => { const key = position.pubkey.toBase58(); @@ -180,6 +189,25 @@ export const AssignProxyModal: React.FC< ); })}
+
+

Expiration Time

+ { + setSelectedDays(e[0]); + }} + /> +
+ {new Date(expirationTime * 1000).toLocaleString()} +
+
+
+ Your assigned proxy will expire by Aug 1 of each year by default, + however you may select any date prior to this epoch date. +
{!wallet && (

Wallet to Assign

@@ -194,17 +222,21 @@ export const AssignProxyModal: React.FC< )}
)} -
+
+ -
@@ -216,35 +248,20 @@ export const PositionItem = ({ position, isSelected, onClick, - mint, }: { position: PositionWithMeta; isSelected: boolean; - mint: PublicKey; onClick: () => void; }) => { - const { info: mintAcc } = useMint(mint); - const { symbol } = useMetaplexMetadata(mint); - const { lockup } = position; - const lockupKind = Object.keys(lockup.kind)[0] as string; - const isConstant = lockupKind === "constant"; - const lockedTokens = - mintAcc && humanReadable(position.amountDepositedNative, mintAcc.decimals); - const lockupTime = isConstant - ? getMinDurationFmt(position.lockup.startTs, position.lockup.endTs) - : getTimeLeftFromNowFmt(position.lockup.endTs); - const lockupLabel = isConstant ? "duration" : "time left"; - const fullLabel = `${lockedTokens} ${symbol} locked with ${lockupTime} ${lockupLabel}`; - return (
- {fullLabel} +
); }; diff --git a/src/components/CreatePositionModal.tsx b/src/components/CreatePositionModal.tsx index 5357f24..974d336 100644 --- a/src/components/CreatePositionModal.tsx +++ b/src/components/CreatePositionModal.tsx @@ -1,18 +1,20 @@ "use client"; -import { daysToSecs, getMinDurationFmt, onInstructions } from "@/lib/utils"; +import { daysToSecs, onInstructions } from "@/lib/utils"; import { useGovernance } from "@/providers/GovernanceProvider"; -import { useAnchorProvider, useOwnedAmount } from "@helium/helium-react-hooks"; +import { useAnchorProvider, useMint, useOwnedAmount } from "@helium/helium-react-hooks"; import { HNT_MINT, toBN, toNumber } from "@helium/spl-utils"; import { + Position, + PositionWithMeta, calcLockupMultiplier, - useCreatePosition, + useCreatePosition } from "@helium/voter-stake-registry-hooks"; +import { WalletSignTransactionError } from "@solana/wallet-adapter-base"; import { useWallet } from "@solana/wallet-adapter-react"; import { PublicKey } from "@solana/web3.js"; import BN from "bn.js"; import { Loader2 } from "lucide-react"; -import Image from "next/image"; import React, { FC, useCallback, useMemo, useState } from "react"; import { toast } from "sonner"; import { @@ -24,7 +26,7 @@ import { StepIndicator } from "./StepIndicator"; import { SubDaoSelection } from "./SubDaoSelection"; import { Button } from "./ui/button"; import { Dialog, DialogContent, DialogTrigger } from "./ui/dialog"; -import { WalletSignTransactionError } from "@solana/wallet-adapter-base"; +import { PositionPreview } from "./PositionPreview"; export const CreatePositionModal: FC> = ({ children, @@ -74,6 +76,24 @@ export const CreatePositionModal: FC> = ({ const handleGoBack = () => { setStep(step - 1); }; + const { info: mintAcc } = useMint(mint); + + const draftPosition: Partial | undefined = useMemo( + () => formValues && ({ + lockup: { + startTs: new BN(new Date().getTime() / 1000), + endTs: new BN( + new Date().setDate( + new Date().getDate() + formValues.lockupPeriodInDays + ) / 1000 + ), + kind: formValues!.lockupKind == LockupKind.cliff ? { cliff: {} } as any : { decay: {} } as any, + }, + amountDepositedNative: toBN(formValues!.amount, mintAcc?.decimals || 6), + delegatedSubDao: selectedSubDaoPk, + }), + [formValues, mintAcc, selectedSubDaoPk] + ); const handleOpenChange = () => { setIsSubmitting(false); @@ -222,51 +242,7 @@ export const CreatePositionModal: FC> = ({ )} {step === steps && ( <> -
-
- {`${network} -
-
-
- - {formValues!.amount} {network.toUpperCase()} - - for - - {getMinDurationFmt( - new BN(Date.now() / 1000), - new BN( - new Date().setDate( - new Date().getDate() + formValues!.lockupPeriodInDays - ) / 1000 - ) - )} - - - {formValues!.lockupKind === LockupKind.cliff - ? "decaying starting today" - : "decaying delayed"} - -
- {selectedSubDao && ( -
- and delegated to -
- {selectedSubDao.dntMetadata.json?.name} -
- {selectedSubDao.dntMetadata.symbol} -
- )} -
-
+ { draftPosition && }
+
+ )} +
+ ); +}; diff --git a/src/components/NetworkSelect.tsx b/src/components/NetworkSelect.tsx new file mode 100644 index 0000000..4cc8401 --- /dev/null +++ b/src/components/NetworkSelect.tsx @@ -0,0 +1,46 @@ +"use client" + +import React from "react"; +import { + Select, + SelectContent, + SelectGroup, + SelectItem, + SelectLabel, + SelectTrigger, + SelectValue, +} from "./ui/select"; +import { useNetwork } from "@/hooks/useNetwork"; +import { useGovernance } from "@/providers/GovernanceProvider"; + +export const NetworkSelect: React.FC<{ + network?: string + onNetworkChange: (network: string) => void +}> = ({ network, onNetworkChange }) => { + const { network: networkDefault } = useGovernance(); + const networkValue = network ?? networkDefault + + return ( + + ); +}; diff --git a/src/components/PositionPreview.tsx b/src/components/PositionPreview.tsx new file mode 100644 index 0000000..d11de74 --- /dev/null +++ b/src/components/PositionPreview.tsx @@ -0,0 +1,69 @@ +import { networksToMint } from "@/lib/constants"; +import { getMinDurationFmt, humanReadable } from "@/lib/utils"; +import { useGovernance } from "@/providers/GovernanceProvider"; +import { PositionWithMeta, useRegistrar } from "@helium/voter-stake-registry-hooks"; +import BN from "bn.js"; +import Image from "next/image"; +import { useMemo } from "react"; + +export const PositionPreview: React.FC<{ + position: Partial; +}> = ({ position }) => { + const { info: registrar } = useRegistrar(position.registrar); + const votingMint = registrar?.votingMints[0].mint; + const network = + Object.entries(networksToMint).find( + ([_, mint]) => votingMint && mint.equals(votingMint) + )?.[0] || "hnt"; + const amount = humanReadable(position.amountDepositedNative, 6); + const { subDaos } = useGovernance() + const subDao = useMemo( + () => + subDaos?.find( + (s) => + position.delegatedSubDao && s.pubkey.equals(position.delegatedSubDao) + ), + [subDaos, position.delegatedSubDao] + ); + + return ( +
+
+ {`${network} +
+
+
+ + {amount} {network.toUpperCase()} + + for + + {position.lockup?.endTs + ? getMinDurationFmt( + new BN(Date.now() / 1000), + position.lockup?.endTs + ) + : null} + + + {position.lockup?.kind?.cliff ? "decaying" : "decaying delayed"} + +
+ {subDao && ( +
+ and delegated to +
+ {subDao.dntMetadata.json?.name} +
+ {subDao.dntMetadata.symbol} +
+ )} +
+
+ ); +}; + diff --git a/src/components/Proposal.tsx b/src/components/Proposal.tsx index b80b49f..436fad3 100644 --- a/src/components/Proposal.tsx +++ b/src/components/Proposal.tsx @@ -28,7 +28,6 @@ import { FaGithub, FaXTwitter, } from "react-icons/fa6"; -import Markdown from "react-markdown"; import { toast } from "sonner"; import { ContentSection } from "./ContentSection"; import { CountdownTimer } from "./CountdownTimer"; @@ -40,6 +39,7 @@ import { Badge } from "./ui/badge"; import { Button } from "./ui/button"; import { Card, CardContent, CardHeader } from "./ui/card"; import { Skeleton } from "./ui/skeleton"; +import { Markdown } from "./Markdown"; const MARKDOWN_MAX = 540; @@ -195,8 +195,6 @@ export const Proposal: FC<{ proposalKey: string; }> = ({ name: initName, content, proposalKey }) => { const { connected, connecting } = useWallet(); - const markdownRef = useRef(null); - const [markdownExpanded, setMarkdownExpanded] = useState(false); const { loading: loadingGov, amountLocked, @@ -234,12 +232,6 @@ export const Proposal: FC<{ return { results, totalVotes }; }, [proposal]); - const markdownHeight = useMemo( - () => markdownRef.current?.clientHeight || 0, - // eslint-disable-next-line react-hooks/exhaustive-deps - [markdownRef.current] - ); - const derivedState = useMemo( () => getDerivedProposalState(proposal as ProposalV0), [proposal] @@ -288,22 +280,6 @@ export const Proposal: FC<{ } }, [proposalKey, endTs, network, completed, name]); - const rewriteLinks = () => { - const visit = require("unist-util-visit"); - - return function transformer(tree: any) { - visit.visit(tree, "link", (node: any) => { - node.data = { - ...node.data, - hProperties: { - ...(node.data || {}).hProperties, - target: "_blank", - }, - }; - }); - }; - }; - if (isLoading) return ; return ( <> @@ -413,41 +389,9 @@ export const Proposal: FC<{ isCancelled={isCancelled} />
-
-
- - {content.replace(name, "")} - -
- - {completed && - markdownHeight > MARKDOWN_MAX && - !markdownExpanded && ( -
- -
- )} -
+ + {content.replace(name, "")} +
diff --git a/src/components/Proxies.tsx b/src/components/Proxies.tsx index 8743319..ba4818c 100644 --- a/src/components/Proxies.tsx +++ b/src/components/Proxies.tsx @@ -1,5 +1,6 @@ "use client"; +import { IoWarningOutline } from "react-icons/io5"; import { useNetwork } from "@/hooks/useNetwork"; import { ellipsisMiddle, humanReadable } from "@/lib/utils"; import { useMint } from "@helium/helium-react-hooks"; @@ -19,6 +20,8 @@ import { Card } from "./ui/card"; import { Input } from "./ui/input"; import { useGovernance } from "@/providers/GovernanceProvider"; +const DECENTRALIZATION_RISK_INDEX = 6; + function CardDetail({ title, value }: { title: string; value: string }) { return (
@@ -61,33 +64,18 @@ export function Proxies() { } }, [voteService?.registrar.toBase58()]); - const handleBrowseProxies = () => { - // TODO: Implement - }; - return (

Browse Proxies

-
-
- - -
- +
+ +
{proxies.map((proxy, index) => ( - - -
- - - {proxy.name} - -
-

{proxy.name}

- - {ellipsisMiddle(proxy.wallet)} - + <> + + +
+ + + {proxy.name} + +
+

{proxy.name}

+ + {ellipsisMiddle(proxy.wallet)} + +
-
-
- - - + + + +
+ + + {index == DECENTRALIZATION_RISK_INDEX ? ( +
+ + + Assigning proxy to top voters may threaten the + decentralization of the network. Consider assigning proxy + to voters below this line. +
- - + ) : null} + ))}
diff --git a/src/components/ProxyButton.tsx b/src/components/ProxyButton.tsx index 38e71cf..f35c623 100644 --- a/src/components/ProxyButton.tsx +++ b/src/components/ProxyButton.tsx @@ -4,6 +4,8 @@ import { PublicKey } from "@solana/web3.js"; import { Button } from "./ui/button"; import { Loader2 } from "lucide-react"; import { useGovernance } from "@/providers/GovernanceProvider"; +import { RiUserSharedFill } from "react-icons/ri"; +import { cn } from "@/lib/utils"; export const ProxyButton: React.FC<{ className?: string; @@ -16,27 +18,27 @@ export const ProxyButton: React.FC<{ const unproxiedPositions = useMemo( () => positions?.filter( - (p) => !p.proxy || p.proxy.nextOwner.equals(PublicKey.default) + (p) => !p.proxy || p.proxy.nextVoter.equals(PublicKey.default) ), [positions] ); - const tooltipContent = !connected - ? "Connect your wallet to claim" - : !unproxiedPositions?.length - ? "You don't have any positions available to proxy." - : ""; - return ( ); }; diff --git a/src/components/ProxyProfile.tsx b/src/components/ProxyProfile.tsx index 35c090a..5188c5c 100644 --- a/src/components/ProxyProfile.tsx +++ b/src/components/ProxyProfile.tsx @@ -15,7 +15,6 @@ import Image from "next/image"; import Link from "next/link"; import { useMemo, useState } from "react"; import { FaArrowLeft } from "react-icons/fa6"; -import ReactMarkdown from "react-markdown"; import { AssignProxyModal } from "./AssignProxyModal"; import { ContentSection } from "./ContentSection"; import { ProxyButton } from "./ProxyButton"; @@ -23,6 +22,7 @@ import { RevokeProxyButton } from "./RevokeProxyButton"; import { RevokeProxyModal } from "./RevokeProxyModal"; import { Card, CardContent, CardHeader } from "./ui/card"; import VoteHistory from "./VoteHistory"; +import { Markdown } from "./Markdown"; export function ProxyProfile({ proxy, @@ -36,10 +36,6 @@ export function ProxyProfile({ const { mint } = useGovernance(); const { info: mintAcc } = useMint(mint); const decimals = mintAcc?.decimals; - const [revokeProxyModalVisible, setRevokeProxyModalVisible] = useState(false); - const handleSetRevokeProxy = () => { - setRevokeProxyModalVisible(true); - }; const { assignProxies } = useAssignProxies(); const { unassignProxies } = useUnassignProxies(); const wallet = useMemo(() => new PublicKey(proxy.wallet), [proxy.wallet]); @@ -55,9 +51,9 @@ export function ProxyProfile({ className="flex flex-row items-center text-sm gap-2" > - Back to Proxies + Back to Proxy Voters -
+
-
+
Current Rank @@ -86,6 +82,13 @@ export function ProxyProfile({
+ + + {}} isLoading={false} /> + + + {}} isLoading={false} /> + @@ -95,27 +98,7 @@ export function ProxyProfile({ {humanReadable(votingPower, decimals)}
)} - - - {}} - isLoading={false} - /> - - {revokeProxyModalVisible && ( - setRevokeProxyModalVisible(false)} - onSubmit={unassignProxies} - wallet={wallet} - /> - )}
Wallet: @@ -138,9 +121,7 @@ export function ProxyProfile({ {Number(proxy.percent).toFixed(2)}
-
- {detail} -
+ {detail} diff --git a/src/components/ProxySearch.tsx b/src/components/ProxySearch.tsx new file mode 100644 index 0000000..c975bae --- /dev/null +++ b/src/components/ProxySearch.tsx @@ -0,0 +1,88 @@ +import React, { useMemo, useState } from "react"; +import { AutoComplete, Option } from "./ui/autocomplete"; +import { useAsync } from "react-async-hook"; +import axios from "axios"; +import { useHeliumVsrState } from "@helium/voter-stake-registry-hooks"; +import { PublicKey } from "@solana/web3.js"; +import { ellipsisMiddle } from "@/lib/utils"; +import { Loader2 } from "lucide-react"; + +export const ProxySearch: React.FC<{ + value: string; + onValueChange: (value: string) => void; +}> = ({ value, onValueChange }) => { + const [isLoading, setLoading] = useState(false); + const [input, setInput] = useState(); + const { voteService } = useHeliumVsrState(); + + const debouncedSearch = useMemo( + () => + debounce(async (query: string | undefined) => { + setLoading(true); + try { + const results = await voteService?.searchProxies({ + query: query || "", + }); + + const resultsAsOptions = + results?.map((r) => { + return { + value: r.wallet, + label: `${r.name} | ${ellipsisMiddle(r.wallet)}`, + }; + }) || []; + + if (isValidPublicKey(query)) { + resultsAsOptions.push({ + value: query || "", + label: query || "", + }); + } + + return resultsAsOptions; + } finally { + setLoading(false); + } + }, 300), + [voteService] + ); + + const { result } = useAsync(debouncedSearch, [input]); + + return result ? ( + onValueChange(v.value)} + value={result?.find((r) => r.value == value)} + onInputChange={setInput} + /> + ) : ( + + ); +}; + +function isValidPublicKey(input: string | undefined) { + try { + new PublicKey(input || ""); + return true; + } catch (e) { + return false; + } +} + +function debounce( + callback: (...args: T) => PromiseLike | U, + wait: number +) { + let timer: any; + + return (...args: T): Promise => { + clearTimeout(timer); + return new Promise((resolve) => { + timer = setTimeout(() => resolve(callback(...args)), wait); + }); + }; +} diff --git a/src/components/RevokeProxyButton.tsx b/src/components/RevokeProxyButton.tsx index a982207..eb0109e 100644 --- a/src/components/RevokeProxyButton.tsx +++ b/src/components/RevokeProxyButton.tsx @@ -4,6 +4,8 @@ import { PublicKey } from "@solana/web3.js"; import { Loader2 } from "lucide-react"; import React, { useMemo } from "react"; import { Button } from "./ui/button"; +import { RiUserReceivedFill } from "react-icons/ri"; +import { cn } from "@/lib/utils"; export const RevokeProxyButton: React.FC<{ className?: string; @@ -19,31 +21,33 @@ export const RevokeProxyButton: React.FC<{ positions?.filter( (p) => p.proxy && - !p.proxy.nextOwner.equals(PublicKey.default) && - (!wallet || p.proxy.nextOwner.equals(wallet)) + !p.proxy.nextVoter.equals(PublicKey.default) && + (!wallet || p.proxy.nextVoter.equals(wallet)) ), [positions] ); - const tooltipContent = !connected - ? "Connect your wallet to claim" - : !proxiedPositions?.length - ? "You don't have any positions available to revoke proxy." - : ""; - const disabled = !connected || loading || !proxiedPositions?.length; return ( ); }; diff --git a/src/components/RevokeProxyModal.tsx b/src/components/RevokeProxyModal.tsx index b92e5fc..6272895 100644 --- a/src/components/RevokeProxyModal.tsx +++ b/src/components/RevokeProxyModal.tsx @@ -1,39 +1,36 @@ import { useGovernance } from "@/providers/GovernanceProvider"; import { PositionWithMeta } from "@helium/voter-stake-registry-hooks"; -import { DialogContent } from "@radix-ui/react-dialog"; import { PublicKey } from "@solana/web3.js"; import { Loader2 } from "lucide-react"; import React, { useMemo, useState } from "react"; import { toast } from "sonner"; import { PositionItem } from "./AssignProxyModal"; import { Button } from "./ui/button"; -import { Dialog } from "./ui/dialog"; +import { Dialog, DialogContent, DialogTrigger } from "./ui/dialog"; interface RevokeProxyModalProps { - isOpen: boolean; - onClose: () => void; onSubmit: (args: { positions: PositionWithMeta[] }) => Promise; wallet?: PublicKey; } -export const RevokeProxyModal: React.FC = ({ - isOpen, - onClose, - onSubmit, - wallet, -}) => { - const { loading, positions, mint } = useGovernance(); +export const RevokeProxyModal: React.FC< + React.PropsWithChildren +> = ({ onSubmit, wallet, children }) => { + const [open, setOpen] = useState(false); + + const { loading, positions } = useGovernance(); const [selectedPositions, setSelectedPositions] = useState>( new Set() ); + console.log(positions) const [isSubmitting, setIsSubmitting] = useState(false); const proxiedPositions = useMemo( () => positions?.filter( (p) => p.proxy && - !p.proxy.nextOwner.equals(PublicKey.default) && - (!wallet || p.proxy.nextOwner.equals(wallet)) + !p.proxy.nextVoter.equals(PublicKey.default) && + (!wallet || p.proxy.nextVoter.equals(wallet)) ), [positions, wallet] ); @@ -53,18 +50,25 @@ export const RevokeProxyModal: React.FC = ({ }); } - onClose(); + setOpen(false); } catch (e: any) { setIsSubmitting(false); toast(e.message || "Unable to Revoke proxy"); } }; + const handleOpenChange = () => { + setIsSubmitting(false); + setOpen(!open); + }; + return ( - - + + {children} + +

- Revoke Voting Proxy + Revoke Proxies

{loading ? ( <> @@ -77,9 +81,7 @@ export const RevokeProxyModal: React.FC = ({ ) : (
-
-

Positions to Revoke

- +
{proxiedPositions?.map((position) => { return ( = ({ position.pubkey.toBase58() )} position={position} - mint={mint!} onClick={() => { setSelectedPositions((sel) => { const key = position.pubkey.toBase58(); @@ -108,17 +109,21 @@ export const RevokeProxyModal: React.FC = ({
)} -
+
+ -
diff --git a/src/components/SubNav.tsx b/src/components/SubNav.tsx index 5b890ba..ee2544b 100644 --- a/src/components/SubNav.tsx +++ b/src/components/SubNav.tsx @@ -17,6 +17,8 @@ import { import { Button } from "./ui/button"; import { DropdownMenuLabel } from "@radix-ui/react-dropdown-menu"; import { IconType } from "react-icons"; +import { HiDotsVertical } from "react-icons/hi"; +import { cn } from "@/lib/utils"; const icons: { [key: string]: IconType } = { proposals: LuScrollText, @@ -28,7 +30,6 @@ export const SubNav: React.FC = () => { const path = usePathname(); const basePath = path.split("/").slice(0, 2).join("/"); const currentPath = path.split("/")[2] || "proposals"; - const Icon = icons[currentPath]; return (
@@ -36,7 +37,7 @@ export const SubNav: React.FC = () => { @@ -68,22 +69,22 @@ export const SubNav: React.FC = () => {
- - + Proposals - + { Proxies - + +
+
+

Proposals

+ + + + hnt Icon + HNT + + + + + moile Icon + MOBILE + + + + + iot Icon + MOBILE + + + +
& Record; + +type AutoCompleteProps = { + options: Option[]; + emptyMessage: string; + value?: Option; + onValueChange?: (value: Option) => void; + onInputChange?: (value: string) => void; + isLoading?: boolean; + disabled?: boolean; + placeholder?: string; +}; + +export const AutoComplete = ({ + options, + placeholder, + emptyMessage, + value, + onValueChange, + onInputChange, + disabled, + isLoading = false, +}: AutoCompleteProps) => { + const inputRef = useRef(null); + + const [isOpen, setOpen] = useState(false); + const [selected, setSelected] = useState
diff --git a/src/components/ProxyProfile.tsx b/src/components/ProxyProfile.tsx index 5188c5c..4dde5d3 100644 --- a/src/components/ProxyProfile.tsx +++ b/src/components/ProxyProfile.tsx @@ -23,6 +23,8 @@ import { RevokeProxyModal } from "./RevokeProxyModal"; import { Card, CardContent, CardHeader } from "./ui/card"; import VoteHistory from "./VoteHistory"; import { Markdown } from "./Markdown"; +import { ToggleGroup, ToggleGroupItem } from "./ui/toggle-group"; +import { usePathname } from "next/navigation"; export function ProxyProfile({ proxy, @@ -39,11 +41,100 @@ export function ProxyProfile({ const { assignProxies } = useAssignProxies(); const { unassignProxies } = useUnassignProxies(); const wallet = useMemo(() => new PublicKey(proxy.wallet), [proxy.wallet]); - const { votingPower } = useProxiedTo(wallet); + const { votingPower, positions } = useProxiedTo(wallet); const { network } = useGovernance(); + const path = usePathname(); + const currentPath = path.split("/")[0] || "hnt"; + function getNetworkPath(network: string) { + const split = path.split("/"); + split.shift(); + return [network, ...split].join("/"); + } + + const infoCard = ( +
+
+
+ VOTING POWER +
+
+
+
+ TOTAL POWER +
+
+ {proxy.delegatedVeTokens + ? humanReadable(new BN(proxy.delegatedVeTokens), decimals) + : "0"} +
+
+
+
+ PERCENTAGE +
+
+ {Number(proxy.percent).toFixed(2)} +
+
+
+
+
+
+ PROXIES +
+
+
+
+ PROPOSALS VOTED +
+
+ {proxy.numProposalsVoted} +
+
+
+
+ NUM ASSIGNMENTS +
+
+ {proxy.numAssignments} +
+
+
+
+ {votingPower?.gt(new BN(0)) && ( + <> +
+
+
+ MY PROXIES +
+
+
+
+ POWER FROM ME +
+
+ {humanReadable(votingPower, decimals)} +
+
+
+
+ POSITIONS ASSIGNED +
+
+ {positions?.length} +
+
+
+
+ + )} +
+ ); + return ( - + - {}} isLoading={false} /> + {}} + isLoading={false} + /> - {}} isLoading={false} /> + {}} + isLoading={false} + /> +
- {votingPower && ( -
- My Delegations: - {humanReadable(votingPower, decimals)} -
- )} - -
-
- Wallet: - {proxy.wallet} -
-
- Num Delegations: - {proxy.numDelegations} -
-
- Delegated Tokens: - - {proxy.delegatedVeTokens - ? humanReadable(new BN(proxy.delegatedVeTokens), decimals) - : "0"} - + {detail} +
{infoCard}
+
+
+
+

Proposals

+ + + + hnt Icon + HNT + + + + + moile Icon + MOBILE + + + + + iot Icon + IOT + + + +
+
-
- Percent: - {Number(proxy.percent).toFixed(2)} +
+ + {}} isLoading={false} /> + + + {}} isLoading={false} /> + +
{infoCard}
- {detail} - diff --git a/src/components/ProxySearch.tsx b/src/components/ProxySearch.tsx index c975bae..889b904 100644 --- a/src/components/ProxySearch.tsx +++ b/src/components/ProxySearch.tsx @@ -1,10 +1,9 @@ import React, { useMemo, useState } from "react"; import { AutoComplete, Option } from "./ui/autocomplete"; import { useAsync } from "react-async-hook"; -import axios from "axios"; import { useHeliumVsrState } from "@helium/voter-stake-registry-hooks"; import { PublicKey } from "@solana/web3.js"; -import { ellipsisMiddle } from "@/lib/utils"; +import { debounce, ellipsisMiddle } from "@/lib/utils"; import { Loader2 } from "lucide-react"; export const ProxySearch: React.FC<{ @@ -72,17 +71,3 @@ function isValidPublicKey(input: string | undefined) { return false; } } - -function debounce( - callback: (...args: T) => PromiseLike | U, - wait: number -) { - let timer: any; - - return (...args: T): Promise => { - clearTimeout(timer); - return new Promise((resolve) => { - timer = setTimeout(() => resolve(callback(...args)), wait); - }); - }; -} diff --git a/src/components/RevokeProxyModal.tsx b/src/components/RevokeProxyModal.tsx index 6272895..16b3622 100644 --- a/src/components/RevokeProxyModal.tsx +++ b/src/components/RevokeProxyModal.tsx @@ -22,7 +22,6 @@ export const RevokeProxyModal: React.FC< const [selectedPositions, setSelectedPositions] = useState>( new Set() ); - console.log(positions) const [isSubmitting, setIsSubmitting] = useState(false); const proxiedPositions = useMemo( () => diff --git a/src/components/VoteHistory.tsx b/src/components/VoteHistory.tsx index 8c39d7b..e284d9a 100644 --- a/src/components/VoteHistory.tsx +++ b/src/components/VoteHistory.tsx @@ -1,33 +1,31 @@ -import { humanReadable } from "@/lib/utils"; -import Image from "next/image" +import { useProposalStatus } from "@/hooks/useProposalStatus"; +import { cn } from "@/lib/utils"; import { useGovernance } from "@/providers/GovernanceProvider"; -import { useMint } from "@helium/helium-react-hooks"; import { ProposalWithVotes } from "@helium/voter-stake-registry-sdk"; import { PublicKey } from "@solana/web3.js"; import BN from "bn.js"; import { useEffect, useState } from "react"; import InfiniteScroll from "react-infinite-scroll-component"; -import { ToggleGroup, ToggleGroupItem } from "./ui/toggle-group"; -import { usePathname } from "next/navigation"; -import Link from "next/link"; +import { CountdownTimer } from "./CountdownTimer"; +import { toNumber } from "@helium/spl-utils"; +import { Pill } from "./Pill"; +import { Loader2 } from "lucide-react"; export default function VoteHistory({ wallet }: { wallet: PublicKey }) { const { voteService, mint } = useGovernance(); - const { info: mintAcc } = useMint(mint); - const decimals = mintAcc?.decimals; const [voteHistories, setVoteHistory] = useState([]); const [hasMore, setHasMore] = useState(true); const [page, setPage] = useState(1); - const fetchMoreData = async () => { + const fetchMoreData = async (page: number) => { + setPage(page); if (voteService) { const newVoteHistory = await voteService.getVotesForWallet({ wallet: wallet, page: page, - limit: 10, + limit: 100, }); - setPage((p) => p + 1); - if (newVoteHistory.length < 10) { + if (newVoteHistory.length < 100) { setHasMore(false); } setVoteHistory((prevVoteHistory) => [ @@ -39,141 +37,134 @@ export default function VoteHistory({ wallet }: { wallet: PublicKey }) { useEffect(() => { if (voteService) { - setPage(1); setHasMore(true); - fetchMoreData(); + setVoteHistory([]); + fetchMoreData(1); } }, [voteService]); - const path = usePathname(); - const currentPath = path.split("/")[0] || "hnt"; - function getNetworkPath(network: string) { - const split = path.split("/") - split.shift(); - return [network, ...split].join("/") - } - return ( -
-
-

Proposals

- - - - hnt Icon - HNT - - - - - moile Icon - MOBILE - - - - - iot Icon - MOBILE - - - -
+
{ + setPage(page + 1); + fetchMoreData(page + 1); + }} hasMore={hasMore} - loader={

Loading...

} + loader={ +
+ +
+ } endMessage={ -

- End of vote history +

+ You've reached the end of the list

} > - - - - - - - - - - - - {voteHistories.map((voteHistory, index) => { - const totalWeight = voteHistory.choices.reduce((acc, c) => { - return acc.add(new BN(c.weight)); - }, new BN(0)); - const percent = voteHistory.votes[0] - ? (100 * Number(voteHistory.votes[0].weight)) / - totalWeight.toNumber() - : 0; - - return ( - - - - - - - - ); - })} - -
- Proposal - - State - - Weight - - Choices - - Percent -
- {voteHistory.name} - - {Object.keys(voteHistory.state)[0]} - - {voteHistory.votes[0]?.weight && - humanReadable( - new BN(voteHistory.votes[0].weight), - decimals - )} - - {voteHistory.votes.map((v) => v.choiceName).join(", ")} - - {percent.toFixed(2)} -
+
+ {voteHistories.map((voteHistory, index) => { + return ; + })} +
); } + +const ProposalItem: React.FC<{ + proposal: ProposalWithVotes; +}> = ({ proposal }) => { + const { + completed, + timeExpired, + endTs, + votingResults, + isActive, + isFailed, + isCancelled, + } = useProposalStatus(proposal); + + return ( +
+
+
+ {!completed && Actively Voting} + {isActive && completed && ( + Voting Closed + )} + {isCancelled && Vote Cancelled} +
+ +
+ HIP 37: H3Dex-based PoC Targeting +
+ {timeExpired ? ( +
+ + +
+ ) : null} +
+
+ {proposal.votes[0].weight ? ( +
+ v.choiceName).join(", ")} + /> + +
+ ) : ( + + Not Voted + + )} + {!timeExpired && ( +
+
+
+ Est. Time Remaining +
+ +
+
+ )} +
+
+ ); +}; + +const InfoItem: React.FC<{ + name: string; + value: React.ReactElement | string; + className?: string; +}> = ({ name, value, className }) => { + return ( +
+
+ {name} +
+
{value}
+
+ ); +}; diff --git a/src/components/ui/select.tsx b/src/components/ui/select.tsx index 5d253ee..72a2422 100644 --- a/src/components/ui/select.tsx +++ b/src/components/ui/select.tsx @@ -19,7 +19,7 @@ const SelectTrigger = React.forwardRef< span]:line-clamp-1", + "h-auto flex w-full items-center justify-between rounded border border-input bg-background px-3 py-1 text-sm ring-offset-background placeholder:text-muted-foreground focus:outline-none focus:ring-2 focus:ring-ring focus:ring-offset-2 disabled:cursor-not-allowed disabled:opacity-50 [&>span]:line-clamp-1", className )} {...props} diff --git a/src/hooks/useProposalInfo.ts b/src/hooks/useProposalInfo.ts new file mode 100644 index 0000000..cbfb0b4 --- /dev/null +++ b/src/hooks/useProposalInfo.ts @@ -0,0 +1,72 @@ +"use client"; + +import { ProposalV0 } from "@/lib/types"; +import { getDerivedProposalState } from "@/lib/utils"; +import { useGovernance } from "@/providers/GovernanceProvider"; +import { useMint } from "@helium/helium-react-hooks"; +import { + useProposal, + useProposalConfig, + useResolutionSettings, +} from "@helium/modular-governance-hooks"; +import { useRegistrar, useVote } from "@helium/voter-stake-registry-hooks"; +import { useWallet } from "@solana/wallet-adapter-react"; +import { PublicKey } from "@solana/web3.js"; +import BN from "bn.js"; +import { useMemo } from "react"; +import { useProposalStatus } from "./useProposalStatus"; + +export function useProposalInfo(pKey: PublicKey) { + const { connecting } = useWallet(); + + const { + loading: loadingGov, + amountLocked, + amountProxyLocked, + } = useGovernance(); + const { loading: loadingProposal, info: proposal } = useProposal(pKey); + const { loading: loadingVote, voteWeights } = useVote(pKey); + const { info: proposalConfig } = useProposalConfig(proposal?.proposalConfig); + const { info: registrar } = useRegistrar(proposalConfig?.voteController); + const decimals = useMint(registrar?.votingMints[0].mint)?.info?.decimals; + + const totalLocked = amountLocked?.add(amountProxyLocked || new BN(0)); + + const { + isLoading: isLoadingStatus, + isActive, + isCancelled, + isFailed, + completed, + timeExpired, + resolution, + endTs, + votingResults, + } = useProposalStatus(proposal); + const isLoading = + connecting || + loadingGov || + isLoadingStatus || + loadingProposal || + loadingVote; + const noVotingPower = !isLoading && (!totalLocked || totalLocked.isZero()); + const voted = !loadingVote && voteWeights?.some((n) => n.gt(new BN(0))); + + return { + voted, + completed, + isFailed, + isCancelled, + isActive, + noVotingPower, + timeExpired, + isLoading, + votingResults, + proposal, + proposalConfig, + registrar, + decimals, + resolution, + endTs, + }; +} diff --git a/src/hooks/useProposalStatus.ts b/src/hooks/useProposalStatus.ts new file mode 100644 index 0000000..eecc8a5 --- /dev/null +++ b/src/hooks/useProposalStatus.ts @@ -0,0 +1,88 @@ +import { ProposalV0 } from "@/lib/types"; +import { getDerivedProposalState } from "@/lib/utils"; +import { + useProposalConfig, + useResolutionSettings, +} from "@helium/modular-governance-hooks"; +import { ProposalWithVotes } from "@helium/voter-stake-registry-sdk"; +import { PublicKey } from "@solana/web3.js"; +import BN from "bn.js"; +import { useMemo } from "react"; + +function usePublicKey( + key: string | PublicKey | undefined +): PublicKey | undefined { + return useMemo(() => { + if (key) { + // @ts-ignore + if (key.toBase58) { + return key as PublicKey; + } + return new PublicKey(key); + } + }, [key]); +} + +export function useProposalStatus(proposal?: ProposalV0 | ProposalWithVotes) { + const { info: proposalConfig, loading: loadingConfig } = useProposalConfig( + usePublicKey(proposal?.proposalConfig) + ); + const { info: resolution, loading: loadingResolution } = + useResolutionSettings(proposalConfig?.stateController); + const derivedState = useMemo( + () => getDerivedProposalState(proposal as ProposalV0), + [proposal] + ); + + const endTs = + resolution && + // @ts-ignore + (proposal?.state.resolved + ? // @ts-ignore + proposal?.state.resolved.endTs + : // @ts-ignore + new BN(proposal?.state.voting?.startTs).add( + resolution.settings.nodes.find( + (node) => typeof node.offsetFromStartTs !== "undefined" + )?.offsetFromStartTs?.offset ?? new BN(0) + )); + + const timeExpired = endTs && endTs.toNumber() <= Date.now().valueOf() / 1000; + const isLoading = loadingConfig || loadingResolution; + const isActive = derivedState === "active"; + const isCancelled = derivedState === "cancelled"; + const isFailed = derivedState === "failed"; + const completed = + timeExpired || (timeExpired && isActive) || isCancelled || isFailed; + + const votingResults = useMemo(() => { + const totalVotes: BN = [...(proposal?.choices || [])].reduce( + (acc, { weight }) => new BN(weight).add(acc) as BN, + new BN(0) + ); + + const results = proposal?.choices.map((r, index) => ({ + ...r, + index, + percent: totalVotes?.isZero() + ? 100 / proposal?.choices.length + : // Calculate with 4 decimals of precision + new BN(r.weight).mul(new BN(10000)).div(totalVotes).toNumber() * + (100 / 10000), + })); + + return { results, totalVotes }; + }, [proposal]); + + return { + isLoading, + isActive, + isCancelled, + isFailed, + completed, + timeExpired, + resolution, + endTs, + votingResults, + }; +} diff --git a/src/lib/utils.ts b/src/lib/utils.ts index 20c20fe..1276769 100644 --- a/src/lib/utils.ts +++ b/src/lib/utils.ts @@ -391,3 +391,17 @@ export const getProposalContent = async (proposalKey: PublicKey) => { const content = await res.text(); return { content, name: proposal.name }; }; + +export function debounce( + callback: (...args: T) => PromiseLike | U, + wait: number +) { + let timer: any; + + return (...args: T): Promise => { + clearTimeout(timer); + return new Promise((resolve) => { + timer = setTimeout(() => resolve(callback(...args)), wait); + }); + }; +} diff --git a/tailwind.config.ts b/tailwind.config.ts index a543f34..dbc1fc5 100644 --- a/tailwind.config.ts +++ b/tailwind.config.ts @@ -46,6 +46,7 @@ const config = { 600: "hsl(215, 19%, 40%)", 700: "hsl(213, 19%, 32%)", 800: "hsl(214, 19%, 24%)", + 850: "hsl(215, 19%, 19%)", 900: "hsl(214, 19%, 15%)", 950: "hsl(214, 17%, 8%)", }, From 0911d14bf00c7bd479d0ba11a3d2c143cebc3c0f Mon Sep 17 00:00:00 2001 From: Noah Prince Date: Thu, 30 May 2024 15:31:51 -0700 Subject: [PATCH 09/41] wip --- src/app/globals.css | 2 + src/components/AssignProxyModal.tsx | 50 +++---- src/components/CreatePositionModal.tsx | 4 +- src/components/Pill.tsx | 1 + src/components/PositionCard.tsx | 83 ++++++++---- .../PositionActionBoundary.tsx | 4 +- .../PositionManager/PositionManager.tsx | 40 +++++- src/components/PositionPreview.tsx | 4 +- src/components/Proposal.tsx | 20 +-- src/components/Proxies.tsx | 2 +- src/components/ProxyButton.tsx | 19 ++- src/components/ProxyProfile.tsx | 127 +++++++++++------- src/components/RevokeProxyButton.tsx | 10 +- src/components/RevokeProxyModal.tsx | 32 ++++- src/components/VoteHistory.tsx | 29 ++-- src/components/ui/autocomplete.tsx | 1 - tailwind.config.ts | 4 + 17 files changed, 303 insertions(+), 129 deletions(-) diff --git a/src/app/globals.css b/src/app/globals.css index 287f217..47482f6 100644 --- a/src/app/globals.css +++ b/src/app/globals.css @@ -28,6 +28,8 @@ --info-foreground: 217 91% 60%; --purple: 274 87 21%; --purple-foreground: 258 90 66%; + --pink: 336, 84%, 17%; + --pink-foreground: 330 81% 60%; --border: 214.3 31.8% 91.4%; --input: 214.3 31.8% 91.4%; --ring: 221.2 83.2% 53.3%; diff --git a/src/components/AssignProxyModal.tsx b/src/components/AssignProxyModal.tsx index 4c35cc2..b39816e 100644 --- a/src/components/AssignProxyModal.tsx +++ b/src/components/AssignProxyModal.tsx @@ -165,30 +165,32 @@ export const AssignProxyModal: React.FC<
- {unproxiedPositions?.map((position) => { - return ( - { - setSelectedPositions((sel) => { - const key = position.pubkey.toBase58(); - const newS = new Set(sel); - if (sel.has(key)) { - newS.delete(key); - return newS; - } else { - newS.add(key); - return newS; - } - }); - }} - /> - ); - })} +
+ {unproxiedPositions?.map((position) => { + return ( + { + setSelectedPositions((sel) => { + const key = position.pubkey.toBase58(); + const newS = new Set(sel); + if (sel.has(key)) { + newS.delete(key); + return newS; + } else { + newS.add(key); + return newS; + } + }); + }} + /> + ); + })} +

Expiration Time

diff --git a/src/components/CreatePositionModal.tsx b/src/components/CreatePositionModal.tsx index 974d336..6c05be8 100644 --- a/src/components/CreatePositionModal.tsx +++ b/src/components/CreatePositionModal.tsx @@ -91,8 +91,10 @@ export const CreatePositionModal: FC> = ({ }, amountDepositedNative: toBN(formValues!.amount, mintAcc?.decimals || 6), delegatedSubDao: selectedSubDaoPk, + // @ts-ignore + registrar: registrar?.pubkey, }), - [formValues, mintAcc, selectedSubDaoPk] + [formValues, mintAcc, selectedSubDaoPk, registrar] ); const handleOpenChange = () => { diff --git a/src/components/Pill.tsx b/src/components/Pill.tsx index 1d7ad61..7c43f9b 100644 --- a/src/components/Pill.tsx +++ b/src/components/Pill.tsx @@ -13,6 +13,7 @@ const pillVariants = cva( "bg-warning text-warning-foreground border-warning-foreground/20", info: "bg-info text-info-foreground border-info-foreground/20", purple: "bg-purple text-purple-foreground border-purple-foreground/20", + pink: "bg-pink text-pink-foreground border-pink-foreground/20", }, }, defaultVariants: { diff --git a/src/components/PositionCard.tsx b/src/components/PositionCard.tsx index ff141a7..a71cc37 100644 --- a/src/components/PositionCard.tsx +++ b/src/components/PositionCard.tsx @@ -1,6 +1,7 @@ "use client"; import { + ellipsisMiddle, getMinDurationFmt, getTimeLeftFromNowFmt, humanReadable, @@ -24,6 +25,10 @@ import { CardTitle, } from "./ui/card"; import { Skeleton } from "./ui/skeleton"; +import { PublicKey } from "@solana/web3.js"; +import { useAsync } from "react-async-hook"; +import { VoteService } from "@helium/voter-stake-registry-sdk"; +import { useKnownProxy } from "@/hooks/useKnownProxy"; export const PositionCardSkeleton: FC<{ compact?: boolean }> = () => { const { network } = useGovernance(); @@ -70,7 +75,13 @@ export const PositionCard: FC<{ }> = ({ position, className = "", compact = false, onClick }) => { const path = usePathname(); const { lockup, hasGenesisMultiplier } = position; - const { loading: loadingGov, network, mintAcc, subDaos } = useGovernance(); + const { + loading: loadingGov, + network, + mintAcc, + subDaos, + voteService, + } = useGovernance(); const unixNow = useSolanaUnixNow() || Date.now() / 1000; const lockupKind = Object.keys(lockup.kind)[0] as string; const isConstant = lockupKind === "constant"; @@ -79,6 +90,7 @@ export const PositionCard: FC<{ const totalTime = lockup.endTs.sub(lockup.startTs); const decayedPercentage = elapsedTime.muln(100).div(totalTime); const canDelegate = network === "hnt"; + const { knownProxy } = useKnownProxy(position?.proxy?.nextVoter) const lockedTokens = mintAcc && humanReadable(position.amountDepositedNative, mintAcc.decimals); @@ -195,7 +207,7 @@ export const PositionCard: FC<{ )} - +

VOTING POWER

@@ -220,30 +232,53 @@ export const PositionCard: FC<{
{canDelegate && ( - -

DELEGATED TO

- {!isDecayed && delegatedSubDaoMetadata ? ( -
-
- delegated-subdao + +
+
+
+
+

DELEGATED TO

+ {!isDecayed && delegatedSubDaoMetadata ? ( +
+
+ delegated-subdao +
+

{delegatedSubDaoMetadata.symbol}

-

{delegatedSubDaoMetadata.symbol}

+ ) : !isDecayed ? ( + + + + ) : ( +

UNDELEGATED

+ )} +
+ {position.proxy && + !position.proxy.nextVoter.equals(PublicKey.default) ? ( +
+

PROXIED TO

+ + + {knownProxy?.name || + ellipsisMiddle(position.proxy.nextVoter.toBase58())} + +
- ) : !isDecayed ? ( - - - - ) : ( -

UNDELEGATED

- )} + ) : null} )} diff --git a/src/components/PositionManager/PositionActionBoundary.tsx b/src/components/PositionManager/PositionActionBoundary.tsx index 9eb842d..2b8aa83 100644 --- a/src/components/PositionManager/PositionActionBoundary.tsx +++ b/src/components/PositionManager/PositionActionBoundary.tsx @@ -28,7 +28,7 @@ export const PositionActionBoundary: FC< const { hasRewards, isDelegated, numActiveVotes } = position; const hasVotes = numActiveVotes > 0; const hasBlockers = hasRewards || isDelegated || hasVotes; - const tryingToUnblock = !hasRewards && action === "delegate"; + const canDoWhileBlocked = !hasRewards && action === "delegate" || action == "proxy"; if (!action) { return children; @@ -36,7 +36,7 @@ export const PositionActionBoundary: FC< return (
- {hasBlockers && !tryingToUnblock && ( + {hasBlockers && !canDoWhileBlocked && (
= ({ setAction(undefined); }, [refetchState, setAction]); + const { loading: isUpdatingProxy, assignProxies } = useAssignProxies(); const { loading: isFlipping, flipPositionLockupKind } = useFlipPositionLockupKind(); const { loading: isClaiming, claimPositionRewards } = @@ -161,6 +167,23 @@ export const PositionManager: FC = ({ const { loading: isRelinquishing, relinquishPositionVotes } = useRelinquishPositionVotes(); + const handleUpdateProxy = async (proxy: string) => { + try { + const nextVoter = new PublicKey(proxy) + await relinquishPositionVotes({ + position, + organization, + onInstructions: onInstructions(provider), + }); + + toast("Proxy assigned"); + } catch (e: any) { + if (!(e instanceof WalletSignTransactionError)) { + toast(e.message || "Relinquish failed, please try again"); + } + } + }; + const handleRelinquishPositionVotes = async () => { try { await relinquishPositionVotes({ @@ -340,6 +363,13 @@ export const PositionManager: FC = ({
+ } + onClick={() => setAction("proxy")} + > + Update Proxy + {canDelegate && ( = ({
)} + {action === "proxy" && ( + setAction(undefined)} + onConfirm={handleUpdateProxy} + /> + )} {action === "flip" && ( votingMint && mint.equals(votingMint) )?.[0] || "hnt"; - const amount = humanReadable(position.amountDepositedNative, 6); + const { info: mint } = useMint(votingMint) + const amount = humanReadable(position.amountDepositedNative, mint?.decimals); const { subDaos } = useGovernance() const subDao = useMemo( () => diff --git a/src/components/Proposal.tsx b/src/components/Proposal.tsx index 1865076..d345b7f 100644 --- a/src/components/Proposal.tsx +++ b/src/components/Proposal.tsx @@ -303,14 +303,18 @@ export const Proposal: FC<{
)} - {connected && !noVotingPower && !completed && ( - - )} - {(completed || (connected && !noVotingPower && voted)) && + {connected && + !noVotingPower && + !completed && + proposal && + votingResults && ( + + )} + {(completed || (connected && !noVotingPower && voted)) && votingResults && votingResults?.totalVotes.gt(new BN(0)) && (
diff --git a/src/components/ProxyButton.tsx b/src/components/ProxyButton.tsx index f35c623..2f35adc 100644 --- a/src/components/ProxyButton.tsx +++ b/src/components/ProxyButton.tsx @@ -7,11 +7,14 @@ import { useGovernance } from "@/providers/GovernanceProvider"; import { RiUserSharedFill } from "react-icons/ri"; import { cn } from "@/lib/utils"; -export const ProxyButton: React.FC<{ - className?: string; - onClick: () => void; - isLoading?: boolean; -}> = ({ className = "", onClick, isLoading = false }) => { +export const ProxyButton = React.forwardRef< + HTMLButtonElement, + { + className?: string; + onClick: () => void; + isLoading?: boolean; + } +>(({ className = "", onClick, isLoading = false }, ref) => { const { connected } = useWallet(); const { loading, positions } = useGovernance(); @@ -25,6 +28,7 @@ export const ProxyButton: React.FC<{ return (
Last Voted - {proxy.lastVotedAt?.toDateString() || "Never"} + + {proxy.lastVotedAt + ? new Date(proxy.lastVotedAt).toLocaleDateString() + : "Never"} +
@@ -199,48 +230,54 @@ export function ProxyProfile({

Proposals

- - - hnt Icon - HNT - - - - - moile Icon - MOBILE - - - - - iot Icon - IOT - - + {networks?.has("hnt") && ( + + + hnt Icon + HNT + + + )} + {networks?.has("mobile") && ( + + + moile Icon + MOBILE + + + )} + {networks?.has("iot") && ( + + + iot Icon + IOT + + + )}
diff --git a/src/components/RevokeProxyButton.tsx b/src/components/RevokeProxyButton.tsx index eb0109e..324ffa2 100644 --- a/src/components/RevokeProxyButton.tsx +++ b/src/components/RevokeProxyButton.tsx @@ -7,12 +7,14 @@ import { Button } from "./ui/button"; import { RiUserReceivedFill } from "react-icons/ri"; import { cn } from "@/lib/utils"; -export const RevokeProxyButton: React.FC<{ +export const RevokeProxyButton = React.forwardRef< + HTMLButtonElement, + { className?: string; onClick: () => void; isLoading?: boolean; wallet?: PublicKey; -}> = ({ wallet, className = "", onClick, isLoading = false }) => { +}>(({ wallet, className = "", onClick, isLoading = false }) => { const { connected } = useWallet(); const { loading, positions } = useGovernance(); @@ -50,4 +52,6 @@ export const RevokeProxyButton: React.FC<{ Revoke Proxies ); -}; +}); + +RevokeProxyButton.displayName = "RevokeProxyButton"; diff --git a/src/components/RevokeProxyModal.tsx b/src/components/RevokeProxyModal.tsx index 16b3622..f1eef1c 100644 --- a/src/components/RevokeProxyModal.tsx +++ b/src/components/RevokeProxyModal.tsx @@ -61,14 +61,40 @@ export const RevokeProxyModal: React.FC< setOpen(!open); }; + const selectedAll = proxiedPositions?.length === selectedPositions.size; + return ( {children} -

- Revoke Proxies -

+
+

+ Revoke Proxies +

+
+ Select the positions you would like to revoke from this voter. +
+
+
+
Proxied Positions
+ +
{loading ? ( <>
diff --git a/src/components/VoteHistory.tsx b/src/components/VoteHistory.tsx index e284d9a..6d5efec 100644 --- a/src/components/VoteHistory.tsx +++ b/src/components/VoteHistory.tsx @@ -10,6 +10,7 @@ import { CountdownTimer } from "./CountdownTimer"; import { toNumber } from "@helium/spl-utils"; import { Pill } from "./Pill"; import { Loader2 } from "lucide-react"; +import Link from "next/link"; export default function VoteHistory({ wallet }: { wallet: PublicKey }) { const { voteService, mint } = useGovernance(); @@ -28,10 +29,16 @@ export default function VoteHistory({ wallet }: { wallet: PublicKey }) { if (newVoteHistory.length < 100) { setHasMore(false); } - setVoteHistory((prevVoteHistory) => [ - ...prevVoteHistory, - ...newVoteHistory, - ]); + setVoteHistory((prev) => { + const seen = new Set() + return [...prev, ...newVoteHistory].filter(x => { + if (!seen.has(x.address)) { + seen.add(x.address) + return true + } + return false + }); + }); } }; @@ -41,7 +48,7 @@ export default function VoteHistory({ wallet }: { wallet: PublicKey }) { setVoteHistory([]); fetchMoreData(1); } - }, [voteService]); + }, [voteService?.registrar.toBase58()]); return (
@@ -65,7 +72,7 @@ export default function VoteHistory({ wallet }: { wallet: PublicKey }) { >
{voteHistories.map((voteHistory, index) => { - return ; + return ; })}
@@ -85,9 +92,13 @@ const ProposalItem: React.FC<{ isFailed, isCancelled, } = useProposalStatus(proposal); + const { network } = useGovernance() return ( -
+
{!completed && Actively Voting} @@ -98,7 +109,7 @@ const ProposalItem: React.FC<{
- HIP 37: H3Dex-based PoC Targeting + {proposal.name}
{timeExpired ? (
@@ -150,7 +161,7 @@ const ProposalItem: React.FC<{
)}
-
+ ); }; diff --git a/src/components/ui/autocomplete.tsx b/src/components/ui/autocomplete.tsx index cfee2e9..62a394f 100644 --- a/src/components/ui/autocomplete.tsx +++ b/src/components/ui/autocomplete.tsx @@ -133,7 +133,6 @@ export const AutoComplete = ({ {options.map((option) => { const isSelected = selected?.value === option.value; - console.log("isSelected", isSelected, selected?.value, option.value) return ( Date: Fri, 31 May 2024 14:17:20 -0700 Subject: [PATCH 10/41] Finish, just need to do more testing --- src/components/AssignProxyModal.tsx | 34 +---- src/components/ExpirationTimeSlider.tsx | 27 ++++ src/components/Pill.tsx | 1 + src/components/PositionCard.tsx | 114 ++++++++------ .../PositionManager/PositionManager.tsx | 42 +++-- .../PositionManager/ProxyPositionPrompt.tsx | 144 ++++++++++++++++++ src/components/Positions.tsx | 36 ++++- src/components/Proposals.tsx | 10 +- src/components/ProxySearch.tsx | 22 ++- src/components/VoteHistory.tsx | 22 ++- src/components/VoteOption.tsx | 79 ++++++---- src/components/VoteOptions.tsx | 60 ++++++-- src/components/ui/autocomplete.tsx | 15 +- src/hooks/useKnownProxy.ts | 27 ++++ 14 files changed, 477 insertions(+), 156 deletions(-) create mode 100644 src/components/ExpirationTimeSlider.tsx create mode 100644 src/components/PositionManager/ProxyPositionPrompt.tsx create mode 100644 src/hooks/useKnownProxy.ts diff --git a/src/components/AssignProxyModal.tsx b/src/components/AssignProxyModal.tsx index b39816e..dec45da 100644 --- a/src/components/AssignProxyModal.tsx +++ b/src/components/AssignProxyModal.tsx @@ -11,6 +11,7 @@ import { ProxySearch } from "./ProxySearch"; import { Button } from "./ui/button"; import { Dialog, DialogContent, DialogTrigger } from "./ui/dialog"; import { Slider } from "./ui/slider"; +import { ExpirationTimeSlider } from "./ExpirationTimeSlider"; interface AssignProxyModalProps { onSubmit: (args: { @@ -192,38 +193,17 @@ export const AssignProxyModal: React.FC< })}
-
-

Expiration Time

- { - setSelectedDays(e[0]); - }} - /> -
- {new Date(expirationTime * 1000).toLocaleString()} -
-
+
Your assigned proxy will expire by Aug 1 of each year by default, however you may select any date prior to this epoch date.
- {!wallet && ( -
-

Wallet to Assign

- -
- )}
)}
diff --git a/src/components/ExpirationTimeSlider.tsx b/src/components/ExpirationTimeSlider.tsx new file mode 100644 index 0000000..9cc2d82 --- /dev/null +++ b/src/components/ExpirationTimeSlider.tsx @@ -0,0 +1,27 @@ +import React from "react"; +import { Slider } from "./ui/slider"; + +export const ExpirationTimeSlider: React.FC<{ + maxDays: number; + selectedDays: number; + setSelectedDays: (days: number) => void; + expirationTime: number; +}> = ({ maxDays, selectedDays, setSelectedDays, expirationTime }) => { + return ( +
+

Expiration Time

+ { + setSelectedDays(e[0]); + }} + /> +
+ {new Date(expirationTime * 1000).toLocaleString()} +
+
+ ); +}; diff --git a/src/components/Pill.tsx b/src/components/Pill.tsx index 7c43f9b..72e41e6 100644 --- a/src/components/Pill.tsx +++ b/src/components/Pill.tsx @@ -14,6 +14,7 @@ const pillVariants = cva( info: "bg-info text-info-foreground border-info-foreground/20", purple: "bg-purple text-purple-foreground border-purple-foreground/20", pink: "bg-pink text-pink-foreground border-pink-foreground/20", + blue: "bg-blue-500 text-white border-blue-500/20", }, }, defaultVariants: { diff --git a/src/components/PositionCard.tsx b/src/components/PositionCard.tsx index a71cc37..d99837a 100644 --- a/src/components/PositionCard.tsx +++ b/src/components/PositionCard.tsx @@ -72,7 +72,14 @@ export const PositionCard: FC<{ className?: string; compact?: boolean; onClick?: () => void; -}> = ({ position, className = "", compact = false, onClick }) => { + canDelegate?: boolean; +}> = ({ + canDelegate: canDelegateIn = true, + position, + className = "", + compact = false, + onClick, +}) => { const path = usePathname(); const { lockup, hasGenesisMultiplier } = position; const { @@ -89,8 +96,8 @@ export const PositionCard: FC<{ const elapsedTime = new BN(unixNow).sub(lockup.startTs); const totalTime = lockup.endTs.sub(lockup.startTs); const decayedPercentage = elapsedTime.muln(100).div(totalTime); - const canDelegate = network === "hnt"; - const { knownProxy } = useKnownProxy(position?.proxy?.nextVoter) + const canDelegate = canDelegateIn && network === "hnt"; + const { knownProxy } = useKnownProxy(position?.proxy?.nextVoter); const lockedTokens = mintAcc && humanReadable(position.amountDepositedNative, mintAcc.decimals); @@ -231,56 +238,65 @@ export const PositionCard: FC<{

- {canDelegate && ( - -
-
-
-
-

DELEGATED TO

- {!isDecayed && delegatedSubDaoMetadata ? ( -
-
- delegated-subdao + + + {canDelegate && ( + <> +
+
+
+
+

DELEGATED TO

+ {!isDecayed && delegatedSubDaoMetadata ? ( +
+
+ delegated-subdao +
+

{delegatedSubDaoMetadata.symbol}

-

{delegatedSubDaoMetadata.symbol}

-
- ) : !isDecayed ? ( - - - - ) : ( -

UNDELEGATED

- )} -
+ + + ) : ( +

UNDELEGATED

+ )} +
+ + )} +
+

PROXIED TO

{position.proxy && !position.proxy.nextVoter.equals(PublicKey.default) ? ( -
-

PROXIED TO

- - - {knownProxy?.name || - ellipsisMiddle(position.proxy.nextVoter.toBase58())} - - -
- ) : null} - - )} + + + {knownProxy?.name || + ellipsisMiddle(position.proxy.nextVoter.toBase58())} + + + ) : ( + + + + )} +
+ ); diff --git a/src/components/PositionManager/PositionManager.tsx b/src/components/PositionManager/PositionManager.tsx index 7c48d1f..22ebee9 100644 --- a/src/components/PositionManager/PositionManager.tsx +++ b/src/components/PositionManager/PositionManager.tsx @@ -20,6 +20,7 @@ import { useRelinquishPositionVotes, useSplitPosition, useTransferPosition, + useUnassignProxies, } from "@helium/voter-stake-registry-hooks"; import { WalletSignTransactionError } from "@solana/wallet-adapter-base"; import BN from "bn.js"; @@ -154,7 +155,9 @@ export const PositionManager: FC = ({ setAction(undefined); }, [refetchState, setAction]); - const { loading: isUpdatingProxy, assignProxies } = useAssignProxies(); + const { loading: isAssigningProxy, assignProxies } = useAssignProxies(); + const { loading: isRevokingProxy, unassignProxies } = useUnassignProxies(); + const isUpdatingProxy = isAssigningProxy || isRevokingProxy const { loading: isFlipping, flipPositionLockupKind } = useFlipPositionLockupKind(); const { loading: isClaiming, claimPositionRewards } = @@ -167,19 +170,36 @@ export const PositionManager: FC = ({ const { loading: isRelinquishing, relinquishPositionVotes } = useRelinquishPositionVotes(); - const handleUpdateProxy = async (proxy: string) => { + const handleUpdateProxy = async ({ + proxy, + expirationTime, + isRevoke, + }: { + proxy?: string; + expirationTime?: number; + isRevoke?: boolean; + }) => { try { - const nextVoter = new PublicKey(proxy) - await relinquishPositionVotes({ - position, - organization, - onInstructions: onInstructions(provider), - }); - - toast("Proxy assigned"); + if (isRevoke) { + await unassignProxies({ + positions: [position], + onInstructions: onInstructions(provider), + }); + } else { + await assignProxies({ + positions: [position], + recipient: new PublicKey(proxy || ""), + expirationTime: new BN(expirationTime || 0), + onInstructions: onInstructions(provider), + }); + } + toast(`Proxy ${isRevoke ? "revoked" : "assigned"}`); } catch (e: any) { if (!(e instanceof WalletSignTransactionError)) { - toast(e.message || "Relinquish failed, please try again"); + toast( + e.message || + `${isRevoke ? "Revoke" : "Assign"} failed, please try again` + ); } } }; diff --git a/src/components/PositionManager/ProxyPositionPrompt.tsx b/src/components/PositionManager/ProxyPositionPrompt.tsx new file mode 100644 index 0000000..fb4ae66 --- /dev/null +++ b/src/components/PositionManager/ProxyPositionPrompt.tsx @@ -0,0 +1,144 @@ +"use client"; + +import { PositionWithMeta } from "@helium/voter-stake-registry-hooks"; +import React, { FC, useMemo, useState } from "react"; +import { Button } from "../ui/button"; +import { Loader2, X } from "lucide-react"; +import { PositionCard } from "../PositionCard"; +import { useKnownProxy } from "@/hooks/useKnownProxy"; +import { ProxySearch } from "../ProxySearch"; +import { ExpirationTimeSlider } from "../ExpirationTimeSlider"; +import { PublicKey } from "@solana/web3.js"; +import { RiUserSharedFill } from "react-icons/ri"; +import { useGovernance } from "@/providers/GovernanceProvider"; +import Link from "next/link"; + +export const ProxyPositionPrompt: FC<{ + position: PositionWithMeta; + isSubmitting?: boolean; + onCancel: () => void; + onConfirm: ({ proxy, expirationTime, isRevoke }: { proxy?: string, expirationTime?: number; isRevoke?: boolean }) => Promise; +}> = ({ position, isSubmitting, onCancel, onConfirm }) => { + const isProxied = + position.proxy?.nextVoter && + !position.proxy?.nextVoter.equals(PublicKey.default); + const { knownProxy } = useKnownProxy(position.proxy?.nextVoter) + const [proxy, setProxy] = useState(position.proxy?.nextVoter?.toBase58() || "") + const { network } = useGovernance() + + const today = new Date(); + const augustFirst = Date.UTC( + today.getMonth() > 7 ? today.getFullYear() + 1 : today.getFullYear(), + 7, + 1 + ); + const maxDate = augustFirst - 1000 + const maxDays = Math.floor( + (maxDate - today.getTime()) / (1000 * 60 * 60 * 24) + ); + const [selectedDays, setSelectedDays] = useState(maxDays); + const expirationTime = useMemo( + () => + selectedDays === maxDays + ? maxDate.valueOf() / 1000 + : new Date().valueOf() / 1000 + selectedDays * (24 * 60 * 60), + [selectedDays, maxDays, maxDate] + ); + + const handleSubmit = async () => { + await onConfirm({ proxy, expirationTime, isRevoke: isProxied }); + }; + + return ( +
+
+ +
+
+

Update Proxy

+ {isProxied ? ( +

+ Your position is currently proxied to{" "} + {knownProxy?.name || position?.proxy?.nextVoter.toBase58()} +

+ ) : ( + <> +

+ Assign proxy to a trusted voter if you don’t want to vote. + You can override any active votes anytime - your vote takes + precedence over a proxy. +

+
+ + + +
+
+
+ + OR + +
+
+ + )} +
+ {isProxied ? ( +
+
+ + +
+
+

+ A network fee will be required +

+
+
+ ) : ( + <> + + +
+
+ + +
+
+

+ A network fee will be required +

+
+
+ + )} +
+ ); +}; diff --git a/src/components/Positions.tsx b/src/components/Positions.tsx index 1819dc6..c7b2ec4 100644 --- a/src/components/Positions.tsx +++ b/src/components/Positions.tsx @@ -56,26 +56,34 @@ export const Positions: FC = () => { [positions, loadingGov] ); + const proxiedPositions = useMemo( + () => sortedPositions?.filter((p) => p.isProxiedToMe), + [sortedPositions] + ); + const unProxiedPositions = useMemo( + () => sortedPositions?.filter((p) => !p.isProxiedToMe), + [sortedPositions] + ); const decayedPositions = useMemo( () => - sortedPositions + unProxiedPositions ?.filter((p) => p.lockup.kind.cliff) .filter((p) => p.lockup.endTs.lte(new BN(Date.now() / 1000))), - [sortedPositions] + [unProxiedPositions] ); const notDecayedPositions = useMemo( () => - sortedPositions?.filter( + unProxiedPositions?.filter( (p) => p.lockup.kind.constant || p.lockup.endTs.gt(new BN(Date.now() / 1000)) ), - [sortedPositions] + [unProxiedPositions] ); const positionsWithRewards = useMemo( - () => positions?.filter((p) => p.hasRewards), - [positions] + () => unProxiedPositions?.filter((p) => p.hasRewards), + [unProxiedPositions] ); const { loading: claimingAllRewards, claimAllPositionsRewards } = @@ -211,6 +219,22 @@ export const Positions: FC = () => { )} + {proxiedPositions && proxiedPositions.length > 0 && ( + + + Proxied to Me + + + {proxiedPositions.map((position) => ( + + ))} + + + )}
); diff --git a/src/components/Proposals.tsx b/src/components/Proposals.tsx index 905e59a..7c04fc1 100644 --- a/src/components/Proposals.tsx +++ b/src/components/Proposals.tsx @@ -22,7 +22,7 @@ export const Proposals: FC> = ({ const { loading, accounts: proposalsWithDups } = useOrganizationProposals(organization); - const undupedProposals = useMemo(() => { + const dedupedProposals = useMemo(() => { const seen = new Set(); return (proposalsWithDups || []) .filter((p) => { @@ -35,20 +35,20 @@ export const Proposals: FC> = ({ const activeProposals = useMemo( () => - undupedProposals.filter( + dedupedProposals.filter( (proposal) => getDerivedProposalState(proposal.info as ProposalV0) === "active" ), - [undupedProposals] + [dedupedProposals] ); const inactiveProposals = useMemo( () => - undupedProposals.filter( + dedupedProposals.filter( (proposal) => getDerivedProposalState(proposal.info as ProposalV0) !== "active" ), - [undupedProposals] + [dedupedProposals] ); const isLoading = useMemo(() => loading || loadingGov, [loading, loadingGov]); diff --git a/src/components/ProxySearch.tsx b/src/components/ProxySearch.tsx index 889b904..6faf20f 100644 --- a/src/components/ProxySearch.tsx +++ b/src/components/ProxySearch.tsx @@ -48,19 +48,15 @@ export const ProxySearch: React.FC<{ const { result } = useAsync(debouncedSearch, [input]); - return result ? ( - onValueChange(v.value)} - value={result?.find((r) => r.value == value)} - onInputChange={setInput} - /> - ) : ( - - ); + return onValueChange(v.value)} + value={result?.find((r) => r.value == value)} + onInputChange={setInput} + />; }; function isValidPublicKey(input: string | undefined) { diff --git a/src/components/VoteHistory.tsx b/src/components/VoteHistory.tsx index 6d5efec..c87b8e6 100644 --- a/src/components/VoteHistory.tsx +++ b/src/components/VoteHistory.tsx @@ -4,7 +4,7 @@ import { useGovernance } from "@/providers/GovernanceProvider"; import { ProposalWithVotes } from "@helium/voter-stake-registry-sdk"; import { PublicKey } from "@solana/web3.js"; import BN from "bn.js"; -import { useEffect, useState } from "react"; +import { useEffect, useMemo, useState } from "react"; import InfiniteScroll from "react-infinite-scroll-component"; import { CountdownTimer } from "./CountdownTimer"; import { toNumber } from "@helium/spl-utils"; @@ -17,6 +17,15 @@ export default function VoteHistory({ wallet }: { wallet: PublicKey }) { const [voteHistories, setVoteHistory] = useState([]); const [hasMore, setHasMore] = useState(true); const [page, setPage] = useState(1); + const dedupedVoteHistories = useMemo(() => { + const seen = new Set(); + return (voteHistories || []) + .filter((p) => { + const has = seen.has(p.name); + seen.add(p.name); + return !has; + }) + }, [voteHistories]); const fetchMoreData = async (page: number) => { setPage(page); @@ -71,8 +80,10 @@ export default function VoteHistory({ wallet }: { wallet: PublicKey }) { } >
- {voteHistories.map((voteHistory, index) => { - return ; + {dedupedVoteHistories.map((voteHistory, index) => { + return ( + + ); })}
@@ -88,8 +99,6 @@ const ProposalItem: React.FC<{ timeExpired, endTs, votingResults, - isActive, - isFailed, isCancelled, } = useProposalStatus(proposal); const { network } = useGovernance() @@ -102,9 +111,6 @@ const ProposalItem: React.FC<{
{!completed && Actively Voting} - {isActive && completed && ( - Voting Closed - )} {isCancelled && Vote Cancelled}
diff --git a/src/components/VoteOption.tsx b/src/components/VoteOption.tsx index 1f039d5..404b112 100644 --- a/src/components/VoteOption.tsx +++ b/src/components/VoteOption.tsx @@ -1,16 +1,20 @@ "use client"; import { VoteChoiceWithMeta } from "@/lib/types"; -import { cn } from "@/lib/utils"; +import { cn, ellipsisMiddle } from "@/lib/utils"; import BN from "bn.js"; import React, { FC } from "react"; import { FaCircle, FaCircleCheck } from "react-icons/fa6"; import { Loader2 } from "lucide-react"; +import { PublicKey } from "@solana/web3.js"; +import { useKnownProxy } from "@/hooks/useKnownProxy"; +import { Pill } from "./Pill"; export const VoteOption: FC<{ option: VoteChoiceWithMeta; myWeight?: BN; canVote: boolean; + voters: PublicKey[]; canRelinquishVote: boolean; voting: boolean; className?: string; @@ -19,6 +23,7 @@ export const VoteOption: FC<{ }> = ({ option, myWeight, + voters, canVote, canRelinquishVote, voting, @@ -31,35 +36,55 @@ export const VoteOption: FC<{ canVote ? onVote : canRelinquishVote ? onRelinquishVote : undefined } className={cn( - "flex flex-row gap-2 py-6 px-4 rounded-sm items-center bg-slate-500 border-2 border-background cursor-pointer hover:bg-slate-500/80 active:bg-slate-500/60", + "flex flex-col gap-2 px-4 rounded-sm bg-slate-500 border-2 border-background cursor-pointer hover:bg-slate-500/80 active:bg-slate-500/60", voting && "bg-primary/15 border-primary hover:bg-inherit", myWeight && "bg-slate-500/25 border-slate-500", - className + className, + voters.length > 0 ? "pt-4 pb-2" : "py-6" )} > - {voting ? ( - - ) : ( - - )} -

{option.name}

- {myWeight && } +
+ {voting ? ( + + ) : ( + + )} +

{option.name}

+ {myWeight && } +
+ + { voters.length > 0 &&
+
Voted by
+ {voters.map((v) => ( + + ))} +
}
); + +const Voter: FC<{ voter: PublicKey }> = ({ voter }) => { + const { knownProxy } = useKnownProxy(voter); + return ( + + {knownProxy?.name || ellipsisMiddle(voter.toBase58())} + + ); +}; + diff --git a/src/components/VoteOptions.tsx b/src/components/VoteOptions.tsx index 44b730f..b4c1fe8 100644 --- a/src/components/VoteOptions.tsx +++ b/src/components/VoteOptions.tsx @@ -1,14 +1,21 @@ "use client"; import { VoteChoiceWithMeta } from "@/lib/types"; -import { useRelinquishVote, useVote } from "@helium/voter-stake-registry-hooks"; -import { PublicKey } from "@solana/web3.js"; -import React, { FC, useState } from "react"; -import { VoteOption } from "./VoteOption"; -import { toast } from "sonner"; -import { WalletSignTransactionError } from "@solana/wallet-adapter-base"; import { onInstructions } from "@/lib/utils"; +import { useGovernance } from "@/providers/GovernanceProvider"; import { useAnchorProvider } from "@helium/helium-react-hooks"; +import { + useAssignProxies, + useRelinquishVote, + useVote, +} from "@helium/voter-stake-registry-hooks"; +import { WalletSignTransactionError } from "@solana/wallet-adapter-base"; +import { PublicKey } from "@solana/web3.js"; +import { FC, useMemo, useState } from "react"; +import { toast } from "sonner"; +import { AssignProxyModal } from "./AssignProxyModal"; +import { ProxyButton } from "./ProxyButton"; +import { VoteOption } from "./VoteOption"; export const VoteOptions: FC<{ choices?: VoteChoiceWithMeta[]; @@ -16,7 +23,18 @@ export const VoteOptions: FC<{ proposalKey: PublicKey; }> = ({ choices = [], maxChoicesPerVoter, proposalKey }) => { const [currVote, setCurrVote] = useState(0); - const { voteWeights, canVote, vote, loading: voting } = useVote(proposalKey); + const { voteWeights, canVote, vote, loading: voting, voters } = useVote(proposalKey); + + const { positions } = useGovernance(); + + const unproxiedPositions = useMemo( + () => + positions?.filter( + (p) => !p.proxy || p.proxy.nextVoter.equals(PublicKey.default) + ), + [positions] + ); + const canProxy = !!unproxiedPositions?.length; const { canRelinquishVote, @@ -61,10 +79,12 @@ export const VoteOptions: FC<{ } }; + const { assignProxies } = useAssignProxies(); + return (
Voting Options
-
+

To vote, click on any option. To remove your vote, click the option again.{" "} @@ -72,12 +92,34 @@ export const VoteOptions: FC<{

Vote for up to {maxChoicesPerVoter} of {choices.length} options.

+ {canProxy && ( + <> +
+
+ + OR + +
+
+

+ Assign proxy to a trusted voter if you don’t want to vote. + You can override any active votes anytime - your vote takes + precedence over a proxy. +

+
+ + {}} isLoading={false} /> + +
+ + )}
- {choices.map((r) => ( + {choices.map((r, index) => ( ) => { + const input = inputRef.current; + if (!input) { + return; + } + + onInputChange?.(input.value); + }, + [onInputChange] + ); + const handleBlur = useCallback(() => { setOpen(false); setInputValue(selected?.label); @@ -99,6 +111,7 @@ export const AutoComplete = ({
{ + if (vs && nv && !nv.equals(PublicKey.default)) { + return ( + await vs.searchProxies({ + query: nv.toBase58(), + }) + )[0]; + } + }, + [nextVoter, voteService] + ); + + return { knownProxy, loading, error }; +} From 2313f9dbcdfe4d44587a276487e0b4565c56a1b3 Mon Sep 17 00:00:00 2001 From: Noah Prince Date: Fri, 14 Jun 2024 15:08:07 -0700 Subject: [PATCH 11/41] WIP: React query --- next.config.mjs | 14 +++- package.json | 2 + src/components/AssignProxyModal.tsx | 2 +- src/components/Proxies.tsx | 52 ++++-------- src/components/ProxyProfile.tsx | 2 +- src/components/ProxySearch.tsx | 89 ++++++++++---------- src/components/VoteHistory.tsx | 103 +++++++++--------------- src/components/ui/autocomplete.tsx | 36 +++++---- src/hooks/useProposalStatus.ts | 2 +- src/providers/GovernanceProvider.tsx | 2 +- src/providers/providers.tsx | 15 ++-- yarn.lock | 116 ++++++++++++++++----------- 12 files changed, 213 insertions(+), 222 deletions(-) diff --git a/next.config.mjs b/next.config.mjs index f6b2ce7..a88a2bf 100644 --- a/next.config.mjs +++ b/next.config.mjs @@ -15,11 +15,23 @@ const nextConfig = { port: "", pathname: "/**/**", }, + { + protocol: "https", + hostname: "helium.io", + port: "", + pathname: "/**/**", + }, + { + protocol: "https", + hostname: "test-helium.com", + port: "", + pathname: "/**/**", + }, ...(process.env.NODE_ENV === "development" && [ { protocol: "http", hostname: "localhost", - port: "8081", + port: "8082", pathname: "/**/**", }, ]), diff --git a/package.json b/package.json index 46ff12c..98096c4 100644 --- a/package.json +++ b/package.json @@ -43,6 +43,8 @@ "@solana/wallet-adapter-solflare": "^0.6.28", "@solana/web3.js": "^1.90.0", "@sqds/sdk": "^2.0.4", + "@tanstack/react-query": "^5.45.0", + "@uidotdev/usehooks": "^2.4.1", "axios": "^1.6.7", "bn.js": "^5.2.1", "class-variance-authority": "^0.7.0", diff --git a/src/components/AssignProxyModal.tsx b/src/components/AssignProxyModal.tsx index dec45da..b9154a0 100644 --- a/src/components/AssignProxyModal.tsx +++ b/src/components/AssignProxyModal.tsx @@ -70,7 +70,7 @@ export const AssignProxyModal: React.FC< if (selectedDays > maxDays) { setSelectedDays(maxDays); } - }, [maxDays]); + }, [maxDays, selectedDays]); const changeRecipient = (e: any) => { setRecipient(e.target.value); diff --git a/src/components/Proxies.tsx b/src/components/Proxies.tsx index c152442..87fd197 100644 --- a/src/components/Proxies.tsx +++ b/src/components/Proxies.tsx @@ -18,6 +18,7 @@ import { Card } from "./ui/card"; import { Input } from "./ui/input"; import { Loader2 } from "lucide-react"; import { Skeleton } from "./ui/skeleton"; +import { useVoters } from "@helium/voter-stake-registry-hooks"; const DECENTRALIZATION_RISK_INDEX = 6; @@ -66,40 +67,19 @@ export function Proxies() { const { voteService, mint } = useGovernance(); const { info: mintAcc } = useMint(mint); const decimals = mintAcc?.decimals; - const [proxies, setProxies] = useState([]); - const [hasMore, setHasMore] = useState(false); - const [page, setPage] = useState(1); const path = usePathname(); const [proxySearch, setProxySearch] = useState(""); - - const fn = useMemo( - () => - debounce(async (page: number, search: string) => { - setPage(page); - if (voteService) { - const newProxies = await voteService.getProxies({ - page, - limit: 100, - query: search, - }); - if (newProxies.length == 100) { - setHasMore(true); - } - setProxies((prevProxies) => [...prevProxies, ...newProxies]); - } - }, 300), - [voteService] - ); - - const { execute: fetchMoreData, loading } = useAsyncCallback(fn); - - useEffect(() => { - if (voteService) { - setProxies([]); - setPage(1); - fetchMoreData(1, proxySearch); - } - }, [voteService?.registrar.toBase58(), proxySearch]); + const { + data: voters, + fetchNextPage, + hasNextPage, + isLoading, + isFetchingNextPage, + } = useVoters({ + search: proxySearch, + amountPerPage: 100, + }); + const proxies = voters?.pages.flat() || []; return ( @@ -118,9 +98,9 @@ export function Proxies() {
fetchMoreData(page + 1, proxySearch)} - hasMore={!loading && hasMore} + dataLength={proxies?.length} + next={() => fetchNextPage()} + hasMore={hasNextPage} loader={
@@ -193,7 +173,7 @@ export function Proxies() { ) : null} ))} - {loading && } + {(isLoading || isFetchingNextPage) && }
diff --git a/src/components/ProxyProfile.tsx b/src/components/ProxyProfile.tsx index b7c3cef..a8710ed 100644 --- a/src/components/ProxyProfile.tsx +++ b/src/components/ProxyProfile.tsx @@ -45,7 +45,7 @@ export function ProxyProfile({ const { mint, voteService } = useGovernance(); const { info: mintAcc } = useMint(mint); const decimals = mintAcc?.decimals; - const { assignProxies } = useAssignProxies(); + const { mutateAsync: assignProxies } = useAssignProxies(); const { unassignProxies } = useUnassignProxies(); const wallet = useMemo(() => new PublicKey(proxy.wallet), [proxy.wallet]); const { votingPower, positions } = useProxiedTo(wallet); diff --git a/src/components/ProxySearch.tsx b/src/components/ProxySearch.tsx index 6faf20f..7cff714 100644 --- a/src/components/ProxySearch.tsx +++ b/src/components/ProxySearch.tsx @@ -1,62 +1,57 @@ -import React, { useMemo, useState } from "react"; -import { AutoComplete, Option } from "./ui/autocomplete"; -import { useAsync } from "react-async-hook"; -import { useHeliumVsrState } from "@helium/voter-stake-registry-hooks"; +import { ellipsisMiddle } from "@/lib/utils"; +import { useVoters } from "@helium/voter-stake-registry-hooks"; import { PublicKey } from "@solana/web3.js"; -import { debounce, ellipsisMiddle } from "@/lib/utils"; +import { useDebounce } from "@uidotdev/usehooks"; +import React, { useMemo, useState } from "react"; +import { AutoComplete } from "./ui/autocomplete"; import { Loader2 } from "lucide-react"; export const ProxySearch: React.FC<{ value: string; onValueChange: (value: string) => void; }> = ({ value, onValueChange }) => { - const [isLoading, setLoading] = useState(false); const [input, setInput] = useState(); - const { voteService } = useHeliumVsrState(); - - const debouncedSearch = useMemo( - () => - debounce(async (query: string | undefined) => { - setLoading(true); - try { - const results = await voteService?.searchProxies({ - query: query || "", - }); + const debouncedInput = useDebounce(input, 300); + const { data: resultPaged, isLoading } = useVoters({ + search: debouncedInput || "", + amountPerPage: 20, + }); - const resultsAsOptions = - results?.map((r) => { - return { - value: r.wallet, - label: `${r.name} | ${ellipsisMiddle(r.wallet)}`, - }; - }) || []; + const result = useMemo(() => { + const resultsAsOptions = + resultPaged?.pages.flat().map((r) => { + return { + value: r.wallet, + label: `${r.name} | ${ellipsisMiddle(r.wallet)}`, + }; + }) || []; + if (isValidPublicKey(debouncedInput)) { + resultsAsOptions.push({ + value: debouncedInput || "", + label: debouncedInput || "", + }); + } + return resultsAsOptions; + }, [resultPaged, debouncedInput]); + const selectedOption = useMemo(() => { + return result?.find((r) => r.value == value); + }, [result, value]) - if (isValidPublicKey(query)) { - resultsAsOptions.push({ - value: query || "", - label: query || "", - }); - } + if (value && !selectedOption) { + return ; + } - return resultsAsOptions; - } finally { - setLoading(false); - } - }, 300), - [voteService] + return ( + onValueChange(v.value)} + value={selectedOption} + onInputChange={setInput} + /> ); - - const { result } = useAsync(debouncedSearch, [input]); - - return onValueChange(v.value)} - value={result?.find((r) => r.value == value)} - onInputChange={setInput} - />; }; function isValidPublicKey(input: string | undefined) { diff --git a/src/components/VoteHistory.tsx b/src/components/VoteHistory.tsx index c87b8e6..1baec8d 100644 --- a/src/components/VoteHistory.tsx +++ b/src/components/VoteHistory.tsx @@ -11,63 +11,32 @@ import { toNumber } from "@helium/spl-utils"; import { Pill } from "./Pill"; import { Loader2 } from "lucide-react"; import Link from "next/link"; +import { useVotesForWallet } from "@helium/voter-stake-registry-hooks"; export default function VoteHistory({ wallet }: { wallet: PublicKey }) { - const { voteService, mint } = useGovernance(); - const [voteHistories, setVoteHistory] = useState([]); - const [hasMore, setHasMore] = useState(true); - const [page, setPage] = useState(1); + const { + data: voteHistoryPages, + fetchNextPage, + hasNextPage, + } = useVotesForWallet({ + wallet, + amountPerPage: 20, + }); const dedupedVoteHistories = useMemo(() => { const seen = new Set(); - return (voteHistories || []) - .filter((p) => { - const has = seen.has(p.name); - seen.add(p.name); - return !has; - }) - }, [voteHistories]); - - const fetchMoreData = async (page: number) => { - setPage(page); - if (voteService) { - const newVoteHistory = await voteService.getVotesForWallet({ - wallet: wallet, - page: page, - limit: 100, - }); - if (newVoteHistory.length < 100) { - setHasMore(false); - } - setVoteHistory((prev) => { - const seen = new Set() - return [...prev, ...newVoteHistory].filter(x => { - if (!seen.has(x.address)) { - seen.add(x.address) - return true - } - return false - }); - }); - } - }; - - useEffect(() => { - if (voteService) { - setHasMore(true); - setVoteHistory([]); - fetchMoreData(1); - } - }, [voteService?.registrar.toBase58()]); + return (voteHistoryPages?.pages?.flat() || []).filter((p) => { + const has = seen.has(p.name); + seen.add(p.name); + return !has; + }); + }, [voteHistoryPages]); return (
{ - setPage(page + 1); - fetchMoreData(page + 1); - }} - hasMore={hasMore} + dataLength={dedupedVoteHistories.length} + next={fetchNextPage} + hasMore={hasNextPage} loader={
@@ -80,7 +49,7 @@ export default function VoteHistory({ wallet }: { wallet: PublicKey }) { } >
- {dedupedVoteHistories.map((voteHistory, index) => { + {dedupedVoteHistories.map((voteHistory) => { return ( ); @@ -94,14 +63,11 @@ export default function VoteHistory({ wallet }: { wallet: PublicKey }) { const ProposalItem: React.FC<{ proposal: ProposalWithVotes; }> = ({ proposal }) => { - const { - completed, - timeExpired, - endTs, - votingResults, - isCancelled, - } = useProposalStatus(proposal); - const { network } = useGovernance() + const { completed, timeExpired, endTs, votingResults, isCancelled } = + useProposalStatus(proposal); + const { network } = useGovernance(); + // @ts-ignore + const choices = proposal.state?.resolved?.choices; return ( Vote Cancelled}
-
- {proposal.name} -
+
{proposal.name}
{timeExpired ? (
+ proposal.choices[c].name) + .join(", ") + : "" + } /> -
) : null}
@@ -162,7 +137,7 @@ const ProposalItem: React.FC<{
Est. Time Remaining
- +
)} diff --git a/src/components/ui/autocomplete.tsx b/src/components/ui/autocomplete.tsx index 8b66a71..831e851 100644 --- a/src/components/ui/autocomplete.tsx +++ b/src/components/ui/autocomplete.tsx @@ -1,17 +1,21 @@ +import { Command as CommandPrimitive } from "cmdk"; +import { + useCallback, + useRef, + useState, + type KeyboardEvent +} from "react"; import { CommandGroup, - CommandItem, - CommandList, CommandInput, - Command, + CommandItem, + CommandList } from "./command"; -import { Command as CommandPrimitive } from "cmdk"; -import { useState, useRef, useCallback, type KeyboardEvent, useEffect } from "react"; import { Skeleton } from "./skeleton"; -import { Check } from "lucide-react"; import { cn } from "@/lib/utils"; +import { Check } from "lucide-react"; export type Option = Record<"value" | "label", string> & Record; @@ -74,17 +78,17 @@ export const AutoComplete = ({ [isOpen, onInputChange, options, onValueChange] ); - const handleKeyUp = useCallback( - (event: KeyboardEvent) => { - const input = inputRef.current; - if (!input) { - return; - } + const handleKeyUp = useCallback( + (event: KeyboardEvent) => { + const input = inputRef.current; + if (!input) { + return; + } - onInputChange?.(input.value); - }, - [onInputChange] - ); + onInputChange?.(input.value); + }, + [onInputChange] + ); const handleBlur = useCallback(() => { setOpen(false); diff --git a/src/hooks/useProposalStatus.ts b/src/hooks/useProposalStatus.ts index eecc8a5..af7f089 100644 --- a/src/hooks/useProposalStatus.ts +++ b/src/hooks/useProposalStatus.ts @@ -39,7 +39,7 @@ export function useProposalStatus(proposal?: ProposalV0 | ProposalWithVotes) { // @ts-ignore (proposal?.state.resolved ? // @ts-ignore - proposal?.state.resolved.endTs + new BN(proposal?.state.resolved.endTs) : // @ts-ignore new BN(proposal?.state.voting?.startTs).add( resolution.settings.nodes.find( diff --git a/src/providers/GovernanceProvider.tsx b/src/providers/GovernanceProvider.tsx index 9b08aad..205b995 100644 --- a/src/providers/GovernanceProvider.tsx +++ b/src/providers/GovernanceProvider.tsx @@ -104,7 +104,7 @@ const GovernanceProvider: FC<{ children: ReactNode }> = ({ children }) => { mint={mint} wallet={anchorProvider?.wallet as Wallet} connection={anchorProvider?.connection} - heliumVoteUri="http://localhost:8081" + heliumVoteUri={process.env.NEXT_PUBLIC_HELIUM_VOTE_URI} > {children} diff --git a/src/providers/providers.tsx b/src/providers/providers.tsx index 90185f2..86da9b0 100644 --- a/src/providers/providers.tsx +++ b/src/providers/providers.tsx @@ -4,11 +4,16 @@ import React, { FC } from "react"; import { WalletProvider } from "./WalletProvider"; import { AccountProvider } from "./AccountProvider"; import { GovernanceProvider } from "./GovernanceProvider"; +import { QueryClient, QueryClientProvider } from "@tanstack/react-query"; + +const queryClient = new QueryClient(); export const Providers: FC = ({ children }) => ( - - - {children} - - + + + + {children} + + + ); diff --git a/yarn.lock b/yarn.lock index fb7642c..6f93ca8 100644 --- a/yarn.lock +++ b/yarn.lock @@ -171,7 +171,7 @@ resolved "https://registry.yarnpkg.com/@floating-ui/utils/-/utils-0.2.1.tgz#16308cea045f0fc777b6ff20a9f25474dd8293d2" integrity sha512-9TANp6GPoMtYzQdt54kfAyMmz1+osLlXdg2ENroU7zzrtflTLrrC/lgrIfaSe+Wu0b89GKccT7vxXA0MoAIO+Q== -"@helium/account-fetch-cache-hooks@^0.5.0", "@helium/account-fetch-cache-hooks@^0.7.11", "@helium/account-fetch-cache-hooks@^0.7.12": +"@helium/account-fetch-cache-hooks@^0.5.0", "@helium/account-fetch-cache-hooks@^0.7.11", "@helium/account-fetch-cache-hooks@^0.7.17": version "0.7.11" resolved "https://registry.yarnpkg.com/@helium/account-fetch-cache-hooks/-/account-fetch-cache-hooks-0.7.11.tgz#cc36cc403958de9b9f230bdd1adf2730b9dfd287" integrity sha512-YoUacY5cQJStezTIw3sbmxxsuyH+P0VNtVVGnQ7jA3g+Y20BISWs/NOxf5w3cyAPscadUzTnqwGFiQ2isd9UTg== @@ -180,7 +180,7 @@ "@solana/web3.js" "^1.78.8" react-async-hook "^4.0.0" -"@helium/account-fetch-cache@^0.5.0", "@helium/account-fetch-cache@^0.7.11", "@helium/account-fetch-cache@^0.7.12": +"@helium/account-fetch-cache@^0.5.0", "@helium/account-fetch-cache@^0.7.11", "@helium/account-fetch-cache@^0.7.17": version "0.7.11" resolved "https://registry.yarnpkg.com/@helium/account-fetch-cache/-/account-fetch-cache-0.7.11.tgz#5813509464214cbfbbe42040eb5a48a386e1eefd" integrity sha512-5HPecniIyU/rcUc+Na7gqPRr352Dw8egrfgOzc24PdquVWvbJzrVwfcjrFL2PGEr858uTx0uIzbICrfsaMvEaQ== @@ -212,26 +212,26 @@ "@solana/spl-token" "^0.3.8" "@solana/web3.js" "^1.78.4" -"@helium/anchor-resolvers@^0.7.12": - version "0.7.12" - resolved "https://registry.yarnpkg.com/@helium/anchor-resolvers/-/anchor-resolvers-0.7.12.tgz#bb6921d252c7ae4c2788569ddbf68fb57a3f2adc" - integrity sha512-KphCkH4IHRMxWq/SSaWRxDVV8b1w8L0tY1qFOvvH/bY+Mr1E8CiVHZCCpdi1c5k/idLDz/wHvHCUSXppFPxdDQ== +"@helium/anchor-resolvers@^0.7.17": + version "0.7.17" + resolved "https://registry.yarnpkg.com/@helium/anchor-resolvers/-/anchor-resolvers-0.7.17.tgz#3404df1190af30f26dd53e477df6f0d6294b9773" + integrity sha512-F5coBe4NJSFyoc2jLetguKr7mnjmOdHv8aVlflPVXTic6YcqlaaLdJ36JHh2VRVmX+ulWbWKdUNJX65vAkWnNA== dependencies: "@solana/spl-token" "^0.3.8" "@solana/web3.js" "^1.78.8" -"@helium/circuit-breaker-sdk@^0.7.12": - version "0.7.12" - resolved "https://registry.yarnpkg.com/@helium/circuit-breaker-sdk/-/circuit-breaker-sdk-0.7.12.tgz#400d28228f473edc80dc8b0a81ef76cf6a3f3bcd" - integrity sha512-4qhoYuW0Aeo9+gg1/z9Fp+IjtS4+v2Wz88imKSHYmpINJ3BNNh7q7zfuYsX/t1utQyaYxhFSejlIIP1yVdlmsw== +"@helium/circuit-breaker-sdk@^0.7.17": + version "0.7.17" + resolved "https://registry.yarnpkg.com/@helium/circuit-breaker-sdk/-/circuit-breaker-sdk-0.7.17.tgz#1f706285e866628ffefe7078962cc961a238fb9f" + integrity sha512-Zs06f1U7R9Ant/Ip/S5SkagM/li/R8XbIVtSlgqqET3y48EVKbPAsSmR+VByOybAb5rIeiOIFitkHTv/bmSicQ== dependencies: "@coral-xyz/anchor" "^0.28.0" - "@helium/anchor-resolvers" "^0.7.12" - "@helium/idls" "^0.7.12" + "@helium/anchor-resolvers" "^0.7.17" + "@helium/idls" "^0.7.17" bn.js "^5.2.0" bs58 "^4.0.1" -"@helium/helium-react-hooks@^0.5.0", "@helium/helium-react-hooks@^0.7.11", "@helium/helium-react-hooks@^0.7.12": +"@helium/helium-react-hooks@^0.5.0", "@helium/helium-react-hooks@^0.7.11", "@helium/helium-react-hooks@^0.7.17": version "0.7.11" resolved "https://registry.yarnpkg.com/@helium/helium-react-hooks/-/helium-react-hooks-0.7.11.tgz#1d67bf58906f9c8d02ee9e7cb064ba6fb1668f3b" integrity sha512-BD3cjdxn+98h+Cm1Dy5duwAk2RmmxqMkLoRQKZTiXK7X91d80bS3bHep6XbPMGlvHFokyrCcITiWp/ivHRHLLw== @@ -245,23 +245,23 @@ pako "^2.0.3" react-async-hook "^4.0.0" -"@helium/helium-sub-daos-sdk@^0.7.12": - version "0.7.12" - resolved "https://registry.yarnpkg.com/@helium/helium-sub-daos-sdk/-/helium-sub-daos-sdk-0.7.12.tgz#7b38a582e8f195c82f307225e48f3f8dedc24e95" - integrity sha512-ziVwT9mo8OK7lWHBXmqy6M9b9UltvphNFNtysdGIWjgnZYYWrZbK6t0PKKciCBg/W9D3SHQzWiiSHfQhHCwCFA== +"@helium/helium-sub-daos-sdk@^0.7.17": + version "0.7.17" + resolved "https://registry.yarnpkg.com/@helium/helium-sub-daos-sdk/-/helium-sub-daos-sdk-0.7.17.tgz#3b6b7a5872e5c0719d198988d2495ed5cbd495a8" + integrity sha512-NF8hfm9npOiEeP9UDkcPBlv28GqfonyWMphDzob4zSnQr/18ZNp+QczP1WNkUHvFwqngt/x2zJVPA3gigp+EKA== dependencies: "@coral-xyz/anchor" "^0.28.0" - "@helium/anchor-resolvers" "^0.7.12" - "@helium/circuit-breaker-sdk" "^0.7.12" - "@helium/treasury-management-sdk" "^0.7.12" - "@helium/voter-stake-registry-sdk" "^0.7.12" + "@helium/anchor-resolvers" "^0.7.17" + "@helium/circuit-breaker-sdk" "^0.7.17" + "@helium/treasury-management-sdk" "^0.7.17" + "@helium/voter-stake-registry-sdk" "^0.7.17" bn.js "^5.2.0" bs58 "^4.0.1" -"@helium/idls@^0.7.12": - version "0.7.12" - resolved "https://registry.yarnpkg.com/@helium/idls/-/idls-0.7.12.tgz#6940c0e4750e8201994e1420b6053e3aefff75d0" - integrity sha512-ZcAw904YsbyUqGuejhGq7YaE+S5RZfNTSkV43T/KA/HwEtxCyWRrz8oiKEVEbYXk+XX/InQX5feW/X+3g/w+5g== +"@helium/idls@^0.7.17": + version "0.7.17" + resolved "https://registry.yarnpkg.com/@helium/idls/-/idls-0.7.17.tgz#72705df5b1ef2d98502175a33b24977733491357" + integrity sha512-8tgojvyu3MEjydHpLqZSPNYVFcn7+69GuOA3EBpaB4PH9zWunMho9Jmcv7OkrJ0M2ftIFCupL2zsyU7tdF5zCw== dependencies: "@coral-xyz/anchor" "^0.28.0" "@solana/web3.js" "^1.78.8" @@ -327,13 +327,13 @@ "@helium/anchor-resolvers" "^0.5.0" "@helium/modular-governance-idls" "^0.0.8" -"@helium/spl-utils@^0.7.12", "@helium/spl-utils@file:.yalc/@helium/spl-utils": - version "0.7.12" +"@helium/spl-utils@^0.7.17", "@helium/spl-utils@file:.yalc/@helium/spl-utils": + version "0.7.17" dependencies: "@coral-xyz/anchor" "^0.28.0" - "@helium/account-fetch-cache" "^0.7.12" + "@helium/account-fetch-cache" "^0.7.17" "@helium/address" "^4.10.2" - "@helium/anchor-resolvers" "^0.7.12" + "@helium/anchor-resolvers" "^0.7.17" "@metaplex-foundation/mpl-token-metadata" "^2.10.0" "@solana/spl-account-compression" "^0.1.7" "@solana/spl-token" "^0.3.8" @@ -352,46 +352,47 @@ "@helium/anchor-resolvers" "^0.5.0" "@helium/modular-governance-idls" "^0.0.8" -"@helium/treasury-management-sdk@^0.7.12": - version "0.7.12" - resolved "https://registry.yarnpkg.com/@helium/treasury-management-sdk/-/treasury-management-sdk-0.7.12.tgz#4d9a4f3f04e92c082eacbf38f9ff6f928863bfad" - integrity sha512-Dv+J/Dr6gd9K5drVlUbaBYAI0FISaxhftY55BrofUDhYhsA8drciu+Y97MXt2BGKstAWAlJCHq3HbbwQbmjsmQ== +"@helium/treasury-management-sdk@^0.7.17": + version "0.7.17" + resolved "https://registry.yarnpkg.com/@helium/treasury-management-sdk/-/treasury-management-sdk-0.7.17.tgz#855443380773aea9b4d190bb3f1f96bbbd2e6eb7" + integrity sha512-mVwMsJ6e7EzETbPnzD3c3qLHwdnlspuhwbYMac+R3VqZVBLPwN0Q6zRoOY5XRAvbGcQKYwJsJjZMCkcYTCdVZw== dependencies: "@coral-xyz/anchor" "^0.28.0" - "@helium/anchor-resolvers" "^0.7.12" - "@helium/circuit-breaker-sdk" "^0.7.12" - "@helium/idls" "^0.7.12" + "@helium/anchor-resolvers" "^0.7.17" + "@helium/circuit-breaker-sdk" "^0.7.17" + "@helium/idls" "^0.7.17" bn.js "^5.2.0" bs58 "^4.0.1" "@helium/voter-stake-registry-hooks@file:.yalc/@helium/voter-stake-registry-hooks": - version "0.7.12" + version "0.7.17" dependencies: "@coral-xyz/anchor" "^0.28.0" - "@helium/account-fetch-cache" "^0.7.12" - "@helium/account-fetch-cache-hooks" "^0.7.12" - "@helium/circuit-breaker-sdk" "^0.7.12" - "@helium/helium-react-hooks" "^0.7.12" - "@helium/helium-sub-daos-sdk" "^0.7.12" + "@helium/account-fetch-cache" "^0.7.17" + "@helium/account-fetch-cache-hooks" "^0.7.17" + "@helium/circuit-breaker-sdk" "^0.7.17" + "@helium/helium-react-hooks" "^0.7.17" + "@helium/helium-sub-daos-sdk" "^0.7.17" "@helium/modular-governance-hooks" "^0.0.8" "@helium/modular-governance-idls" "0.0.8-next.19+4fa4c6b" - "@helium/spl-utils" "^0.7.12" - "@helium/voter-stake-registry-sdk" "^0.7.12" + "@helium/spl-utils" "^0.7.17" + "@helium/voter-stake-registry-sdk" "^0.7.17" "@solana/wallet-adapter-base" "^0.9.22" "@solana/wallet-adapter-react" "^0.15.32" "@solana/web3.js" "^1.78.8" + "@tanstack/react-query" "^5.45.0" axios "^1.3.6" bs58 "^4.0.1" react-async-hook "^4.0.0" -"@helium/voter-stake-registry-sdk@^0.7.12", "@helium/voter-stake-registry-sdk@file:.yalc/@helium/voter-stake-registry-sdk": - version "0.7.12" +"@helium/voter-stake-registry-sdk@^0.7.17", "@helium/voter-stake-registry-sdk@file:.yalc/@helium/voter-stake-registry-sdk": + version "0.7.17" dependencies: "@coral-xyz/anchor" "^0.28.0" - "@helium/anchor-resolvers" "^0.7.12" - "@helium/idls" "^0.7.12" + "@helium/anchor-resolvers" "^0.7.17" + "@helium/idls" "^0.7.17" "@helium/nft-proxy-sdk" "0.0.8-next.19+4fa4c6b" - "@helium/spl-utils" "^0.7.12" + "@helium/spl-utils" "^0.7.17" "@metaplex-foundation/mpl-token-metadata" "^2.10.0" "@solana/spl-token" "^0.3.8" bn.js "^5.2.0" @@ -1408,6 +1409,18 @@ lodash.merge "^4.6.2" postcss-selector-parser "6.0.10" +"@tanstack/query-core@5.45.0": + version "5.45.0" + resolved "https://registry.yarnpkg.com/@tanstack/query-core/-/query-core-5.45.0.tgz#47a662d311c2588867341238960ec21dc7f0714e" + integrity sha512-RVfIZQmFUTdjhSAAblvueimfngYyfN6HlwaJUPK71PKd7yi43Vs1S/rdimmZedPWX/WGppcq/U1HOj7O7FwYxw== + +"@tanstack/react-query@^5.45.0": + version "5.45.0" + resolved "https://registry.yarnpkg.com/@tanstack/react-query/-/react-query-5.45.0.tgz#6806bb7db1190840c2a7a727cdf192e0d7662a0a" + integrity sha512-y272cKRJp1BvehrWG4ashOBuqBj1Qm2O6fgYJ9LYSHrLdsCXl74GbSVjUQTReUdHuRIl9cEOoyPa6HYag400lw== + dependencies: + "@tanstack/query-core" "5.45.0" + "@tsconfig/node10@^1.0.7": version "1.0.9" resolved "https://registry.yarnpkg.com/@tsconfig/node10/-/node10-1.0.9.tgz#df4907fc07a886922637b15e02d4cebc4c0021b2" @@ -1630,6 +1643,11 @@ "@typescript-eslint/types" "6.21.0" eslint-visitor-keys "^3.4.1" +"@uidotdev/usehooks@^2.4.1": + version "2.4.1" + resolved "https://registry.yarnpkg.com/@uidotdev/usehooks/-/usehooks-2.4.1.tgz#4b733eaeae09a7be143c6c9ca158b56cc1ea75bf" + integrity sha512-1I+RwWyS+kdv3Mv0Vmc+p0dPYH0DTRAo04HLyXReYBL9AeseDWUJyi4THuksBJcu9F0Pih69Ak150VDnqbVnXg== + "@ungap/structured-clone@^1.0.0", "@ungap/structured-clone@^1.2.0": version "1.2.0" resolved "https://registry.yarnpkg.com/@ungap/structured-clone/-/structured-clone-1.2.0.tgz#756641adb587851b5ccb3e095daf27ae581c8406" From 504398dc11129b3c8590b71c8f73454b2f0f1973 Mon Sep 17 00:00:00 2001 From: Noah Prince Date: Mon, 17 Jun 2024 15:57:16 -0700 Subject: [PATCH 12/41] WIP: React query --- src/app/[network]/proxies/[wallet]/page.tsx | 64 ++++++++++--------- src/app/layout.tsx | 2 + .../PositionManager/PositionManager.tsx | 4 +- src/components/Proxies.tsx | 24 ++++--- src/components/ProxyProfile.tsx | 48 +++++++------- src/components/ProxySearch.tsx | 15 +++-- src/components/VeTokensCallout.tsx | 32 +++------- src/components/VoteHistory.tsx | 20 ++++-- src/hooks/useKnownProxy.ts | 27 -------- src/providers/providers.tsx | 35 ++++++---- 10 files changed, 134 insertions(+), 137 deletions(-) delete mode 100644 src/hooks/useKnownProxy.ts diff --git a/src/app/[network]/proxies/[wallet]/page.tsx b/src/app/[network]/proxies/[wallet]/page.tsx index 4fc93b5..eed5c10 100644 --- a/src/app/[network]/proxies/[wallet]/page.tsx +++ b/src/app/[network]/proxies/[wallet]/page.tsx @@ -1,47 +1,51 @@ import { Header } from "@/components/Header"; import { ProxyProfile } from "@/components/ProxyProfile"; -import { WalletBoundary } from "@/components/WalletBoundary"; -import { networksToMint } from "@/lib/constants"; +import { networksToMint } from "@helium/spl-utils"; +import { + proxyQuery +} from "@helium/voter-stake-registry-hooks"; import { VoteService, getRegistrarKey } from "@helium/voter-stake-registry-sdk"; import { PublicKey } from "@solana/web3.js"; +import { HydrationBoundary, QueryClient, dehydrate, useQueryClient } from "@tanstack/react-query"; +import { useMemo } from "react"; + +function getVoteService({ mint }: { mint: PublicKey }) { + const registrar = getRegistrarKey(mint); + return new VoteService({ + baseURL: process.env.NEXT_PUBLIC_HELIUM_VOTE_URI, + registrar, + }); +} export default async function ProxyPage({ - params: { wallet, network }, + params: { wallet: walletRaw, network }, }: { params: { wallet: string; network: string }; }) { - const mint = networksToMint[network]; - const { proxy, detail, image } = await getData( - new PublicKey(wallet as string), - mint + const voteService = useMemo( + () => getVoteService({ mint: networksToMint[network] }), + [network] + ); + const wallet = useMemo(() => new PublicKey(walletRaw), [walletRaw]); + const queryClient = new QueryClient(); + + await queryClient.prefetchQuery( + proxyQuery({ + wallet, + voteService, + }) + ); + const dehydrated = dehydrate( + queryClient, ); + console.log(dehydrated); return ( <>
- + + + ); } - -export async function getData(wallet: PublicKey, mint: PublicKey) { - const registrar = getRegistrarKey(mint); - - const voteService = new VoteService({ - baseURL: process.env.NEXT_PUBLIC_HELIUM_VOTE_URI, - registrar, - }); - const proxy = await voteService.getProxy(wallet.toBase58()); - let detail = null; - if (proxy.detail) { - const res = await fetch(proxy.detail); - detail = await res.text(); - } - - return { - proxy, - detail, - image: proxy.image ? proxy.image : null, - // revalidate: 10 * 60, - }; -} diff --git a/src/app/layout.tsx b/src/app/layout.tsx index a64a92a..850c77b 100644 --- a/src/app/layout.tsx +++ b/src/app/layout.tsx @@ -10,8 +10,10 @@ export const metadata = formMetaTags(); export default function RootLayout({ children, + dehydratedState, }: { children: React.ReactNode; + dehydratedState: any; }) { return ( diff --git a/src/components/PositionManager/PositionManager.tsx b/src/components/PositionManager/PositionManager.tsx index 22ebee9..17c9d04 100644 --- a/src/components/PositionManager/PositionManager.tsx +++ b/src/components/PositionManager/PositionManager.tsx @@ -155,8 +155,8 @@ export const PositionManager: FC = ({ setAction(undefined); }, [refetchState, setAction]); - const { loading: isAssigningProxy, assignProxies } = useAssignProxies(); - const { loading: isRevokingProxy, unassignProxies } = useUnassignProxies(); + const { isPending: isAssigningProxy, mutateAsync: assignProxies } = useAssignProxies(); + const { isPending: isRevokingProxy, mutateAsync: unassignProxies } = useUnassignProxies(); const isUpdatingProxy = isAssigningProxy || isRevokingProxy const { loading: isFlipping, flipPositionLockupKind } = useFlipPositionLockupKind(); diff --git a/src/components/Proxies.tsx b/src/components/Proxies.tsx index 87fd197..050d81a 100644 --- a/src/components/Proxies.tsx +++ b/src/components/Proxies.tsx @@ -1,14 +1,15 @@ "use client"; -import { debounce, ellipsisMiddle, humanReadable } from "@/lib/utils"; +import { ellipsisMiddle, humanReadable } from "@/lib/utils"; import { useGovernance } from "@/providers/GovernanceProvider"; import { useMint } from "@helium/helium-react-hooks"; -import { EnhancedProxy } from "@helium/voter-stake-registry-sdk"; +import { proxiesQuery } from "@helium/voter-stake-registry-hooks"; +import { useInfiniteQuery } from "@tanstack/react-query"; import BN from "bn.js"; +import { Loader2 } from "lucide-react"; import Link from "next/link"; import { usePathname } from "next/navigation"; -import { useEffect, useMemo, useState } from "react"; -import { useAsyncCallback } from "react-async-hook"; +import { useState } from "react"; import { FaMagnifyingGlass } from "react-icons/fa6"; import { IoWarningOutline } from "react-icons/io5"; import InfiniteScroll from "react-infinite-scroll-component"; @@ -16,9 +17,8 @@ import { ContentSection } from "./ContentSection"; import { Avatar, AvatarFallback, AvatarImage } from "./ui/avatar"; import { Card } from "./ui/card"; import { Input } from "./ui/input"; -import { Loader2 } from "lucide-react"; import { Skeleton } from "./ui/skeleton"; -import { useVoters } from "@helium/voter-stake-registry-hooks"; +import { useDebounce } from "@uidotdev/usehooks"; const DECENTRALIZATION_RISK_INDEX = 6; @@ -69,16 +69,20 @@ export function Proxies() { const decimals = mintAcc?.decimals; const path = usePathname(); const [proxySearch, setProxySearch] = useState(""); + const searchDebounced = useDebounce(proxySearch, 300); const { data: voters, fetchNextPage, hasNextPage, isLoading, isFetchingNextPage, - } = useVoters({ - search: proxySearch, - amountPerPage: 100, - }); + } = useInfiniteQuery( + proxiesQuery({ + search: searchDebounced, + amountPerPage: 100, + voteService: voteService, + }) + ); const proxies = voters?.pages.flat() || []; return ( diff --git a/src/components/ProxyProfile.tsx b/src/components/ProxyProfile.tsx index a8710ed..1d5c39f 100644 --- a/src/components/ProxyProfile.tsx +++ b/src/components/ProxyProfile.tsx @@ -1,55 +1,57 @@ "use client"; +import { networksToMint } from "@/lib/constants"; import { ellipsisMiddle, humanReadable } from "@/lib/utils"; import { useGovernance } from "@/providers/GovernanceProvider"; import { useMint } from "@helium/helium-react-hooks"; import { + proxyQuery, useAssignProxies, useProxiedTo, useUnassignProxies, } from "@helium/voter-stake-registry-hooks"; import { - EnhancedProxy, VoteService, - WithRank, - getRegistrarKey, + getRegistrarKey } from "@helium/voter-stake-registry-sdk"; import { PublicKey } from "@solana/web3.js"; +import { useQuery } from "@tanstack/react-query"; import BN from "bn.js"; import Image from "next/image"; import Link from "next/link"; -import { useMemo, useState } from "react"; +import { usePathname } from "next/navigation"; +import { useMemo } from "react"; +import { useAsync } from "react-async-hook"; import { FaArrowLeft } from "react-icons/fa6"; import { AssignProxyModal } from "./AssignProxyModal"; import { ContentSection } from "./ContentSection"; +import { Markdown } from "./Markdown"; import { ProxyButton } from "./ProxyButton"; import { RevokeProxyButton } from "./RevokeProxyButton"; import { RevokeProxyModal } from "./RevokeProxyModal"; -import { Card, CardContent, CardHeader } from "./ui/card"; import VoteHistory from "./VoteHistory"; -import { Markdown } from "./Markdown"; +import { Card, CardContent, CardHeader } from "./ui/card"; import { ToggleGroup, ToggleGroupItem } from "./ui/toggle-group"; -import { usePathname } from "next/navigation"; -import { useAsync } from "react-async-hook"; -import { networksToMint } from "@/lib/constants"; -export function ProxyProfile({ - proxy, - detail, - image, -}: { - proxy: EnhancedProxy & WithRank; - detail: string; - image: string; -}) { - const { mint, voteService } = useGovernance(); +export function ProxyProfile({ wallet: walletRaw }: { wallet: string }) { + const wallet = useMemo(() => new PublicKey(walletRaw), [walletRaw]); + const { mint, network, voteService } = useGovernance(); + const { data: proxyRaw, error } = useQuery( + proxyQuery({ + wallet: useMemo(() => new PublicKey(wallet), [wallet]), + voteService, + }) + ); + console.log("raw", error); + // Due to hydration, should always be present + const proxy = proxyRaw!; + const detail = proxy.detail; + const image = proxy.image; const { info: mintAcc } = useMint(mint); const decimals = mintAcc?.decimals; const { mutateAsync: assignProxies } = useAssignProxies(); - const { unassignProxies } = useUnassignProxies(); - const wallet = useMemo(() => new PublicKey(proxy.wallet), [proxy.wallet]); + const { mutateAsync: unassignProxies } = useUnassignProxies(); const { votingPower, positions } = useProxiedTo(wallet); - const { network } = useGovernance(); const { result: networks } = useAsync( async (vs: VoteService | undefined) => { if (vs) { @@ -66,7 +68,7 @@ export function ProxyProfile({ ); } } - return new Set() + return new Set(); }, [voteService] ); diff --git a/src/components/ProxySearch.tsx b/src/components/ProxySearch.tsx index 7cff714..6c9726e 100644 --- a/src/components/ProxySearch.tsx +++ b/src/components/ProxySearch.tsx @@ -1,21 +1,24 @@ import { ellipsisMiddle } from "@/lib/utils"; -import { useVoters } from "@helium/voter-stake-registry-hooks"; import { PublicKey } from "@solana/web3.js"; import { useDebounce } from "@uidotdev/usehooks"; import React, { useMemo, useState } from "react"; import { AutoComplete } from "./ui/autocomplete"; import { Loader2 } from "lucide-react"; +import { useInfiniteQuery } from "@tanstack/react-query"; +import { proxiesQuery } from "@helium/voter-stake-registry-hooks"; export const ProxySearch: React.FC<{ value: string; onValueChange: (value: string) => void; }> = ({ value, onValueChange }) => { - const [input, setInput] = useState(); + const [input, setInput] = useState(value); const debouncedInput = useDebounce(input, 300); - const { data: resultPaged, isLoading } = useVoters({ - search: debouncedInput || "", - amountPerPage: 20, - }); + const { data: resultPaged, isLoading, error } = useInfiniteQuery( + proxiesQuery({ + search: debouncedInput || "", + amountPerPage: 20, + }) + ); const result = useMemo(() => { const resultsAsOptions = diff --git a/src/components/VeTokensCallout.tsx b/src/components/VeTokensCallout.tsx index ac413d9..3754f6c 100644 --- a/src/components/VeTokensCallout.tsx +++ b/src/components/VeTokensCallout.tsx @@ -10,12 +10,14 @@ import { import { HNT_MINT, IOT_MINT, MOBILE_MINT, toNumber } from "@helium/spl-utils"; import { calcPositionVotingPower, - getPositionKeys, + positionKeysForWalletQuery, + useHeliumVsrState, usePositions, useRegistrar, } from "@helium/voter-stake-registry-hooks"; import { getRegistrarKey } from "@helium/voter-stake-registry-sdk"; import { PublicKey } from "@solana/web3.js"; +import { useQuery } from "@tanstack/react-query"; import BN from "bn.js"; import Image from "next/image"; import React, { FC, useMemo } from "react"; @@ -33,30 +35,16 @@ const VeTokenItem: FC<{ mint: PublicKey }> = ({ mint }) => { ); const { info: registrar } = useRegistrar(registrarKey); - const args = useMemo( - () => - wallet && - mint && - connection && { - wallet: wallet.publicKey, - mint, - provider, - }, - // eslint-disable-next-line react-hooks/exhaustive-deps - [wallet?.publicKey?.toBase58(), mint.toBase58(), connection, provider] - ); - - const { result, loading: loadingPositionKeys } = useAsync( - async (args: any | undefined) => { - if (args) { - return getPositionKeys(args); - } - }, - [args] + const { voteService } = useHeliumVsrState(); + const { data: result, isLoading: loadingPositionKeys } = useQuery( + positionKeysForWalletQuery({ + wallet: wallet?.publicKey, + voteService, + }) ); const { loading: loadingFetchedPositions, accounts: fetchedPositions } = - usePositions(result?.positionKeys); + usePositions(result?.positions); const positions = useMemo( () => fetchedPositions?.map((fetched) => fetched.info), diff --git a/src/components/VoteHistory.tsx b/src/components/VoteHistory.tsx index 1baec8d..4018dff 100644 --- a/src/components/VoteHistory.tsx +++ b/src/components/VoteHistory.tsx @@ -11,17 +11,25 @@ import { toNumber } from "@helium/spl-utils"; import { Pill } from "./Pill"; import { Loader2 } from "lucide-react"; import Link from "next/link"; -import { useVotesForWallet } from "@helium/voter-stake-registry-hooks"; +import { + useHeliumVsrState, + votesForWalletQuery, +} from "@helium/voter-stake-registry-hooks"; +import { useInfiniteQuery } from "@tanstack/react-query"; export default function VoteHistory({ wallet }: { wallet: PublicKey }) { + const { voteService } = useHeliumVsrState(); const { data: voteHistoryPages, fetchNextPage, hasNextPage, - } = useVotesForWallet({ - wallet, - amountPerPage: 20, - }); + } = useInfiniteQuery( + votesForWalletQuery({ + voteService, + wallet, + amountPerPage: 20, + }) + ); const dedupedVoteHistories = useMemo(() => { const seen = new Set(); return (voteHistoryPages?.pages?.flat() || []).filter((p) => { @@ -137,7 +145,7 @@ const ProposalItem: React.FC<{
Est. Time Remaining
- + )} diff --git a/src/hooks/useKnownProxy.ts b/src/hooks/useKnownProxy.ts deleted file mode 100644 index 0200398..0000000 --- a/src/hooks/useKnownProxy.ts +++ /dev/null @@ -1,27 +0,0 @@ -import { useGovernance } from "@/providers/GovernanceProvider"; -import { PositionWithMeta } from "@helium/voter-stake-registry-hooks"; -import { VoteService } from "@helium/voter-stake-registry-sdk"; -import { PublicKey } from "@solana/web3.js"; -import { useAsync } from "react-async-hook"; - -export function useKnownProxy(nextVoter: PublicKey | undefined) { - const { voteService } = useGovernance(); - const { - result: knownProxy, - loading, - error, - } = useAsync( - async (nv: PublicKey | undefined, vs: VoteService | undefined) => { - if (vs && nv && !nv.equals(PublicKey.default)) { - return ( - await vs.searchProxies({ - query: nv.toBase58(), - }) - )[0]; - } - }, - [nextVoter, voteService] - ); - - return { knownProxy, loading, error }; -} diff --git a/src/providers/providers.tsx b/src/providers/providers.tsx index 86da9b0..b802e5d 100644 --- a/src/providers/providers.tsx +++ b/src/providers/providers.tsx @@ -6,14 +6,27 @@ import { AccountProvider } from "./AccountProvider"; import { GovernanceProvider } from "./GovernanceProvider"; import { QueryClient, QueryClientProvider } from "@tanstack/react-query"; -const queryClient = new QueryClient(); - -export const Providers: FC = ({ children }) => ( - - - - {children} - - - -); +export const Providers: FC = ({ children }) => { + const queryClient = React.useMemo( + () => + new QueryClient({ + defaultOptions: { + queries: { + // With SSR, we usually want to set some default staleTime + // above 0 to avoid refetching immediately on the client + staleTime: 60 * 1000, + }, + }, + }), + [] + ); + return ( + + + + {children} + + + + ); +}; From 87444166f5339ca555c7aec49d603b310fc6eb54 Mon Sep 17 00:00:00 2001 From: Noah Prince Date: Fri, 21 Jun 2024 09:25:56 -0500 Subject: [PATCH 13/41] Finishing touches --- src/app/[network]/proxies/[wallet]/page.tsx | 11 +++++-- src/app/globals.css | 4 +-- src/app/layout.tsx | 2 -- src/components/PositionCard.tsx | 3 +- .../PositionManager/ProxyPositionPrompt.tsx | 28 +++++++++--------- src/components/Proxies.tsx | 9 ++++-- src/components/ProxyProfile.tsx | 29 ++++++++++++------- src/components/ProxySearch.tsx | 11 +++++-- src/components/VoteHistory.tsx | 2 +- src/components/VoteOption.tsx | 2 +- 10 files changed, 60 insertions(+), 41 deletions(-) diff --git a/src/app/[network]/proxies/[wallet]/page.tsx b/src/app/[network]/proxies/[wallet]/page.tsx index eed5c10..e1b2d30 100644 --- a/src/app/[network]/proxies/[wallet]/page.tsx +++ b/src/app/[network]/proxies/[wallet]/page.tsx @@ -8,6 +8,7 @@ import { VoteService, getRegistrarKey } from "@helium/voter-stake-registry-sdk"; import { PublicKey } from "@solana/web3.js"; import { HydrationBoundary, QueryClient, dehydrate, useQueryClient } from "@tanstack/react-query"; import { useMemo } from "react"; +import { notFound } from "next/navigation"; function getVoteService({ mint }: { mint: PublicKey }) { const registrar = getRegistrarKey(mint); @@ -29,16 +30,22 @@ export default async function ProxyPage({ const wallet = useMemo(() => new PublicKey(walletRaw), [walletRaw]); const queryClient = new QueryClient(); - await queryClient.prefetchQuery( + // Do not use prefetch here, because we want to error when it errors + const result = await queryClient.fetchQuery( proxyQuery({ wallet, voteService, }) ); + + + if (!result) { + return notFound(); + } + const dehydrated = dehydrate( queryClient, ); - console.log(dehydrated); return ( <> diff --git a/src/app/globals.css b/src/app/globals.css index 47482f6..1370407 100644 --- a/src/app/globals.css +++ b/src/app/globals.css @@ -28,8 +28,6 @@ --info-foreground: 217 91% 60%; --purple: 274 87 21%; --purple-foreground: 258 90 66%; - --pink: 336, 84%, 17%; - --pink-foreground: 330 81% 60%; --border: 214.3 31.8% 91.4%; --input: 214.3 31.8% 91.4%; --ring: 221.2 83.2% 53.3%; @@ -48,7 +46,7 @@ --secondary: 213 19% 32%; --secondary-foreground: 210 40% 98%; --muted: 217.2 32.6% 17.5%; - --muted-foreground: 213 19% 56%; + --muted-foreground: 215 20.2% 65.1%; --accent: 217.2 32.6% 17.5%; --accent-foreground: 210 40% 98%; --destructive: 0 62.8% 30.6%; diff --git a/src/app/layout.tsx b/src/app/layout.tsx index 850c77b..a64a92a 100644 --- a/src/app/layout.tsx +++ b/src/app/layout.tsx @@ -10,10 +10,8 @@ export const metadata = formMetaTags(); export default function RootLayout({ children, - dehydratedState, }: { children: React.ReactNode; - dehydratedState: any; }) { return ( diff --git a/src/components/PositionCard.tsx b/src/components/PositionCard.tsx index d99837a..db6eba8 100644 --- a/src/components/PositionCard.tsx +++ b/src/components/PositionCard.tsx @@ -8,7 +8,7 @@ import { } from "@/lib/utils"; import { useGovernance } from "@/providers/GovernanceProvider"; import { useSolanaUnixNow } from "@helium/helium-react-hooks"; -import { PositionWithMeta } from "@helium/voter-stake-registry-hooks"; +import { PositionWithMeta, useKnownProxy } from "@helium/voter-stake-registry-hooks"; import BN from "bn.js"; import classNames from "classnames"; import Image from "next/image"; @@ -28,7 +28,6 @@ import { Skeleton } from "./ui/skeleton"; import { PublicKey } from "@solana/web3.js"; import { useAsync } from "react-async-hook"; import { VoteService } from "@helium/voter-stake-registry-sdk"; -import { useKnownProxy } from "@/hooks/useKnownProxy"; export const PositionCardSkeleton: FC<{ compact?: boolean }> = () => { const { network } = useGovernance(); diff --git a/src/components/PositionManager/ProxyPositionPrompt.tsx b/src/components/PositionManager/ProxyPositionPrompt.tsx index fb4ae66..6d4da0f 100644 --- a/src/components/PositionManager/ProxyPositionPrompt.tsx +++ b/src/components/PositionManager/ProxyPositionPrompt.tsx @@ -1,17 +1,15 @@ "use client"; -import { PositionWithMeta } from "@helium/voter-stake-registry-hooks"; -import React, { FC, useMemo, useState } from "react"; -import { Button } from "../ui/button"; -import { Loader2, X } from "lucide-react"; -import { PositionCard } from "../PositionCard"; -import { useKnownProxy } from "@/hooks/useKnownProxy"; -import { ProxySearch } from "../ProxySearch"; -import { ExpirationTimeSlider } from "../ExpirationTimeSlider"; -import { PublicKey } from "@solana/web3.js"; -import { RiUserSharedFill } from "react-icons/ri"; import { useGovernance } from "@/providers/GovernanceProvider"; +import { PositionWithMeta, useKnownProxy } from "@helium/voter-stake-registry-hooks"; +import { PublicKey } from "@solana/web3.js"; +import { Loader2, X } from "lucide-react"; import Link from "next/link"; +import { FC, useMemo, useState } from "react"; +import { RiUserSharedFill } from "react-icons/ri"; +import { ExpirationTimeSlider } from "../ExpirationTimeSlider"; +import { ProxySearch } from "../ProxySearch"; +import { Button } from "../ui/button"; export const ProxyPositionPrompt: FC<{ position: PositionWithMeta; @@ -22,9 +20,13 @@ export const ProxyPositionPrompt: FC<{ const isProxied = position.proxy?.nextVoter && !position.proxy?.nextVoter.equals(PublicKey.default); - const { knownProxy } = useKnownProxy(position.proxy?.nextVoter) - const [proxy, setProxy] = useState(position.proxy?.nextVoter?.toBase58() || "") - const { network } = useGovernance() + const { knownProxy } = useKnownProxy(position.proxy?.nextVoter); + const [proxy, setProxy] = useState( + position.proxy?.nextVoter.equals(PublicKey.default) + ? "" + : position.proxy?.nextVoter.toBase58() || "" + ); + const { network } = useGovernance(); const today = new Date(); const augustFirst = Date.UTC( diff --git a/src/components/Proxies.tsx b/src/components/Proxies.tsx index 050d81a..c2f1430 100644 --- a/src/components/Proxies.tsx +++ b/src/components/Proxies.tsx @@ -144,9 +144,12 @@ export function Proxies() { title="Total Voting Power" value={ proxy.delegatedVeTokens - ? humanReadable( - new BN(proxy.delegatedVeTokens), - decimals + ? // force 2 decimals + humanReadable( + new BN(proxy.delegatedVeTokens).div( + new BN(Math.pow(10, (decimals || 0) - 2)) + ), + 2 )! : "0" } diff --git a/src/components/ProxyProfile.tsx b/src/components/ProxyProfile.tsx index 1d5c39f..363db3d 100644 --- a/src/components/ProxyProfile.tsx +++ b/src/components/ProxyProfile.tsx @@ -10,10 +10,7 @@ import { useProxiedTo, useUnassignProxies, } from "@helium/voter-stake-registry-hooks"; -import { - VoteService, - getRegistrarKey -} from "@helium/voter-stake-registry-sdk"; +import { VoteService, getRegistrarKey } from "@helium/voter-stake-registry-sdk"; import { PublicKey } from "@solana/web3.js"; import { useQuery } from "@tanstack/react-query"; import BN from "bn.js"; @@ -42,7 +39,6 @@ export function ProxyProfile({ wallet: walletRaw }: { wallet: string }) { voteService, }) ); - console.log("raw", error); // Due to hydration, should always be present const proxy = proxyRaw!; const detail = proxy.detail; @@ -93,8 +89,14 @@ export function ProxyProfile({ wallet: walletRaw }: { wallet: string }) { TOTAL POWER
- {proxy.delegatedVeTokens - ? humanReadable(new BN(proxy.delegatedVeTokens), decimals) + {proxy.delegatedVeTokens && decimals + ? // Force 2 decimals + humanReadable( + new BN(proxy.delegatedVeTokens).div( + new BN(Math.pow(10, decimals - 2)) + ), + 2 + ) : "0"}
@@ -144,7 +146,10 @@ export function ProxyProfile({ wallet: walletRaw }: { wallet: string }) { POWER FROM ME
- {humanReadable(votingPower, decimals)} + {humanReadable( + votingPower.div(new BN(Math.pow(10, (decimals || 0) - 2))), + 2 + )}
@@ -177,7 +182,7 @@ export function ProxyProfile({ wallet: walletRaw }: { wallet: string }) {
Profile

{proxy.name}

- {ellipsisMiddle(proxy.wallet)} + + {proxy.wallet && ellipsisMiddle(proxy.wallet)} +
@@ -225,7 +232,7 @@ export function ProxyProfile({ wallet: walletRaw }: { wallet: string }) {
- {detail} + {detail || `${proxy.wallet}`}
{infoCard}
diff --git a/src/components/ProxySearch.tsx b/src/components/ProxySearch.tsx index 6c9726e..8faaf59 100644 --- a/src/components/ProxySearch.tsx +++ b/src/components/ProxySearch.tsx @@ -5,7 +5,10 @@ import React, { useMemo, useState } from "react"; import { AutoComplete } from "./ui/autocomplete"; import { Loader2 } from "lucide-react"; import { useInfiniteQuery } from "@tanstack/react-query"; -import { proxiesQuery } from "@helium/voter-stake-registry-hooks"; +import { + proxiesQuery, + useHeliumVsrState, +} from "@helium/voter-stake-registry-hooks"; export const ProxySearch: React.FC<{ value: string; @@ -13,10 +16,12 @@ export const ProxySearch: React.FC<{ }> = ({ value, onValueChange }) => { const [input, setInput] = useState(value); const debouncedInput = useDebounce(input, 300); - const { data: resultPaged, isLoading, error } = useInfiniteQuery( + const { voteService } = useHeliumVsrState(); + const { data: resultPaged, isLoading } = useInfiniteQuery( proxiesQuery({ search: debouncedInput || "", amountPerPage: 20, + voteService, }) ); @@ -38,7 +43,7 @@ export const ProxySearch: React.FC<{ }, [resultPaged, debouncedInput]); const selectedOption = useMemo(() => { return result?.find((r) => r.value == value); - }, [result, value]) + }, [result, value]); if (value && !selectedOption) { return ; diff --git a/src/components/VoteHistory.tsx b/src/components/VoteHistory.tsx index 4018dff..942615d 100644 --- a/src/components/VoteHistory.tsx +++ b/src/components/VoteHistory.tsx @@ -123,7 +123,7 @@ const ProposalItem: React.FC<{ name="Percent of Vote" value={ // Calc with 4 decimals precision - proposal.votes[0].weight + proposal.votes[0].weight && !votingResults.totalVotes.isZero() ? ( new BN(proposal.votes[0].weight) .mul(new BN(10000)) diff --git a/src/components/VoteOption.tsx b/src/components/VoteOption.tsx index 404b112..f5694d5 100644 --- a/src/components/VoteOption.tsx +++ b/src/components/VoteOption.tsx @@ -7,8 +7,8 @@ import React, { FC } from "react"; import { FaCircle, FaCircleCheck } from "react-icons/fa6"; import { Loader2 } from "lucide-react"; import { PublicKey } from "@solana/web3.js"; -import { useKnownProxy } from "@/hooks/useKnownProxy"; import { Pill } from "./Pill"; +import { useKnownProxy } from "@helium/voter-stake-registry-hooks"; export const VoteOption: FC<{ option: VoteChoiceWithMeta; From 344e0c29cc49ae24b46e2a54b2c054f2d41bcb71 Mon Sep 17 00:00:00 2001 From: Noah Prince Date: Fri, 21 Jun 2024 10:33:44 -0500 Subject: [PATCH 14/41] Rm yalc --- package.json | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/package.json b/package.json index 98096c4..2d5d0d1 100644 --- a/package.json +++ b/package.json @@ -16,10 +16,10 @@ "@helium/modular-governance-hooks": "^0.0.8", "@helium/modular-governance-idls": "^0.0.8-next.19+4fa4c6b", "@helium/organization-sdk": "^0.0.8", - "@helium/spl-utils": "file:.yalc/@helium/spl-utils", + "@helium/spl-utils": "^0.8.2", "@helium/state-controller-sdk": "^0.0.8", - "@helium/voter-stake-registry-hooks": "file:.yalc/@helium/voter-stake-registry-hooks", - "@helium/voter-stake-registry-sdk": "file:.yalc/@helium/voter-stake-registry-sdk", + "@helium/voter-stake-registry-hooks": "^0.8.2", + "@helium/voter-stake-registry-sdk": "^0.8.2", "@hookform/resolvers": "^3.3.4", "@metaplex-foundation/mpl-token-metadata": "2.10.0", "@project-serum/anchor": "^0.26.0", @@ -75,11 +75,11 @@ "@helium/account-fetch-cache": "^0.7.11", "@helium/account-fetch-cache-hooks": "^0.7.11", "@helium/helium-react-hooks": "^0.7.11", - "@helium/voter-stake-registry-hooks": "file:.yalc/@helium/voter-stake-registry-hooks", - "@helium/spl-utils": "file:.yalc/@helium/spl-utils", + "@helium/voter-stake-registry-hooks": "^0.8.2", + "@helium/spl-utils": "^0.8.2", "@helium/modular-governance-hooks": "^0.0.8", "@solana/wallet-adapter-react": "^0.15.35", - "@helium/voter-stake-registry-sdk": "file:.yalc/@helium/voter-stake-registry-sdk" + "@helium/voter-stake-registry-sdk": "^0.8.2" }, "devDependencies": { "@tailwindcss/typography": "^0.5.10", From 29889f1d2a711fea01a632cfddab77045f9dee40 Mon Sep 17 00:00:00 2001 From: Noah Prince Date: Tue, 2 Jul 2024 12:49:08 -0700 Subject: [PATCH 15/41] Fix bugs --- package.json | 24 +++---- src/components/Proxies.tsx | 2 +- yarn.lock | 130 +++++++++++++++++++------------------ 3 files changed, 81 insertions(+), 75 deletions(-) diff --git a/package.json b/package.json index 2d5d0d1..714be4f 100644 --- a/package.json +++ b/package.json @@ -10,16 +10,16 @@ }, "dependencies": { "@coral-xyz/anchor": "^0.29.0", - "@helium/account-fetch-cache": "^0.7.11", - "@helium/account-fetch-cache-hooks": "^0.7.11", - "@helium/helium-react-hooks": "^0.7.11", + "@helium/account-fetch-cache": "^0.9.0-alpha.0", + "@helium/account-fetch-cache-hooks": "^0.9.0-alpha.0", + "@helium/helium-react-hooks": "^0.9.0-alpha.0", "@helium/modular-governance-hooks": "^0.0.8", "@helium/modular-governance-idls": "^0.0.8-next.19+4fa4c6b", "@helium/organization-sdk": "^0.0.8", - "@helium/spl-utils": "^0.8.2", + "@helium/spl-utils": "^0.9.0-alpha.0", "@helium/state-controller-sdk": "^0.0.8", - "@helium/voter-stake-registry-hooks": "^0.8.2", - "@helium/voter-stake-registry-sdk": "^0.8.2", + "@helium/voter-stake-registry-hooks": "^0.9.0-alpha.0", + "@helium/voter-stake-registry-sdk": "^0.9.0-alpha.0", "@hookform/resolvers": "^3.3.4", "@metaplex-foundation/mpl-token-metadata": "2.10.0", "@project-serum/anchor": "^0.26.0", @@ -72,14 +72,14 @@ }, "resolutions": { "@solana/web3.js": "^1.90.0", - "@helium/account-fetch-cache": "^0.7.11", - "@helium/account-fetch-cache-hooks": "^0.7.11", - "@helium/helium-react-hooks": "^0.7.11", - "@helium/voter-stake-registry-hooks": "^0.8.2", - "@helium/spl-utils": "^0.8.2", + "@helium/account-fetch-cache": "^0.9.0-alpha.0", + "@helium/account-fetch-cache-hooks": "^0.9.0-alpha.0", + "@helium/helium-react-hooks": "^0.9.0-alpha.0", + "@helium/voter-stake-registry-hooks": "^0.9.0-alpha.0", + "@helium/spl-utils": "^0.9.0-alpha.0", "@helium/modular-governance-hooks": "^0.0.8", "@solana/wallet-adapter-react": "^0.15.35", - "@helium/voter-stake-registry-sdk": "^0.8.2" + "@helium/voter-stake-registry-sdk": "^0.9.0-alpha.0" }, "devDependencies": { "@tailwindcss/typography": "^0.5.10", diff --git a/src/components/Proxies.tsx b/src/components/Proxies.tsx index c2f1430..b078970 100644 --- a/src/components/Proxies.tsx +++ b/src/components/Proxies.tsx @@ -143,7 +143,7 @@ export function Proxies() { Date: Tue, 2 Jul 2024 13:25:30 -0700 Subject: [PATCH 16/41] Fix 404 --- next.config.mjs | 2 +- src/components/ProxyProfile.tsx | 2 +- src/components/VoteHistory.tsx | 17 ++++++++--------- 3 files changed, 10 insertions(+), 11 deletions(-) diff --git a/next.config.mjs b/next.config.mjs index a88a2bf..208cee5 100644 --- a/next.config.mjs +++ b/next.config.mjs @@ -23,7 +23,7 @@ const nextConfig = { }, { protocol: "https", - hostname: "test-helium.com", + hostname: "*.test-helium.com", port: "", pathname: "/**/**", }, diff --git a/src/components/ProxyProfile.tsx b/src/components/ProxyProfile.tsx index 363db3d..0d910ee 100644 --- a/src/components/ProxyProfile.tsx +++ b/src/components/ProxyProfile.tsx @@ -74,7 +74,7 @@ export function ProxyProfile({ wallet: walletRaw }: { wallet: string }) { function getNetworkPath(network: string) { const split = path.split("/"); split.shift(); - return [network, ...split].join("/"); + return "/" + [network, ...split].join("/"); } const infoCard = ( diff --git a/src/components/VoteHistory.tsx b/src/components/VoteHistory.tsx index 942615d..bf278b3 100644 --- a/src/components/VoteHistory.tsx +++ b/src/components/VoteHistory.tsx @@ -1,21 +1,20 @@ import { useProposalStatus } from "@/hooks/useProposalStatus"; import { cn } from "@/lib/utils"; import { useGovernance } from "@/providers/GovernanceProvider"; +import { + useHeliumVsrState, + votesForWalletQuery, +} from "@helium/voter-stake-registry-hooks"; import { ProposalWithVotes } from "@helium/voter-stake-registry-sdk"; import { PublicKey } from "@solana/web3.js"; +import { useInfiniteQuery } from "@tanstack/react-query"; import BN from "bn.js"; -import { useEffect, useMemo, useState } from "react"; +import { Loader2 } from "lucide-react"; +import Link from "next/link"; +import { useMemo } from "react"; import InfiniteScroll from "react-infinite-scroll-component"; import { CountdownTimer } from "./CountdownTimer"; -import { toNumber } from "@helium/spl-utils"; import { Pill } from "./Pill"; -import { Loader2 } from "lucide-react"; -import Link from "next/link"; -import { - useHeliumVsrState, - votesForWalletQuery, -} from "@helium/voter-stake-registry-hooks"; -import { useInfiniteQuery } from "@tanstack/react-query"; export default function VoteHistory({ wallet }: { wallet: PublicKey }) { const { voteService } = useHeliumVsrState(); From da0ee8b94751c03e9ca6a713a1f2fa3239183fc8 Mon Sep 17 00:00:00 2001 From: Noah Prince Date: Tue, 2 Jul 2024 13:52:49 -0700 Subject: [PATCH 17/41] Fix linking --- src/components/ProxyProfile.tsx | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) diff --git a/src/components/ProxyProfile.tsx b/src/components/ProxyProfile.tsx index 0d910ee..804d4cd 100644 --- a/src/components/ProxyProfile.tsx +++ b/src/components/ProxyProfile.tsx @@ -70,10 +70,9 @@ export function ProxyProfile({ wallet: walletRaw }: { wallet: string }) { ); const path = usePathname(); - const currentPath = path.split("/")[0] || "hnt"; + const currentPath = path.split("/")[1] || "hnt"; function getNetworkPath(network: string) { - const split = path.split("/"); - split.shift(); + const [_firstSlash, _network, ...split] = path.split("/"); return "/" + [network, ...split].join("/"); } @@ -272,7 +271,7 @@ export function ProxyProfile({ wallet: walletRaw }: { wallet: string }) { )} {networks?.has("iot") && ( - + Date: Wed, 3 Jul 2024 09:31:13 -0700 Subject: [PATCH 18/41] Fix top callouts --- package.json | 24 ++--- src/components/Positions.tsx | 2 +- src/components/Proxies.tsx | 4 +- src/components/ProxyProfile.tsx | 4 +- src/components/VeTokensCallout.tsx | 47 ++++++---- yarn.lock | 136 ++++++++++++++--------------- 6 files changed, 117 insertions(+), 100 deletions(-) diff --git a/package.json b/package.json index 714be4f..9c0584f 100644 --- a/package.json +++ b/package.json @@ -10,16 +10,16 @@ }, "dependencies": { "@coral-xyz/anchor": "^0.29.0", - "@helium/account-fetch-cache": "^0.9.0-alpha.0", - "@helium/account-fetch-cache-hooks": "^0.9.0-alpha.0", - "@helium/helium-react-hooks": "^0.9.0-alpha.0", + "@helium/account-fetch-cache": "^0.9.0-alpha.1", + "@helium/account-fetch-cache-hooks": "^0.9.0-alpha.2", + "@helium/helium-react-hooks": "^0.9.0-alpha.2", "@helium/modular-governance-hooks": "^0.0.8", "@helium/modular-governance-idls": "^0.0.8-next.19+4fa4c6b", "@helium/organization-sdk": "^0.0.8", - "@helium/spl-utils": "^0.9.0-alpha.0", + "@helium/spl-utils": "^0.9.0-alpha.2", "@helium/state-controller-sdk": "^0.0.8", - "@helium/voter-stake-registry-hooks": "^0.9.0-alpha.0", - "@helium/voter-stake-registry-sdk": "^0.9.0-alpha.0", + "@helium/voter-stake-registry-hooks": "^0.9.0-alpha.2", + "@helium/voter-stake-registry-sdk": "^0.9.0-alpha.2", "@hookform/resolvers": "^3.3.4", "@metaplex-foundation/mpl-token-metadata": "2.10.0", "@project-serum/anchor": "^0.26.0", @@ -72,14 +72,14 @@ }, "resolutions": { "@solana/web3.js": "^1.90.0", - "@helium/account-fetch-cache": "^0.9.0-alpha.0", - "@helium/account-fetch-cache-hooks": "^0.9.0-alpha.0", - "@helium/helium-react-hooks": "^0.9.0-alpha.0", - "@helium/voter-stake-registry-hooks": "^0.9.0-alpha.0", - "@helium/spl-utils": "^0.9.0-alpha.0", + "@helium/account-fetch-cache": "^0.9.0-alpha.2", + "@helium/account-fetch-cache-hooks": "^0.9.0-alpha.2", + "@helium/helium-react-hooks": "^0.9.0-alpha.2", + "@helium/voter-stake-registry-hooks": "^0.9.0-alpha.2", + "@helium/spl-utils": "^0.9.0-alpha.2", "@helium/modular-governance-hooks": "^0.0.8", "@solana/wallet-adapter-react": "^0.15.35", - "@helium/voter-stake-registry-sdk": "^0.9.0-alpha.0" + "@helium/voter-stake-registry-sdk": "^0.9.0-alpha.2" }, "devDependencies": { "@tailwindcss/typography": "^0.5.10", diff --git a/src/components/Positions.tsx b/src/components/Positions.tsx index c7b2ec4..950f327 100644 --- a/src/components/Positions.tsx +++ b/src/components/Positions.tsx @@ -160,7 +160,7 @@ export const Positions: FC = () => {
{!notDecayedPositions?.length && !decayedPositions?.length && ( - +

No positions

diff --git a/src/components/Proxies.tsx b/src/components/Proxies.tsx index b078970..a400662 100644 --- a/src/components/Proxies.tsx +++ b/src/components/Proxies.tsx @@ -143,10 +143,10 @@ export function Proxies() {
- {proxy.delegatedVeTokens && decimals + {proxy.proxiedVeTokens && decimals ? // Force 2 decimals humanReadable( - new BN(proxy.delegatedVeTokens).div( + new BN(proxy.proxiedVeTokens).div( new BN(Math.pow(10, decimals - 2)) ), 2 diff --git a/src/components/VeTokensCallout.tsx b/src/components/VeTokensCallout.tsx index 3754f6c..cbce7d8 100644 --- a/src/components/VeTokensCallout.tsx +++ b/src/components/VeTokensCallout.tsx @@ -2,6 +2,7 @@ import { usePrevious } from "@/hooks/usePrevious"; import { abbreviateNumber } from "@/lib/utils"; +import { useGovernance } from "@/providers/GovernanceProvider"; import { useAnchorProvider, useMint, @@ -10,18 +11,15 @@ import { import { HNT_MINT, IOT_MINT, MOBILE_MINT, toNumber } from "@helium/spl-utils"; import { calcPositionVotingPower, - positionKeysForWalletQuery, - useHeliumVsrState, + usePositionKeysAndProxies, usePositions, - useRegistrar, + useRegistrar } from "@helium/voter-stake-registry-hooks"; import { getRegistrarKey } from "@helium/voter-stake-registry-sdk"; import { PublicKey } from "@solana/web3.js"; -import { useQuery } from "@tanstack/react-query"; import BN from "bn.js"; import Image from "next/image"; -import React, { FC, useMemo } from "react"; -import { useAsync } from "react-async-hook"; +import { FC, useMemo } from "react"; const VeTokenItem: FC<{ mint: PublicKey }> = ({ mint }) => { const provider = useAnchorProvider(); @@ -35,16 +33,35 @@ const VeTokenItem: FC<{ mint: PublicKey }> = ({ mint }) => { ); const { info: registrar } = useRegistrar(registrarKey); - const { voteService } = useHeliumVsrState(); - const { data: result, isLoading: loadingPositionKeys } = useQuery( - positionKeysForWalletQuery({ - wallet: wallet?.publicKey, - voteService, - }) - ); + const { voteService } = useGovernance(); + const { + positionKeys, + proxiedPositionKeys, + isLoading: loadingPositionKeys, + } = usePositionKeysAndProxies({ + wallet: wallet?.publicKey, + provider, + voteService, + }); - const { loading: loadingFetchedPositions, accounts: fetchedPositions } = - usePositions(result?.positions); + // Assume that my positions are a small amount, so we don't need to say they're static + const { accounts: myPositions, loading: loadingMyPositions } = + usePositions(positionKeys); + // Proxied positions may be a lot, set to static + const { accounts: proxiedPositions, loading: loadingProxyPositions } = + usePositions(proxiedPositionKeys, true); + const loadingFetchedPositions = loadingMyPositions || loadingProxyPositions + const fetchedPositions = useMemo(() => { + const uniquePositions = new Map(); + [...(myPositions || []), ...(proxiedPositions || [])].forEach( + (position) => { + if (position) { + uniquePositions.set(position.publicKey.toBase58(), position); + } + } + ); + return Array.from(uniquePositions.values()); + }, [myPositions, proxiedPositions]); const positions = useMemo( () => fetchedPositions?.map((fetched) => fetched.info), diff --git a/yarn.lock b/yarn.lock index 511d448..111da76 100644 --- a/yarn.lock +++ b/yarn.lock @@ -171,19 +171,19 @@ resolved "https://registry.yarnpkg.com/@floating-ui/utils/-/utils-0.2.1.tgz#16308cea045f0fc777b6ff20a9f25474dd8293d2" integrity sha512-9TANp6GPoMtYzQdt54kfAyMmz1+osLlXdg2ENroU7zzrtflTLrrC/lgrIfaSe+Wu0b89GKccT7vxXA0MoAIO+Q== -"@helium/account-fetch-cache-hooks@^0.5.0", "@helium/account-fetch-cache-hooks@^0.9.0-alpha.0": - version "0.9.0-alpha.0" - resolved "https://registry.yarnpkg.com/@helium/account-fetch-cache-hooks/-/account-fetch-cache-hooks-0.9.0-alpha.0.tgz#9757810abfadee20968214661ac4a966bd9d3852" - integrity sha512-f1Fn0vMRJg72LMf6WvuR1FKJLuAqawgQerxK6MzYtJ2yckRhMG2G5GVBV0eYkfnQxDrX/HF3mypJiLiFjIdCcQ== +"@helium/account-fetch-cache-hooks@^0.5.0", "@helium/account-fetch-cache-hooks@^0.9.0-alpha.2": + version "0.9.0-alpha.2" + resolved "https://registry.yarnpkg.com/@helium/account-fetch-cache-hooks/-/account-fetch-cache-hooks-0.9.0-alpha.2.tgz#3b02dd40ada358bca4dca7566f757d75f7fa8c59" + integrity sha512-JOfqPKWSVZLaAtfZp4/kfjKJJB0JD3SMyGRokiuqBQC86O1M2FrKpRBSTOitHsThxMu2XfIApoTj0aLxQ3mZJA== dependencies: - "@helium/account-fetch-cache" "^0.9.0-alpha.0" + "@helium/account-fetch-cache" "^0.9.0-alpha.1" "@solana/web3.js" "^1.78.8" react-async-hook "^4.0.0" -"@helium/account-fetch-cache@^0.5.0", "@helium/account-fetch-cache@^0.9.0-alpha.0": - version "0.9.0-alpha.0" - resolved "https://registry.yarnpkg.com/@helium/account-fetch-cache/-/account-fetch-cache-0.9.0-alpha.0.tgz#e4490dbb76dc9bef824842ac919e31295abe689a" - integrity sha512-wLLv/1sA7A8kEy4y3EtFGmkKXN1JPjBODgSrPEhGm7ePZodGMY0aIrhCJDW33TyJ+r0KmuewEQOO1Aq52/b9Vg== +"@helium/account-fetch-cache@^0.5.0", "@helium/account-fetch-cache@^0.9.0-alpha.1", "@helium/account-fetch-cache@^0.9.0-alpha.2": + version "0.9.0-alpha.1" + resolved "https://registry.yarnpkg.com/@helium/account-fetch-cache/-/account-fetch-cache-0.9.0-alpha.1.tgz#d6d5d93e57718680d7f3c23372f56bec4aee8428" + integrity sha512-J2E9OsoL7HiCtfk20rXzi6N0c3645KVy07kFCXMsft5VHRQ3jSkjma2iCdZEt1JhwFxQW/XLtePYYp1Plp4Luw== dependencies: "@solana/web3.js" "^1.78.8" @@ -212,56 +212,56 @@ "@solana/spl-token" "^0.3.8" "@solana/web3.js" "^1.78.4" -"@helium/anchor-resolvers@^0.9.0-alpha.0": - version "0.9.0-alpha.0" - resolved "https://registry.yarnpkg.com/@helium/anchor-resolvers/-/anchor-resolvers-0.9.0-alpha.0.tgz#48d461e877604528dad895dcbf4f013ffab7e9ce" - integrity sha512-MBf6EJyBPJM9lSiI/KQ7a791OroD8o96bAJUBkr/+ziJL3+u389NSg8lducSEdnDSZ9nH1SNP4prSf37hvU9gQ== +"@helium/anchor-resolvers@^0.9.0-alpha.1": + version "0.9.0-alpha.1" + resolved "https://registry.yarnpkg.com/@helium/anchor-resolvers/-/anchor-resolvers-0.9.0-alpha.1.tgz#b9b3790b45e2f46533fc221b8d8e9898a95fd9ab" + integrity sha512-Wf/VrZ8sNu8aE7EvsQm8mUwjI1KVroNNqomlNTyxvM0C2CviJcwM9n4wD4fsIx3cxTGAse2gBF4/NhHAhRJYLQ== dependencies: "@solana/spl-token" "^0.3.8" "@solana/web3.js" "^1.78.8" -"@helium/circuit-breaker-sdk@^0.9.0-alpha.0": - version "0.9.0-alpha.0" - resolved "https://registry.yarnpkg.com/@helium/circuit-breaker-sdk/-/circuit-breaker-sdk-0.9.0-alpha.0.tgz#bd5d4defe74f55cdc1e71178ebd2c8258d83ac95" - integrity sha512-5U4C/TmzHyT4lBBgRlmDqIfIBfVM69fHpt7O3QlI6IK+1GEmtvK6LXhIbiI7NdSCstFqtTl686K7bQ60z1G5lg== +"@helium/circuit-breaker-sdk@^0.9.0-alpha.2": + version "0.9.0-alpha.2" + resolved "https://registry.yarnpkg.com/@helium/circuit-breaker-sdk/-/circuit-breaker-sdk-0.9.0-alpha.2.tgz#f69e68cce135f830b21788dff2936c9e23e43fc7" + integrity sha512-VXKxdj51dKH5GInM1AuLJYxXkyOU/e0Vx1519KkLwwf8a9osTU8nt4lrxAgfEcMq3qoIJpyzZVRqHBugXCbOcA== dependencies: "@coral-xyz/anchor" "^0.28.0" - "@helium/anchor-resolvers" "^0.9.0-alpha.0" - "@helium/idls" "^0.9.0-alpha.0" + "@helium/anchor-resolvers" "^0.9.0-alpha.1" + "@helium/idls" "^0.9.0-alpha.1" bn.js "^5.2.0" bs58 "^4.0.1" -"@helium/helium-react-hooks@^0.5.0", "@helium/helium-react-hooks@^0.9.0-alpha.0": - version "0.9.0-alpha.0" - resolved "https://registry.yarnpkg.com/@helium/helium-react-hooks/-/helium-react-hooks-0.9.0-alpha.0.tgz#cdc46f6292af32001454f217903d56b2fdfcace0" - integrity sha512-3eEzNs/jvMZTA6OHLHzkeg5nN8cOwfga7QhqhPXeNFXptjpWTMrrVmdEzXdB8xr4GSu8iy8CuDEEpGZgWefl6w== +"@helium/helium-react-hooks@^0.5.0", "@helium/helium-react-hooks@^0.9.0-alpha.2": + version "0.9.0-alpha.2" + resolved "https://registry.yarnpkg.com/@helium/helium-react-hooks/-/helium-react-hooks-0.9.0-alpha.2.tgz#f853c7109d53e399d2de037b1a2d45d694a4a043" + integrity sha512-1ksNYJvUd24sJhmm49Mt2kPZfM7WUQ4/EIWAT25Y7iCaLPbpZI/7Mfh6NVUzcW1T5WfCEKcvCmCvaHpPseoxeA== dependencies: "@coral-xyz/anchor" "^0.28.0" - "@helium/account-fetch-cache" "^0.9.0-alpha.0" - "@helium/account-fetch-cache-hooks" "^0.9.0-alpha.0" + "@helium/account-fetch-cache" "^0.9.0-alpha.1" + "@helium/account-fetch-cache-hooks" "^0.9.0-alpha.2" "@solana/spl-token" "^0.3.8" "@solana/web3.js" "^1.78.8" bs58 "^4.0.1" pako "^2.0.3" react-async-hook "^4.0.0" -"@helium/helium-sub-daos-sdk@^0.9.0-alpha.0": - version "0.9.0-alpha.0" - resolved "https://registry.yarnpkg.com/@helium/helium-sub-daos-sdk/-/helium-sub-daos-sdk-0.9.0-alpha.0.tgz#9dfa909fd76c46f3f6aa4b85a7591c7f2b5bf1c3" - integrity sha512-J9/VAro/1a0FXrKGVRdrS/ggoKP4mZpEZ/hgS5Dqd36rI3mnBL4sI6R8159T3+hTlJfyrWARYq7DjZH1xFxf4Q== +"@helium/helium-sub-daos-sdk@^0.9.0-alpha.2": + version "0.9.0-alpha.2" + resolved "https://registry.yarnpkg.com/@helium/helium-sub-daos-sdk/-/helium-sub-daos-sdk-0.9.0-alpha.2.tgz#11178f5fb894d12233f35ad6901d36862227a423" + integrity sha512-olCTIBR7A6F/dgkpmvfEdwNgkw268zPBMnXf8SGdGPPbuG23UB0/BrorXRl29MDKAJdFsd6nm/Nxmm6BhVIC6Q== dependencies: "@coral-xyz/anchor" "^0.28.0" - "@helium/anchor-resolvers" "^0.9.0-alpha.0" - "@helium/circuit-breaker-sdk" "^0.9.0-alpha.0" - "@helium/treasury-management-sdk" "^0.9.0-alpha.0" - "@helium/voter-stake-registry-sdk" "^0.9.0-alpha.0" + "@helium/anchor-resolvers" "^0.9.0-alpha.1" + "@helium/circuit-breaker-sdk" "^0.9.0-alpha.2" + "@helium/treasury-management-sdk" "^0.9.0-alpha.2" + "@helium/voter-stake-registry-sdk" "^0.9.0-alpha.2" bn.js "^5.2.0" bs58 "^4.0.1" -"@helium/idls@^0.9.0-alpha.0": - version "0.9.0-alpha.0" - resolved "https://registry.yarnpkg.com/@helium/idls/-/idls-0.9.0-alpha.0.tgz#cf8cf5e1543be2568b8af40874b0baeb72868d0d" - integrity sha512-ghT/B9wXVPkAc1N7lNdnpw5hoYTBlSYoORTvk572M5fq7M1jSO0XwUVvMFwRgDf4kbuKGY3YuMXm7/SFdM7c8Q== +"@helium/idls@^0.9.0-alpha.1": + version "0.9.0-alpha.1" + resolved "https://registry.yarnpkg.com/@helium/idls/-/idls-0.9.0-alpha.1.tgz#a87e01535b8f3a31cece57c1a6885a866a8c3181" + integrity sha512-L1R2mtI8MsWMmepBs8xC3XiCQiTWuaN8yWaDTEMiexV62SUPgi2wL2256rdBPFUr088ZYdLOSGr+WM3hNj34nQ== dependencies: "@coral-xyz/anchor" "^0.28.0" "@solana/web3.js" "^1.78.8" @@ -327,15 +327,15 @@ "@helium/anchor-resolvers" "^0.5.0" "@helium/modular-governance-idls" "^0.0.8" -"@helium/spl-utils@^0.9.0-alpha.0": - version "0.9.0-alpha.0" - resolved "https://registry.yarnpkg.com/@helium/spl-utils/-/spl-utils-0.9.0-alpha.0.tgz#75b5bd1802c2c21d1262bca6434e4b02155d8e29" - integrity sha512-bc2y6YlkPh+fBLXS5Tes6e7LjcqnU68ArRT6yDZH63eI4pFyH7O1FKRqmcRzbHWL6CkPWSNHOiYhK/u2cyhEMA== +"@helium/spl-utils@^0.9.0-alpha.2": + version "0.9.0-alpha.2" + resolved "https://registry.yarnpkg.com/@helium/spl-utils/-/spl-utils-0.9.0-alpha.2.tgz#44888a644ff49c13e2589e000202b795cd8b086b" + integrity sha512-BAdf74wezU1XjKj7679JZ8a413aO8OULzpRvskp7dcbwiGTFaWZAAZYkq4lhS07sGfyHFx1UgSdq/7tlB/afkw== dependencies: "@coral-xyz/anchor" "^0.28.0" - "@helium/account-fetch-cache" "^0.9.0-alpha.0" + "@helium/account-fetch-cache" "^0.9.0-alpha.1" "@helium/address" "^4.10.2" - "@helium/anchor-resolvers" "^0.9.0-alpha.0" + "@helium/anchor-resolvers" "^0.9.0-alpha.1" "@metaplex-foundation/mpl-token-metadata" "^2.10.0" "@solana/spl-account-compression" "^0.1.7" "@solana/spl-token" "^0.3.8" @@ -354,33 +354,33 @@ "@helium/anchor-resolvers" "^0.5.0" "@helium/modular-governance-idls" "^0.0.8" -"@helium/treasury-management-sdk@^0.9.0-alpha.0": - version "0.9.0-alpha.0" - resolved "https://registry.yarnpkg.com/@helium/treasury-management-sdk/-/treasury-management-sdk-0.9.0-alpha.0.tgz#f06991f7fce234d57ced46945d7749df3049f668" - integrity sha512-oo8caYX31tzku42RILAKfL4b6AekC9ny4+kmzhFIgP/nE4Rwow/4fyntVOPylFMJKyRogVo6fhSmSOr1ZvMdJQ== +"@helium/treasury-management-sdk@^0.9.0-alpha.2": + version "0.9.0-alpha.2" + resolved "https://registry.yarnpkg.com/@helium/treasury-management-sdk/-/treasury-management-sdk-0.9.0-alpha.2.tgz#498992115e0b4e3f9eecfdb7484c243209c34fa9" + integrity sha512-eo1h7qb4/g1UFc/nxh0Kh/g7VrydPLue6a+vSE+VkCwTKPXSZGPiLomZ+eNhzu89k7nyhmhsoB9nL6hPsduTdA== dependencies: "@coral-xyz/anchor" "^0.28.0" - "@helium/anchor-resolvers" "^0.9.0-alpha.0" - "@helium/circuit-breaker-sdk" "^0.9.0-alpha.0" - "@helium/idls" "^0.9.0-alpha.0" + "@helium/anchor-resolvers" "^0.9.0-alpha.1" + "@helium/circuit-breaker-sdk" "^0.9.0-alpha.2" + "@helium/idls" "^0.9.0-alpha.1" bn.js "^5.2.0" bs58 "^4.0.1" -"@helium/voter-stake-registry-hooks@^0.9.0-alpha.0": - version "0.9.0-alpha.0" - resolved "https://registry.yarnpkg.com/@helium/voter-stake-registry-hooks/-/voter-stake-registry-hooks-0.9.0-alpha.0.tgz#f05b988348d49513b830600390d9d7476aa7c7a2" - integrity sha512-NAtTt+fnnfy6/7NYJAIz46tJFf/ASXgi/9Ah7NiAAwxrlyD8Y/Qg5LRh40t//rZwyxaYPaJeKS6YhBaPM9fNvQ== +"@helium/voter-stake-registry-hooks@^0.9.0-alpha.2": + version "0.9.0-alpha.2" + resolved "https://registry.yarnpkg.com/@helium/voter-stake-registry-hooks/-/voter-stake-registry-hooks-0.9.0-alpha.2.tgz#8c4de7c640970efe7e332e7bbf9e5469f5dd2282" + integrity sha512-o3LkOsdoj5c/BYtd5dhyfzZC//tvLh/4rnwYY9SVWuzdIAER3bpwAiszmWehmjgAXYQtR4oHwua8McA6bQh7Ug== dependencies: "@coral-xyz/anchor" "^0.28.0" - "@helium/account-fetch-cache" "^0.9.0-alpha.0" - "@helium/account-fetch-cache-hooks" "^0.9.0-alpha.0" - "@helium/circuit-breaker-sdk" "^0.9.0-alpha.0" - "@helium/helium-react-hooks" "^0.9.0-alpha.0" - "@helium/helium-sub-daos-sdk" "^0.9.0-alpha.0" + "@helium/account-fetch-cache" "^0.9.0-alpha.1" + "@helium/account-fetch-cache-hooks" "^0.9.0-alpha.2" + "@helium/circuit-breaker-sdk" "^0.9.0-alpha.2" + "@helium/helium-react-hooks" "^0.9.0-alpha.2" + "@helium/helium-sub-daos-sdk" "^0.9.0-alpha.2" "@helium/modular-governance-hooks" "^0.0.8" "@helium/modular-governance-idls" "0.0.8-next.19+4fa4c6b" - "@helium/spl-utils" "^0.9.0-alpha.0" - "@helium/voter-stake-registry-sdk" "^0.9.0-alpha.0" + "@helium/spl-utils" "^0.9.0-alpha.2" + "@helium/voter-stake-registry-sdk" "^0.9.0-alpha.2" "@solana/wallet-adapter-base" "^0.9.22" "@solana/wallet-adapter-react" "^0.15.32" "@solana/web3.js" "^1.78.8" @@ -389,16 +389,16 @@ bs58 "^4.0.1" react-async-hook "^4.0.0" -"@helium/voter-stake-registry-sdk@^0.9.0-alpha.0": - version "0.9.0-alpha.0" - resolved "https://registry.yarnpkg.com/@helium/voter-stake-registry-sdk/-/voter-stake-registry-sdk-0.9.0-alpha.0.tgz#37b6e5533c5353ed925a4b478bfb13770b8bf4e3" - integrity sha512-cEZPNxlcDMyl58j72cwAoykLQmkn7wWjABCYQ9WAvjOr2WGM4fFCV6W3uk12uIZ4V/ZlxTCc5WoF/YlneIqiqg== +"@helium/voter-stake-registry-sdk@^0.9.0-alpha.2": + version "0.9.0-alpha.2" + resolved "https://registry.yarnpkg.com/@helium/voter-stake-registry-sdk/-/voter-stake-registry-sdk-0.9.0-alpha.2.tgz#cc502f094ccddcc8df5753575810055b498d749d" + integrity sha512-SfUPPsZGMooesh2UhmCEgygirpq+Lx4hLD9tUA3wbCc6iHPa/NMANsSk2bXadS27hKmCx20zOgyFysv08Vxhvw== dependencies: "@coral-xyz/anchor" "^0.28.0" - "@helium/anchor-resolvers" "^0.9.0-alpha.0" - "@helium/idls" "^0.9.0-alpha.0" + "@helium/anchor-resolvers" "^0.9.0-alpha.1" + "@helium/idls" "^0.9.0-alpha.1" "@helium/nft-proxy-sdk" "0.0.8-next.19+4fa4c6b" - "@helium/spl-utils" "^0.9.0-alpha.0" + "@helium/spl-utils" "^0.9.0-alpha.2" "@metaplex-foundation/mpl-token-metadata" "^2.10.0" "@solana/spl-token" "^0.3.8" bn.js "^5.2.0" From 3b4143c87e255dd23ba941b556ef0a0e42b0b618 Mon Sep 17 00:00:00 2001 From: bry Date: Wed, 3 Jul 2024 10:06:04 -0500 Subject: [PATCH 19/41] Flex layout of position card --- src/components/PositionCard.tsx | 153 +++++++++++++++++--------------- src/components/Positions.tsx | 6 +- src/components/SubNav.tsx | 2 +- src/components/ui/button.tsx | 6 +- 4 files changed, 88 insertions(+), 79 deletions(-) diff --git a/src/components/PositionCard.tsx b/src/components/PositionCard.tsx index db6eba8..b90713e 100644 --- a/src/components/PositionCard.tsx +++ b/src/components/PositionCard.tsx @@ -8,7 +8,10 @@ import { } from "@/lib/utils"; import { useGovernance } from "@/providers/GovernanceProvider"; import { useSolanaUnixNow } from "@helium/helium-react-hooks"; -import { PositionWithMeta, useKnownProxy } from "@helium/voter-stake-registry-hooks"; +import { + PositionWithMeta, + useKnownProxy, +} from "@helium/voter-stake-registry-hooks"; import BN from "bn.js"; import classNames from "classnames"; import Image from "next/image"; @@ -26,8 +29,6 @@ import { } from "./ui/card"; import { Skeleton } from "./ui/skeleton"; import { PublicKey } from "@solana/web3.js"; -import { useAsync } from "react-async-hook"; -import { VoteService } from "@helium/voter-stake-registry-sdk"; export const PositionCardSkeleton: FC<{ compact?: boolean }> = () => { const { network } = useGovernance(); @@ -81,13 +82,7 @@ export const PositionCard: FC<{ }) => { const path = usePathname(); const { lockup, hasGenesisMultiplier } = position; - const { - loading: loadingGov, - network, - mintAcc, - subDaos, - voteService, - } = useGovernance(); + const { loading: loadingGov, network, mintAcc, subDaos } = useGovernance(); const unixNow = useSolanaUnixNow() || Date.now() / 1000; const lockupKind = Object.keys(lockup.kind)[0] as string; const isConstant = lockupKind === "constant"; @@ -180,52 +175,36 @@ export const PositionCard: FC<{ return ( - - -
-
+ + +
+
{`%{network}`}
-
- {isDecayed && 100% Decayed} - {isConstant && Paused} - {!isConstant && !isDecayed && ( - - {decayedPercentage.toString()}% Decayed - - )} -
-
- -
- {lockedTokens} for - + + {`${lockedTokens} ${network.toUpperCase()}`}{" "} + {getMinDurationFmt( position.lockup.startTs, position.lockup.endTs )} -
- {hasGenesisMultiplier && ( - - Landrush - - )} -
+ +
- -
+ +

VOTING POWER

-
+

{votingPower}

{hasGenesisMultiplier && ( - + x3 )}
-
+

TIME LEFT

{isConstant @@ -236,19 +215,17 @@ export const PositionCard: FC<{ : getTimeLeftFromNowFmt(position.lockup.endTs)}

- - - - {canDelegate && ( - <> -
-
-
-
+
+ {canDelegate && ( + <>

DELEGATED TO

{!isDecayed && delegatedSubDaoMetadata ? ( -
-
+
+
delegated-subdao ) : ( -

UNDELEGATED

+

Undelegated

)} -
+ + )} +
+
+ <> +

PROXIED TO

+ {position.proxy && + !position.proxy.nextVoter.equals(PublicKey.default) ? ( + + + {knownProxy?.name || + ellipsisMiddle(position.proxy.nextVoter.toBase58())} + + + ) : ( + + + + )} - )} -
-

PROXIED TO

- {position.proxy && - !position.proxy.nextVoter.equals(PublicKey.default) ? ( - - - {knownProxy?.name || - ellipsisMiddle(position.proxy.nextVoter.toBase58())} +
+
+
+ {hasGenesisMultiplier && ( + + Landrush - - ) : ( - - - - )} + )} + {isDecayed && 100% Decayed} + {isConstant && Paused} + {!isConstant && !isDecayed && ( + + {decayedPercentage.toString()}% Decayed + + )} +
- + ); diff --git a/src/components/Positions.tsx b/src/components/Positions.tsx index 950f327..0d6b5ce 100644 --- a/src/components/Positions.tsx +++ b/src/components/Positions.tsx @@ -183,7 +183,7 @@ export const Positions: FC = () => { Reclaim All */} - + {decayedPositions.map((position) => ( {
*/} - + {notDecayedPositions.map((position) => ( { Proxied to Me - + {proxiedPositions.map((position) => ( { diff --git a/src/components/ui/button.tsx b/src/components/ui/button.tsx index 5850a85..f8d6883 100644 --- a/src/components/ui/button.tsx +++ b/src/components/ui/button.tsx @@ -22,6 +22,7 @@ const buttonVariants = cva( size: { default: "h-11 px-4 md:px-6 py-2", xs: "h-8 text-xs rounded-md px-3", + xxs: "h-6 text-xs rounded-sm py-0 px-2", sm: "h-10 rounded-md px-3", lg: "h-12 rounded-md px-8", icon: "h-10 w-10", @@ -42,7 +43,10 @@ export interface ButtonProps } const Button = React.forwardRef( - ({ className, variant, size, element = "button", asChild = false, ...props }, ref) => { + ( + { className, variant, size, element = "button", asChild = false, ...props }, + ref + ) => { const Comp = asChild ? Slot : element; return ( Date: Wed, 3 Jul 2024 12:52:29 -0500 Subject: [PATCH 20/41] Redesign of positions --- src/components/PositionCard.tsx | 214 +++++++++++++++++--------------- src/components/Positions.tsx | 2 +- src/components/ui/button.tsx | 2 +- 3 files changed, 114 insertions(+), 104 deletions(-) diff --git a/src/components/PositionCard.tsx b/src/components/PositionCard.tsx index b90713e..f2a535c 100644 --- a/src/components/PositionCard.tsx +++ b/src/components/PositionCard.tsx @@ -35,34 +35,34 @@ export const PositionCardSkeleton: FC<{ compact?: boolean }> = () => { const canDelegate = network === "hnt"; return ( - - + +
- -
+ +
-
+
{canDelegate && (
-
+
)} - + ); }; @@ -173,12 +173,35 @@ export const PositionCard: FC<{ ); } + const renderTags = () => ( +
+ {hasGenesisMultiplier && ( + + Landrush + + )} + {isDecayed && ( + + 100%{" "} +  Decayed + + )} + {isConstant && Paused} + {!isConstant && !isDecayed && ( + + {decayedPercentage.toString()}% +  Decayed + + )} +
+ ); + return ( - - -
-
+ + +
+
{`%{network}`}
@@ -191,114 +214,101 @@ export const PositionCard: FC<{
+
{renderTags()}
- -
-

VOTING POWER

-
-

{votingPower}

- {hasGenesisMultiplier && ( - - x3 - - )} + +
+
+

VOTING POWER

+
+

{votingPower}

+ {hasGenesisMultiplier && ( + + x3 + + )} +
+
+
+

TIME LEFT

+

+ {isConstant + ? getMinDurationFmt( + position.lockup.startTs, + position.lockup.endTs + ) + : getTimeLeftFromNowFmt(position.lockup.endTs)} +

-
-

TIME LEFT

-

- {isConstant - ? getMinDurationFmt( - position.lockup.startTs, - position.lockup.endTs - ) - : getTimeLeftFromNowFmt(position.lockup.endTs)} -

-
+
- {canDelegate && ( - <> -

DELEGATED TO

- {!isDecayed && delegatedSubDaoMetadata ? ( -
-
- delegated-subdao -
-

{delegatedSubDaoMetadata.symbol}

-
- ) : !isDecayed ? ( - - - - ) : ( -

Undelegated

- )} - + className={classNames( + "flex flex-col w-3/12 lg:w-2/12 max-md:p-4 max-md:w-full max-md:flex-row max-md:items-center max-md:justify-between", + !position.proxy ? "gap-1" : "gap-2" )} -
-
- <> -

PROXIED TO

- {position.proxy && - !position.proxy.nextVoter.equals(PublicKey.default) ? ( - PROXIED TO

+ {position.proxy && + !position.proxy.nextVoter.equals(PublicKey.default) ? ( + + + {knownProxy?.name || + ellipsisMiddle(position.proxy.nextVoter.toBase58())} + + + ) : ( + + + + )} +
+ {canDelegate && ( +
+

DELEGATED TO

+ {!isDecayed && delegatedSubDaoMetadata ? ( +
+
+ delegated-subdao +
+

{delegatedSubDaoMetadata.symbol}

+
+ ) : !isDecayed ? ( - )} - -
-
-
- {hasGenesisMultiplier && ( - - Landrush - - )} - {isDecayed && 100% Decayed} - {isConstant && Paused} - {!isConstant && !isDecayed && ( - - {decayedPercentage.toString()}% Decayed - + ) : ( +

Undelegated

)}
+ )} +
+ {renderTags()}
diff --git a/src/components/Positions.tsx b/src/components/Positions.tsx index 0d6b5ce..e2da9a5 100644 --- a/src/components/Positions.tsx +++ b/src/components/Positions.tsx @@ -124,7 +124,7 @@ export const Positions: FC = () => {
- + {[...Array(5)].map((_, i) => ( ))} diff --git a/src/components/ui/button.tsx b/src/components/ui/button.tsx index f8d6883..92de282 100644 --- a/src/components/ui/button.tsx +++ b/src/components/ui/button.tsx @@ -13,7 +13,7 @@ const buttonVariants = cva( destructive: "bg-destructive text-destructive-foreground hover:bg-destructive/90", outline: - "border border-input bg-background hover:bg-accent hover:text-accent-foreground", + "border border-input hover:bg-accent hover:text-accent-foreground", secondary: "bg-secondary text-secondary-foreground hover:bg-secondary/80", ghost: "hover:bg-accent hover:text-accent-foreground", From b0dac8b595d81c04544623226cea9f08dc987d51 Mon Sep 17 00:00:00 2001 From: bry Date: Wed, 3 Jul 2024 15:11:14 -0500 Subject: [PATCH 21/41] round of style tweaks --- .../PositionManager/ProxyPositionPrompt.tsx | 21 ++++++-- src/components/Proxies.tsx | 13 +++-- src/components/ProxySearch.tsx | 2 +- src/components/ui/autocomplete.tsx | 21 +++----- src/components/ui/command.tsx | 54 +++++++++---------- 5 files changed, 61 insertions(+), 50 deletions(-) diff --git a/src/components/PositionManager/ProxyPositionPrompt.tsx b/src/components/PositionManager/ProxyPositionPrompt.tsx index 6d4da0f..526a4b4 100644 --- a/src/components/PositionManager/ProxyPositionPrompt.tsx +++ b/src/components/PositionManager/ProxyPositionPrompt.tsx @@ -1,7 +1,10 @@ "use client"; import { useGovernance } from "@/providers/GovernanceProvider"; -import { PositionWithMeta, useKnownProxy } from "@helium/voter-stake-registry-hooks"; +import { + PositionWithMeta, + useKnownProxy, +} from "@helium/voter-stake-registry-hooks"; import { PublicKey } from "@solana/web3.js"; import { Loader2, X } from "lucide-react"; import Link from "next/link"; @@ -15,7 +18,15 @@ export const ProxyPositionPrompt: FC<{ position: PositionWithMeta; isSubmitting?: boolean; onCancel: () => void; - onConfirm: ({ proxy, expirationTime, isRevoke }: { proxy?: string, expirationTime?: number; isRevoke?: boolean }) => Promise; + onConfirm: ({ + proxy, + expirationTime, + isRevoke, + }: { + proxy?: string; + expirationTime?: number; + isRevoke?: boolean; + }) => Promise; }> = ({ position, isSubmitting, onCancel, onConfirm }) => { const isProxied = position.proxy?.nextVoter && @@ -34,7 +45,7 @@ export const ProxyPositionPrompt: FC<{ 7, 1 ); - const maxDate = augustFirst - 1000 + const maxDate = augustFirst - 1000; const maxDays = Math.floor( (maxDate - today.getTime()) / (1000 * 60 * 60 * 24) ); @@ -71,8 +82,8 @@ export const ProxyPositionPrompt: FC<{ precedence over a proxy.

- - diff --git a/src/components/Proxies.tsx b/src/components/Proxies.tsx index a400662..83a2395 100644 --- a/src/components/Proxies.tsx +++ b/src/components/Proxies.tsx @@ -10,7 +10,7 @@ import { Loader2 } from "lucide-react"; import Link from "next/link"; import { usePathname } from "next/navigation"; import { useState } from "react"; -import { FaMagnifyingGlass } from "react-icons/fa6"; +import { FaMagnifyingGlass, FaX } from "react-icons/fa6"; import { IoWarningOutline } from "react-icons/io5"; import InfiniteScroll from "react-infinite-scroll-component"; import { ContentSection } from "./ContentSection"; @@ -91,13 +91,18 @@ export function Proxies() {

Browse Proxies

- + + {proxySearch ? ( + setProxySearch("")} + /> + ) : null} setProxySearch(e.target.value)} - type="search" placeholder="Search name or address..." - className="w-full appearance-none bg-secondary border-none pl-8 shadow-none" + className="w-full appearance-none bg-secondary border-none pl-12 pr-10 shadow-none" />
diff --git a/src/components/ProxySearch.tsx b/src/components/ProxySearch.tsx index 8faaf59..695ef36 100644 --- a/src/components/ProxySearch.tsx +++ b/src/components/ProxySearch.tsx @@ -53,7 +53,7 @@ export const ProxySearch: React.FC<{ onValueChange(v.value)} value={selectedOption} diff --git a/src/components/ui/autocomplete.tsx b/src/components/ui/autocomplete.tsx index 831e851..f541091 100644 --- a/src/components/ui/autocomplete.tsx +++ b/src/components/ui/autocomplete.tsx @@ -1,15 +1,10 @@ import { Command as CommandPrimitive } from "cmdk"; -import { - useCallback, - useRef, - useState, - type KeyboardEvent -} from "react"; +import { useCallback, useRef, useState, type KeyboardEvent } from "react"; import { CommandGroup, CommandInput, CommandItem, - CommandList + CommandList, } from "./command"; import { Skeleton } from "./skeleton"; @@ -131,14 +126,14 @@ export const AutoComplete = ({ />
-
+
- + {isLoading ? (
@@ -147,8 +142,8 @@ export const AutoComplete = ({ ) : null} {options.length > 0 && !isLoading ? ( - - {options.map((option) => { + + {[...options, ...options].map((option) => { const isSelected = selected?.value === option.value; return ( handleSelectOption(option)} className={cn( - "flex w-full items-center gap-2", + "flex w-full items-center gap-2 cursor-pointer !bg-transparent hover:!bg-gray-700", !isSelected ? "pl-8" : null )} > diff --git a/src/components/ui/command.tsx b/src/components/ui/command.tsx index dead3c1..34b079c 100644 --- a/src/components/ui/command.tsx +++ b/src/components/ui/command.tsx @@ -1,12 +1,12 @@ -"use client" +"use client"; -import * as React from "react" -import { type DialogProps } from "@radix-ui/react-dialog" -import { Command as CommandPrimitive } from "cmdk" -import { Search } from "lucide-react" +import * as React from "react"; +import { type DialogProps } from "@radix-ui/react-dialog"; +import { Command as CommandPrimitive } from "cmdk"; +import { Search } from "lucide-react"; -import { cn } from "@/lib/utils" -import { Dialog, DialogContent } from "@/components/ui/dialog" +import { cn } from "@/lib/utils"; +import { Dialog, DialogContent } from "@/components/ui/dialog"; const Command = React.forwardRef< React.ElementRef, @@ -20,8 +20,8 @@ const Command = React.forwardRef< )} {...props} /> -)) -Command.displayName = CommandPrimitive.displayName +)); +Command.displayName = CommandPrimitive.displayName; interface CommandDialogProps extends DialogProps {} @@ -34,8 +34,8 @@ const CommandDialog = ({ children, ...props }: CommandDialogProps) => { - ) -} + ); +}; const CommandInput = React.forwardRef< React.ElementRef, @@ -52,9 +52,9 @@ const CommandInput = React.forwardRef< {...props} />
-)) +)); -CommandInput.displayName = CommandPrimitive.Input.displayName +CommandInput.displayName = CommandPrimitive.Input.displayName; const CommandList = React.forwardRef< React.ElementRef, @@ -65,9 +65,9 @@ const CommandList = React.forwardRef< className={cn("max-h-[300px] overflow-y-auto overflow-x-hidden", className)} {...props} /> -)) +)); -CommandList.displayName = CommandPrimitive.List.displayName +CommandList.displayName = CommandPrimitive.List.displayName; const CommandEmpty = React.forwardRef< React.ElementRef, @@ -78,9 +78,9 @@ const CommandEmpty = React.forwardRef< className="py-6 text-center text-sm" {...props} /> -)) +)); -CommandEmpty.displayName = CommandPrimitive.Empty.displayName +CommandEmpty.displayName = CommandPrimitive.Empty.displayName; const CommandGroup = React.forwardRef< React.ElementRef, @@ -94,9 +94,9 @@ const CommandGroup = React.forwardRef< )} {...props} /> -)) +)); -CommandGroup.displayName = CommandPrimitive.Group.displayName +CommandGroup.displayName = CommandPrimitive.Group.displayName; const CommandSeparator = React.forwardRef< React.ElementRef, @@ -107,8 +107,8 @@ const CommandSeparator = React.forwardRef< className={cn("-mx-1 h-px bg-border", className)} {...props} /> -)) -CommandSeparator.displayName = CommandPrimitive.Separator.displayName +)); +CommandSeparator.displayName = CommandPrimitive.Separator.displayName; const CommandItem = React.forwardRef< React.ElementRef, @@ -122,9 +122,9 @@ const CommandItem = React.forwardRef< )} {...props} /> -)) +)); -CommandItem.displayName = CommandPrimitive.Item.displayName +CommandItem.displayName = CommandPrimitive.Item.displayName; const CommandShortcut = ({ className, @@ -138,9 +138,9 @@ const CommandShortcut = ({ )} {...props} /> - ) -} -CommandShortcut.displayName = "CommandShortcut" + ); +}; +CommandShortcut.displayName = "CommandShortcut"; export { Command, @@ -152,4 +152,4 @@ export { CommandItem, CommandShortcut, CommandSeparator, -} +}; From c6284e7773eb0135a1c5c96deef392d20872f022 Mon Sep 17 00:00:00 2001 From: bry Date: Wed, 3 Jul 2024 15:53:18 -0500 Subject: [PATCH 22/41] remove dup destructuring --- src/components/ui/autocomplete.tsx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/components/ui/autocomplete.tsx b/src/components/ui/autocomplete.tsx index f541091..872bd3d 100644 --- a/src/components/ui/autocomplete.tsx +++ b/src/components/ui/autocomplete.tsx @@ -143,7 +143,7 @@ export const AutoComplete = ({ ) : null} {options.length > 0 && !isLoading ? ( - {[...options, ...options].map((option) => { + {options.map((option) => { const isSelected = selected?.value === option.value; return ( Date: Wed, 3 Jul 2024 17:03:09 -0500 Subject: [PATCH 23/41] style tweaks round 2 --- src/app/globals.css | 4 ++++ src/components/PositionCard.tsx | 12 ++++++------ src/components/VoteOption.tsx | 17 ++++++++++------- 3 files changed, 20 insertions(+), 13 deletions(-) diff --git a/src/app/globals.css b/src/app/globals.css index 1370407..abe4e9f 100644 --- a/src/app/globals.css +++ b/src/app/globals.css @@ -28,6 +28,8 @@ --info-foreground: 217 91% 60%; --purple: 274 87 21%; --purple-foreground: 258 90 66%; + --pink: 336 84 17%; + --pink-foreground: 330 81 60%; --border: 214.3 31.8% 91.4%; --input: 214.3 31.8% 91.4%; --ring: 221.2 83.2% 53.3%; @@ -59,6 +61,8 @@ --info-foreground: 217 91% 60%; --purple: 274 87 21%; --purple-foreground: 258 90 66%; + --pink: 336 84 17%; + --pink-foreground: 330 81 60%; --border: 217.2 32.6% 17.5%; --input: 217.2 32.6% 17.5%; --ring: 224.3 76.3% 48%; diff --git a/src/components/PositionCard.tsx b/src/components/PositionCard.tsx index f2a535c..1a4250e 100644 --- a/src/components/PositionCard.tsx +++ b/src/components/PositionCard.tsx @@ -216,14 +216,14 @@ export const PositionCard: FC<{
{renderTags()}
- +

VOTING POWER

-
+

{votingPower}

- {hasGenesisMultiplier && ( - + {!hasGenesisMultiplier && ( + x3 )} @@ -245,7 +245,7 @@ export const PositionCard: FC<{

PROXIED TO

@@ -254,7 +254,7 @@ export const PositionCard: FC<{ - + {knownProxy?.name || ellipsisMiddle(position.proxy.nextVoter.toBase58())} diff --git a/src/components/VoteOption.tsx b/src/components/VoteOption.tsx index f5694d5..551bd1e 100644 --- a/src/components/VoteOption.tsx +++ b/src/components/VoteOption.tsx @@ -70,12 +70,16 @@ export const VoteOption: FC<{ {myWeight && }
- { voters.length > 0 &&
-
Voted by
- {voters.map((v) => ( - - ))} -
} + {voters.length > 0 && ( +
+
+ Voted by +
+ {voters.map((v) => ( + + ))} +
+ )}
); @@ -87,4 +91,3 @@ const Voter: FC<{ voter: PublicKey }> = ({ voter }) => { ); }; - From 76a400f06025a2a6643a7498b6c017c4edf2c750 Mon Sep 17 00:00:00 2001 From: bry Date: Mon, 8 Jul 2024 16:22:52 -0500 Subject: [PATCH 24/41] Proposal view tweaks --- src/components/AssignProxyModal.tsx | 18 +- src/components/LegacyProposal.tsx | 200 +++++++------ src/components/Markdown.tsx | 18 +- src/components/PositionCard.tsx | 2 +- src/components/Proposal.tsx | 423 +++++++++++++++------------ src/components/ProxyButton.tsx | 3 +- src/components/ProxyProfile.tsx | 4 +- src/components/RealmProposal.tsx | 142 ++++----- src/components/RevokeProxyButton.tsx | 13 +- src/components/VoteBreakdown.tsx | 34 +-- src/components/VoteOptions.tsx | 33 ++- src/hooks/useProposalInfo.ts | 5 +- 12 files changed, 483 insertions(+), 412 deletions(-) diff --git a/src/components/AssignProxyModal.tsx b/src/components/AssignProxyModal.tsx index b9154a0..dd6ac00 100644 --- a/src/components/AssignProxyModal.tsx +++ b/src/components/AssignProxyModal.tsx @@ -3,15 +3,14 @@ import { PositionWithMeta } from "@helium/voter-stake-registry-hooks"; import { PublicKey } from "@solana/web3.js"; import BN from "bn.js"; import { Loader2 } from "lucide-react"; -import React, { useEffect, useMemo, useState } from "react"; +import React, { useMemo, useState } from "react"; import { toast } from "sonner"; +import { ExpirationTimeSlider } from "./ExpirationTimeSlider"; import { NetworkSelect } from "./NetworkSelect"; import { PositionPreview } from "./PositionPreview"; import { ProxySearch } from "./ProxySearch"; import { Button } from "./ui/button"; import { Dialog, DialogContent, DialogTrigger } from "./ui/dialog"; -import { Slider } from "./ui/slider"; -import { ExpirationTimeSlider } from "./ExpirationTimeSlider"; interface AssignProxyModalProps { onSubmit: (args: { @@ -66,14 +65,9 @@ export const AssignProxyModal: React.FC< : new Date().valueOf() / 1000 + selectedDays * (24 * 60 * 60), [selectedDays, maxDays, maxDate] ); - useEffect(() => { - if (selectedDays > maxDays) { - setSelectedDays(maxDays); - } - }, [maxDays, selectedDays]); - const changeRecipient = (e: any) => { - setRecipient(e.target.value); + const handleSelectedDays = (days: number) => { + setSelectedDays(days > maxDays ? maxDays : days); }; const handleOnSubmit = async () => { @@ -195,7 +189,7 @@ export const AssignProxyModal: React.FC<
@@ -217,7 +211,7 @@ export const AssignProxyModal: React.FC<
)} diff --git a/src/components/PositionCard.tsx b/src/components/PositionCard.tsx index 1a4250e..8f49188 100644 --- a/src/components/PositionCard.tsx +++ b/src/components/PositionCard.tsx @@ -222,7 +222,7 @@ export const PositionCard: FC<{

VOTING POWER

{votingPower}

- {!hasGenesisMultiplier && ( + {hasGenesisMultiplier && ( x3 diff --git a/src/components/Proposal.tsx b/src/components/Proposal.tsx index d345b7f..0d922d2 100644 --- a/src/components/Proposal.tsx +++ b/src/components/Proposal.tsx @@ -18,8 +18,13 @@ import { FaCopy, FaDiscord, FaGithub, - FaXTwitter + FaXTwitter, } from "react-icons/fa6"; +import { + IoStopwatchOutline, + IoFlagOutline, + IoFlashOutline, +} from "react-icons/io5"; import { toast } from "sonner"; import { ContentSection } from "./ContentSection"; import { CountdownTimer } from "./CountdownTimer"; @@ -37,51 +42,68 @@ const MARKDOWN_MAX = 540; export const ProposalSkeleton = () => ( <> - - - - - -
-
- {[...Array(3)].map((_, i) => ( - - ))} -
-
- - {[...Array(3)].map((_, i) => ( -
-
- -
- - - - + + +
+
+ + + +
+
+ {[...Array(3)].map((_, i) => ( + + ))}
-
- ))} - - + + {[...Array(3)].map((_, i) => ( +
+
+ +
+ + + + +
+
+
+ ))} + + +
+
+ + + + + + + + + + +
+
+
); const ProposalHipBlurb: FC<{ network: string }> = ({ network }) => ( -
-
+
+
{`ve${network}`}
-

+

This HIP affects the {network.toUpperCase()} network which requires ve {network.toUpperCase()} positions for vote participation.

- + Manage Voting Power
@@ -94,30 +116,45 @@ export const ProposalBreakdown: FC<{ totalVotes?: BN; decimals?: number; }> = ({ timeExpired, endTs, isCancelled, totalVotes, decimals }) => ( -
-
-

{timeExpired ? "DATE OCCURRED" : "DEADLINE"}

-

- {format(new Date((endTs?.toNumber() || 0) * 1000), "PPp")} -

+
+
+ +
+

+ {timeExpired ? "DATE OCCURRED" : "DEADLINE"} +

+

+ {format(new Date((endTs?.toNumber() || 0) * 1000), "PPp")} +

+
{!timeExpired && !isCancelled ? ( -
+ <> -

EST. TIME REMAINING

-
- +
+ +
+

EST. TIME REMAINING

+
+ +
+
-
+ ) : null} {totalVotes && ( -
+ <> -

TOTAL veTOKENS

-

- {humanReadable(totalVotes, decimals)} -

-
+
+ +
+

TOTAL veTOKENS

+

+ {humanReadable(totalVotes, decimals)} +

+
+
+ )}
); @@ -130,16 +167,19 @@ export const ProposalSocial: FC<{ isCancelled?: boolean; }> = ({ network, proposalKey, githubUrl, twitterUrl, isCancelled }) => { return ( -
+
- {githubUrl && ( @@ -147,11 +187,14 @@ export const ProposalSocial: FC<{ href={githubUrl} rel="noopener noreferrer" target="_blank" - className="flex flex-row" + className="flex flex-1" > - )} @@ -160,23 +203,31 @@ export const ProposalSocial: FC<{ href={twitterUrl.toString()} rel="noopener noreferrer" target="_blank" - className="flex flex-row" + className="flex flex-1" > - )} - toast("Link copied to clipboard")} - > - - +
+ toast("Link copied to clipboard")} + > + + +
); }; @@ -187,12 +238,7 @@ export const Proposal: FC<{ proposalKey: string; }> = ({ name: initName, content, proposalKey }) => { const { connected, connecting } = useWallet(); - const { - loading: loadingGov, - amountLocked, - amountProxyLocked, - network, - } = useGovernance(); + const { network } = useGovernance(); const pKey = useMemo(() => new PublicKey(proposalKey), [proposalKey]); const { voted, @@ -206,6 +252,7 @@ export const Proposal: FC<{ decimals, endTs, } = useProposalInfo(pKey); + const name = proposal?.name || initName; const twitterUrl = useMemo(() => { @@ -227,7 +274,13 @@ export const Proposal: FC<{ } }, [proposalKey, endTs, network, completed, name]); - if (isLoading) return ; + if (connecting || isLoading) + return ( +
+ +
+ ); + return ( <>
- - - - - - Back to Votes - -
- {proposal?.tags - .filter((tag) => tag !== "tags") - .map((tag, i) => ( - 0, - } - )} +
+ +
+
+ + + - {tag} - - ))} -
-

{name}

- - -
-
- {!completed && !connected && ( -
- Please connect a wallet to participate. - + + Back to Votes + +
+ {proposal?.tags + .filter((tag) => tag !== "tags") + .map((tag, i) => ( + 0, + } + )} + > + {tag} + + ))}
- )} - {connected && noVotingPower && !completed && ( -
-

- No voting power detected. This HIP affects the{" "} - {network.toUpperCase()} network which requires ve - {network.toUpperCase()} positions for vote participation. -

-
- - Manage Voting Power - +

{name}

+ + +
+
+ {!completed && !connected && ( +
+ Please connect a wallet to participate. + +
+ )} + {connected && noVotingPower && !completed && ( +
+

+ No voting power detected. This HIP affects the{" "} + {network.toUpperCase()} network which requires ve + {network.toUpperCase()} positions for vote + participation. +

+
+ + Manage Voting Power + +
+
+ )} + {connected && + !noVotingPower && + !completed && + proposal && + votingResults && ( + + )} + {(completed || (connected && !noVotingPower && voted)) && + votingResults && + votingResults?.totalVotes.gt(new BN(0)) && ( +
+ +
+ )}
- )} - {connected && - !noVotingPower && - !completed && - proposal && - votingResults && ( - - )} - {(completed || (connected && !noVotingPower && voted)) && votingResults && - votingResults?.totalVotes.gt(new BN(0)) && ( -
- -
- )} -
- - - -
- - {content.replace(name, "")} - -
-
+ + +
+ {!isCancelled && completed && ( + + + + )} + + + {content.replace(name, "")} + +
- {!isCancelled && completed && ( -
- -
- )} - - - +
+ + + +
+
+ +
); }; diff --git a/src/components/ProxyButton.tsx b/src/components/ProxyButton.tsx index 2f35adc..28699c6 100644 --- a/src/components/ProxyButton.tsx +++ b/src/components/ProxyButton.tsx @@ -11,7 +11,7 @@ export const ProxyButton = React.forwardRef< HTMLButtonElement, { className?: string; - onClick: () => void; + onClick?: () => void; isLoading?: boolean; } >(({ className = "", onClick, isLoading = false }, ref) => { @@ -48,4 +48,3 @@ export const ProxyButton = React.forwardRef< }); ProxyButton.displayName = "ProxyButton"; - diff --git a/src/components/ProxyProfile.tsx b/src/components/ProxyProfile.tsx index 249ad47..fdcd035 100644 --- a/src/components/ProxyProfile.tsx +++ b/src/components/ProxyProfile.tsx @@ -292,10 +292,10 @@ export function ProxyProfile({ wallet: walletRaw }: { wallet: string }) {
- {}} isLoading={false} /> + - {}} isLoading={false} /> +
{infoCard}
diff --git a/src/components/RealmProposal.tsx b/src/components/RealmProposal.tsx index 9f0104f..8853e6f 100644 --- a/src/components/RealmProposal.tsx +++ b/src/components/RealmProposal.tsx @@ -44,77 +44,83 @@ export const RealmProposal: FC<{

Voting is Closed

- - - - - - Back to Votes - -
- {Object.values(tags) - .filter((tag) => tag !== "tags") - .map((tag, i) => ( - 0, - } - )} +
+ +
+
+ + + - {tag} - - ))} + + Back to Votes + +
+ {Object.values(tags) + .filter((tag) => tag !== "tags") + .map((tag, i) => ( + 0, + } + )} + > + {tag} + + ))} +
+

{name}

+
+ +
+
+ +
+ + +
+
+ + {content.replace(name, "")} + +
+
+
+
+
-

{name}

- - -
-
- -
- - -
-
- - {content.replace(name, "")} - -
-
-
- - -
+
+ +
- - - +
+ +
); }; diff --git a/src/components/RevokeProxyButton.tsx b/src/components/RevokeProxyButton.tsx index 324ffa2..e296a5a 100644 --- a/src/components/RevokeProxyButton.tsx +++ b/src/components/RevokeProxyButton.tsx @@ -10,11 +10,12 @@ import { cn } from "@/lib/utils"; export const RevokeProxyButton = React.forwardRef< HTMLButtonElement, { - className?: string; - onClick: () => void; - isLoading?: boolean; - wallet?: PublicKey; -}>(({ wallet, className = "", onClick, isLoading = false }) => { + className?: string; + onClick?: () => void; + isLoading?: boolean; + wallet?: PublicKey; + } +>(({ wallet, className = "", onClick, isLoading = false }) => { const { connected } = useWallet(); const { loading, positions } = useGovernance(); @@ -26,7 +27,7 @@ export const RevokeProxyButton = React.forwardRef< !p.proxy.nextVoter.equals(PublicKey.default) && (!wallet || p.proxy.nextVoter.equals(wallet)) ), - [positions] + [wallet, positions] ); const disabled = !connected || loading || !proxiedPositions?.length; diff --git a/src/components/VoteBreakdown.tsx b/src/components/VoteBreakdown.tsx index 45a74c8..d7985c4 100644 --- a/src/components/VoteBreakdown.tsx +++ b/src/components/VoteBreakdown.tsx @@ -133,35 +133,32 @@ export const VoteBreakdown: FC<{ return (
-
Voter Breakdown
- +

Voter Breakdown

+ Download as CSV
-

+

Note: For MOBILE/IOT subnetworks, this is shown as 1/10 of your vote power becuase the underlying contracts in spl-governance onlysupport 64-bits of precision

- - Download as CSV - - +
{groupedSortedMarkers && groupedSortedMarkers.length > displayCount && ( )} - OWNER - CHOICES - VOTE POWER - + + OWNER + + + CHOICES + + + VOTE POWER + + PERCENTAGE @@ -212,7 +209,8 @@ export const VoteBreakdown: FC<{ - {canDelegate && ( - + {!isProxy && ( + <> + {!isDecayed ? ( +
+ + {canDelegate && ( + + )} +
+ ) : ( +
+ +
)} - - ) : ( -
- -
+ )} ); diff --git a/src/components/PositionManager/PositionManager.tsx b/src/components/PositionManager/PositionManager.tsx index 17c9d04..5e8bd52 100644 --- a/src/components/PositionManager/PositionManager.tsx +++ b/src/components/PositionManager/PositionManager.tsx @@ -60,6 +60,7 @@ export type PositionAction = | "proxy"; export interface PositionManagerProps { + isProxy?: boolean; initAction?: PositionAction; position: PositionWithMeta; } @@ -96,6 +97,7 @@ const PositionAction: FC< export const PositionManager: FC = ({ position, initAction, + isProxy = false, }) => { const [action, setAction] = useState(initAction); const provider = useAnchorProvider(); @@ -108,6 +110,7 @@ export const PositionManager: FC = ({ } = useGovernance(); const router = useRouter(); const { lockup } = position; + const isConstant = Object.keys(lockup.kind)[0] === "constant"; const unixNow = useSolanaUnixNow() || Date.now() / 1000; const isDecayed = !isConstant && lockup.endTs.lte(new BN(unixNow)); @@ -117,7 +120,6 @@ export const PositionManager: FC = ({ return []; } - const { lockup } = position; const lockupKind = Object.keys(lockup.kind)[0]; const positionLockupPeriodInDays = secsToDays( lockupKind === "constant" @@ -144,6 +146,7 @@ export const PositionManager: FC = ({ lockupPeriodInDays >= positionLockupPeriodInDays ); }); + // eslint-disable-next-line react-hooks/exhaustive-deps }, [position, unixNow, positions]); const maxActionableAmount = mintAcc @@ -155,9 +158,11 @@ export const PositionManager: FC = ({ setAction(undefined); }, [refetchState, setAction]); - const { isPending: isAssigningProxy, mutateAsync: assignProxies } = useAssignProxies(); - const { isPending: isRevokingProxy, mutateAsync: unassignProxies } = useUnassignProxies(); - const isUpdatingProxy = isAssigningProxy || isRevokingProxy + const { isPending: isAssigningProxy, mutateAsync: assignProxies } = + useAssignProxies(); + const { isPending: isRevokingProxy, mutateAsync: unassignProxies } = + useUnassignProxies(); + const isUpdatingProxy = isAssigningProxy || isRevokingProxy; const { loading: isFlipping, flipPositionLockupKind } = useFlipPositionLockupKind(); const { loading: isClaiming, claimPositionRewards } = @@ -372,60 +377,63 @@ export const PositionManager: FC = ({ position={position} isClaiming={isClaiming} isReclaiming={isReclaiming} + isProxy={isProxy} setManagerAction={setAction} handleClaimRewards={handleClaimPositionRewards} /> -
-
- - Position Actions - -
-
- } - onClick={() => setAction("proxy")} - > - Update Proxy - - {canDelegate && ( + {!isProxy && ( +
+
+ + Position Actions + +
+
setAction("delegate")} + active={action === "proxy"} + Icon={() => } + onClick={() => setAction("proxy")} > - Update Delegation + Update Proxy - )} - ( - + {canDelegate && ( + setAction("delegate")} + > + Update Delegation + )} - onClick={() => setAction("extend")} - > - Extend Position - - setAction("split")} - > - Split Position - - setAction("merge")} - > - Merge Position - + ( + + )} + onClick={() => setAction("extend")} + > + Extend Position + + setAction("split")} + > + Split Position + + setAction("merge")} + > + Merge Position + +
+
- -
+ )}
{ {proxiedPositions.map((position) => ( Date: Tue, 9 Jul 2024 14:34:38 -0500 Subject: [PATCH 26/41] Update packages --- package.json | 14 +++++++------- yarn.lock | 50 +++++++++++++++++++++++++------------------------- 2 files changed, 32 insertions(+), 32 deletions(-) diff --git a/package.json b/package.json index 9c0584f..8915102 100644 --- a/package.json +++ b/package.json @@ -12,14 +12,14 @@ "@coral-xyz/anchor": "^0.29.0", "@helium/account-fetch-cache": "^0.9.0-alpha.1", "@helium/account-fetch-cache-hooks": "^0.9.0-alpha.2", - "@helium/helium-react-hooks": "^0.9.0-alpha.2", + "@helium/helium-react-hooks": "^0.9.0-alpha.3", "@helium/modular-governance-hooks": "^0.0.8", "@helium/modular-governance-idls": "^0.0.8-next.19+4fa4c6b", "@helium/organization-sdk": "^0.0.8", "@helium/spl-utils": "^0.9.0-alpha.2", "@helium/state-controller-sdk": "^0.0.8", - "@helium/voter-stake-registry-hooks": "^0.9.0-alpha.2", - "@helium/voter-stake-registry-sdk": "^0.9.0-alpha.2", + "@helium/voter-stake-registry-hooks": "^0.9.0-alpha.3", + "@helium/voter-stake-registry-sdk": "^0.9.0-alpha.3", "@hookform/resolvers": "^3.3.4", "@metaplex-foundation/mpl-token-metadata": "2.10.0", "@project-serum/anchor": "^0.26.0", @@ -72,14 +72,14 @@ }, "resolutions": { "@solana/web3.js": "^1.90.0", - "@helium/account-fetch-cache": "^0.9.0-alpha.2", + "@helium/account-fetch-cache": "^0.9.0-alpha.1", "@helium/account-fetch-cache-hooks": "^0.9.0-alpha.2", - "@helium/helium-react-hooks": "^0.9.0-alpha.2", - "@helium/voter-stake-registry-hooks": "^0.9.0-alpha.2", + "@helium/helium-react-hooks": "^0.9.0-alpha.3", + "@helium/voter-stake-registry-hooks": "^0.9.0-alpha.3", "@helium/spl-utils": "^0.9.0-alpha.2", "@helium/modular-governance-hooks": "^0.0.8", "@solana/wallet-adapter-react": "^0.15.35", - "@helium/voter-stake-registry-sdk": "^0.9.0-alpha.2" + "@helium/voter-stake-registry-sdk": "^0.9.0-alpha.3" }, "devDependencies": { "@tailwindcss/typography": "^0.5.10", diff --git a/yarn.lock b/yarn.lock index 111da76..b3388cb 100644 --- a/yarn.lock +++ b/yarn.lock @@ -231,10 +231,10 @@ bn.js "^5.2.0" bs58 "^4.0.1" -"@helium/helium-react-hooks@^0.5.0", "@helium/helium-react-hooks@^0.9.0-alpha.2": - version "0.9.0-alpha.2" - resolved "https://registry.yarnpkg.com/@helium/helium-react-hooks/-/helium-react-hooks-0.9.0-alpha.2.tgz#f853c7109d53e399d2de037b1a2d45d694a4a043" - integrity sha512-1ksNYJvUd24sJhmm49Mt2kPZfM7WUQ4/EIWAT25Y7iCaLPbpZI/7Mfh6NVUzcW1T5WfCEKcvCmCvaHpPseoxeA== +"@helium/helium-react-hooks@^0.5.0", "@helium/helium-react-hooks@^0.9.0-alpha.3": + version "0.9.0-alpha.3" + resolved "https://registry.yarnpkg.com/@helium/helium-react-hooks/-/helium-react-hooks-0.9.0-alpha.3.tgz#d17222abd09b179ce0385c5f5a0786aa55d6c210" + integrity sha512-gTs7tyh+wDoblTq41xy0N0QNMIwX4+wu0elj89v1HgNxtgirDSU9b7Njn1SNqzKlqILjDotnDQe4wdp84+9eEQ== dependencies: "@coral-xyz/anchor" "^0.28.0" "@helium/account-fetch-cache" "^0.9.0-alpha.1" @@ -245,16 +245,16 @@ pako "^2.0.3" react-async-hook "^4.0.0" -"@helium/helium-sub-daos-sdk@^0.9.0-alpha.2": - version "0.9.0-alpha.2" - resolved "https://registry.yarnpkg.com/@helium/helium-sub-daos-sdk/-/helium-sub-daos-sdk-0.9.0-alpha.2.tgz#11178f5fb894d12233f35ad6901d36862227a423" - integrity sha512-olCTIBR7A6F/dgkpmvfEdwNgkw268zPBMnXf8SGdGPPbuG23UB0/BrorXRl29MDKAJdFsd6nm/Nxmm6BhVIC6Q== +"@helium/helium-sub-daos-sdk@^0.9.0-alpha.3": + version "0.9.0-alpha.3" + resolved "https://registry.yarnpkg.com/@helium/helium-sub-daos-sdk/-/helium-sub-daos-sdk-0.9.0-alpha.3.tgz#cd957bfddde93de07fa48824d341e2a9d4a1338d" + integrity sha512-gsYXbOhc7GBMyB7OvgPfLaRyP0EfK86bxh5mNDliOpJx3oJ1149lJmCxwAhshX9MZtzr9I4wG+xrKYfejLrTLQ== dependencies: "@coral-xyz/anchor" "^0.28.0" "@helium/anchor-resolvers" "^0.9.0-alpha.1" "@helium/circuit-breaker-sdk" "^0.9.0-alpha.2" - "@helium/treasury-management-sdk" "^0.9.0-alpha.2" - "@helium/voter-stake-registry-sdk" "^0.9.0-alpha.2" + "@helium/treasury-management-sdk" "^0.9.0-alpha.3" + "@helium/voter-stake-registry-sdk" "^0.9.0-alpha.3" bn.js "^5.2.0" bs58 "^4.0.1" @@ -354,10 +354,10 @@ "@helium/anchor-resolvers" "^0.5.0" "@helium/modular-governance-idls" "^0.0.8" -"@helium/treasury-management-sdk@^0.9.0-alpha.2": - version "0.9.0-alpha.2" - resolved "https://registry.yarnpkg.com/@helium/treasury-management-sdk/-/treasury-management-sdk-0.9.0-alpha.2.tgz#498992115e0b4e3f9eecfdb7484c243209c34fa9" - integrity sha512-eo1h7qb4/g1UFc/nxh0Kh/g7VrydPLue6a+vSE+VkCwTKPXSZGPiLomZ+eNhzu89k7nyhmhsoB9nL6hPsduTdA== +"@helium/treasury-management-sdk@^0.9.0-alpha.3": + version "0.9.0-alpha.3" + resolved "https://registry.yarnpkg.com/@helium/treasury-management-sdk/-/treasury-management-sdk-0.9.0-alpha.3.tgz#45de517c441944594bb7f81c40db9867f4303023" + integrity sha512-kInSvyXmlnaEzkFXJ+oPsaH16+wzMlil+m1FUeWLjkLHuXRvMlopxjtr/WkMiCLx84aMF6JP1gMKAhEbhZF+Hg== dependencies: "@coral-xyz/anchor" "^0.28.0" "@helium/anchor-resolvers" "^0.9.0-alpha.1" @@ -366,21 +366,21 @@ bn.js "^5.2.0" bs58 "^4.0.1" -"@helium/voter-stake-registry-hooks@^0.9.0-alpha.2": - version "0.9.0-alpha.2" - resolved "https://registry.yarnpkg.com/@helium/voter-stake-registry-hooks/-/voter-stake-registry-hooks-0.9.0-alpha.2.tgz#8c4de7c640970efe7e332e7bbf9e5469f5dd2282" - integrity sha512-o3LkOsdoj5c/BYtd5dhyfzZC//tvLh/4rnwYY9SVWuzdIAER3bpwAiszmWehmjgAXYQtR4oHwua8McA6bQh7Ug== +"@helium/voter-stake-registry-hooks@^0.9.0-alpha.3": + version "0.9.0-alpha.3" + resolved "https://registry.yarnpkg.com/@helium/voter-stake-registry-hooks/-/voter-stake-registry-hooks-0.9.0-alpha.3.tgz#1e566deebbd781b25661ffa827bf9d1d985cc49d" + integrity sha512-0mX3pCr5Sjn6+VtyiykK8feEkln6cEQyl0Jfv9Y7yrdCYrOpYDKobr8nnmY1cYgyDo/iNSgngLiIQOf7w+4AEw== dependencies: "@coral-xyz/anchor" "^0.28.0" "@helium/account-fetch-cache" "^0.9.0-alpha.1" "@helium/account-fetch-cache-hooks" "^0.9.0-alpha.2" "@helium/circuit-breaker-sdk" "^0.9.0-alpha.2" - "@helium/helium-react-hooks" "^0.9.0-alpha.2" - "@helium/helium-sub-daos-sdk" "^0.9.0-alpha.2" + "@helium/helium-react-hooks" "^0.9.0-alpha.3" + "@helium/helium-sub-daos-sdk" "^0.9.0-alpha.3" "@helium/modular-governance-hooks" "^0.0.8" "@helium/modular-governance-idls" "0.0.8-next.19+4fa4c6b" "@helium/spl-utils" "^0.9.0-alpha.2" - "@helium/voter-stake-registry-sdk" "^0.9.0-alpha.2" + "@helium/voter-stake-registry-sdk" "^0.9.0-alpha.3" "@solana/wallet-adapter-base" "^0.9.22" "@solana/wallet-adapter-react" "^0.15.32" "@solana/web3.js" "^1.78.8" @@ -389,10 +389,10 @@ bs58 "^4.0.1" react-async-hook "^4.0.0" -"@helium/voter-stake-registry-sdk@^0.9.0-alpha.2": - version "0.9.0-alpha.2" - resolved "https://registry.yarnpkg.com/@helium/voter-stake-registry-sdk/-/voter-stake-registry-sdk-0.9.0-alpha.2.tgz#cc502f094ccddcc8df5753575810055b498d749d" - integrity sha512-SfUPPsZGMooesh2UhmCEgygirpq+Lx4hLD9tUA3wbCc6iHPa/NMANsSk2bXadS27hKmCx20zOgyFysv08Vxhvw== +"@helium/voter-stake-registry-sdk@^0.9.0-alpha.3": + version "0.9.0-alpha.3" + resolved "https://registry.yarnpkg.com/@helium/voter-stake-registry-sdk/-/voter-stake-registry-sdk-0.9.0-alpha.3.tgz#f9c74a2c043cbc13fd692919a0def073adc71f1a" + integrity sha512-4L4zddlcYZFUAxwhvMcROSyotNQl13BO8vCNLOs4pizWOWHlL6kndYeH8K5CVZJm6WSwrTyeq56kzis+2YeUxA== dependencies: "@coral-xyz/anchor" "^0.28.0" "@helium/anchor-resolvers" "^0.9.0-alpha.1" From 3d9b44ae70044c6a4a04e7e8516527e8622e4387 Mon Sep 17 00:00:00 2001 From: bry Date: Tue, 9 Jul 2024 14:40:05 -0500 Subject: [PATCH 27/41] update logic for isProxy on position manager --- src/app/[network]/positions/[positionKey]/page.tsx | 13 +++---------- src/components/PositionCard.tsx | 4 +--- src/components/PositionManager/PositionCallout.tsx | 4 +--- src/components/PositionManager/PositionManager.tsx | 5 +---- src/components/Positions.tsx | 1 - 5 files changed, 6 insertions(+), 21 deletions(-) diff --git a/src/app/[network]/positions/[positionKey]/page.tsx b/src/app/[network]/positions/[positionKey]/page.tsx index 403773e..f6cb767 100644 --- a/src/app/[network]/positions/[positionKey]/page.tsx +++ b/src/app/[network]/positions/[positionKey]/page.tsx @@ -15,10 +15,7 @@ export interface PositionsPageParams { network: string; positionKey: string; }; - searchParams: - | { action: PositionAction; isProxy?: boolean } - | null - | undefined; + searchParams: { action: PositionAction } | null | undefined; } export default function PositionsPage({ @@ -26,7 +23,7 @@ export default function PositionsPage({ searchParams, }: PositionsPageParams) { const { positionKey } = params; - const { action, isProxy = false } = searchParams || {}; + const { action } = searchParams || {}; const { positions } = useGovernance(); const positionK = useMemo(() => new PublicKey(positionKey), [positionKey]); const position = useMemo( @@ -39,11 +36,7 @@ export default function PositionsPage({
{position && ( - + )} diff --git a/src/components/PositionCard.tsx b/src/components/PositionCard.tsx index 903799e..13a45fe 100644 --- a/src/components/PositionCard.tsx +++ b/src/components/PositionCard.tsx @@ -67,10 +67,8 @@ export const PositionCard: FC<{ compact?: boolean; onClick?: () => void; canDelegate?: boolean; - isProxy?: boolean; }> = ({ canDelegate: canDelegateIn = true, - isProxy: isProxyIn = false, position, className = "", compact = false, @@ -195,7 +193,7 @@ export const PositionCard: FC<{ return ( diff --git a/src/components/PositionManager/PositionCallout.tsx b/src/components/PositionManager/PositionCallout.tsx index 04ed9de..4abc1ef 100644 --- a/src/components/PositionManager/PositionCallout.tsx +++ b/src/components/PositionManager/PositionCallout.tsx @@ -23,14 +23,12 @@ export const PositionCallout: FC<{ position: PositionWithMeta; isClaiming?: boolean; isReclaiming?: boolean; - isProxy?: boolean; setManagerAction: (action: PositionAction) => void; handleClaimRewards: () => Promise; }> = ({ position, isClaiming, isReclaiming, - isProxy, setManagerAction, handleClaimRewards, }) => { @@ -170,7 +168,7 @@ export const PositionCallout: FC<{

- {!isProxy && ( + {!position.isProxiedToMe && ( <> {!isDecayed ? (
diff --git a/src/components/PositionManager/PositionManager.tsx b/src/components/PositionManager/PositionManager.tsx index 5e8bd52..a1f9ac1 100644 --- a/src/components/PositionManager/PositionManager.tsx +++ b/src/components/PositionManager/PositionManager.tsx @@ -60,7 +60,6 @@ export type PositionAction = | "proxy"; export interface PositionManagerProps { - isProxy?: boolean; initAction?: PositionAction; position: PositionWithMeta; } @@ -97,7 +96,6 @@ const PositionAction: FC< export const PositionManager: FC = ({ position, initAction, - isProxy = false, }) => { const [action, setAction] = useState(initAction); const provider = useAnchorProvider(); @@ -377,12 +375,11 @@ export const PositionManager: FC = ({ position={position} isClaiming={isClaiming} isReclaiming={isReclaiming} - isProxy={isProxy} setManagerAction={setAction} handleClaimRewards={handleClaimPositionRewards} />
- {!isProxy && ( + {!position.isProxiedToMe && (
diff --git a/src/components/Positions.tsx b/src/components/Positions.tsx index 4987fdd..e2da9a5 100644 --- a/src/components/Positions.tsx +++ b/src/components/Positions.tsx @@ -227,7 +227,6 @@ export const Positions: FC = () => { {proxiedPositions.map((position) => ( Date: Tue, 9 Jul 2024 15:12:07 -0700 Subject: [PATCH 28/41] Add fix for faster vote txns --- package.json | 22 ++++++------- scripts/create-proposal.ts | 1 + src/components/VoteOptions.tsx | 18 ++++++++--- src/lib/utils.ts | 11 +++++-- yarn.lock | 56 +++++++++++++++++----------------- 5 files changed, 63 insertions(+), 45 deletions(-) diff --git a/package.json b/package.json index 9c0584f..27d8210 100644 --- a/package.json +++ b/package.json @@ -11,15 +11,15 @@ "dependencies": { "@coral-xyz/anchor": "^0.29.0", "@helium/account-fetch-cache": "^0.9.0-alpha.1", - "@helium/account-fetch-cache-hooks": "^0.9.0-alpha.2", - "@helium/helium-react-hooks": "^0.9.0-alpha.2", + "@helium/account-fetch-cache-hooks": "^0.9.0-alpha.3", + "@helium/helium-react-hooks": "^0.9.0-alpha.3", "@helium/modular-governance-hooks": "^0.0.8", "@helium/modular-governance-idls": "^0.0.8-next.19+4fa4c6b", "@helium/organization-sdk": "^0.0.8", - "@helium/spl-utils": "^0.9.0-alpha.2", + "@helium/spl-utils": "file:.yalc/@helium/spl-utils", "@helium/state-controller-sdk": "^0.0.8", - "@helium/voter-stake-registry-hooks": "^0.9.0-alpha.2", - "@helium/voter-stake-registry-sdk": "^0.9.0-alpha.2", + "@helium/voter-stake-registry-hooks": "file:.yalc/@helium/voter-stake-registry-hooks", + "@helium/voter-stake-registry-sdk": "file:.yalc/@helium/voter-stake-registry-sdk", "@hookform/resolvers": "^3.3.4", "@metaplex-foundation/mpl-token-metadata": "2.10.0", "@project-serum/anchor": "^0.26.0", @@ -72,14 +72,14 @@ }, "resolutions": { "@solana/web3.js": "^1.90.0", - "@helium/account-fetch-cache": "^0.9.0-alpha.2", - "@helium/account-fetch-cache-hooks": "^0.9.0-alpha.2", - "@helium/helium-react-hooks": "^0.9.0-alpha.2", - "@helium/voter-stake-registry-hooks": "^0.9.0-alpha.2", - "@helium/spl-utils": "^0.9.0-alpha.2", + "@helium/account-fetch-cache": "^0.9.0-alpha.3", + "@helium/account-fetch-cache-hooks": "^0.9.0-alpha.3", + "@helium/helium-react-hooks": "^0.9.0-alpha.3", + "@helium/voter-stake-registry-hooks": "^0.9.0-alpha.3", + "@helium/spl-utils": "^0.9.0-alpha.3", "@helium/modular-governance-hooks": "^0.0.8", "@solana/wallet-adapter-react": "^0.15.35", - "@helium/voter-stake-registry-sdk": "^0.9.0-alpha.2" + "@helium/voter-stake-registry-sdk": "^0.9.0-alpha.3" }, "devDependencies": { "@tailwindcss/typography": "^0.5.10", diff --git a/scripts/create-proposal.ts b/scripts/create-proposal.ts index 51a3c60..2f322c9 100644 --- a/scripts/create-proposal.ts +++ b/scripts/create-proposal.ts @@ -98,6 +98,7 @@ export async function run(args: any = process.argv) { tags: ["test", "tags"], }) .accounts({ + payer: authority, authority, organization: organizationK, owner: authority, diff --git a/src/components/VoteOptions.tsx b/src/components/VoteOptions.tsx index b4c1fe8..16de708 100644 --- a/src/components/VoteOptions.tsx +++ b/src/components/VoteOptions.tsx @@ -23,7 +23,13 @@ export const VoteOptions: FC<{ proposalKey: PublicKey; }> = ({ choices = [], maxChoicesPerVoter, proposalKey }) => { const [currVote, setCurrVote] = useState(0); - const { voteWeights, canVote, vote, loading: voting, voters } = useVote(proposalKey); + const { + voteWeights, + canVote, + vote, + loading: voting, + voters, + } = useVote(proposalKey); const { positions } = useGovernance(); @@ -49,7 +55,9 @@ export const VoteOptions: FC<{ setCurrVote(choice.index); await vote({ choice: choice.index, - onInstructions: onInstructions(provider), + onInstructions: onInstructions(provider, { + useFirstEstimateForAll: true, + }), }); toast("Vote submitted"); } catch (e: any) { @@ -67,7 +75,9 @@ export const VoteOptions: FC<{ setCurrVote(choice.index); await relinquishVote({ choice: choice.index, - onInstructions: onInstructions(provider), + onInstructions: onInstructions(provider, { + useFirstEstimateForAll: true, + }), }); toast("Vote relinquished"); } catch (e: any) { @@ -79,7 +89,7 @@ export const VoteOptions: FC<{ } }; - const { assignProxies } = useAssignProxies(); + const { mutateAsync: assignProxies } = useAssignProxies(); return (
diff --git a/src/lib/utils.ts b/src/lib/utils.ts index 1276769..f277694 100644 --- a/src/lib/utils.ts +++ b/src/lib/utils.ts @@ -6,7 +6,7 @@ import { batchInstructionsToTxsWithPriorityFee, bulkSendTransactions, sendAndConfirmWithRetry, - toVersionedTx + toVersionedTx, } from "@helium/spl-utils"; import { PositionWithMeta } from "@helium/voter-stake-registry-hooks"; import { Mint } from "@solana/spl-token"; @@ -294,7 +294,12 @@ export const precision = (a: number) => { }; export const onInstructions = - (provider?: AnchorProvider) => + ( + provider?: AnchorProvider, + { + useFirstEstimateForAll = false, + }: { useFirstEstimateForAll?: boolean } = {} + ) => async (instructions: TransactionInstruction[], sigs?: Keypair[]) => { if (provider) { if (sigs) { @@ -309,6 +314,7 @@ export const onInstructions = ? HELIUM_COMMON_LUT_DEVNET : HELIUM_COMMON_LUT, ], + useFirstEstimateForAll, } ); const asVersionedTx = transactions.map(toVersionedTx); @@ -344,6 +350,7 @@ export const onInstructions = ? HELIUM_COMMON_LUT_DEVNET : HELIUM_COMMON_LUT, ], + useFirstEstimateForAll, } ); diff --git a/yarn.lock b/yarn.lock index 111da76..5318268 100644 --- a/yarn.lock +++ b/yarn.lock @@ -171,7 +171,7 @@ resolved "https://registry.yarnpkg.com/@floating-ui/utils/-/utils-0.2.1.tgz#16308cea045f0fc777b6ff20a9f25474dd8293d2" integrity sha512-9TANp6GPoMtYzQdt54kfAyMmz1+osLlXdg2ENroU7zzrtflTLrrC/lgrIfaSe+Wu0b89GKccT7vxXA0MoAIO+Q== -"@helium/account-fetch-cache-hooks@^0.5.0", "@helium/account-fetch-cache-hooks@^0.9.0-alpha.2": +"@helium/account-fetch-cache-hooks@^0.5.0", "@helium/account-fetch-cache-hooks@^0.9.0-alpha.2", "@helium/account-fetch-cache-hooks@^0.9.0-alpha.3": version "0.9.0-alpha.2" resolved "https://registry.yarnpkg.com/@helium/account-fetch-cache-hooks/-/account-fetch-cache-hooks-0.9.0-alpha.2.tgz#3b02dd40ada358bca4dca7566f757d75f7fa8c59" integrity sha512-JOfqPKWSVZLaAtfZp4/kfjKJJB0JD3SMyGRokiuqBQC86O1M2FrKpRBSTOitHsThxMu2XfIApoTj0aLxQ3mZJA== @@ -180,7 +180,7 @@ "@solana/web3.js" "^1.78.8" react-async-hook "^4.0.0" -"@helium/account-fetch-cache@^0.5.0", "@helium/account-fetch-cache@^0.9.0-alpha.1", "@helium/account-fetch-cache@^0.9.0-alpha.2": +"@helium/account-fetch-cache@^0.5.0", "@helium/account-fetch-cache@^0.9.0-alpha.1", "@helium/account-fetch-cache@^0.9.0-alpha.3": version "0.9.0-alpha.1" resolved "https://registry.yarnpkg.com/@helium/account-fetch-cache/-/account-fetch-cache-0.9.0-alpha.1.tgz#d6d5d93e57718680d7f3c23372f56bec4aee8428" integrity sha512-J2E9OsoL7HiCtfk20rXzi6N0c3645KVy07kFCXMsft5VHRQ3jSkjma2iCdZEt1JhwFxQW/XLtePYYp1Plp4Luw== @@ -231,10 +231,10 @@ bn.js "^5.2.0" bs58 "^4.0.1" -"@helium/helium-react-hooks@^0.5.0", "@helium/helium-react-hooks@^0.9.0-alpha.2": - version "0.9.0-alpha.2" - resolved "https://registry.yarnpkg.com/@helium/helium-react-hooks/-/helium-react-hooks-0.9.0-alpha.2.tgz#f853c7109d53e399d2de037b1a2d45d694a4a043" - integrity sha512-1ksNYJvUd24sJhmm49Mt2kPZfM7WUQ4/EIWAT25Y7iCaLPbpZI/7Mfh6NVUzcW1T5WfCEKcvCmCvaHpPseoxeA== +"@helium/helium-react-hooks@^0.5.0", "@helium/helium-react-hooks@^0.9.0-alpha.3": + version "0.9.0-alpha.3" + resolved "https://registry.yarnpkg.com/@helium/helium-react-hooks/-/helium-react-hooks-0.9.0-alpha.3.tgz#d17222abd09b179ce0385c5f5a0786aa55d6c210" + integrity sha512-gTs7tyh+wDoblTq41xy0N0QNMIwX4+wu0elj89v1HgNxtgirDSU9b7Njn1SNqzKlqILjDotnDQe4wdp84+9eEQ== dependencies: "@coral-xyz/anchor" "^0.28.0" "@helium/account-fetch-cache" "^0.9.0-alpha.1" @@ -245,16 +245,16 @@ pako "^2.0.3" react-async-hook "^4.0.0" -"@helium/helium-sub-daos-sdk@^0.9.0-alpha.2": - version "0.9.0-alpha.2" - resolved "https://registry.yarnpkg.com/@helium/helium-sub-daos-sdk/-/helium-sub-daos-sdk-0.9.0-alpha.2.tgz#11178f5fb894d12233f35ad6901d36862227a423" - integrity sha512-olCTIBR7A6F/dgkpmvfEdwNgkw268zPBMnXf8SGdGPPbuG23UB0/BrorXRl29MDKAJdFsd6nm/Nxmm6BhVIC6Q== +"@helium/helium-sub-daos-sdk@^0.9.0-alpha.3": + version "0.9.0-alpha.3" + resolved "https://registry.yarnpkg.com/@helium/helium-sub-daos-sdk/-/helium-sub-daos-sdk-0.9.0-alpha.3.tgz#cd957bfddde93de07fa48824d341e2a9d4a1338d" + integrity sha512-gsYXbOhc7GBMyB7OvgPfLaRyP0EfK86bxh5mNDliOpJx3oJ1149lJmCxwAhshX9MZtzr9I4wG+xrKYfejLrTLQ== dependencies: "@coral-xyz/anchor" "^0.28.0" "@helium/anchor-resolvers" "^0.9.0-alpha.1" "@helium/circuit-breaker-sdk" "^0.9.0-alpha.2" - "@helium/treasury-management-sdk" "^0.9.0-alpha.2" - "@helium/voter-stake-registry-sdk" "^0.9.0-alpha.2" + "@helium/treasury-management-sdk" "^0.9.0-alpha.3" + "@helium/voter-stake-registry-sdk" "^0.9.0-alpha.3" bn.js "^5.2.0" bs58 "^4.0.1" @@ -327,7 +327,7 @@ "@helium/anchor-resolvers" "^0.5.0" "@helium/modular-governance-idls" "^0.0.8" -"@helium/spl-utils@^0.9.0-alpha.2": +"@helium/spl-utils@^0.9.0-alpha.2", "@helium/spl-utils@^0.9.0-alpha.3": version "0.9.0-alpha.2" resolved "https://registry.yarnpkg.com/@helium/spl-utils/-/spl-utils-0.9.0-alpha.2.tgz#44888a644ff49c13e2589e000202b795cd8b086b" integrity sha512-BAdf74wezU1XjKj7679JZ8a413aO8OULzpRvskp7dcbwiGTFaWZAAZYkq4lhS07sGfyHFx1UgSdq/7tlB/afkw== @@ -354,10 +354,10 @@ "@helium/anchor-resolvers" "^0.5.0" "@helium/modular-governance-idls" "^0.0.8" -"@helium/treasury-management-sdk@^0.9.0-alpha.2": - version "0.9.0-alpha.2" - resolved "https://registry.yarnpkg.com/@helium/treasury-management-sdk/-/treasury-management-sdk-0.9.0-alpha.2.tgz#498992115e0b4e3f9eecfdb7484c243209c34fa9" - integrity sha512-eo1h7qb4/g1UFc/nxh0Kh/g7VrydPLue6a+vSE+VkCwTKPXSZGPiLomZ+eNhzu89k7nyhmhsoB9nL6hPsduTdA== +"@helium/treasury-management-sdk@^0.9.0-alpha.3": + version "0.9.0-alpha.3" + resolved "https://registry.yarnpkg.com/@helium/treasury-management-sdk/-/treasury-management-sdk-0.9.0-alpha.3.tgz#45de517c441944594bb7f81c40db9867f4303023" + integrity sha512-kInSvyXmlnaEzkFXJ+oPsaH16+wzMlil+m1FUeWLjkLHuXRvMlopxjtr/WkMiCLx84aMF6JP1gMKAhEbhZF+Hg== dependencies: "@coral-xyz/anchor" "^0.28.0" "@helium/anchor-resolvers" "^0.9.0-alpha.1" @@ -366,21 +366,21 @@ bn.js "^5.2.0" bs58 "^4.0.1" -"@helium/voter-stake-registry-hooks@^0.9.0-alpha.2": - version "0.9.0-alpha.2" - resolved "https://registry.yarnpkg.com/@helium/voter-stake-registry-hooks/-/voter-stake-registry-hooks-0.9.0-alpha.2.tgz#8c4de7c640970efe7e332e7bbf9e5469f5dd2282" - integrity sha512-o3LkOsdoj5c/BYtd5dhyfzZC//tvLh/4rnwYY9SVWuzdIAER3bpwAiszmWehmjgAXYQtR4oHwua8McA6bQh7Ug== +"@helium/voter-stake-registry-hooks@^0.9.0-alpha.3": + version "0.9.0-alpha.3" + resolved "https://registry.yarnpkg.com/@helium/voter-stake-registry-hooks/-/voter-stake-registry-hooks-0.9.0-alpha.3.tgz#1e566deebbd781b25661ffa827bf9d1d985cc49d" + integrity sha512-0mX3pCr5Sjn6+VtyiykK8feEkln6cEQyl0Jfv9Y7yrdCYrOpYDKobr8nnmY1cYgyDo/iNSgngLiIQOf7w+4AEw== dependencies: "@coral-xyz/anchor" "^0.28.0" "@helium/account-fetch-cache" "^0.9.0-alpha.1" "@helium/account-fetch-cache-hooks" "^0.9.0-alpha.2" "@helium/circuit-breaker-sdk" "^0.9.0-alpha.2" - "@helium/helium-react-hooks" "^0.9.0-alpha.2" - "@helium/helium-sub-daos-sdk" "^0.9.0-alpha.2" + "@helium/helium-react-hooks" "^0.9.0-alpha.3" + "@helium/helium-sub-daos-sdk" "^0.9.0-alpha.3" "@helium/modular-governance-hooks" "^0.0.8" "@helium/modular-governance-idls" "0.0.8-next.19+4fa4c6b" "@helium/spl-utils" "^0.9.0-alpha.2" - "@helium/voter-stake-registry-sdk" "^0.9.0-alpha.2" + "@helium/voter-stake-registry-sdk" "^0.9.0-alpha.3" "@solana/wallet-adapter-base" "^0.9.22" "@solana/wallet-adapter-react" "^0.15.32" "@solana/web3.js" "^1.78.8" @@ -389,10 +389,10 @@ bs58 "^4.0.1" react-async-hook "^4.0.0" -"@helium/voter-stake-registry-sdk@^0.9.0-alpha.2": - version "0.9.0-alpha.2" - resolved "https://registry.yarnpkg.com/@helium/voter-stake-registry-sdk/-/voter-stake-registry-sdk-0.9.0-alpha.2.tgz#cc502f094ccddcc8df5753575810055b498d749d" - integrity sha512-SfUPPsZGMooesh2UhmCEgygirpq+Lx4hLD9tUA3wbCc6iHPa/NMANsSk2bXadS27hKmCx20zOgyFysv08Vxhvw== +"@helium/voter-stake-registry-sdk@^0.9.0-alpha.3": + version "0.9.0-alpha.3" + resolved "https://registry.yarnpkg.com/@helium/voter-stake-registry-sdk/-/voter-stake-registry-sdk-0.9.0-alpha.3.tgz#f9c74a2c043cbc13fd692919a0def073adc71f1a" + integrity sha512-4L4zddlcYZFUAxwhvMcROSyotNQl13BO8vCNLOs4pizWOWHlL6kndYeH8K5CVZJm6WSwrTyeq56kzis+2YeUxA== dependencies: "@coral-xyz/anchor" "^0.28.0" "@helium/anchor-resolvers" "^0.9.0-alpha.1" From 0d8e56f4e189054b737ab80f3d5e46146f4a0a18 Mon Sep 17 00:00:00 2001 From: Noah Prince Date: Wed, 17 Jul 2024 08:06:40 -0700 Subject: [PATCH 29/41] FIx large position actions --- package.json | 14 +-- .../PositionManager/PositionManager.tsx | 8 +- src/components/Positions.tsx | 2 +- src/components/ProxyProfile.tsx | 54 +++++++- src/components/RevokeProxyModal.tsx | 2 + src/components/VoteOptions.tsx | 11 +- src/lib/utils.ts | 1 + yarn.lock | 117 +++++++++++++++--- 8 files changed, 175 insertions(+), 34 deletions(-) diff --git a/package.json b/package.json index 135988e..77be43f 100644 --- a/package.json +++ b/package.json @@ -10,16 +10,16 @@ }, "dependencies": { "@coral-xyz/anchor": "^0.29.0", - "@helium/account-fetch-cache": "^0.9.0-alpha.1", - "@helium/account-fetch-cache-hooks": "^0.9.0-alpha.3", - "@helium/helium-react-hooks": "^0.9.0-alpha.3", + "@helium/account-fetch-cache": "0.9.0-alpha.5", + "@helium/account-fetch-cache-hooks": "0.9.0-alpha.5", + "@helium/helium-react-hooks": "0.9.0-alpha.5", "@helium/modular-governance-hooks": "^0.0.8", - "@helium/modular-governance-idls": "^0.0.8-next.19+4fa4c6b", + "@helium/modular-governance-idls": "^0.0.8-next.22+7098baa", "@helium/organization-sdk": "^0.0.8", - "@helium/spl-utils": "file:.yalc/@helium/spl-utils", + "@helium/spl-utils": "0.9.0-alpha.5", "@helium/state-controller-sdk": "^0.0.8", - "@helium/voter-stake-registry-hooks": "^0.9.0-alpha.3", - "@helium/voter-stake-registry-sdk": "^0.9.0-alpha.3", + "@helium/voter-stake-registry-hooks": "0.9.0-alpha.5", + "@helium/voter-stake-registry-sdk": "0.9.0-alpha.5", "@hookform/resolvers": "^3.3.4", "@metaplex-foundation/mpl-token-metadata": "2.10.0", "@project-serum/anchor": "^0.26.0", diff --git a/src/components/PositionManager/PositionManager.tsx b/src/components/PositionManager/PositionManager.tsx index a1f9ac1..1b8c8e2 100644 --- a/src/components/PositionManager/PositionManager.tsx +++ b/src/components/PositionManager/PositionManager.tsx @@ -186,14 +186,18 @@ export const PositionManager: FC = ({ if (isRevoke) { await unassignProxies({ positions: [position], - onInstructions: onInstructions(provider), + onInstructions: onInstructions(provider, { + useFirstEstimateForAll: true + }), }); } else { await assignProxies({ positions: [position], recipient: new PublicKey(proxy || ""), expirationTime: new BN(expirationTime || 0), - onInstructions: onInstructions(provider), + onInstructions: onInstructions(provider, { + useFirstEstimateForAll: true + }), }); } toast(`Proxy ${isRevoke ? "revoked" : "assigned"}`); diff --git a/src/components/Positions.tsx b/src/components/Positions.tsx index e2da9a5..352e901 100644 --- a/src/components/Positions.tsx +++ b/src/components/Positions.tsx @@ -14,7 +14,7 @@ import { toast } from "sonner"; import { Skeleton } from "./ui/skeleton"; import { CreatePositionButton } from "./CreatePositionButton"; import { onInstructions } from "@/lib/utils"; -import { useAnchorProvider } from "@helium/helium-react-hooks"; +import { useAnchorProvider, useSolanaUnixNow } from "@helium/helium-react-hooks"; import { ContentSection } from "./ContentSection"; import { WalletSignTransactionError } from "@solana/wallet-adapter-base"; diff --git a/src/components/ProxyProfile.tsx b/src/components/ProxyProfile.tsx index fdcd035..dc13f7e 100644 --- a/src/components/ProxyProfile.tsx +++ b/src/components/ProxyProfile.tsx @@ -1,9 +1,9 @@ "use client"; import { networksToMint } from "@/lib/constants"; -import { ellipsisMiddle, humanReadable } from "@/lib/utils"; +import { ellipsisMiddle, humanReadable, onInstructions } from "@/lib/utils"; import { useGovernance } from "@/providers/GovernanceProvider"; -import { useMint } from "@helium/helium-react-hooks"; +import { useAnchorProvider, useMint } from "@helium/helium-react-hooks"; import { proxyQuery, useAssignProxies, @@ -166,6 +166,8 @@ export function ProxyProfile({ wallet: walletRaw }: { wallet: string }) {
); + const provider = useAnchorProvider() + return ( @@ -213,14 +215,34 @@ export function ProxyProfile({ wallet: walletRaw }: { wallet: string }) {
- + { + return assignProxies({ + ...args, + onInstructions: onInstructions(provider, { + useFirstEstimateForAll: true, + }), + }); + }} + wallet={wallet} + > {}} isLoading={false} /> - + + unassignProxies({ + ...args, + onInstructions: onInstructions(provider, { + useFirstEstimateForAll: true, + }), + }) + } + wallet={wallet} + > {}} @@ -291,10 +313,30 @@ export function ProxyProfile({ wallet: walletRaw }: { wallet: string }) {
- + { + return assignProxies({ + ...args, + onInstructions: onInstructions(provider, { + useFirstEstimateForAll: true, + }), + }); + }} + wallet={wallet} + > - + + unassignProxies({ + ...args, + onInstructions: onInstructions(provider, { + useFirstEstimateForAll: true, + }), + }) + } + wallet={wallet} + >
{infoCard}
diff --git a/src/components/RevokeProxyModal.tsx b/src/components/RevokeProxyModal.tsx index f1eef1c..f51344a 100644 --- a/src/components/RevokeProxyModal.tsx +++ b/src/components/RevokeProxyModal.tsx @@ -7,6 +7,8 @@ import { toast } from "sonner"; import { PositionItem } from "./AssignProxyModal"; import { Button } from "./ui/button"; import { Dialog, DialogContent, DialogTrigger } from "./ui/dialog"; +import { useSolanaUnixNow } from "@helium/helium-react-hooks"; +import BN from "bn.js"; interface RevokeProxyModalProps { onSubmit: (args: { positions: PositionWithMeta[] }) => Promise; diff --git a/src/components/VoteOptions.tsx b/src/components/VoteOptions.tsx index 9dea63d..f83598c 100644 --- a/src/components/VoteOptions.tsx +++ b/src/components/VoteOptions.tsx @@ -117,7 +117,16 @@ export const VoteOptions: FC<{ You can override any active votes anytime - your vote takes precedence over a proxy.

- + { + return assignProxies({ + ...args, + onInstructions: onInstructions(provider, { + useFirstEstimateForAll: true, + }), + }); + }} + > diff --git a/src/lib/utils.ts b/src/lib/utils.ts index f277694..4f265b9 100644 --- a/src/lib/utils.ts +++ b/src/lib/utils.ts @@ -315,6 +315,7 @@ export const onInstructions = : HELIUM_COMMON_LUT, ], useFirstEstimateForAll, + computeScaleUp: useFirstEstimateForAll ? 1.4 : 1.1 } ); const asVersionedTx = transactions.map(toVersionedTx); diff --git a/yarn.lock b/yarn.lock index 5318268..565c5d4 100644 --- a/yarn.lock +++ b/yarn.lock @@ -171,19 +171,19 @@ resolved "https://registry.yarnpkg.com/@floating-ui/utils/-/utils-0.2.1.tgz#16308cea045f0fc777b6ff20a9f25474dd8293d2" integrity sha512-9TANp6GPoMtYzQdt54kfAyMmz1+osLlXdg2ENroU7zzrtflTLrrC/lgrIfaSe+Wu0b89GKccT7vxXA0MoAIO+Q== -"@helium/account-fetch-cache-hooks@^0.5.0", "@helium/account-fetch-cache-hooks@^0.9.0-alpha.2", "@helium/account-fetch-cache-hooks@^0.9.0-alpha.3": - version "0.9.0-alpha.2" - resolved "https://registry.yarnpkg.com/@helium/account-fetch-cache-hooks/-/account-fetch-cache-hooks-0.9.0-alpha.2.tgz#3b02dd40ada358bca4dca7566f757d75f7fa8c59" - integrity sha512-JOfqPKWSVZLaAtfZp4/kfjKJJB0JD3SMyGRokiuqBQC86O1M2FrKpRBSTOitHsThxMu2XfIApoTj0aLxQ3mZJA== +"@helium/account-fetch-cache-hooks@0.9.0-alpha.5", "@helium/account-fetch-cache-hooks@^0.5.0", "@helium/account-fetch-cache-hooks@^0.9.0-alpha.2", "@helium/account-fetch-cache-hooks@^0.9.0-alpha.3", "@helium/account-fetch-cache-hooks@^0.9.0-alpha.5": + version "0.9.0-alpha.5" + resolved "https://registry.yarnpkg.com/@helium/account-fetch-cache-hooks/-/account-fetch-cache-hooks-0.9.0-alpha.5.tgz#34473e1f07abc028982da0dfc53798f93a86cf84" + integrity sha512-img5tw7UyCeEpbl9yXGQokfTNdlFviu4zK7fMrIOYhk8heZMXM2YkV2LBOweA8ENqcyVWXEss5H/Y2cybGS69g== dependencies: - "@helium/account-fetch-cache" "^0.9.0-alpha.1" + "@helium/account-fetch-cache" "^0.9.0-alpha.4" "@solana/web3.js" "^1.78.8" react-async-hook "^4.0.0" -"@helium/account-fetch-cache@^0.5.0", "@helium/account-fetch-cache@^0.9.0-alpha.1", "@helium/account-fetch-cache@^0.9.0-alpha.3": - version "0.9.0-alpha.1" - resolved "https://registry.yarnpkg.com/@helium/account-fetch-cache/-/account-fetch-cache-0.9.0-alpha.1.tgz#d6d5d93e57718680d7f3c23372f56bec4aee8428" - integrity sha512-J2E9OsoL7HiCtfk20rXzi6N0c3645KVy07kFCXMsft5VHRQ3jSkjma2iCdZEt1JhwFxQW/XLtePYYp1Plp4Luw== +"@helium/account-fetch-cache@0.9.0-alpha.5", "@helium/account-fetch-cache@^0.5.0", "@helium/account-fetch-cache@^0.9.0-alpha.1", "@helium/account-fetch-cache@^0.9.0-alpha.3", "@helium/account-fetch-cache@^0.9.0-alpha.4": + version "0.9.0-alpha.4" + resolved "https://registry.yarnpkg.com/@helium/account-fetch-cache/-/account-fetch-cache-0.9.0-alpha.4.tgz#865f974060f693760b6cb51a06cd62c9ff730828" + integrity sha512-d8+sdL5RKQxBG7Mf3wVwguLU0hlBXdVsfC5BlyMBsYpMs66jkZ7bWkIeVLIzoJVV/U0fZIXnCTGkQxTKhAOSdg== dependencies: "@solana/web3.js" "^1.78.8" @@ -231,7 +231,21 @@ bn.js "^5.2.0" bs58 "^4.0.1" -"@helium/helium-react-hooks@^0.5.0", "@helium/helium-react-hooks@^0.9.0-alpha.3": +"@helium/helium-react-hooks@0.9.0-alpha.5": + version "0.9.0-alpha.5" + resolved "https://registry.yarnpkg.com/@helium/helium-react-hooks/-/helium-react-hooks-0.9.0-alpha.5.tgz#1f24bbc36ba251531bf0861cf12b87b14532d586" + integrity sha512-fv+SqMEaz8a69zlzoWV8b+R1pMq+BwVMHmIQSuYxSG3BsBRMuX9SgoWZJNCq+5WAFPrA9Wt5uXvoubZHxpzVtQ== + dependencies: + "@coral-xyz/anchor" "^0.28.0" + "@helium/account-fetch-cache" "^0.9.0-alpha.4" + "@helium/account-fetch-cache-hooks" "^0.9.0-alpha.5" + "@solana/spl-token" "^0.3.8" + "@solana/web3.js" "^1.78.8" + bs58 "^4.0.1" + pako "^2.0.3" + react-async-hook "^4.0.0" + +"@helium/helium-react-hooks@^0.5.0", "@helium/helium-react-hooks@^0.9.0-alpha.3", "@helium/helium-react-hooks@^0.9.0-alpha.5": version "0.9.0-alpha.3" resolved "https://registry.yarnpkg.com/@helium/helium-react-hooks/-/helium-react-hooks-0.9.0-alpha.3.tgz#d17222abd09b179ce0385c5f5a0786aa55d6c210" integrity sha512-gTs7tyh+wDoblTq41xy0N0QNMIwX4+wu0elj89v1HgNxtgirDSU9b7Njn1SNqzKlqILjDotnDQe4wdp84+9eEQ== @@ -258,6 +272,19 @@ bn.js "^5.2.0" bs58 "^4.0.1" +"@helium/helium-sub-daos-sdk@^0.9.0-alpha.5": + version "0.9.0-alpha.5" + resolved "https://registry.yarnpkg.com/@helium/helium-sub-daos-sdk/-/helium-sub-daos-sdk-0.9.0-alpha.5.tgz#b263ea5918aa3a206d22672107ef82d0a2f3e764" + integrity sha512-74ODxxgaFAZ18Z42yKpxFFFc06N9uWM5caSK0EA9aqzV043JEvtld9yCMwC9PYCADT+bKDCKBX2swlajIYc9tQ== + dependencies: + "@coral-xyz/anchor" "^0.28.0" + "@helium/anchor-resolvers" "^0.9.0-alpha.1" + "@helium/circuit-breaker-sdk" "^0.9.0-alpha.2" + "@helium/treasury-management-sdk" "^0.9.0-alpha.3" + "@helium/voter-stake-registry-sdk" "^0.9.0-alpha.5" + bn.js "^5.2.0" + bs58 "^4.0.1" + "@helium/idls@^0.9.0-alpha.1": version "0.9.0-alpha.1" resolved "https://registry.yarnpkg.com/@helium/idls/-/idls-0.9.0-alpha.1.tgz#a87e01535b8f3a31cece57c1a6885a866a8c3181" @@ -290,7 +317,15 @@ "@coral-xyz/anchor" "^0.28.0" "@solana/web3.js" "^1.78.4" -"@helium/modular-governance-idls@^0.0.8", "@helium/modular-governance-idls@^0.0.8-next.19+4fa4c6b": +"@helium/modular-governance-idls@0.0.8-next.22+7098baa": + version "0.0.8-next.22" + resolved "https://registry.yarnpkg.com/@helium/modular-governance-idls/-/modular-governance-idls-0.0.8-next.22.tgz#e8832a61eb5dee9cb6ed80676b6b4b64cd8d185b" + integrity sha512-FEY+e8oPkpVMYDKUCodg8aRu34q2JM7Sm3KC92Bfxe9T0b8LB4V//etlPH38B9ehd5T7SryZ2ZOLe/CSN+3+mQ== + dependencies: + "@coral-xyz/anchor" "^0.28.0" + "@solana/web3.js" "^1.78.4" + +"@helium/modular-governance-idls@^0.0.8", "@helium/modular-governance-idls@^0.0.8-next.19+4fa4c6b", "@helium/modular-governance-idls@^0.0.8-next.22+7098baa": version "0.0.8" resolved "https://registry.yarnpkg.com/@helium/modular-governance-idls/-/modular-governance-idls-0.0.8.tgz#b913b28790ff80359c7470d9d6665468f5f1b435" integrity sha512-vmBw9dRUsYKX5ZXiMJaCoKYv5yNBLHpXKb5LI/5cIq0KrGNC4quzMuoMzeehXGgDkIIM9VLnk8YP1Bz8CvUzqA== @@ -308,6 +343,16 @@ "@helium/modular-governance-idls" "^0.0.8-next.19+4fa4c6b" "@solana/spl-token" "^0.3.8" +"@helium/nft-proxy-sdk@0.0.8-next.22+7098baa": + version "0.0.8-next.22" + resolved "https://registry.yarnpkg.com/@helium/nft-proxy-sdk/-/nft-proxy-sdk-0.0.8-next.22.tgz#04ec212392e70ad27710b98af99cc55f18fbb711" + integrity sha512-owjFurBzs7Rl38Z/9gewOpDmwQYb/vSj7KvUNg0CDOo0AoGtHVugOQxD4LimUylqIDvHAFeus5M/3jvBqjwDgA== + dependencies: + "@coral-xyz/anchor" "^0.28.0" + "@helium/anchor-resolvers" "^0.2.17" + "@helium/modular-governance-idls" "^0.0.8-next.22+7098baa" + "@solana/spl-token" "^0.3.8" + "@helium/organization-sdk@^0.0.8": version "0.0.8" resolved "https://registry.yarnpkg.com/@helium/organization-sdk/-/organization-sdk-0.0.8.tgz#4738619a929999af6529f21e80e79ab766472322" @@ -327,13 +372,13 @@ "@helium/anchor-resolvers" "^0.5.0" "@helium/modular-governance-idls" "^0.0.8" -"@helium/spl-utils@^0.9.0-alpha.2", "@helium/spl-utils@^0.9.0-alpha.3": - version "0.9.0-alpha.2" - resolved "https://registry.yarnpkg.com/@helium/spl-utils/-/spl-utils-0.9.0-alpha.2.tgz#44888a644ff49c13e2589e000202b795cd8b086b" - integrity sha512-BAdf74wezU1XjKj7679JZ8a413aO8OULzpRvskp7dcbwiGTFaWZAAZYkq4lhS07sGfyHFx1UgSdq/7tlB/afkw== +"@helium/spl-utils@0.9.0-alpha.5", "@helium/spl-utils@^0.9.0-alpha.2", "@helium/spl-utils@^0.9.0-alpha.3", "@helium/spl-utils@^0.9.0-alpha.5": + version "0.9.0-alpha.5" + resolved "https://registry.yarnpkg.com/@helium/spl-utils/-/spl-utils-0.9.0-alpha.5.tgz#d324706f699451eb4872ec8cdbf517886b9b2bbc" + integrity sha512-STB3tCtRDZgUbxNgeOrrxQFdwE2mUXpSd78kgw0mQXjjREWeFlKmPhTL9rMCiGv35qYf+/vxzqSPIlyOg8yTzg== dependencies: "@coral-xyz/anchor" "^0.28.0" - "@helium/account-fetch-cache" "^0.9.0-alpha.1" + "@helium/account-fetch-cache" "^0.9.0-alpha.4" "@helium/address" "^4.10.2" "@helium/anchor-resolvers" "^0.9.0-alpha.1" "@metaplex-foundation/mpl-token-metadata" "^2.10.0" @@ -366,6 +411,29 @@ bn.js "^5.2.0" bs58 "^4.0.1" +"@helium/voter-stake-registry-hooks@0.9.0-alpha.5": + version "0.9.0-alpha.5" + resolved "https://registry.yarnpkg.com/@helium/voter-stake-registry-hooks/-/voter-stake-registry-hooks-0.9.0-alpha.5.tgz#acf2b217195b3d5141d9df2fd4296356f0e8a6cd" + integrity sha512-HbdvpbZpbhxewLWETRV8nyyXKx6Qo71Ek4b1ipH8pNLroAGnGRsB+TNbk+Vi66w6+Q8dI6X3PVpFj5atV6ceQw== + dependencies: + "@coral-xyz/anchor" "^0.28.0" + "@helium/account-fetch-cache" "^0.9.0-alpha.4" + "@helium/account-fetch-cache-hooks" "^0.9.0-alpha.5" + "@helium/circuit-breaker-sdk" "^0.9.0-alpha.2" + "@helium/helium-react-hooks" "^0.9.0-alpha.5" + "@helium/helium-sub-daos-sdk" "^0.9.0-alpha.5" + "@helium/modular-governance-hooks" "^0.0.8" + "@helium/modular-governance-idls" "0.0.8-next.22+7098baa" + "@helium/spl-utils" "^0.9.0-alpha.5" + "@helium/voter-stake-registry-sdk" "^0.9.0-alpha.5" + "@solana/wallet-adapter-base" "^0.9.22" + "@solana/wallet-adapter-react" "^0.15.32" + "@solana/web3.js" "^1.78.8" + "@tanstack/react-query" "^5.45.0" + axios "^1.3.6" + bs58 "^4.0.1" + react-async-hook "^4.0.0" + "@helium/voter-stake-registry-hooks@^0.9.0-alpha.3": version "0.9.0-alpha.3" resolved "https://registry.yarnpkg.com/@helium/voter-stake-registry-hooks/-/voter-stake-registry-hooks-0.9.0-alpha.3.tgz#1e566deebbd781b25661ffa827bf9d1d985cc49d" @@ -389,7 +457,22 @@ bs58 "^4.0.1" react-async-hook "^4.0.0" -"@helium/voter-stake-registry-sdk@^0.9.0-alpha.3": +"@helium/voter-stake-registry-sdk@0.9.0-alpha.5": + version "0.9.0-alpha.5" + resolved "https://registry.yarnpkg.com/@helium/voter-stake-registry-sdk/-/voter-stake-registry-sdk-0.9.0-alpha.5.tgz#b2f2ab44c3bdee640ed67bfa4672606d7c822217" + integrity sha512-uWhUieSBFYb6+eaj4VFDgEZxF+bZqaklX9BgkMwkGtagwZgLF6m2iDHJMuE8iTDt8dDvRANrw1Pk6xYLz7hzXw== + dependencies: + "@coral-xyz/anchor" "^0.28.0" + "@helium/anchor-resolvers" "^0.9.0-alpha.1" + "@helium/idls" "^0.9.0-alpha.1" + "@helium/nft-proxy-sdk" "0.0.8-next.22+7098baa" + "@helium/spl-utils" "^0.9.0-alpha.5" + "@metaplex-foundation/mpl-token-metadata" "^2.10.0" + "@solana/spl-token" "^0.3.8" + bn.js "^5.2.0" + bs58 "^4.0.1" + +"@helium/voter-stake-registry-sdk@^0.9.0-alpha.3", "@helium/voter-stake-registry-sdk@^0.9.0-alpha.5": version "0.9.0-alpha.3" resolved "https://registry.yarnpkg.com/@helium/voter-stake-registry-sdk/-/voter-stake-registry-sdk-0.9.0-alpha.3.tgz#f9c74a2c043cbc13fd692919a0def073adc71f1a" integrity sha512-4L4zddlcYZFUAxwhvMcROSyotNQl13BO8vCNLOs4pizWOWHlL6kndYeH8K5CVZJm6WSwrTyeq56kzis+2YeUxA== From 2bb982ca9c9f297d490f53c4c3abbd0dd0c5bc21 Mon Sep 17 00:00:00 2001 From: Noah Prince Date: Wed, 24 Jul 2024 11:56:28 -0700 Subject: [PATCH 30/41] Purge yalc --- package.json | 24 ++-- scripts/resolve-proposals.ts | 1 + src/components/Proxies.tsx | 14 ++- yarn.lock | 221 +++++++++++------------------------ 4 files changed, 93 insertions(+), 167 deletions(-) diff --git a/package.json b/package.json index 77be43f..299b028 100644 --- a/package.json +++ b/package.json @@ -10,16 +10,16 @@ }, "dependencies": { "@coral-xyz/anchor": "^0.29.0", - "@helium/account-fetch-cache": "0.9.0-alpha.5", - "@helium/account-fetch-cache-hooks": "0.9.0-alpha.5", - "@helium/helium-react-hooks": "0.9.0-alpha.5", + "@helium/account-fetch-cache": "0.9.0-alpha.6", + "@helium/account-fetch-cache-hooks": "0.9.0-alpha.6", + "@helium/helium-react-hooks": "0.9.0-alpha.6", "@helium/modular-governance-hooks": "^0.0.8", "@helium/modular-governance-idls": "^0.0.8-next.22+7098baa", "@helium/organization-sdk": "^0.0.8", - "@helium/spl-utils": "0.9.0-alpha.5", + "@helium/spl-utils": "0.9.0-alpha.6", "@helium/state-controller-sdk": "^0.0.8", - "@helium/voter-stake-registry-hooks": "0.9.0-alpha.5", - "@helium/voter-stake-registry-sdk": "0.9.0-alpha.5", + "@helium/voter-stake-registry-hooks": "0.9.0-alpha.6", + "@helium/voter-stake-registry-sdk": "0.9.0-alpha.6", "@hookform/resolvers": "^3.3.4", "@metaplex-foundation/mpl-token-metadata": "2.10.0", "@project-serum/anchor": "^0.26.0", @@ -72,14 +72,14 @@ }, "resolutions": { "@solana/web3.js": "^1.90.0", - "@helium/account-fetch-cache": "^0.9.0-alpha.3", - "@helium/account-fetch-cache-hooks": "^0.9.0-alpha.3", - "@helium/helium-react-hooks": "^0.9.0-alpha.3", - "@helium/voter-stake-registry-hooks": "^0.9.0-alpha.3", - "@helium/spl-utils": "^0.9.0-alpha.3", + "@helium/account-fetch-cache": "^0.9.0-alpha.6", + "@helium/account-fetch-cache-hooks": "^0.9.0-alpha.6", + "@helium/helium-react-hooks": "^0.9.0-alpha.6", + "@helium/voter-stake-registry-hooks": "^0.9.0-alpha.6", + "@helium/spl-utils": "^0.9.0-alpha.6", "@helium/modular-governance-hooks": "^0.0.8", "@solana/wallet-adapter-react": "^0.15.35", - "@helium/voter-stake-registry-sdk": "^0.9.0-alpha.3" + "@helium/voter-stake-registry-sdk": "^0.9.0-alpha.6" }, "devDependencies": { "@tailwindcss/typography": "^0.5.10", diff --git a/scripts/resolve-proposals.ts b/scripts/resolve-proposals.ts index 4d5b35b..2e1724b 100644 --- a/scripts/resolve-proposals.ts +++ b/scripts/resolve-proposals.ts @@ -37,6 +37,7 @@ export async function run(args: any = process.argv) { connection: provider.connection, commitment: "confirmed", extendConnection: true, + enableLogging: true }); const orgProgram = await initOrg(provider); const stateProgram = await initState(provider); diff --git a/src/components/Proxies.tsx b/src/components/Proxies.tsx index 83a2395..e7ad587 100644 --- a/src/components/Proxies.tsx +++ b/src/components/Proxies.tsx @@ -9,7 +9,7 @@ import BN from "bn.js"; import { Loader2 } from "lucide-react"; import Link from "next/link"; import { usePathname } from "next/navigation"; -import { useState } from "react"; +import { useMemo, useState } from "react"; import { FaMagnifyingGlass, FaX } from "react-icons/fa6"; import { IoWarningOutline } from "react-icons/io5"; import InfiniteScroll from "react-infinite-scroll-component"; @@ -20,7 +20,7 @@ import { Input } from "./ui/input"; import { Skeleton } from "./ui/skeleton"; import { useDebounce } from "@uidotdev/usehooks"; -const DECENTRALIZATION_RISK_INDEX = 6; +const DECENTRALIZATION_RISK_PERCENT = 10; function CardDetail({ title, value }: { title: string; value: string }) { return ( @@ -85,6 +85,14 @@ export function Proxies() { ); const proxies = voters?.pages.flat() || []; + const renderBelowIndex = useMemo( + () => + proxies.findIndex( + (proxy) => Number(proxy.percent) < DECENTRALIZATION_RISK_PERCENT + ), + [proxies] + ); + return (
@@ -170,7 +178,7 @@ export function Proxies() {
- {index == DECENTRALIZATION_RISK_INDEX ? ( + {renderBelowIndex > 0 && index === renderBelowIndex ? (
Date: Wed, 24 Jul 2024 14:37:54 -0700 Subject: [PATCH 31/41] Bump --- package.json | 24 ++++----- yarn.lock | 136 +++++++++++++++++++++++++-------------------------- 2 files changed, 80 insertions(+), 80 deletions(-) diff --git a/package.json b/package.json index 299b028..7ee3c35 100644 --- a/package.json +++ b/package.json @@ -10,16 +10,16 @@ }, "dependencies": { "@coral-xyz/anchor": "^0.29.0", - "@helium/account-fetch-cache": "0.9.0-alpha.6", - "@helium/account-fetch-cache-hooks": "0.9.0-alpha.6", - "@helium/helium-react-hooks": "0.9.0-alpha.6", + "@helium/account-fetch-cache": "0.9.0-alpha.7", + "@helium/account-fetch-cache-hooks": "0.9.0-alpha.7", + "@helium/helium-react-hooks": "0.9.0-alpha.7", "@helium/modular-governance-hooks": "^0.0.8", "@helium/modular-governance-idls": "^0.0.8-next.22+7098baa", "@helium/organization-sdk": "^0.0.8", - "@helium/spl-utils": "0.9.0-alpha.6", + "@helium/spl-utils": "0.9.0-alpha.7", "@helium/state-controller-sdk": "^0.0.8", - "@helium/voter-stake-registry-hooks": "0.9.0-alpha.6", - "@helium/voter-stake-registry-sdk": "0.9.0-alpha.6", + "@helium/voter-stake-registry-hooks": "0.9.0-alpha.7", + "@helium/voter-stake-registry-sdk": "0.9.0-alpha.7", "@hookform/resolvers": "^3.3.4", "@metaplex-foundation/mpl-token-metadata": "2.10.0", "@project-serum/anchor": "^0.26.0", @@ -72,14 +72,14 @@ }, "resolutions": { "@solana/web3.js": "^1.90.0", - "@helium/account-fetch-cache": "^0.9.0-alpha.6", - "@helium/account-fetch-cache-hooks": "^0.9.0-alpha.6", - "@helium/helium-react-hooks": "^0.9.0-alpha.6", - "@helium/voter-stake-registry-hooks": "^0.9.0-alpha.6", - "@helium/spl-utils": "^0.9.0-alpha.6", + "@helium/account-fetch-cache": "^0.9.0-alpha.7", + "@helium/account-fetch-cache-hooks": "^0.9.0-alpha.7", + "@helium/helium-react-hooks": "^0.9.0-alpha.7", + "@helium/voter-stake-registry-hooks": "^0.9.0-alpha.7", + "@helium/spl-utils": "^0.9.0-alpha.7", "@helium/modular-governance-hooks": "^0.0.8", "@solana/wallet-adapter-react": "^0.15.35", - "@helium/voter-stake-registry-sdk": "^0.9.0-alpha.6" + "@helium/voter-stake-registry-sdk": "^0.9.0-alpha.7" }, "devDependencies": { "@tailwindcss/typography": "^0.5.10", diff --git a/yarn.lock b/yarn.lock index 52cc1c4..1f1c969 100644 --- a/yarn.lock +++ b/yarn.lock @@ -171,19 +171,19 @@ resolved "https://registry.yarnpkg.com/@floating-ui/utils/-/utils-0.2.1.tgz#16308cea045f0fc777b6ff20a9f25474dd8293d2" integrity sha512-9TANp6GPoMtYzQdt54kfAyMmz1+osLlXdg2ENroU7zzrtflTLrrC/lgrIfaSe+Wu0b89GKccT7vxXA0MoAIO+Q== -"@helium/account-fetch-cache-hooks@0.9.0-alpha.6", "@helium/account-fetch-cache-hooks@^0.5.0", "@helium/account-fetch-cache-hooks@^0.9.0-alpha.6": - version "0.9.0-alpha.6" - resolved "https://registry.yarnpkg.com/@helium/account-fetch-cache-hooks/-/account-fetch-cache-hooks-0.9.0-alpha.6.tgz#8b40867a11179cdad1a568a1a6377f1144d3a52c" - integrity sha512-6tCzMj1glrbYBhULiUBOOr0RJqy+u+BWRX+H6mda0uGmrYWh1il3UrrHBQNofLf1c8CkqAnDrBdiLRWIUQ3h2A== +"@helium/account-fetch-cache-hooks@0.9.0-alpha.7", "@helium/account-fetch-cache-hooks@^0.5.0", "@helium/account-fetch-cache-hooks@^0.9.0-alpha.7": + version "0.9.0-alpha.7" + resolved "https://registry.yarnpkg.com/@helium/account-fetch-cache-hooks/-/account-fetch-cache-hooks-0.9.0-alpha.7.tgz#5200063a8dbfabd851a7a0f8e6f143935d47297b" + integrity sha512-em2FS+WGb/97i7yvFM35+fCgqLml+cS3nOAhLuKMS4Z8z8G78YnN5wJvLH0TIewusDrJ2OvVOffmsSCwLks+0Q== dependencies: - "@helium/account-fetch-cache" "^0.9.0-alpha.6" + "@helium/account-fetch-cache" "^0.9.0-alpha.7" "@solana/web3.js" "^1.78.8" react-async-hook "^4.0.0" -"@helium/account-fetch-cache@0.9.0-alpha.6", "@helium/account-fetch-cache@^0.5.0", "@helium/account-fetch-cache@^0.9.0-alpha.6": - version "0.9.0-alpha.6" - resolved "https://registry.yarnpkg.com/@helium/account-fetch-cache/-/account-fetch-cache-0.9.0-alpha.6.tgz#f107eea7871eac9f54eefd2f64946512c6fce70b" - integrity sha512-hBNRsPp3TXgnWYmeiX+/cZ+NSc9XBUHIlp8+FEtDGYgLXbG6dKJESjqcHRt97Hgae7IR3IQXTWR2+vDR+N9ooA== +"@helium/account-fetch-cache@0.9.0-alpha.7", "@helium/account-fetch-cache@^0.5.0", "@helium/account-fetch-cache@^0.9.0-alpha.7": + version "0.9.0-alpha.7" + resolved "https://registry.yarnpkg.com/@helium/account-fetch-cache/-/account-fetch-cache-0.9.0-alpha.7.tgz#95dde16230623ce8260ede720e4af80ec7fa6d3d" + integrity sha512-KzGDXog9IfF5lQYtKAzPMhCSKQDwSX7vbbJvXlVdgFqRDAuF1QPwU6pxS1ubmxfmvmEMD2xDCOockL9LSAPz7w== dependencies: "@solana/web3.js" "^1.78.8" @@ -212,56 +212,56 @@ "@solana/spl-token" "^0.3.8" "@solana/web3.js" "^1.78.4" -"@helium/anchor-resolvers@^0.9.0-alpha.6": - version "0.9.0-alpha.6" - resolved "https://registry.yarnpkg.com/@helium/anchor-resolvers/-/anchor-resolvers-0.9.0-alpha.6.tgz#253266d8f9bbd9807c6cfd4706fac1be41c80a1f" - integrity sha512-8OWXzEDsZBfBetgvJISvmCbDGkyJlzjXLYp5iqFB/rBBfKB4UH3RnaAcuRId8HynBd/+Gj2Y6CKHyHUCrXhzLQ== +"@helium/anchor-resolvers@^0.9.0-alpha.7": + version "0.9.0-alpha.7" + resolved "https://registry.yarnpkg.com/@helium/anchor-resolvers/-/anchor-resolvers-0.9.0-alpha.7.tgz#cf1154091de779fcccbbef8ef6ac81493925d6e3" + integrity sha512-BMJLdC6uGu3EY2sOoMtiOlA9zpPcQgGBO38Ac4Sa6uqKMwVkeazx9+GWmaHFax+ej4QQaj2FiRbSJImJKZeWlg== dependencies: "@solana/spl-token" "^0.3.8" "@solana/web3.js" "^1.78.8" -"@helium/circuit-breaker-sdk@^0.9.0-alpha.6": - version "0.9.0-alpha.6" - resolved "https://registry.yarnpkg.com/@helium/circuit-breaker-sdk/-/circuit-breaker-sdk-0.9.0-alpha.6.tgz#2cc7914a43cc31ef10bc45de980e6a490c7d76f3" - integrity sha512-blR1cEtihY8ER9lVCN2evyRnUMBnxW47r5Qh6PebQ7Se1h+0AeDgLs1d2m8UUzB08LYy1hNxdlSEH/0T13aPzQ== +"@helium/circuit-breaker-sdk@^0.9.0-alpha.7": + version "0.9.0-alpha.7" + resolved "https://registry.yarnpkg.com/@helium/circuit-breaker-sdk/-/circuit-breaker-sdk-0.9.0-alpha.7.tgz#5884980d8896821d9e28ca25846dada755e37373" + integrity sha512-vHyMK5GLBYq0n+J8+/mrSvVITa2796O4N+cUDgzYgQtHTslYpv4py0iWu2rObbzkgiTJBzdUizDyPujXkpJUNQ== dependencies: "@coral-xyz/anchor" "^0.28.0" - "@helium/anchor-resolvers" "^0.9.0-alpha.6" - "@helium/idls" "^0.9.0-alpha.6" + "@helium/anchor-resolvers" "^0.9.0-alpha.7" + "@helium/idls" "^0.9.0-alpha.7" bn.js "^5.2.0" bs58 "^4.0.1" -"@helium/helium-react-hooks@0.9.0-alpha.6", "@helium/helium-react-hooks@^0.5.0", "@helium/helium-react-hooks@^0.9.0-alpha.6": - version "0.9.0-alpha.6" - resolved "https://registry.yarnpkg.com/@helium/helium-react-hooks/-/helium-react-hooks-0.9.0-alpha.6.tgz#046c04f5eb4d82ce81a148ae84f074ee989a8619" - integrity sha512-Tfhj1PQez86PX/69Nyd4lpit8KtrfgfHl4O/DZ16N3x+0aF1dgyBKMZ+mvChqQP+g8UMMovepundHwWoftWLIw== +"@helium/helium-react-hooks@0.9.0-alpha.7", "@helium/helium-react-hooks@^0.5.0", "@helium/helium-react-hooks@^0.9.0-alpha.7": + version "0.9.0-alpha.7" + resolved "https://registry.yarnpkg.com/@helium/helium-react-hooks/-/helium-react-hooks-0.9.0-alpha.7.tgz#ac30678012c713a6608ea107ff3c0c2521af4292" + integrity sha512-fyR8Mmo+0ojetPODF1ki0JGEOAKl7OosDAe0KM0mc7+vXm8xNOD1/JW/pELJ1o1FbxKTtcY7hRaGLxbq0NoQOw== dependencies: "@coral-xyz/anchor" "^0.28.0" - "@helium/account-fetch-cache" "^0.9.0-alpha.6" - "@helium/account-fetch-cache-hooks" "^0.9.0-alpha.6" + "@helium/account-fetch-cache" "^0.9.0-alpha.7" + "@helium/account-fetch-cache-hooks" "^0.9.0-alpha.7" "@solana/spl-token" "^0.3.8" "@solana/web3.js" "^1.78.8" bs58 "^4.0.1" pako "^2.0.3" react-async-hook "^4.0.0" -"@helium/helium-sub-daos-sdk@^0.9.0-alpha.6": - version "0.9.0-alpha.6" - resolved "https://registry.yarnpkg.com/@helium/helium-sub-daos-sdk/-/helium-sub-daos-sdk-0.9.0-alpha.6.tgz#387ff41eeb64d05caaca4b88cdc79ce1bdffafae" - integrity sha512-kyymnm6XNT7beeot6NfVfMXgAhvKRoSpOvPmbEf2Frq788c7tjxtcwzbC4yzFKFL0LNx1Xl/3yy76/YL8TYVZA== +"@helium/helium-sub-daos-sdk@^0.9.0-alpha.7": + version "0.9.0-alpha.7" + resolved "https://registry.yarnpkg.com/@helium/helium-sub-daos-sdk/-/helium-sub-daos-sdk-0.9.0-alpha.7.tgz#5ffb321b844a62a15dc50ac3cbfb9daaae16321c" + integrity sha512-eFsYGL+4hxibjAljoU9UyN6UwDhGa86wlFeRfsy0bc/bUqOHbFCgHjklbCjyk6mi3vfsb5BWITXQ1tgdIkp1og== dependencies: "@coral-xyz/anchor" "^0.28.0" - "@helium/anchor-resolvers" "^0.9.0-alpha.6" - "@helium/circuit-breaker-sdk" "^0.9.0-alpha.6" - "@helium/treasury-management-sdk" "^0.9.0-alpha.6" - "@helium/voter-stake-registry-sdk" "^0.9.0-alpha.6" + "@helium/anchor-resolvers" "^0.9.0-alpha.7" + "@helium/circuit-breaker-sdk" "^0.9.0-alpha.7" + "@helium/treasury-management-sdk" "^0.9.0-alpha.7" + "@helium/voter-stake-registry-sdk" "^0.9.0-alpha.7" bn.js "^5.2.0" bs58 "^4.0.1" -"@helium/idls@^0.9.0-alpha.6": - version "0.9.0-alpha.6" - resolved "https://registry.yarnpkg.com/@helium/idls/-/idls-0.9.0-alpha.6.tgz#2217c55c8221887016d628793307520356e1b024" - integrity sha512-P9AFySHsd5qp0GK+pOEWo3tiM97vW7w2HoVz4KW/dkrxEMScnk4MGNdaT3mFskrX3LEO+u+NWhGA9FsAjkE2iA== +"@helium/idls@^0.9.0-alpha.7": + version "0.9.0-alpha.7" + resolved "https://registry.yarnpkg.com/@helium/idls/-/idls-0.9.0-alpha.7.tgz#25d7facbf8bd920de416c15e47f90648e5f1275f" + integrity sha512-esXskH/HCy3cFp9IWS+4N8ch2S5Og59AEi18dj64KkWhu0rnr51vYK3zGmo/Jq3skUpSEAOklZMLQyO5U74eZg== dependencies: "@coral-xyz/anchor" "^0.28.0" "@solana/web3.js" "^1.78.8" @@ -327,15 +327,15 @@ "@helium/anchor-resolvers" "^0.5.0" "@helium/modular-governance-idls" "^0.0.8" -"@helium/spl-utils@0.9.0-alpha.6", "@helium/spl-utils@^0.9.0-alpha.6": - version "0.9.0-alpha.6" - resolved "https://registry.yarnpkg.com/@helium/spl-utils/-/spl-utils-0.9.0-alpha.6.tgz#c27df0717a44cb574e9318fc2eb701f64aa6c6fd" - integrity sha512-KKFtpfXCDNdNyRU4jzyO/5liz7XzmbdHWY7K3z7BdZPKq1v4vnHmwJvesHUjGBTCsLDq8uJhCwP8P3QSTElC7g== +"@helium/spl-utils@0.9.0-alpha.7", "@helium/spl-utils@^0.9.0-alpha.7": + version "0.9.0-alpha.7" + resolved "https://registry.yarnpkg.com/@helium/spl-utils/-/spl-utils-0.9.0-alpha.7.tgz#fb427162a07c5c3dcf556ad912bc2c30ff5b58b8" + integrity sha512-O7Bejv5T+5TJ2UFc9SLzHzkrXvxEaeQN43d4QLhi547cAsBbjERu2lzpBIsEu+tfEpo3n6PWa4rZiNqGuLBsFw== dependencies: "@coral-xyz/anchor" "^0.28.0" - "@helium/account-fetch-cache" "^0.9.0-alpha.6" + "@helium/account-fetch-cache" "^0.9.0-alpha.7" "@helium/address" "^4.10.2" - "@helium/anchor-resolvers" "^0.9.0-alpha.6" + "@helium/anchor-resolvers" "^0.9.0-alpha.7" "@metaplex-foundation/mpl-token-metadata" "^2.10.0" "@solana/spl-account-compression" "^0.1.7" "@solana/spl-token" "^0.3.8" @@ -354,33 +354,33 @@ "@helium/anchor-resolvers" "^0.5.0" "@helium/modular-governance-idls" "^0.0.8" -"@helium/treasury-management-sdk@^0.9.0-alpha.6": - version "0.9.0-alpha.6" - resolved "https://registry.yarnpkg.com/@helium/treasury-management-sdk/-/treasury-management-sdk-0.9.0-alpha.6.tgz#d673fda5ce1038a01c12a7119779ec575b025f60" - integrity sha512-vbHvcEhAy4a9l7DzodlKj1wVwDrxViFxnjljTmZuj9awqYlgnd7IqcpQmCed74vhS8DUiIm9zL0Gp7aMoWZ+qQ== +"@helium/treasury-management-sdk@^0.9.0-alpha.7": + version "0.9.0-alpha.7" + resolved "https://registry.yarnpkg.com/@helium/treasury-management-sdk/-/treasury-management-sdk-0.9.0-alpha.7.tgz#3f6543ce407c77ebc4ad34cd3bf8279209898102" + integrity sha512-x+4GSNxcjmEY45vwma5TzVJIxvD1UOOYTyRdLjATcAh2UJgjBeySbZOJPEO94fVNB7eLtt7HqddKuOwugYyaQg== dependencies: "@coral-xyz/anchor" "^0.28.0" - "@helium/anchor-resolvers" "^0.9.0-alpha.6" - "@helium/circuit-breaker-sdk" "^0.9.0-alpha.6" - "@helium/idls" "^0.9.0-alpha.6" + "@helium/anchor-resolvers" "^0.9.0-alpha.7" + "@helium/circuit-breaker-sdk" "^0.9.0-alpha.7" + "@helium/idls" "^0.9.0-alpha.7" bn.js "^5.2.0" bs58 "^4.0.1" -"@helium/voter-stake-registry-hooks@0.9.0-alpha.6", "@helium/voter-stake-registry-hooks@^0.9.0-alpha.6": - version "0.9.0-alpha.6" - resolved "https://registry.yarnpkg.com/@helium/voter-stake-registry-hooks/-/voter-stake-registry-hooks-0.9.0-alpha.6.tgz#806d61c847c2cb2dc4ccdebf0ae844d4636f0268" - integrity sha512-fu65v3m3/TjBdOKzDBTcPeYZwqN2y/5aaRmyLDJLRjCDuwFkwBK2dTRcXxOEc+dtdOHjoAIAlUtrN3qA2sgtTw== +"@helium/voter-stake-registry-hooks@0.9.0-alpha.7", "@helium/voter-stake-registry-hooks@^0.9.0-alpha.7": + version "0.9.0-alpha.7" + resolved "https://registry.yarnpkg.com/@helium/voter-stake-registry-hooks/-/voter-stake-registry-hooks-0.9.0-alpha.7.tgz#a683a09dbbbeee341b2da4672e14f9fe2aaf09fe" + integrity sha512-NyWOsfJdbbrxcbnrJK6GLN5EBXtKBR4PWr2Bt9RrzjxBOKYAL1AJfIceeZHf6VW0Taqd2B9j2ls6QOelrYWKeQ== dependencies: "@coral-xyz/anchor" "^0.28.0" - "@helium/account-fetch-cache" "^0.9.0-alpha.6" - "@helium/account-fetch-cache-hooks" "^0.9.0-alpha.6" - "@helium/circuit-breaker-sdk" "^0.9.0-alpha.6" - "@helium/helium-react-hooks" "^0.9.0-alpha.6" - "@helium/helium-sub-daos-sdk" "^0.9.0-alpha.6" + "@helium/account-fetch-cache" "^0.9.0-alpha.7" + "@helium/account-fetch-cache-hooks" "^0.9.0-alpha.7" + "@helium/circuit-breaker-sdk" "^0.9.0-alpha.7" + "@helium/helium-react-hooks" "^0.9.0-alpha.7" + "@helium/helium-sub-daos-sdk" "^0.9.0-alpha.7" "@helium/modular-governance-hooks" "^0.0.8" "@helium/modular-governance-idls" "0.0.8-next.22+7098baa" - "@helium/spl-utils" "^0.9.0-alpha.6" - "@helium/voter-stake-registry-sdk" "^0.9.0-alpha.6" + "@helium/spl-utils" "^0.9.0-alpha.7" + "@helium/voter-stake-registry-sdk" "^0.9.0-alpha.7" "@solana/wallet-adapter-base" "^0.9.22" "@solana/wallet-adapter-react" "^0.15.32" "@solana/web3.js" "^1.78.8" @@ -389,16 +389,16 @@ bs58 "^4.0.1" react-async-hook "^4.0.0" -"@helium/voter-stake-registry-sdk@0.9.0-alpha.6", "@helium/voter-stake-registry-sdk@^0.9.0-alpha.6": - version "0.9.0-alpha.6" - resolved "https://registry.yarnpkg.com/@helium/voter-stake-registry-sdk/-/voter-stake-registry-sdk-0.9.0-alpha.6.tgz#b70d98c2fabe193cf63c09a6cc8932ed57e3d195" - integrity sha512-qOTCXEpcgxgVoDW+fSeEnuLI8CmhgTA+7C9YByNCZUxJT4SRDasPqqe0kwHUKd5x1T6DvnnXjb1OQbvagB1+RA== +"@helium/voter-stake-registry-sdk@0.9.0-alpha.7", "@helium/voter-stake-registry-sdk@^0.9.0-alpha.7": + version "0.9.0-alpha.7" + resolved "https://registry.yarnpkg.com/@helium/voter-stake-registry-sdk/-/voter-stake-registry-sdk-0.9.0-alpha.7.tgz#38ceddcd656ff8b090597376968d0ee7d3662cbe" + integrity sha512-EBQcklR4MSJTF3zdDix7mOfVc/DHuJwtmID95aCYRyINlXSzZUAYYgltCaRbf84TwSctvWdeXEoyC3ntmZ0lUA== dependencies: "@coral-xyz/anchor" "^0.28.0" - "@helium/anchor-resolvers" "^0.9.0-alpha.6" - "@helium/idls" "^0.9.0-alpha.6" + "@helium/anchor-resolvers" "^0.9.0-alpha.7" + "@helium/idls" "^0.9.0-alpha.7" "@helium/nft-proxy-sdk" "0.0.8-next.22+7098baa" - "@helium/spl-utils" "^0.9.0-alpha.6" + "@helium/spl-utils" "^0.9.0-alpha.7" "@metaplex-foundation/mpl-token-metadata" "^2.10.0" "@solana/spl-token" "^0.3.8" bn.js "^5.2.0" From d201f36ae2a607f5cd601e6915b7edf91624d3b3 Mon Sep 17 00:00:00 2001 From: Noah Prince Date: Tue, 30 Jul 2024 08:15:56 -0700 Subject: [PATCH 32/41] Fix build --- next.config.mjs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/next.config.mjs b/next.config.mjs index 208cee5..f9cce5b 100644 --- a/next.config.mjs +++ b/next.config.mjs @@ -27,14 +27,14 @@ const nextConfig = { port: "", pathname: "/**/**", }, - ...(process.env.NODE_ENV === "development" && [ + ...(process.env.NODE_ENV === "development" ? [ { protocol: "http", hostname: "localhost", port: "8082", pathname: "/**/**", }, - ]), + ] : []), ], }, logging: { From a8b661e8e641c2687b00c7767771567278194b6a Mon Sep 17 00:00:00 2001 From: Noah Prince Date: Tue, 30 Jul 2024 10:32:51 -0700 Subject: [PATCH 33/41] Bump ver --- package.json | 24 ++++----- yarn.lock | 136 +++++++++++++++++++++++++-------------------------- 2 files changed, 80 insertions(+), 80 deletions(-) diff --git a/package.json b/package.json index 7ee3c35..9003861 100644 --- a/package.json +++ b/package.json @@ -10,16 +10,16 @@ }, "dependencies": { "@coral-xyz/anchor": "^0.29.0", - "@helium/account-fetch-cache": "0.9.0-alpha.7", - "@helium/account-fetch-cache-hooks": "0.9.0-alpha.7", - "@helium/helium-react-hooks": "0.9.0-alpha.7", + "@helium/account-fetch-cache": "0.9.1", + "@helium/account-fetch-cache-hooks": "0.9.1", + "@helium/helium-react-hooks": "0.9.1", "@helium/modular-governance-hooks": "^0.0.8", "@helium/modular-governance-idls": "^0.0.8-next.22+7098baa", "@helium/organization-sdk": "^0.0.8", - "@helium/spl-utils": "0.9.0-alpha.7", + "@helium/spl-utils": "0.9.1", "@helium/state-controller-sdk": "^0.0.8", - "@helium/voter-stake-registry-hooks": "0.9.0-alpha.7", - "@helium/voter-stake-registry-sdk": "0.9.0-alpha.7", + "@helium/voter-stake-registry-hooks": "0.9.1", + "@helium/voter-stake-registry-sdk": "0.9.1", "@hookform/resolvers": "^3.3.4", "@metaplex-foundation/mpl-token-metadata": "2.10.0", "@project-serum/anchor": "^0.26.0", @@ -72,14 +72,14 @@ }, "resolutions": { "@solana/web3.js": "^1.90.0", - "@helium/account-fetch-cache": "^0.9.0-alpha.7", - "@helium/account-fetch-cache-hooks": "^0.9.0-alpha.7", - "@helium/helium-react-hooks": "^0.9.0-alpha.7", - "@helium/voter-stake-registry-hooks": "^0.9.0-alpha.7", - "@helium/spl-utils": "^0.9.0-alpha.7", + "@helium/account-fetch-cache": "^0.9.1", + "@helium/account-fetch-cache-hooks": "^0.9.1", + "@helium/helium-react-hooks": "^0.9.1", + "@helium/voter-stake-registry-hooks": "0.9.1", + "@helium/spl-utils": "^0.9.1", "@helium/modular-governance-hooks": "^0.0.8", "@solana/wallet-adapter-react": "^0.15.35", - "@helium/voter-stake-registry-sdk": "^0.9.0-alpha.7" + "@helium/voter-stake-registry-sdk": "0.9.1" }, "devDependencies": { "@tailwindcss/typography": "^0.5.10", diff --git a/yarn.lock b/yarn.lock index 1f1c969..06022d3 100644 --- a/yarn.lock +++ b/yarn.lock @@ -171,19 +171,19 @@ resolved "https://registry.yarnpkg.com/@floating-ui/utils/-/utils-0.2.1.tgz#16308cea045f0fc777b6ff20a9f25474dd8293d2" integrity sha512-9TANp6GPoMtYzQdt54kfAyMmz1+osLlXdg2ENroU7zzrtflTLrrC/lgrIfaSe+Wu0b89GKccT7vxXA0MoAIO+Q== -"@helium/account-fetch-cache-hooks@0.9.0-alpha.7", "@helium/account-fetch-cache-hooks@^0.5.0", "@helium/account-fetch-cache-hooks@^0.9.0-alpha.7": - version "0.9.0-alpha.7" - resolved "https://registry.yarnpkg.com/@helium/account-fetch-cache-hooks/-/account-fetch-cache-hooks-0.9.0-alpha.7.tgz#5200063a8dbfabd851a7a0f8e6f143935d47297b" - integrity sha512-em2FS+WGb/97i7yvFM35+fCgqLml+cS3nOAhLuKMS4Z8z8G78YnN5wJvLH0TIewusDrJ2OvVOffmsSCwLks+0Q== +"@helium/account-fetch-cache-hooks@0.9.1", "@helium/account-fetch-cache-hooks@^0.5.0", "@helium/account-fetch-cache-hooks@^0.9.1": + version "0.9.1" + resolved "https://registry.yarnpkg.com/@helium/account-fetch-cache-hooks/-/account-fetch-cache-hooks-0.9.1.tgz#633d7344eda574011028f1158fae1db5ace468c5" + integrity sha512-+HUA2Tlq8rRlt7MyEDkHBnckjVZi+O2gzoqQW3J0UHJiVZS2plQCo5UhMLm1II1GXYIRPSg4eaxfLtrkixO35Q== dependencies: - "@helium/account-fetch-cache" "^0.9.0-alpha.7" + "@helium/account-fetch-cache" "^0.9.1" "@solana/web3.js" "^1.78.8" react-async-hook "^4.0.0" -"@helium/account-fetch-cache@0.9.0-alpha.7", "@helium/account-fetch-cache@^0.5.0", "@helium/account-fetch-cache@^0.9.0-alpha.7": - version "0.9.0-alpha.7" - resolved "https://registry.yarnpkg.com/@helium/account-fetch-cache/-/account-fetch-cache-0.9.0-alpha.7.tgz#95dde16230623ce8260ede720e4af80ec7fa6d3d" - integrity sha512-KzGDXog9IfF5lQYtKAzPMhCSKQDwSX7vbbJvXlVdgFqRDAuF1QPwU6pxS1ubmxfmvmEMD2xDCOockL9LSAPz7w== +"@helium/account-fetch-cache@0.9.1", "@helium/account-fetch-cache@^0.5.0", "@helium/account-fetch-cache@^0.9.1": + version "0.9.1" + resolved "https://registry.yarnpkg.com/@helium/account-fetch-cache/-/account-fetch-cache-0.9.1.tgz#ab1ea0507bfff01628dd521b8c08eaaa591850f0" + integrity sha512-0H/OTaOnfgpPXSmTmbVAM7AtdDOTzhXi8ki/hE0dy4eBX+dW51OyTN8SN/584Gr1Eby4fT64Fe2CfLgyArogoQ== dependencies: "@solana/web3.js" "^1.78.8" @@ -212,56 +212,56 @@ "@solana/spl-token" "^0.3.8" "@solana/web3.js" "^1.78.4" -"@helium/anchor-resolvers@^0.9.0-alpha.7": - version "0.9.0-alpha.7" - resolved "https://registry.yarnpkg.com/@helium/anchor-resolvers/-/anchor-resolvers-0.9.0-alpha.7.tgz#cf1154091de779fcccbbef8ef6ac81493925d6e3" - integrity sha512-BMJLdC6uGu3EY2sOoMtiOlA9zpPcQgGBO38Ac4Sa6uqKMwVkeazx9+GWmaHFax+ej4QQaj2FiRbSJImJKZeWlg== +"@helium/anchor-resolvers@^0.9.1": + version "0.9.1" + resolved "https://registry.yarnpkg.com/@helium/anchor-resolvers/-/anchor-resolvers-0.9.1.tgz#f6bc21d7c7ba54c3fed353ab0610dec2b432d600" + integrity sha512-ZeTn5t7N34WYO+5N2eC0/spAWGo8jAbOwV9DlZwoYYLESJ89CNVYgQKouOrejhRe4BI/V0qN67GpyBqjxLUDfA== dependencies: "@solana/spl-token" "^0.3.8" "@solana/web3.js" "^1.78.8" -"@helium/circuit-breaker-sdk@^0.9.0-alpha.7": - version "0.9.0-alpha.7" - resolved "https://registry.yarnpkg.com/@helium/circuit-breaker-sdk/-/circuit-breaker-sdk-0.9.0-alpha.7.tgz#5884980d8896821d9e28ca25846dada755e37373" - integrity sha512-vHyMK5GLBYq0n+J8+/mrSvVITa2796O4N+cUDgzYgQtHTslYpv4py0iWu2rObbzkgiTJBzdUizDyPujXkpJUNQ== +"@helium/circuit-breaker-sdk@^0.9.1": + version "0.9.1" + resolved "https://registry.yarnpkg.com/@helium/circuit-breaker-sdk/-/circuit-breaker-sdk-0.9.1.tgz#8a856ef658360b57999941f9a387161e70dc6873" + integrity sha512-elDKH3vtGEzIuV3sZYodc1FK3VoIBUsSqowbw4Oh9Q1lKODpVE0llbau3ywxV9gQDTQ6zwFgo3yOpWNTUziK1g== dependencies: "@coral-xyz/anchor" "^0.28.0" - "@helium/anchor-resolvers" "^0.9.0-alpha.7" - "@helium/idls" "^0.9.0-alpha.7" + "@helium/anchor-resolvers" "^0.9.1" + "@helium/idls" "^0.9.1" bn.js "^5.2.0" bs58 "^4.0.1" -"@helium/helium-react-hooks@0.9.0-alpha.7", "@helium/helium-react-hooks@^0.5.0", "@helium/helium-react-hooks@^0.9.0-alpha.7": - version "0.9.0-alpha.7" - resolved "https://registry.yarnpkg.com/@helium/helium-react-hooks/-/helium-react-hooks-0.9.0-alpha.7.tgz#ac30678012c713a6608ea107ff3c0c2521af4292" - integrity sha512-fyR8Mmo+0ojetPODF1ki0JGEOAKl7OosDAe0KM0mc7+vXm8xNOD1/JW/pELJ1o1FbxKTtcY7hRaGLxbq0NoQOw== +"@helium/helium-react-hooks@0.9.1", "@helium/helium-react-hooks@^0.5.0", "@helium/helium-react-hooks@^0.9.1": + version "0.9.1" + resolved "https://registry.yarnpkg.com/@helium/helium-react-hooks/-/helium-react-hooks-0.9.1.tgz#e616fcea0d5869f3f9e5107b16ee0857b79b6a51" + integrity sha512-Cq13JlB6SeR3Z9Td/mFZycYWPzbSRdcD6YWerlSkfKY6ZkSMIOMXYmB7kSCr0LS0qAv4Aa2xqYuzw6no3jj9Ow== dependencies: "@coral-xyz/anchor" "^0.28.0" - "@helium/account-fetch-cache" "^0.9.0-alpha.7" - "@helium/account-fetch-cache-hooks" "^0.9.0-alpha.7" + "@helium/account-fetch-cache" "^0.9.1" + "@helium/account-fetch-cache-hooks" "^0.9.1" "@solana/spl-token" "^0.3.8" "@solana/web3.js" "^1.78.8" bs58 "^4.0.1" pako "^2.0.3" react-async-hook "^4.0.0" -"@helium/helium-sub-daos-sdk@^0.9.0-alpha.7": - version "0.9.0-alpha.7" - resolved "https://registry.yarnpkg.com/@helium/helium-sub-daos-sdk/-/helium-sub-daos-sdk-0.9.0-alpha.7.tgz#5ffb321b844a62a15dc50ac3cbfb9daaae16321c" - integrity sha512-eFsYGL+4hxibjAljoU9UyN6UwDhGa86wlFeRfsy0bc/bUqOHbFCgHjklbCjyk6mi3vfsb5BWITXQ1tgdIkp1og== +"@helium/helium-sub-daos-sdk@^0.9.1": + version "0.9.1" + resolved "https://registry.yarnpkg.com/@helium/helium-sub-daos-sdk/-/helium-sub-daos-sdk-0.9.1.tgz#ce16caa501df7c6be70bd7ee1448dfb3b9b79856" + integrity sha512-SxZnnpSTVUjj4Ts6cWm7mNJ8Aw3HXhX2seapP1hgbZDpqbeC30CUSM3N/OggKVX5T9PfD1b9axH6UwHLoqHZ8w== dependencies: "@coral-xyz/anchor" "^0.28.0" - "@helium/anchor-resolvers" "^0.9.0-alpha.7" - "@helium/circuit-breaker-sdk" "^0.9.0-alpha.7" - "@helium/treasury-management-sdk" "^0.9.0-alpha.7" - "@helium/voter-stake-registry-sdk" "^0.9.0-alpha.7" + "@helium/anchor-resolvers" "^0.9.1" + "@helium/circuit-breaker-sdk" "^0.9.1" + "@helium/treasury-management-sdk" "^0.9.1" + "@helium/voter-stake-registry-sdk" "^0.9.1" bn.js "^5.2.0" bs58 "^4.0.1" -"@helium/idls@^0.9.0-alpha.7": - version "0.9.0-alpha.7" - resolved "https://registry.yarnpkg.com/@helium/idls/-/idls-0.9.0-alpha.7.tgz#25d7facbf8bd920de416c15e47f90648e5f1275f" - integrity sha512-esXskH/HCy3cFp9IWS+4N8ch2S5Og59AEi18dj64KkWhu0rnr51vYK3zGmo/Jq3skUpSEAOklZMLQyO5U74eZg== +"@helium/idls@^0.9.1": + version "0.9.1" + resolved "https://registry.yarnpkg.com/@helium/idls/-/idls-0.9.1.tgz#12a242c86e918f51edccda8689f49893383aa6e2" + integrity sha512-k9i8u1eKurGyfbwLjNKep4bp0+SM87H2WDUJjLUUPXBUJwJknIgp4er31tQJLiMDUL901OcK4nIta8qa0NMFWg== dependencies: "@coral-xyz/anchor" "^0.28.0" "@solana/web3.js" "^1.78.8" @@ -327,15 +327,15 @@ "@helium/anchor-resolvers" "^0.5.0" "@helium/modular-governance-idls" "^0.0.8" -"@helium/spl-utils@0.9.0-alpha.7", "@helium/spl-utils@^0.9.0-alpha.7": - version "0.9.0-alpha.7" - resolved "https://registry.yarnpkg.com/@helium/spl-utils/-/spl-utils-0.9.0-alpha.7.tgz#fb427162a07c5c3dcf556ad912bc2c30ff5b58b8" - integrity sha512-O7Bejv5T+5TJ2UFc9SLzHzkrXvxEaeQN43d4QLhi547cAsBbjERu2lzpBIsEu+tfEpo3n6PWa4rZiNqGuLBsFw== +"@helium/spl-utils@0.9.1", "@helium/spl-utils@^0.9.1": + version "0.9.1" + resolved "https://registry.yarnpkg.com/@helium/spl-utils/-/spl-utils-0.9.1.tgz#7facdbda3175c35d6425da2164db72d63a42f3ad" + integrity sha512-hg2r31gxWMLsV/d50pX9VZ70IVoUMJVNircRK8bbofH29NLlOy1jOm4IE2ES6vFh79BoUSjS8XpmxlVBMYFmxw== dependencies: "@coral-xyz/anchor" "^0.28.0" - "@helium/account-fetch-cache" "^0.9.0-alpha.7" + "@helium/account-fetch-cache" "^0.9.1" "@helium/address" "^4.10.2" - "@helium/anchor-resolvers" "^0.9.0-alpha.7" + "@helium/anchor-resolvers" "^0.9.1" "@metaplex-foundation/mpl-token-metadata" "^2.10.0" "@solana/spl-account-compression" "^0.1.7" "@solana/spl-token" "^0.3.8" @@ -354,33 +354,33 @@ "@helium/anchor-resolvers" "^0.5.0" "@helium/modular-governance-idls" "^0.0.8" -"@helium/treasury-management-sdk@^0.9.0-alpha.7": - version "0.9.0-alpha.7" - resolved "https://registry.yarnpkg.com/@helium/treasury-management-sdk/-/treasury-management-sdk-0.9.0-alpha.7.tgz#3f6543ce407c77ebc4ad34cd3bf8279209898102" - integrity sha512-x+4GSNxcjmEY45vwma5TzVJIxvD1UOOYTyRdLjATcAh2UJgjBeySbZOJPEO94fVNB7eLtt7HqddKuOwugYyaQg== +"@helium/treasury-management-sdk@^0.9.1": + version "0.9.1" + resolved "https://registry.yarnpkg.com/@helium/treasury-management-sdk/-/treasury-management-sdk-0.9.1.tgz#319286aa11fe955793c5dcb8a1172b3b7d59deb6" + integrity sha512-xULRlaXW5aekS3BqzX4Bwz2TAuQjtTWZNNZ5ti7oKFjwab6szImwJA8SXwEzRKMC1/1s+rbJv2u3tb/3s8vTNA== dependencies: "@coral-xyz/anchor" "^0.28.0" - "@helium/anchor-resolvers" "^0.9.0-alpha.7" - "@helium/circuit-breaker-sdk" "^0.9.0-alpha.7" - "@helium/idls" "^0.9.0-alpha.7" + "@helium/anchor-resolvers" "^0.9.1" + "@helium/circuit-breaker-sdk" "^0.9.1" + "@helium/idls" "^0.9.1" bn.js "^5.2.0" bs58 "^4.0.1" -"@helium/voter-stake-registry-hooks@0.9.0-alpha.7", "@helium/voter-stake-registry-hooks@^0.9.0-alpha.7": - version "0.9.0-alpha.7" - resolved "https://registry.yarnpkg.com/@helium/voter-stake-registry-hooks/-/voter-stake-registry-hooks-0.9.0-alpha.7.tgz#a683a09dbbbeee341b2da4672e14f9fe2aaf09fe" - integrity sha512-NyWOsfJdbbrxcbnrJK6GLN5EBXtKBR4PWr2Bt9RrzjxBOKYAL1AJfIceeZHf6VW0Taqd2B9j2ls6QOelrYWKeQ== +"@helium/voter-stake-registry-hooks@0.9.1": + version "0.9.1" + resolved "https://registry.yarnpkg.com/@helium/voter-stake-registry-hooks/-/voter-stake-registry-hooks-0.9.1.tgz#e2bcbb5dc8762fe034b7ba322b43cc1abfbd12eb" + integrity sha512-ITZFHbtxE/5qvIO0YXyq4CC+ivpw2hxGP3VQPR/hju3yHddn8oSKie9wCNqqwlUyH7hsFnMTZa4WMIZvQCfhWg== dependencies: "@coral-xyz/anchor" "^0.28.0" - "@helium/account-fetch-cache" "^0.9.0-alpha.7" - "@helium/account-fetch-cache-hooks" "^0.9.0-alpha.7" - "@helium/circuit-breaker-sdk" "^0.9.0-alpha.7" - "@helium/helium-react-hooks" "^0.9.0-alpha.7" - "@helium/helium-sub-daos-sdk" "^0.9.0-alpha.7" + "@helium/account-fetch-cache" "^0.9.1" + "@helium/account-fetch-cache-hooks" "^0.9.1" + "@helium/circuit-breaker-sdk" "^0.9.1" + "@helium/helium-react-hooks" "^0.9.1" + "@helium/helium-sub-daos-sdk" "^0.9.1" "@helium/modular-governance-hooks" "^0.0.8" "@helium/modular-governance-idls" "0.0.8-next.22+7098baa" - "@helium/spl-utils" "^0.9.0-alpha.7" - "@helium/voter-stake-registry-sdk" "^0.9.0-alpha.7" + "@helium/spl-utils" "^0.9.1" + "@helium/voter-stake-registry-sdk" "^0.9.1" "@solana/wallet-adapter-base" "^0.9.22" "@solana/wallet-adapter-react" "^0.15.32" "@solana/web3.js" "^1.78.8" @@ -389,16 +389,16 @@ bs58 "^4.0.1" react-async-hook "^4.0.0" -"@helium/voter-stake-registry-sdk@0.9.0-alpha.7", "@helium/voter-stake-registry-sdk@^0.9.0-alpha.7": - version "0.9.0-alpha.7" - resolved "https://registry.yarnpkg.com/@helium/voter-stake-registry-sdk/-/voter-stake-registry-sdk-0.9.0-alpha.7.tgz#38ceddcd656ff8b090597376968d0ee7d3662cbe" - integrity sha512-EBQcklR4MSJTF3zdDix7mOfVc/DHuJwtmID95aCYRyINlXSzZUAYYgltCaRbf84TwSctvWdeXEoyC3ntmZ0lUA== +"@helium/voter-stake-registry-sdk@0.9.1", "@helium/voter-stake-registry-sdk@^0.9.1": + version "0.9.1" + resolved "https://registry.yarnpkg.com/@helium/voter-stake-registry-sdk/-/voter-stake-registry-sdk-0.9.1.tgz#080d4960529ac36a906a9838f24a5e904c4d48eb" + integrity sha512-lksZXqHhnLPNIx91yDr2IwpNBtGHFPHgy9BzwEGvV3QdNAPWAIiIw28WUaAx5IH9OESN1qpAHT+VyHrBS+fhlA== dependencies: "@coral-xyz/anchor" "^0.28.0" - "@helium/anchor-resolvers" "^0.9.0-alpha.7" - "@helium/idls" "^0.9.0-alpha.7" + "@helium/anchor-resolvers" "^0.9.1" + "@helium/idls" "^0.9.1" "@helium/nft-proxy-sdk" "0.0.8-next.22+7098baa" - "@helium/spl-utils" "^0.9.0-alpha.7" + "@helium/spl-utils" "^0.9.1" "@metaplex-foundation/mpl-token-metadata" "^2.10.0" "@solana/spl-token" "^0.3.8" bn.js "^5.2.0" From da731518dfb37064abb8b853567a7a0e3d869885 Mon Sep 17 00:00:00 2001 From: Noah Prince Date: Tue, 30 Jul 2024 10:37:24 -0700 Subject: [PATCH 34/41] Fix build issue --- src/hooks/useProposalStatus.ts | 1 + 1 file changed, 1 insertion(+) diff --git a/src/hooks/useProposalStatus.ts b/src/hooks/useProposalStatus.ts index af7f089..5e92b15 100644 --- a/src/hooks/useProposalStatus.ts +++ b/src/hooks/useProposalStatus.ts @@ -63,6 +63,7 @@ export function useProposalStatus(proposal?: ProposalV0 | ProposalWithVotes) { const results = proposal?.choices.map((r, index) => ({ ...r, + weight: new BN(r.weight), index, percent: totalVotes?.isZero() ? 100 / proposal?.choices.length From 87f58bb58dbbf4dc0909f24e82426db3f6149a10 Mon Sep 17 00:00:00 2001 From: Noah Prince Date: Thu, 1 Aug 2024 09:50:26 -0700 Subject: [PATCH 35/41] Bugfix --- src/components/AssignProxyModal.tsx | 2 +- src/components/PositionManager/ProxyPositionPrompt.tsx | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/src/components/AssignProxyModal.tsx b/src/components/AssignProxyModal.tsx index dd6ac00..b11564a 100644 --- a/src/components/AssignProxyModal.tsx +++ b/src/components/AssignProxyModal.tsx @@ -42,7 +42,7 @@ export const AssignProxyModal: React.FC< ); const today = new Date(); const augustFirst = Date.UTC( - today.getMonth() > 7 ? today.getFullYear() + 1 : today.getFullYear(), + today.getMonth() >= 7 ? today.getFullYear() + 1 : today.getFullYear(), 7, 1 ); diff --git a/src/components/PositionManager/ProxyPositionPrompt.tsx b/src/components/PositionManager/ProxyPositionPrompt.tsx index 526a4b4..8038acc 100644 --- a/src/components/PositionManager/ProxyPositionPrompt.tsx +++ b/src/components/PositionManager/ProxyPositionPrompt.tsx @@ -41,7 +41,7 @@ export const ProxyPositionPrompt: FC<{ const today = new Date(); const augustFirst = Date.UTC( - today.getMonth() > 7 ? today.getFullYear() + 1 : today.getFullYear(), + today.getMonth() >= 7 ? today.getFullYear() + 1 : today.getFullYear(), 7, 1 ); From b507b87a3ac03d63941b7b38b69bc4c7116d5b1b Mon Sep 17 00:00:00 2001 From: Noah Prince Date: Mon, 9 Sep 2024 14:26:13 -0700 Subject: [PATCH 36/41] Fix package versions --- package.json | 10 +++++----- yarn.lock | 54 ++++++++++++++++++++++++++++++---------------------- 2 files changed, 36 insertions(+), 28 deletions(-) diff --git a/package.json b/package.json index 9003861..1612511 100644 --- a/package.json +++ b/package.json @@ -13,11 +13,11 @@ "@helium/account-fetch-cache": "0.9.1", "@helium/account-fetch-cache-hooks": "0.9.1", "@helium/helium-react-hooks": "0.9.1", - "@helium/modular-governance-hooks": "^0.0.8", - "@helium/modular-governance-idls": "^0.0.8-next.22+7098baa", - "@helium/organization-sdk": "^0.0.8", + "@helium/modular-governance-hooks": "^0.0.13", + "@helium/modular-governance-idls": "^0.0.13", + "@helium/organization-sdk": "^0.0.13", "@helium/spl-utils": "0.9.1", - "@helium/state-controller-sdk": "^0.0.8", + "@helium/state-controller-sdk": "^0.0.13", "@helium/voter-stake-registry-hooks": "0.9.1", "@helium/voter-stake-registry-sdk": "0.9.1", "@hookform/resolvers": "^3.3.4", @@ -77,7 +77,7 @@ "@helium/helium-react-hooks": "^0.9.1", "@helium/voter-stake-registry-hooks": "0.9.1", "@helium/spl-utils": "^0.9.1", - "@helium/modular-governance-hooks": "^0.0.8", + "@helium/modular-governance-hooks": "^0.0.13", "@solana/wallet-adapter-react": "^0.15.35", "@helium/voter-stake-registry-sdk": "0.9.1" }, diff --git a/yarn.lock b/yarn.lock index 06022d3..0a4f251 100644 --- a/yarn.lock +++ b/yarn.lock @@ -269,17 +269,17 @@ borsh "^0.7.0" bs58 "^4.0.1" -"@helium/modular-governance-hooks@^0.0.8": - version "0.0.8" - resolved "https://registry.yarnpkg.com/@helium/modular-governance-hooks/-/modular-governance-hooks-0.0.8.tgz#4c19d3368ca8e3bb38068bdd05451f5822abaa0e" - integrity sha512-6qUoW7heG7KhHLWZSuDu174/LazfkbtqashfU4TLnxXTsEyUh0YXH5vCZSjesEpkWTOZeJ/Hsz6mbsJoMJ9egg== +"@helium/modular-governance-hooks@^0.0.13", "@helium/modular-governance-hooks@^0.0.8": + version "0.0.13" + resolved "https://registry.yarnpkg.com/@helium/modular-governance-hooks/-/modular-governance-hooks-0.0.13.tgz#31cbedf94b652a0ce2bd1ed93583fe8f1fe1c1f7" + integrity sha512-KMaARL329oj6Cgsna7h85GEquFGMQ3L8MfI+QVvIVjXYPm2N/rFJYndzOS6sgH68r6T3lKlCEp4tuizh8R5sDA== dependencies: "@coral-xyz/anchor" "^0.28.0" "@helium/account-fetch-cache" "^0.5.0" "@helium/account-fetch-cache-hooks" "^0.5.0" "@helium/helium-react-hooks" "^0.5.0" - "@helium/modular-governance-idls" "^0.0.8" - "@helium/organization-sdk" "^0.0.8" + "@helium/modular-governance-idls" "^0.0.13" + "@helium/organization-sdk" "^0.0.13" "@solana/web3.js" "^1.78.4" "@helium/modular-governance-idls@0.0.8-next.22+7098baa": @@ -290,7 +290,15 @@ "@coral-xyz/anchor" "^0.28.0" "@solana/web3.js" "^1.78.4" -"@helium/modular-governance-idls@^0.0.8", "@helium/modular-governance-idls@^0.0.8-next.22+7098baa": +"@helium/modular-governance-idls@^0.0.13": + version "0.0.13" + resolved "https://registry.yarnpkg.com/@helium/modular-governance-idls/-/modular-governance-idls-0.0.13.tgz#38a46166d1b48272531c948507adebc8353c0418" + integrity sha512-j/DQu0OoncnsGq68NNwZOF/5RiJEipdYDCBJYxXJxp5MbRAyrDU+GNHGaDyfOs0tLuTkLM2Ya5jjK4PIJz1fcA== + dependencies: + "@coral-xyz/anchor" "^0.28.0" + "@solana/web3.js" "^1.78.4" + +"@helium/modular-governance-idls@^0.0.8-next.22+7098baa": version "0.0.8" resolved "https://registry.yarnpkg.com/@helium/modular-governance-idls/-/modular-governance-idls-0.0.8.tgz#b913b28790ff80359c7470d9d6665468f5f1b435" integrity sha512-vmBw9dRUsYKX5ZXiMJaCoKYv5yNBLHpXKb5LI/5cIq0KrGNC4quzMuoMzeehXGgDkIIM9VLnk8YP1Bz8CvUzqA== @@ -308,24 +316,24 @@ "@helium/modular-governance-idls" "^0.0.8-next.22+7098baa" "@solana/spl-token" "^0.3.8" -"@helium/organization-sdk@^0.0.8": - version "0.0.8" - resolved "https://registry.yarnpkg.com/@helium/organization-sdk/-/organization-sdk-0.0.8.tgz#4738619a929999af6529f21e80e79ab766472322" - integrity sha512-T8RElL6338lLyU/PQpCztcCW+qEjLhh9Kf3LHJZFD5IWDt1/1NhoxPFzuW9MquozDPOeSneKOVY3+mrSHl5kBw== +"@helium/organization-sdk@^0.0.13": + version "0.0.13" + resolved "https://registry.yarnpkg.com/@helium/organization-sdk/-/organization-sdk-0.0.13.tgz#20b6eff7c0a092b63caf74716d829abea24df5ef" + integrity sha512-GhxBopIxfo0ixrg0aY6lcmD8uiLdEOVpf/C+XCdeO56aaqDu2AQ59pB8QMkPpjISxJpsyAsytm4Ncd9yMdQITg== dependencies: "@coral-xyz/anchor" "^0.28.0" "@helium/anchor-resolvers" "^0.5.0" - "@helium/modular-governance-idls" "^0.0.8" - "@helium/proposal-sdk" "^0.0.8" + "@helium/modular-governance-idls" "^0.0.13" + "@helium/proposal-sdk" "^0.0.13" -"@helium/proposal-sdk@^0.0.8": - version "0.0.8" - resolved "https://registry.yarnpkg.com/@helium/proposal-sdk/-/proposal-sdk-0.0.8.tgz#44a7daf4bc8541450839d74f814c784eaacfbc7e" - integrity sha512-oWGQPp9EzV8zqVlvSz2GkHkEFJJx4aJgCo3FSwhPKkyvjefVYoX5+BYzNecPGcYAquTxrDSNxV2xLb5S0BrV/w== +"@helium/proposal-sdk@^0.0.13": + version "0.0.13" + resolved "https://registry.yarnpkg.com/@helium/proposal-sdk/-/proposal-sdk-0.0.13.tgz#302464d7f64a510c75bceb9ee8889bd38e71347e" + integrity sha512-IpxScczrNj8TXsAKzujuh+Ia90nvq1R/0IfeqVzulBsjvFt5nHDP94jpFS04k2WOsIjRCN8a1l9te+7+U6ht9g== dependencies: "@coral-xyz/anchor" "^0.28.0" "@helium/anchor-resolvers" "^0.5.0" - "@helium/modular-governance-idls" "^0.0.8" + "@helium/modular-governance-idls" "^0.0.13" "@helium/spl-utils@0.9.1", "@helium/spl-utils@^0.9.1": version "0.9.1" @@ -345,14 +353,14 @@ borsh "^0.7.0" bs58 "^4.0.1" -"@helium/state-controller-sdk@^0.0.8": - version "0.0.8" - resolved "https://registry.yarnpkg.com/@helium/state-controller-sdk/-/state-controller-sdk-0.0.8.tgz#f51b63f59ae1916638723de270bfe6ddd82da087" - integrity sha512-NDGcJewQp9YaDCoMfk8QYVnFuBI2zD82dffX5ghrDBh5mJvVGH6yZKPa1edJoyqCc277oaYzlnhEQZ1hVDTGKA== +"@helium/state-controller-sdk@^0.0.13": + version "0.0.13" + resolved "https://registry.yarnpkg.com/@helium/state-controller-sdk/-/state-controller-sdk-0.0.13.tgz#cc95b85df36210d062576911ddff234dc09ccb19" + integrity sha512-7bv/oPZMUFb5y+HwsAf0pEUjYR5ubn3i5okapnsyFzPV9cPniJSGbt2ox3Rb8WmyNYD81P4d6rNz4sj6SOVJ9w== dependencies: "@coral-xyz/anchor" "^0.28.0" "@helium/anchor-resolvers" "^0.5.0" - "@helium/modular-governance-idls" "^0.0.8" + "@helium/modular-governance-idls" "^0.0.13" "@helium/treasury-management-sdk@^0.9.1": version "0.9.1" From d563f81a5556b0c2930c2b59ed69e1d879560dd4 Mon Sep 17 00:00:00 2001 From: Noah Prince Date: Mon, 9 Sep 2024 14:37:36 -0700 Subject: [PATCH 37/41] Bugfix image --- src/components/ProxyProfile.tsx | 13 +++++-------- 1 file changed, 5 insertions(+), 8 deletions(-) diff --git a/src/components/ProxyProfile.tsx b/src/components/ProxyProfile.tsx index dc13f7e..f756ab4 100644 --- a/src/components/ProxyProfile.tsx +++ b/src/components/ProxyProfile.tsx @@ -29,6 +29,7 @@ import { RevokeProxyModal } from "./RevokeProxyModal"; import VoteHistory from "./VoteHistory"; import { Card, CardContent, CardHeader } from "./ui/card"; import { ToggleGroup, ToggleGroupItem } from "./ui/toggle-group"; +import { Avatar, AvatarFallback, AvatarImage } from "./ui/avatar"; export function ProxyProfile({ wallet: walletRaw }: { wallet: string }) { const wallet = useMemo(() => new PublicKey(walletRaw), [walletRaw]); @@ -181,14 +182,10 @@ export function ProxyProfile({ wallet: walletRaw }: { wallet: string }) {
- + + + {proxy.name} +

{proxy.name}

From 5cfcfd5045af01426a8ff3063d5dae01fa59508d Mon Sep 17 00:00:00 2001 From: Noah Prince Date: Mon, 9 Sep 2024 14:41:25 -0700 Subject: [PATCH 38/41] Fix build --- scripts/bootstrap.ts | 1 + 1 file changed, 1 insertion(+) diff --git a/scripts/bootstrap.ts b/scripts/bootstrap.ts index 4df3e66..c591482 100644 --- a/scripts/bootstrap.ts +++ b/scripts/bootstrap.ts @@ -121,6 +121,7 @@ export async function run(args: any = process.argv) { voteController, stateController: resolutionSettings!, onVoteHook: stateProgram.programId, + authority: wallet.publicKey, } ); const proposalConfig = (await initProposalConfig.pubkeys()).proposalConfig!; From 32f3a6e9c818a2d57e250aa982c4a4b9c9791266 Mon Sep 17 00:00:00 2001 From: Noah Prince Date: Tue, 10 Sep 2024 09:48:11 -0700 Subject: [PATCH 39/41] Fix minor bugs --- src/components/AssignProxyModal.tsx | 1 + src/components/RevokeProxyModal.tsx | 8 ++++++++ 2 files changed, 9 insertions(+) diff --git a/src/components/AssignProxyModal.tsx b/src/components/AssignProxyModal.tsx index b11564a..0fb1884 100644 --- a/src/components/AssignProxyModal.tsx +++ b/src/components/AssignProxyModal.tsx @@ -88,6 +88,7 @@ export const AssignProxyModal: React.FC< Math.min(expirationTime, maxDate.valueOf() / 1000) ), }); + setSelectedPositions(new Set([])); setOpen(false); } } catch (e: any) { diff --git a/src/components/RevokeProxyModal.tsx b/src/components/RevokeProxyModal.tsx index f51344a..adbe758 100644 --- a/src/components/RevokeProxyModal.tsx +++ b/src/components/RevokeProxyModal.tsx @@ -35,6 +35,12 @@ export const RevokeProxyModal: React.FC< ), [positions, wallet] ); + React.useEffect(() => { + console.log("proxiedPositions", proxiedPositions?.map(p => ({ + pubkey: p.pubkey.toBase58(), + proxy: p.proxy + }))); + }, [proxiedPositions]); const handleOnSubmit = async () => { try { @@ -52,8 +58,10 @@ export const RevokeProxyModal: React.FC< } setOpen(false); + setSelectedPositions(new Set([])); } catch (e: any) { setIsSubmitting(false); + console.error(e) toast(e.message || "Unable to Revoke proxy"); } }; From 71af3e5df70fab6357891124d2c9fcbde7104c2f Mon Sep 17 00:00:00 2001 From: Noah Prince Date: Tue, 10 Sep 2024 13:12:23 -0700 Subject: [PATCH 40/41] Bump versions --- package.json | 24 ++--- yarn.lock | 252 +++++++++++++++++++++++++++++++++------------------ 2 files changed, 175 insertions(+), 101 deletions(-) diff --git a/package.json b/package.json index 1612511..e057271 100644 --- a/package.json +++ b/package.json @@ -10,16 +10,16 @@ }, "dependencies": { "@coral-xyz/anchor": "^0.29.0", - "@helium/account-fetch-cache": "0.9.1", - "@helium/account-fetch-cache-hooks": "0.9.1", - "@helium/helium-react-hooks": "0.9.1", + "@helium/account-fetch-cache": "file:.yalc/@helium/account-fetch-cache", + "@helium/account-fetch-cache-hooks": "file:.yalc/@helium/account-fetch-cache-hooks", + "@helium/helium-react-hooks": "file:.yalc/@helium/helium-react-hooks", "@helium/modular-governance-hooks": "^0.0.13", "@helium/modular-governance-idls": "^0.0.13", "@helium/organization-sdk": "^0.0.13", - "@helium/spl-utils": "0.9.1", + "@helium/spl-utils": "file:.yalc/@helium/spl-utils", "@helium/state-controller-sdk": "^0.0.13", - "@helium/voter-stake-registry-hooks": "0.9.1", - "@helium/voter-stake-registry-sdk": "0.9.1", + "@helium/voter-stake-registry-hooks": "file:.yalc/@helium/voter-stake-registry-hooks", + "@helium/voter-stake-registry-sdk": "file:.yalc/@helium/voter-stake-registry-sdk", "@hookform/resolvers": "^3.3.4", "@metaplex-foundation/mpl-token-metadata": "2.10.0", "@project-serum/anchor": "^0.26.0", @@ -72,14 +72,14 @@ }, "resolutions": { "@solana/web3.js": "^1.90.0", - "@helium/account-fetch-cache": "^0.9.1", - "@helium/account-fetch-cache-hooks": "^0.9.1", - "@helium/helium-react-hooks": "^0.9.1", - "@helium/voter-stake-registry-hooks": "0.9.1", - "@helium/spl-utils": "^0.9.1", + "@helium/account-fetch-cache": "^0.9.5", + "@helium/account-fetch-cache-hooks": "^0.9.5", + "@helium/helium-react-hooks": "^0.9.5", + "@helium/voter-stake-registry-hooks": "0.9.5", + "@helium/spl-utils": "^0.9.5", "@helium/modular-governance-hooks": "^0.0.13", "@solana/wallet-adapter-react": "^0.15.35", - "@helium/voter-stake-registry-sdk": "0.9.1" + "@helium/voter-stake-registry-sdk": "0.9.5" }, "devDependencies": { "@tailwindcss/typography": "^0.5.10", diff --git a/yarn.lock b/yarn.lock index 0a4f251..f722b54 100644 --- a/yarn.lock +++ b/yarn.lock @@ -171,19 +171,31 @@ resolved "https://registry.yarnpkg.com/@floating-ui/utils/-/utils-0.2.1.tgz#16308cea045f0fc777b6ff20a9f25474dd8293d2" integrity sha512-9TANp6GPoMtYzQdt54kfAyMmz1+osLlXdg2ENroU7zzrtflTLrrC/lgrIfaSe+Wu0b89GKccT7vxXA0MoAIO+Q== -"@helium/account-fetch-cache-hooks@0.9.1", "@helium/account-fetch-cache-hooks@^0.5.0", "@helium/account-fetch-cache-hooks@^0.9.1": - version "0.9.1" - resolved "https://registry.yarnpkg.com/@helium/account-fetch-cache-hooks/-/account-fetch-cache-hooks-0.9.1.tgz#633d7344eda574011028f1158fae1db5ace468c5" - integrity sha512-+HUA2Tlq8rRlt7MyEDkHBnckjVZi+O2gzoqQW3J0UHJiVZS2plQCo5UhMLm1II1GXYIRPSg4eaxfLtrkixO35Q== +"@helium/account-fetch-cache-hooks@^0.5.0", "@helium/account-fetch-cache-hooks@^0.9.0-alpha.5", "@helium/account-fetch-cache-hooks@^0.9.4", "@helium/account-fetch-cache-hooks@^0.9.5": + version "0.9.5" + resolved "https://registry.yarnpkg.com/@helium/account-fetch-cache-hooks/-/account-fetch-cache-hooks-0.9.5.tgz#4524a604c1aab763f24c3514cace06814c726cfc" + integrity sha512-e98/QxNg+3awrhELOHveYono6WA9ojpgW8XyD5vU1oIhttuYewLprY/SDtKE7fhO4vUewwg6k3H5MhSG9KURqg== dependencies: - "@helium/account-fetch-cache" "^0.9.1" + "@helium/account-fetch-cache" "^0.9.5" "@solana/web3.js" "^1.78.8" react-async-hook "^4.0.0" -"@helium/account-fetch-cache@0.9.1", "@helium/account-fetch-cache@^0.5.0", "@helium/account-fetch-cache@^0.9.1": - version "0.9.1" - resolved "https://registry.yarnpkg.com/@helium/account-fetch-cache/-/account-fetch-cache-0.9.1.tgz#ab1ea0507bfff01628dd521b8c08eaaa591850f0" - integrity sha512-0H/OTaOnfgpPXSmTmbVAM7AtdDOTzhXi8ki/hE0dy4eBX+dW51OyTN8SN/584Gr1Eby4fT64Fe2CfLgyArogoQ== +"@helium/account-fetch-cache-hooks@file:.yalc/@helium/account-fetch-cache-hooks": + version "0.9.4" + dependencies: + "@helium/account-fetch-cache" "^0.9.4" + "@solana/web3.js" "^1.78.8" + react-async-hook "^4.0.0" + +"@helium/account-fetch-cache@^0.5.0", "@helium/account-fetch-cache@^0.9.0-alpha.4", "@helium/account-fetch-cache@^0.9.4", "@helium/account-fetch-cache@^0.9.5": + version "0.9.5" + resolved "https://registry.yarnpkg.com/@helium/account-fetch-cache/-/account-fetch-cache-0.9.5.tgz#b344eaeff37412d15753411582b14a92fe6a436b" + integrity sha512-+wX03CC5KGQt4n6zHEtbDK03O6qB15pUp1GQDtapPzdujGEO6Dio1BLJvl5ya+8xtf5FMQY6iszcgGoYxXJYbA== + dependencies: + "@solana/web3.js" "^1.78.8" + +"@helium/account-fetch-cache@file:.yalc/@helium/account-fetch-cache": + version "0.9.4" dependencies: "@solana/web3.js" "^1.78.8" @@ -212,56 +224,68 @@ "@solana/spl-token" "^0.3.8" "@solana/web3.js" "^1.78.4" -"@helium/anchor-resolvers@^0.9.1": - version "0.9.1" - resolved "https://registry.yarnpkg.com/@helium/anchor-resolvers/-/anchor-resolvers-0.9.1.tgz#f6bc21d7c7ba54c3fed353ab0610dec2b432d600" - integrity sha512-ZeTn5t7N34WYO+5N2eC0/spAWGo8jAbOwV9DlZwoYYLESJ89CNVYgQKouOrejhRe4BI/V0qN67GpyBqjxLUDfA== +"@helium/anchor-resolvers@^0.9.4", "@helium/anchor-resolvers@^0.9.5": + version "0.9.5" + resolved "https://registry.yarnpkg.com/@helium/anchor-resolvers/-/anchor-resolvers-0.9.5.tgz#304d2575b60b8a37b1e200c0991151125a89444b" + integrity sha512-sU6GTXMhRVJ/tPPHWqiZVah+z9Fer2W2TuHL7+0cdJ/qotLuP8fM9bdAylAYUQGZTEEOKVQnbUjsOYuUqYwRPA== dependencies: "@solana/spl-token" "^0.3.8" "@solana/web3.js" "^1.78.8" -"@helium/circuit-breaker-sdk@^0.9.1": - version "0.9.1" - resolved "https://registry.yarnpkg.com/@helium/circuit-breaker-sdk/-/circuit-breaker-sdk-0.9.1.tgz#8a856ef658360b57999941f9a387161e70dc6873" - integrity sha512-elDKH3vtGEzIuV3sZYodc1FK3VoIBUsSqowbw4Oh9Q1lKODpVE0llbau3ywxV9gQDTQ6zwFgo3yOpWNTUziK1g== +"@helium/circuit-breaker-sdk@^0.9.4", "@helium/circuit-breaker-sdk@^0.9.5": + version "0.9.5" + resolved "https://registry.yarnpkg.com/@helium/circuit-breaker-sdk/-/circuit-breaker-sdk-0.9.5.tgz#5355650c7c23d4ace41640ebda5c241107270e47" + integrity sha512-8AOwnm7/eUhK9D/BgW9VJNDO4/E0n8Oo8u+lZsJrKdXUMkiABteSRCHtRR5iODwjCLCbVnTc34ofiEOjFarS/Q== dependencies: "@coral-xyz/anchor" "^0.28.0" - "@helium/anchor-resolvers" "^0.9.1" - "@helium/idls" "^0.9.1" + "@helium/anchor-resolvers" "^0.9.5" + "@helium/idls" "^0.9.5" bn.js "^5.2.0" bs58 "^4.0.1" -"@helium/helium-react-hooks@0.9.1", "@helium/helium-react-hooks@^0.5.0", "@helium/helium-react-hooks@^0.9.1": - version "0.9.1" - resolved "https://registry.yarnpkg.com/@helium/helium-react-hooks/-/helium-react-hooks-0.9.1.tgz#e616fcea0d5869f3f9e5107b16ee0857b79b6a51" - integrity sha512-Cq13JlB6SeR3Z9Td/mFZycYWPzbSRdcD6YWerlSkfKY6ZkSMIOMXYmB7kSCr0LS0qAv4Aa2xqYuzw6no3jj9Ow== +"@helium/helium-react-hooks@^0.5.0", "@helium/helium-react-hooks@^0.9.4", "@helium/helium-react-hooks@^0.9.5": + version "0.9.5" + resolved "https://registry.yarnpkg.com/@helium/helium-react-hooks/-/helium-react-hooks-0.9.5.tgz#9182157099534c550e1ab11d369ad54a82cbc03f" + integrity sha512-TSM1JpPTXxwKF7peBIHamFgh3P2bc3RTNNyuIf66JOM6Vz+fvd9pL4FGCFm3uaNonTMvTgBmps00EXwRzVw7Sg== dependencies: "@coral-xyz/anchor" "^0.28.0" - "@helium/account-fetch-cache" "^0.9.1" - "@helium/account-fetch-cache-hooks" "^0.9.1" + "@helium/account-fetch-cache" "^0.9.5" + "@helium/account-fetch-cache-hooks" "^0.9.5" "@solana/spl-token" "^0.3.8" "@solana/web3.js" "^1.78.8" bs58 "^4.0.1" pako "^2.0.3" react-async-hook "^4.0.0" -"@helium/helium-sub-daos-sdk@^0.9.1": - version "0.9.1" - resolved "https://registry.yarnpkg.com/@helium/helium-sub-daos-sdk/-/helium-sub-daos-sdk-0.9.1.tgz#ce16caa501df7c6be70bd7ee1448dfb3b9b79856" - integrity sha512-SxZnnpSTVUjj4Ts6cWm7mNJ8Aw3HXhX2seapP1hgbZDpqbeC30CUSM3N/OggKVX5T9PfD1b9axH6UwHLoqHZ8w== +"@helium/helium-react-hooks@file:.yalc/@helium/helium-react-hooks": + version "0.9.0-alpha.5" dependencies: "@coral-xyz/anchor" "^0.28.0" - "@helium/anchor-resolvers" "^0.9.1" - "@helium/circuit-breaker-sdk" "^0.9.1" - "@helium/treasury-management-sdk" "^0.9.1" - "@helium/voter-stake-registry-sdk" "^0.9.1" + "@helium/account-fetch-cache" "^0.9.0-alpha.4" + "@helium/account-fetch-cache-hooks" "^0.9.0-alpha.5" + "@solana/spl-token" "^0.3.8" + "@solana/web3.js" "^1.78.8" + bs58 "^4.0.1" + pako "^2.0.3" + react-async-hook "^4.0.0" + +"@helium/helium-sub-daos-sdk@^0.9.4", "@helium/helium-sub-daos-sdk@^0.9.5": + version "0.9.5" + resolved "https://registry.yarnpkg.com/@helium/helium-sub-daos-sdk/-/helium-sub-daos-sdk-0.9.5.tgz#988132fe4856e59143fdf26bdf73d3db99472e4b" + integrity sha512-PrtaQt7YyKy6sHN/FsmEyHXgCFNpVOcZJbDelyyv+XauA4sRz8uIq4tCzkT2b6+xP74q8u17fpuE9/SejAFjVg== + dependencies: + "@coral-xyz/anchor" "^0.28.0" + "@helium/anchor-resolvers" "^0.9.5" + "@helium/circuit-breaker-sdk" "^0.9.5" + "@helium/treasury-management-sdk" "^0.9.5" + "@helium/voter-stake-registry-sdk" "^0.9.5" bn.js "^5.2.0" bs58 "^4.0.1" -"@helium/idls@^0.9.1": - version "0.9.1" - resolved "https://registry.yarnpkg.com/@helium/idls/-/idls-0.9.1.tgz#12a242c86e918f51edccda8689f49893383aa6e2" - integrity sha512-k9i8u1eKurGyfbwLjNKep4bp0+SM87H2WDUJjLUUPXBUJwJknIgp4er31tQJLiMDUL901OcK4nIta8qa0NMFWg== +"@helium/idls@^0.9.4", "@helium/idls@^0.9.5": + version "0.9.5" + resolved "https://registry.yarnpkg.com/@helium/idls/-/idls-0.9.5.tgz#cddcdfd01aa5904d39c1b2d9a3cc036600f89ab7" + integrity sha512-Ii0jAEaa/gJ3N/Vm7x8Y2MkzAeTzH2rIPag/sLYv3c08dhF41WIvzN4rURt4o5djKYzeuRG+y76twPL1F/XCig== dependencies: "@coral-xyz/anchor" "^0.28.0" "@solana/web3.js" "^1.78.8" @@ -269,7 +293,7 @@ borsh "^0.7.0" bs58 "^4.0.1" -"@helium/modular-governance-hooks@^0.0.13", "@helium/modular-governance-hooks@^0.0.8": +"@helium/modular-governance-hooks@^0.0.12", "@helium/modular-governance-hooks@^0.0.13": version "0.0.13" resolved "https://registry.yarnpkg.com/@helium/modular-governance-hooks/-/modular-governance-hooks-0.0.13.tgz#31cbedf94b652a0ce2bd1ed93583fe8f1fe1c1f7" integrity sha512-KMaARL329oj6Cgsna7h85GEquFGMQ3L8MfI+QVvIVjXYPm2N/rFJYndzOS6sgH68r6T3lKlCEp4tuizh8R5sDA== @@ -282,38 +306,38 @@ "@helium/organization-sdk" "^0.0.13" "@solana/web3.js" "^1.78.4" -"@helium/modular-governance-idls@0.0.8-next.22+7098baa": - version "0.0.8-next.22" - resolved "https://registry.yarnpkg.com/@helium/modular-governance-idls/-/modular-governance-idls-0.0.8-next.22.tgz#e8832a61eb5dee9cb6ed80676b6b4b64cd8d185b" - integrity sha512-FEY+e8oPkpVMYDKUCodg8aRu34q2JM7Sm3KC92Bfxe9T0b8LB4V//etlPH38B9ehd5T7SryZ2ZOLe/CSN+3+mQ== +"@helium/modular-governance-idls@^0.0.10": + version "0.0.10" + resolved "https://registry.yarnpkg.com/@helium/modular-governance-idls/-/modular-governance-idls-0.0.10.tgz#8384cdca7c44949cbe33c776b44cca668a704315" + integrity sha512-fMDYhCnU18uCKzkeD8pFED3ubkKzeqw58EUZt7Qk4mxWQGM4KJ3qd1L9dp5jh9F4pVWohZ2d5EK5VqakC8JVGg== dependencies: "@coral-xyz/anchor" "^0.28.0" "@solana/web3.js" "^1.78.4" -"@helium/modular-governance-idls@^0.0.13": - version "0.0.13" - resolved "https://registry.yarnpkg.com/@helium/modular-governance-idls/-/modular-governance-idls-0.0.13.tgz#38a46166d1b48272531c948507adebc8353c0418" - integrity sha512-j/DQu0OoncnsGq68NNwZOF/5RiJEipdYDCBJYxXJxp5MbRAyrDU+GNHGaDyfOs0tLuTkLM2Ya5jjK4PIJz1fcA== +"@helium/modular-governance-idls@^0.0.12": + version "0.0.12" + resolved "https://registry.yarnpkg.com/@helium/modular-governance-idls/-/modular-governance-idls-0.0.12.tgz#14b78395ebe98951b404e130ac5f0e2011fc8cf0" + integrity sha512-Esri56pgnfUmt4Sa4CbXq68iBE8nqPeURu9DbhdTmHqRVpD2qIZSgALIq5CMAdNOzgoe4O2nGynEaXfqcaMrKA== dependencies: "@coral-xyz/anchor" "^0.28.0" "@solana/web3.js" "^1.78.4" -"@helium/modular-governance-idls@^0.0.8-next.22+7098baa": - version "0.0.8" - resolved "https://registry.yarnpkg.com/@helium/modular-governance-idls/-/modular-governance-idls-0.0.8.tgz#b913b28790ff80359c7470d9d6665468f5f1b435" - integrity sha512-vmBw9dRUsYKX5ZXiMJaCoKYv5yNBLHpXKb5LI/5cIq0KrGNC4quzMuoMzeehXGgDkIIM9VLnk8YP1Bz8CvUzqA== +"@helium/modular-governance-idls@^0.0.13": + version "0.0.13" + resolved "https://registry.yarnpkg.com/@helium/modular-governance-idls/-/modular-governance-idls-0.0.13.tgz#38a46166d1b48272531c948507adebc8353c0418" + integrity sha512-j/DQu0OoncnsGq68NNwZOF/5RiJEipdYDCBJYxXJxp5MbRAyrDU+GNHGaDyfOs0tLuTkLM2Ya5jjK4PIJz1fcA== dependencies: "@coral-xyz/anchor" "^0.28.0" "@solana/web3.js" "^1.78.4" -"@helium/nft-proxy-sdk@0.0.8-next.22+7098baa": - version "0.0.8-next.22" - resolved "https://registry.yarnpkg.com/@helium/nft-proxy-sdk/-/nft-proxy-sdk-0.0.8-next.22.tgz#04ec212392e70ad27710b98af99cc55f18fbb711" - integrity sha512-owjFurBzs7Rl38Z/9gewOpDmwQYb/vSj7KvUNg0CDOo0AoGtHVugOQxD4LimUylqIDvHAFeus5M/3jvBqjwDgA== +"@helium/nft-proxy-sdk@^0.0.12": + version "0.0.12" + resolved "https://registry.yarnpkg.com/@helium/nft-proxy-sdk/-/nft-proxy-sdk-0.0.12.tgz#2ac4673a8d02916f93456f9697229a77ca329046" + integrity sha512-XDaVv8Fcov9ytTC36v6kjUDmb1M3nUi2TrSd9bVvQBmbRksJlC58WxzPoSyBDMEXv9juGzSvmYp44hPciRvD1Q== dependencies: "@coral-xyz/anchor" "^0.28.0" "@helium/anchor-resolvers" "^0.2.17" - "@helium/modular-governance-idls" "^0.0.8-next.22+7098baa" + "@helium/modular-governance-idls" "^0.0.10" "@solana/spl-token" "^0.3.8" "@helium/organization-sdk@^0.0.13": @@ -335,15 +359,31 @@ "@helium/anchor-resolvers" "^0.5.0" "@helium/modular-governance-idls" "^0.0.13" -"@helium/spl-utils@0.9.1", "@helium/spl-utils@^0.9.1": - version "0.9.1" - resolved "https://registry.yarnpkg.com/@helium/spl-utils/-/spl-utils-0.9.1.tgz#7facdbda3175c35d6425da2164db72d63a42f3ad" - integrity sha512-hg2r31gxWMLsV/d50pX9VZ70IVoUMJVNircRK8bbofH29NLlOy1jOm4IE2ES6vFh79BoUSjS8XpmxlVBMYFmxw== +"@helium/spl-utils@^0.9.4", "@helium/spl-utils@^0.9.5": + version "0.9.5" + resolved "https://registry.yarnpkg.com/@helium/spl-utils/-/spl-utils-0.9.5.tgz#fa0a244d8ee6dde2c25f87886a38485c7a06aab2" + integrity sha512-DF/5LULripvs9dgvtv6vikDuOwTvPa0nRviHf1K1pK8CjFfLdg2+jbExN5n6HPwH/kuHV3vIMQBVMFXlPnfbIA== dependencies: "@coral-xyz/anchor" "^0.28.0" - "@helium/account-fetch-cache" "^0.9.1" + "@helium/account-fetch-cache" "^0.9.5" "@helium/address" "^4.10.2" - "@helium/anchor-resolvers" "^0.9.1" + "@helium/anchor-resolvers" "^0.9.5" + "@metaplex-foundation/mpl-token-metadata" "^2.10.0" + "@solana/spl-account-compression" "^0.1.7" + "@solana/spl-token" "^0.3.8" + "@solana/web3.js" "^1.78.8" + axios "^1.5.0" + bn.js "^5.2.0" + borsh "^0.7.0" + bs58 "^4.0.1" + +"@helium/spl-utils@file:.yalc/@helium/spl-utils": + version "0.9.4" + dependencies: + "@coral-xyz/anchor" "^0.28.0" + "@helium/account-fetch-cache" "^0.9.4" + "@helium/address" "^4.10.2" + "@helium/anchor-resolvers" "^0.9.4" "@metaplex-foundation/mpl-token-metadata" "^2.10.0" "@solana/spl-account-compression" "^0.1.7" "@solana/spl-token" "^0.3.8" @@ -362,33 +402,54 @@ "@helium/anchor-resolvers" "^0.5.0" "@helium/modular-governance-idls" "^0.0.13" -"@helium/treasury-management-sdk@^0.9.1": - version "0.9.1" - resolved "https://registry.yarnpkg.com/@helium/treasury-management-sdk/-/treasury-management-sdk-0.9.1.tgz#319286aa11fe955793c5dcb8a1172b3b7d59deb6" - integrity sha512-xULRlaXW5aekS3BqzX4Bwz2TAuQjtTWZNNZ5ti7oKFjwab6szImwJA8SXwEzRKMC1/1s+rbJv2u3tb/3s8vTNA== +"@helium/treasury-management-sdk@^0.9.5": + version "0.9.5" + resolved "https://registry.yarnpkg.com/@helium/treasury-management-sdk/-/treasury-management-sdk-0.9.5.tgz#971bfde2a68a3f7d0007c491ddfcc2cf850fdd5a" + integrity sha512-8FqYzELkmcq99ha/arDPdTNhvbxGTWr39Oa2bEJYcR2T9fX2fNEAK5YilMiCi92W/HUAWZjap5I8zp94kYLm/A== dependencies: "@coral-xyz/anchor" "^0.28.0" - "@helium/anchor-resolvers" "^0.9.1" - "@helium/circuit-breaker-sdk" "^0.9.1" - "@helium/idls" "^0.9.1" + "@helium/anchor-resolvers" "^0.9.5" + "@helium/circuit-breaker-sdk" "^0.9.5" + "@helium/idls" "^0.9.5" bn.js "^5.2.0" bs58 "^4.0.1" -"@helium/voter-stake-registry-hooks@0.9.1": - version "0.9.1" - resolved "https://registry.yarnpkg.com/@helium/voter-stake-registry-hooks/-/voter-stake-registry-hooks-0.9.1.tgz#e2bcbb5dc8762fe034b7ba322b43cc1abfbd12eb" - integrity sha512-ITZFHbtxE/5qvIO0YXyq4CC+ivpw2hxGP3VQPR/hju3yHddn8oSKie9wCNqqwlUyH7hsFnMTZa4WMIZvQCfhWg== +"@helium/voter-stake-registry-hooks@0.9.5": + version "0.9.5" + resolved "https://registry.yarnpkg.com/@helium/voter-stake-registry-hooks/-/voter-stake-registry-hooks-0.9.5.tgz#845e8bba5dbfc7ec0e30f8e78b5ed6a0c1deee44" + integrity sha512-n7wvOX1XODKubGlSl4ee8zwUzwnFcT/oNRa1VquYK32skGdj8VGRESNKKqPn4N69xqvb+uu+PJkn7+hUvQs3fw== + dependencies: + "@coral-xyz/anchor" "^0.28.0" + "@helium/account-fetch-cache" "^0.9.5" + "@helium/account-fetch-cache-hooks" "^0.9.5" + "@helium/circuit-breaker-sdk" "^0.9.5" + "@helium/helium-react-hooks" "^0.9.5" + "@helium/helium-sub-daos-sdk" "^0.9.5" + "@helium/modular-governance-hooks" "^0.0.12" + "@helium/modular-governance-idls" "^0.0.12" + "@helium/spl-utils" "^0.9.5" + "@helium/voter-stake-registry-sdk" "^0.9.5" + "@solana/wallet-adapter-base" "^0.9.22" + "@solana/wallet-adapter-react" "^0.15.32" + "@solana/web3.js" "^1.78.8" + "@tanstack/react-query" "^5.45.0" + axios "^1.3.6" + bs58 "^4.0.1" + react-async-hook "^4.0.0" + +"@helium/voter-stake-registry-hooks@file:.yalc/@helium/voter-stake-registry-hooks": + version "0.9.4" dependencies: "@coral-xyz/anchor" "^0.28.0" - "@helium/account-fetch-cache" "^0.9.1" - "@helium/account-fetch-cache-hooks" "^0.9.1" - "@helium/circuit-breaker-sdk" "^0.9.1" - "@helium/helium-react-hooks" "^0.9.1" - "@helium/helium-sub-daos-sdk" "^0.9.1" - "@helium/modular-governance-hooks" "^0.0.8" - "@helium/modular-governance-idls" "0.0.8-next.22+7098baa" - "@helium/spl-utils" "^0.9.1" - "@helium/voter-stake-registry-sdk" "^0.9.1" + "@helium/account-fetch-cache" "^0.9.4" + "@helium/account-fetch-cache-hooks" "^0.9.4" + "@helium/circuit-breaker-sdk" "^0.9.4" + "@helium/helium-react-hooks" "^0.9.4" + "@helium/helium-sub-daos-sdk" "^0.9.4" + "@helium/modular-governance-hooks" "^0.0.12" + "@helium/modular-governance-idls" "^0.0.12" + "@helium/spl-utils" "^0.9.4" + "@helium/voter-stake-registry-sdk" "^0.9.4" "@solana/wallet-adapter-base" "^0.9.22" "@solana/wallet-adapter-react" "^0.15.32" "@solana/web3.js" "^1.78.8" @@ -397,16 +458,29 @@ bs58 "^4.0.1" react-async-hook "^4.0.0" -"@helium/voter-stake-registry-sdk@0.9.1", "@helium/voter-stake-registry-sdk@^0.9.1": - version "0.9.1" - resolved "https://registry.yarnpkg.com/@helium/voter-stake-registry-sdk/-/voter-stake-registry-sdk-0.9.1.tgz#080d4960529ac36a906a9838f24a5e904c4d48eb" - integrity sha512-lksZXqHhnLPNIx91yDr2IwpNBtGHFPHgy9BzwEGvV3QdNAPWAIiIw28WUaAx5IH9OESN1qpAHT+VyHrBS+fhlA== +"@helium/voter-stake-registry-sdk@0.9.5", "@helium/voter-stake-registry-sdk@^0.9.4", "@helium/voter-stake-registry-sdk@^0.9.5": + version "0.9.5" + resolved "https://registry.yarnpkg.com/@helium/voter-stake-registry-sdk/-/voter-stake-registry-sdk-0.9.5.tgz#fd3c5a7c1e6dd5c83efd1c8d9de82bf269a71a35" + integrity sha512-G4JzNVSGuwpfxcv8aU9vAwBOkt+aamhShTUPk8DjgA0uih7jxjP6tuVtk3m9ks4LxtstDu+arxxSv4cr368pXw== + dependencies: + "@coral-xyz/anchor" "^0.28.0" + "@helium/anchor-resolvers" "^0.9.5" + "@helium/idls" "^0.9.5" + "@helium/nft-proxy-sdk" "^0.0.12" + "@helium/spl-utils" "^0.9.5" + "@metaplex-foundation/mpl-token-metadata" "^2.10.0" + "@solana/spl-token" "^0.3.8" + bn.js "^5.2.0" + bs58 "^4.0.1" + +"@helium/voter-stake-registry-sdk@file:.yalc/@helium/voter-stake-registry-sdk": + version "0.9.4" dependencies: "@coral-xyz/anchor" "^0.28.0" - "@helium/anchor-resolvers" "^0.9.1" - "@helium/idls" "^0.9.1" - "@helium/nft-proxy-sdk" "0.0.8-next.22+7098baa" - "@helium/spl-utils" "^0.9.1" + "@helium/anchor-resolvers" "^0.9.4" + "@helium/idls" "^0.9.4" + "@helium/nft-proxy-sdk" "^0.0.12" + "@helium/spl-utils" "^0.9.4" "@metaplex-foundation/mpl-token-metadata" "^2.10.0" "@solana/spl-token" "^0.3.8" bn.js "^5.2.0" From 2c5784842160e73a36b467e7eb456dee016a2a6d Mon Sep 17 00:00:00 2001 From: Noah Prince Date: Mon, 14 Oct 2024 18:51:53 -0700 Subject: [PATCH 41/41] Fix build issues --- next-env.d.ts | 2 +- package.json | 28 +++++++++++---------- src/app/[network]/proxies/[wallet]/page.tsx | 8 +++--- src/components/LockTokensForm.tsx | 3 +-- src/components/Proxies.tsx | 5 ++-- src/components/ProxySearch.tsx | 1 + src/components/VoteBreakdown.tsx | 7 +++--- tsconfig.json | 1 + 8 files changed, 29 insertions(+), 26 deletions(-) diff --git a/next-env.d.ts b/next-env.d.ts index 4f11a03..40c3d68 100644 --- a/next-env.d.ts +++ b/next-env.d.ts @@ -2,4 +2,4 @@ /// // NOTE: This file should not be edited -// see https://nextjs.org/docs/basic-features/typescript for more information. +// see https://nextjs.org/docs/app/building-your-application/configuring/typescript for more information. diff --git a/package.json b/package.json index 484e0f4..756259d 100644 --- a/package.json +++ b/package.json @@ -10,16 +10,16 @@ }, "dependencies": { "@coral-xyz/anchor": "^0.29.0", - "@helium/account-fetch-cache": "^0.9.6", - "@helium/account-fetch-cache-hooks": "^0.9.6", - "@helium/helium-react-hooks": "^0.9.6", + "@helium/account-fetch-cache": "^0.9.7", + "@helium/account-fetch-cache-hooks": "^0.9.7", + "@helium/helium-react-hooks": "^0.9.7", "@helium/modular-governance-hooks": "^0.0.13", "@helium/modular-governance-idls": "^0.0.13", "@helium/organization-sdk": "^0.0.13", - "@helium/spl-utils": "^0.9.6", + "@helium/spl-utils": "^0.9.7", "@helium/state-controller-sdk": "^0.0.13", - "@helium/voter-stake-registry-hooks": "^0.9.6", - "@helium/voter-stake-registry-sdk": "^0.9.6", + "@helium/voter-stake-registry-hooks": "^0.9.7", + "@helium/voter-stake-registry-sdk": "^0.9.7", "@hookform/resolvers": "^3.3.4", "@metaplex-foundation/mpl-token-metadata": "2.10.0", "@project-serum/anchor": "^0.26.0", @@ -43,7 +43,7 @@ "@solana/wallet-adapter-wallets": "^0.19.32", "@solana/web3.js": "^1.90.0", "@sqds/sdk": "^2.0.4", - "@tanstack/react-query": "^5.45.0", + "@tanstack/react-query": "5.45.1", "@uidotdev/usehooks": "^2.4.1", "axios": "^1.6.7", "bn.js": "^5.2.1", @@ -71,15 +71,17 @@ "yargs": "^17.7.2" }, "resolutions": { + "@tanstack/react-query": "5.45.1", "@solana/web3.js": "^1.90.0", - "@helium/account-fetch-cache": "^0.9.6", - "@helium/account-fetch-cache-hooks": "^0.9.6", - "@helium/helium-react-hooks": "^0.9.6", - "@helium/voter-stake-registry-hooks": "0.9.6", - "@helium/spl-utils": "^0.9.6", + "@helium/account-fetch-cache": "^0.9.7", + "@helium/account-fetch-cache-hooks": "^0.9.7", + "@helium/helium-react-hooks": "^0.9.7", + "@helium/voter-stake-registry-hooks": "^0.9.7", + "@helium/modular-governance-idls": "^0.0.13", + "@helium/spl-utils": "^0.9.7", "@helium/modular-governance-hooks": "^0.0.13", "@solana/wallet-adapter-react": "^0.15.35", - "@helium/voter-stake-registry-sdk": "0.9.6" + "@helium/voter-stake-registry-sdk": "^0.9.7" }, "devDependencies": { "@tailwindcss/typography": "^0.5.10", diff --git a/src/app/[network]/proxies/[wallet]/page.tsx b/src/app/[network]/proxies/[wallet]/page.tsx index e1b2d30..01a98ab 100644 --- a/src/app/[network]/proxies/[wallet]/page.tsx +++ b/src/app/[network]/proxies/[wallet]/page.tsx @@ -23,15 +23,13 @@ export default async function ProxyPage({ }: { params: { wallet: string; network: string }; }) { - const voteService = useMemo( - () => getVoteService({ mint: networksToMint[network] }), - [network] - ); - const wallet = useMemo(() => new PublicKey(walletRaw), [walletRaw]); + const voteService = getVoteService({ mint: networksToMint[network] }); + const wallet = new PublicKey(walletRaw); const queryClient = new QueryClient(); // Do not use prefetch here, because we want to error when it errors const result = await queryClient.fetchQuery( + // @ts-ignore proxyQuery({ wallet, voteService, diff --git a/src/components/LockTokensForm.tsx b/src/components/LockTokensForm.tsx index 46cb87d..a609141 100644 --- a/src/components/LockTokensForm.tsx +++ b/src/components/LockTokensForm.tsx @@ -244,8 +244,7 @@ export const LockTokensForm: FC<{ className={classNames( "flex flex-row flex-1 justify-center items-center py-4 rounded-md bg-slate-600 cursor-pointer border-2 border-transparent hover:bg-opacity-80 active:bg-opacity-70", lockupPeriodOptions[0].value === lockupPeriod.value - ? "surfaceSecondaryText" && - "!bg-info !border-info-foreground font-medium" + ? "surfaceSecondaryText !bg-info !border-info-foreground font-medium" : "primaryText" )} onClick={() => { diff --git a/src/components/Proxies.tsx b/src/components/Proxies.tsx index e7ad587..b502ed8 100644 --- a/src/components/Proxies.tsx +++ b/src/components/Proxies.tsx @@ -19,6 +19,7 @@ import { Card } from "./ui/card"; import { Input } from "./ui/input"; import { Skeleton } from "./ui/skeleton"; import { useDebounce } from "@uidotdev/usehooks"; +import { EnhancedProxy } from "@helium/voter-stake-registry-sdk"; const DECENTRALIZATION_RISK_PERCENT = 10; @@ -80,10 +81,10 @@ export function Proxies() { proxiesQuery({ search: searchDebounced, amountPerPage: 100, - voteService: voteService, + voteService, }) ); - const proxies = voters?.pages.flat() || []; + const proxies = useMemo(() => voters?.pages.flat() || [], [voters]); const renderBelowIndex = useMemo( () => diff --git a/src/components/ProxySearch.tsx b/src/components/ProxySearch.tsx index 695ef36..668272c 100644 --- a/src/components/ProxySearch.tsx +++ b/src/components/ProxySearch.tsx @@ -9,6 +9,7 @@ import { proxiesQuery, useHeliumVsrState, } from "@helium/voter-stake-registry-hooks"; +import { EnhancedProxy } from "@helium/voter-stake-registry-sdk"; export const ProxySearch: React.FC<{ value: string; diff --git a/src/components/VoteBreakdown.tsx b/src/components/VoteBreakdown.tsx index d7985c4..a67050c 100644 --- a/src/components/VoteBreakdown.tsx +++ b/src/components/VoteBreakdown.tsx @@ -9,7 +9,7 @@ import { useRegistrar } from "@helium/voter-stake-registry-hooks"; import { useMint } from "@helium/helium-react-hooks"; import BN from "bn.js"; import { useVotes } from "@/hooks/useVotes"; -import { toNumber } from "@helium/spl-utils"; +import { toNumber, truthy } from "@helium/spl-utils"; import { Table, TableBody, @@ -72,13 +72,14 @@ export const VoteBreakdown: FC<{ }, [markers, decimals]); const csvData = useMemo(() => { - const rows = []; + const rows: string[][] = []; rows.push(["Owner", "Choices", "Vote Power", "Percentage"]); (groupedSortedMarkers || []).forEach((marker) => { const owner = marker.voter.toBase58(); const choices = marker.choices .map((c) => proposal?.choices[c].name) + .filter(truthy) .join(", "); const voteWeight = humanReadable(marker.totalWeight, decimals); @@ -89,7 +90,7 @@ export const VoteBreakdown: FC<{ .toNumber() .toFixed(2); - rows.push([owner, choices, voteWeight, percentage]); + rows.push([owner, choices, voteWeight || "", percentage]); }); const csvContent = rows diff --git a/tsconfig.json b/tsconfig.json index 4fbf1fd..6d6bd17 100644 --- a/tsconfig.json +++ b/tsconfig.json @@ -8,6 +8,7 @@ "lib": ["dom", "dom.iterable", "esnext"], "allowJs": true, "skipLibCheck": true, + "noImplicitAny": false, "strict": true, "noEmit": true, "esModuleInterop": true,