From d0518ad3a113a3ecc7a91580e5683f5c4ef12084 Mon Sep 17 00:00:00 2001 From: 0xfirefist Date: Tue, 5 Dec 2023 21:02:11 +0530 Subject: [PATCH 01/13] add llc modal to stake panel --- frontend/components/modals/LlcModal.tsx | 186 ++++++++++++++++++++++ frontend/components/panels/StakePanel.tsx | 34 +++- frontend/styles/globals.css | 11 ++ 3 files changed, 230 insertions(+), 1 deletion(-) create mode 100644 frontend/components/modals/LlcModal.tsx diff --git a/frontend/components/modals/LlcModal.tsx b/frontend/components/modals/LlcModal.tsx new file mode 100644 index 00000000..88dc4103 --- /dev/null +++ b/frontend/components/modals/LlcModal.tsx @@ -0,0 +1,186 @@ +import Spinner from '@components/Spinner' +import { BaseModal } from './BaseModal' +import CloseIcon from '@components/icons/CloseIcon' +import { Transition, Dialog } from '@headlessui/react' +import { title } from 'process' +import { Fragment } from 'react' + +type LlcModalProps = { + isLlcModalOpen: boolean + setIsLlcModalOpen: (open: boolean) => void + onSignLlc: () => void + isSigning?: boolean +} +export function LlcModal({ + isSigning, + isLlcModalOpen, + setIsLlcModalOpen, + onSignLlc, +}: LlcModalProps) { + return ( + <> + + setIsLlcModalOpen(false)} + > + +
+ +
+
+ + + +
+ + JOINDER AGREEMENT TO OPERATING AGREEMENT OF PYTH DAO LLC + +
+

+ This Joinder Agreement to the Operating Agreement (this + “Joinder”) is made and entered into as + of the date hereof (the “Effective Date + ”) by and between PYTH DAO LLC, a non-profit limited + liability company incorporated as per the laws of + Republic of the Marshall Islands (the “ + Company”) and you (the “ + Joining Party”). Capitalized terms used + but not defined in this Joinder shall have the + respective meanings ascribed to such terms in the + Operating Agreement (as defined below). +

+

+ The Joining Party acknowledges that: +

+

+ The Members of the Company have entered into that + certain Operating Agreement, dated as of [__] (the “ + Operating Agreement”), a copy of which + is available at the following link: [___________].{' '} +

+

+ The Joining Party desires to become a Member of the + Company, pursuant to the terms and conditions set forth + in the Operating Agreement. +

+

+ Pursuant to the Article III of the Operating Agreement, + the Joining Party intends to acquire a Membership + Interest in the Company by staking PYTH SPL Tokens in + the Pyth Staking Program. +

+

+ Pursuant to Article IX of the Operating Agreement, any + prospective member may become a Member automatically by + acquiring a Membership Interest as described in Article + III of the Operating Agreement and upon signing an + agreement (including electronically via their wallet + address) stating, among other things that they agree to + become a Member of the Company and be bound by the terms + of the Operating Agreement. +

+

+ AGREEMENT +

+

+ NOW, THEREFORE, in consideration of the mutual covenants + and agreements herein contained, and other good and + valuable consideration, the receipt and sufficiency of + which are hereby acknowledged, the Joining Party and the + Company agree as follows: +

+

+ Joinder. The Joining Party hereby agrees to (i) + become a Member, pursuant to Articles III and IX of the + Operating Agreement, and (ii) be bound by and adhere to + the terms and conditions of the Operating Agreement. +

+

+ Disclaimer. The Joining Party has had the + opportunity to consult with its own tax adviser and + counsel to discuss and understand any tax and other + legal consequences of acquisition, ownership and + disposition of the Tokens, and any voting of their + Membership Interests. +

+

+ Representations and Warranties of Joining Party. + The Joining Party hereby represents and warrants to + Company as follows: +

+

+ Authorization. The Joining Party has full power + and authority and, with respect to any individual, the + capacity to enter into this Joinder. This Joinder when + executed and delivered by Joining Party, will constitute + valid and legally binding obligations of the Joining + Party, enforceable in accordance with its terms. +

+

+ Restricted Persons. The Joining Party is not a + resident of Iran, Syria, Cuba, North Korea, or the + Crimea, Donetsk, or Luhansk regions of the Ukraine or + any other regions and jurisdictions, as updated per RMI + government guidelines and set forth in the Pyth + Governance Program. +

+

+ Miscellaneous. +

+

+ Governing Law. This Joinder is governed by and + shall be construed in accordance with the laws of the + Republic of the Marshall Islands without regard to the + conflicts of law principles thereof. +

+

+ Amendment. Any provision of this Joinder may be + amended only by a written agreement executed by you and + the Company. +

+
+ + +
+
+
+
+
+
+
+ + ) +} diff --git a/frontend/components/panels/StakePanel.tsx b/frontend/components/panels/StakePanel.tsx index 641c4e91..f2dd0d82 100644 --- a/frontend/components/panels/StakePanel.tsx +++ b/frontend/components/panels/StakePanel.tsx @@ -16,6 +16,8 @@ import { } from './components' import { isSufficientBalance as isSufficientBalanceFn } from 'utils/isSufficientBalance' import { WalletModalButton } from '@components/WalletModalButton' +import { LlcModal } from '@components/modals/LlcModal' +import toast from 'react-hot-toast' type StakePanelProps = { mainStakeAccount: MainStakeAccount @@ -57,6 +59,25 @@ export function StakePanel({ mainStakeAccount }: StakePanelProps) { [] ) + const [isLlcModalOpen, setIsLlcModalOpen] = useState(false) + + // This only executes if deposit action is enabled + const onAction = useCallback(async () => { + if (mainStakeAccount === 'NA') setIsLlcModalOpen(true) + else { + try { + const isLlcMember = await stakeConnection!.isLlcMember( + mainStakeAccount! + ) + + if (isLlcMember === true) deposit(amount) + else setIsLlcModalOpen(true) + } catch { + toast.error('Error: depositing') + } + } + }, [deposit, amount, stakeConnection, mainStakeAccount]) + const isSufficientBalance = isSufficientBalanceFn(amount, pythBalance) // set amount when input changes @@ -92,7 +113,7 @@ export function StakePanel({ mainStakeAccount }: StakePanelProps) { ) : ( deposit(amount)} + onAction={onAction} isActionDisabled={ !isSufficientBalance || // if mainStakeAccount is undefined, the action should be disabled @@ -111,6 +132,17 @@ export function StakePanel({ mainStakeAccount }: StakePanelProps) { /> )} + { + // Once the user clicks sign llc + // Sign and deposit will happen in the same transaction + // We are handling the loading in the panel itself. + deposit(amount) + setIsLlcModalOpen(false) + }} + /> ) diff --git a/frontend/styles/globals.css b/frontend/styles/globals.css index d3a3f9ff..162b6885 100644 --- a/frontend/styles/globals.css +++ b/frontend/styles/globals.css @@ -95,3 +95,14 @@ html::-webkit-scrollbar-thumb { background-color: #e6dafe; border-radius: 3px; } + +.scrollbar { + overflow-y: auto; +} +.scrollbar::-webkit-scrollbar { + width: 3px; +} +.scrollbar::-webkit-scrollbar-thumb { + background-color: #e6dafe; + border-radius: 3px; +} From 8d44e5e643a96813bddf23bfe10e114588b10b07 Mon Sep 17 00:00:00 2001 From: 0xfirefist Date: Tue, 5 Dec 2023 21:02:43 +0530 Subject: [PATCH 02/13] add llc to locked modal --- frontend/components/modals/LockedModal.tsx | 42 ++++++++++++++++++---- 1 file changed, 36 insertions(+), 6 deletions(-) diff --git a/frontend/components/modals/LockedModal.tsx b/frontend/components/modals/LockedModal.tsx index b4f8545d..879a5961 100644 --- a/frontend/components/modals/LockedModal.tsx +++ b/frontend/components/modals/LockedModal.tsx @@ -12,6 +12,9 @@ import { useBalance } from 'hooks/useBalance' import { useNextVestingEvent } from 'hooks/useNextVestingEvent' import { useStakeConnection } from 'hooks/useStakeConnection' import { MainStakeAccount } from 'pages' +import { LlcModal } from './LlcModal' +import { useCallback, useState } from 'react' +import toast from 'react-hot-toast' export type LockedModalProps = { isLockedModalOpen: boolean @@ -188,6 +191,24 @@ function LockedModalButton({ const unvestedPreUnlockAll = useUnvestedPreUnlockAllMutation() const unvestedUnlockAll = useUnvestedUnlockAllMutation() + const [isLlcModalOpen, setIsLlcModalOpen] = useState(false) + + const onStakeAll = useCallback(async () => { + if (mainStakeAccount === 'NA' || mainStakeAccount === undefined) return + try { + const isLlcMember = await stakeConnection!.isLlcMember(mainStakeAccount) + + if (isLlcMember === true) + unvestedLockAll.mutate({ + mainStakeAccount: mainStakeAccount, + stakeConnection: stakeConnection!, + }) + else setIsLlcModalOpen(true) + } catch { + toast.error('Error: staking') + } + }, [stakeConnection, mainStakeAccount]) + if (mainStakeAccount === 'NA') return <> switch (currentVestingAccountState) { @@ -234,12 +255,7 @@ function LockedModalButton({ + + { + // Once the user clicks sign llc + // Sign and stake will happen in the same transaction + unvestedLockAll.mutate({ + mainStakeAccount: mainStakeAccount as StakeAccount, + stakeConnection: stakeConnection!, + }) + setIsLlcModalOpen(false) + }} + /> ) } From 26cb7328a5563683255e4a7dfc367cbda5094a70 Mon Sep 17 00:00:00 2001 From: 0xfirefist Date: Tue, 5 Dec 2023 21:02:59 +0530 Subject: [PATCH 03/13] signLlc method in stake connection --- staking/app/StakeConnection.ts | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/staking/app/StakeConnection.ts b/staking/app/StakeConnection.ts index b3c9d669..941b0293 100644 --- a/staking/app/StakeConnection.ts +++ b/staking/app/StakeConnection.ts @@ -597,6 +597,15 @@ export class StakeConnection { await this.provider.sendAndConfirm(transaction); } + /** + * Locks the specified amount of tokens in governance. + */ + public async signLlc(stakeAccount: StakeAccount) { + const transaction: Transaction = new Transaction(); + await this.withJoinDaoLlc(transaction.instructions, stakeAccount.address); + await this.provider.sendAndConfirm(transaction); + } + public async setupVestingAccount( amount: PythBalance, owner: PublicKey, From dfea5fc347681bf1841a72e3340b8863287de921 Mon Sep 17 00:00:00 2001 From: 0xfirefist Date: Tue, 5 Dec 2023 21:22:46 +0530 Subject: [PATCH 04/13] show llc on wallet connect --- frontend/hooks/useSignLlcMutation.ts | 28 ++++++++++++++++++++ frontend/pages/index.tsx | 39 +++++++++++++++++++++++++++- 2 files changed, 66 insertions(+), 1 deletion(-) create mode 100644 frontend/hooks/useSignLlcMutation.ts diff --git a/frontend/hooks/useSignLlcMutation.ts b/frontend/hooks/useSignLlcMutation.ts new file mode 100644 index 00000000..5ac53d92 --- /dev/null +++ b/frontend/hooks/useSignLlcMutation.ts @@ -0,0 +1,28 @@ +import { + PythBalance, + StakeAccount, + StakeConnection, +} from '@pythnetwork/staking' +import toast from 'react-hot-toast' +import { useMutation } from 'react-query' + +export function useSignLlcMutation() { + return useMutation( + ['sign-llc-mutation'], + async ({ + stakeConnection, + mainStakeAccount, + }: { + stakeConnection: StakeConnection + mainStakeAccount: StakeAccount + }) => { + await stakeConnection.signLlc(mainStakeAccount) + toast.success(`Successfully signed LLC!`) + }, + { + onError(error: Error) { + toast.error(error.message) + }, + } + ) +} diff --git a/frontend/pages/index.tsx b/frontend/pages/index.tsx index 477980ab..db55ad0d 100644 --- a/frontend/pages/index.tsx +++ b/frontend/pages/index.tsx @@ -22,6 +22,8 @@ import { StakePanel } from '@components/panels/StakePanel' import { UnstakePanel } from '@components/panels/UnstakePanel' import { WithdrawPanel } from '@components/panels/WithdrawPanel' import { useStakeConnection } from 'hooks/useStakeConnection' +import { LlcModal } from '@components/modals/LlcModal' +import { useSignLlcMutation } from 'hooks/useSignLlcMutation' enum TabEnum { Stake, @@ -50,7 +52,8 @@ const Staking: NextPage = () => { const wallet = useAnchorWallet() const isWalletConnected = wallet !== undefined - const { isLoading: isStakeConnectionLoading } = useStakeConnection() + const { data: stakeConnection, isLoading: isStakeConnectionLoading } = + useStakeConnection() const { data: stakeAccounts, isLoading: isStakeAccountsLoading } = useStakeAccounts() @@ -93,6 +96,21 @@ const Staking: NextPage = () => { const { data: currentVestingAccountState } = useVestingAccountState(mainStakeAccount) + const signLlcMutation = useSignLlcMutation() + const [isLlcModalOpen, setIsLlcModalOpen] = useState(false) + useEffect(() => { + if ( + stakeConnection === undefined || + mainStakeAccount === undefined || + mainStakeAccount === 'NA' + ) + return + ;(async () => { + if (!(await stakeConnection.isLlcMember(mainStakeAccount))) + setIsLlcModalOpen(true) + })() + }, [stakeConnection, mainStakeAccount]) + // First stake connection will load, then stake accounts, and // then if a main stake account exists, the balance will load // else the balance won't load, it will be undefined @@ -404,6 +422,25 @@ const Staking: NextPage = () => { + { + // this modal will only be shown if there is a stakeConnection and mainStakeAccount + signLlcMutation.mutate( + { + stakeConnection: stakeConnection!, + mainStakeAccount: mainStakeAccount as StakeAccount, + }, + { + onSettled() { + setIsLlcModalOpen(false) + }, + } + ) + }} + isSigning={signLlcMutation.isLoading} + /> ) } From 240e5f5408d3c896b83f1fda763cc836371431b0 Mon Sep 17 00:00:00 2001 From: 0xfirefist Date: Tue, 5 Dec 2023 23:12:35 +0530 Subject: [PATCH 05/13] correct comments --- frontend/components/modals/LlcModal.tsx | 14 +++++++++++--- 1 file changed, 11 insertions(+), 3 deletions(-) diff --git a/frontend/components/modals/LlcModal.tsx b/frontend/components/modals/LlcModal.tsx index 88dc4103..7ca077b1 100644 --- a/frontend/components/modals/LlcModal.tsx +++ b/frontend/components/modals/LlcModal.tsx @@ -1,8 +1,6 @@ import Spinner from '@components/Spinner' -import { BaseModal } from './BaseModal' import CloseIcon from '@components/icons/CloseIcon' import { Transition, Dialog } from '@headlessui/react' -import { title } from 'process' import { Fragment } from 'react' type LlcModalProps = { @@ -19,6 +17,7 @@ export function LlcModal({ }: LlcModalProps) { return ( <> + {/* TODO: refactor base modal to follow composition approach */}

The Members of the Company have entered into that + {/* TODO: correct date */} certain Operating Agreement, dated as of [__] (the “ Operating Agreement”), a copy of which - is available at the following link: [___________].{' '} + is available at the following link:{' '} + + Operating Agreement + + .{' '}

The Joining Party desires to become a Member of the From b38942865695a840b69f51107d50ce37ed464dbd Mon Sep 17 00:00:00 2001 From: 0xfirefist Date: Wed, 6 Dec 2023 21:35:41 +0530 Subject: [PATCH 06/13] rename sign llc --- ...{useSignLlcMutation.ts => useJoinDaoLlcMutation.ts} | 10 +++------- frontend/pages/index.tsx | 8 ++++---- staking/app/StakeConnection.ts | 4 ++-- 3 files changed, 9 insertions(+), 13 deletions(-) rename frontend/hooks/{useSignLlcMutation.ts => useJoinDaoLlcMutation.ts} (70%) diff --git a/frontend/hooks/useSignLlcMutation.ts b/frontend/hooks/useJoinDaoLlcMutation.ts similarity index 70% rename from frontend/hooks/useSignLlcMutation.ts rename to frontend/hooks/useJoinDaoLlcMutation.ts index 5ac53d92..ebbb4d13 100644 --- a/frontend/hooks/useSignLlcMutation.ts +++ b/frontend/hooks/useJoinDaoLlcMutation.ts @@ -1,12 +1,8 @@ -import { - PythBalance, - StakeAccount, - StakeConnection, -} from '@pythnetwork/staking' +import { StakeAccount, StakeConnection } from '@pythnetwork/staking' import toast from 'react-hot-toast' import { useMutation } from 'react-query' -export function useSignLlcMutation() { +export function useJoinDaoLlcMutation() { return useMutation( ['sign-llc-mutation'], async ({ @@ -16,7 +12,7 @@ export function useSignLlcMutation() { stakeConnection: StakeConnection mainStakeAccount: StakeAccount }) => { - await stakeConnection.signLlc(mainStakeAccount) + await stakeConnection.joinDaoLlc(mainStakeAccount) toast.success(`Successfully signed LLC!`) }, { diff --git a/frontend/pages/index.tsx b/frontend/pages/index.tsx index db55ad0d..11e544d6 100644 --- a/frontend/pages/index.tsx +++ b/frontend/pages/index.tsx @@ -23,7 +23,7 @@ import { UnstakePanel } from '@components/panels/UnstakePanel' import { WithdrawPanel } from '@components/panels/WithdrawPanel' import { useStakeConnection } from 'hooks/useStakeConnection' import { LlcModal } from '@components/modals/LlcModal' -import { useSignLlcMutation } from 'hooks/useSignLlcMutation' +import { useJoinDaoLlcMutation } from 'hooks/useJoinDaoLlcMutation' enum TabEnum { Stake, @@ -96,7 +96,7 @@ const Staking: NextPage = () => { const { data: currentVestingAccountState } = useVestingAccountState(mainStakeAccount) - const signLlcMutation = useSignLlcMutation() + const joinDaoLlcMutation = useJoinDaoLlcMutation() const [isLlcModalOpen, setIsLlcModalOpen] = useState(false) useEffect(() => { if ( @@ -427,7 +427,7 @@ const Staking: NextPage = () => { setIsLlcModalOpen={setIsLlcModalOpen} onSignLlc={() => { // this modal will only be shown if there is a stakeConnection and mainStakeAccount - signLlcMutation.mutate( + joinDaoLlcMutation.mutate( { stakeConnection: stakeConnection!, mainStakeAccount: mainStakeAccount as StakeAccount, @@ -439,7 +439,7 @@ const Staking: NextPage = () => { } ) }} - isSigning={signLlcMutation.isLoading} + isSigning={joinDaoLlcMutation.isLoading} /> ) diff --git a/staking/app/StakeConnection.ts b/staking/app/StakeConnection.ts index 941b0293..0a98bcd7 100644 --- a/staking/app/StakeConnection.ts +++ b/staking/app/StakeConnection.ts @@ -598,9 +598,9 @@ export class StakeConnection { } /** - * Locks the specified amount of tokens in governance. + * Join the DAO LLC for the give stake account. */ - public async signLlc(stakeAccount: StakeAccount) { + public async joinDaoLlc(stakeAccount: StakeAccount) { const transaction: Transaction = new Transaction(); await this.withJoinDaoLlc(transaction.instructions, stakeAccount.address); await this.provider.sendAndConfirm(transaction); From f103b95c3cc052df7188a6b183d9ac5ddff3a7a8 Mon Sep 17 00:00:00 2001 From: 0xfirefist Date: Wed, 6 Dec 2023 21:41:02 +0530 Subject: [PATCH 07/13] some requested changes - comments --- frontend/components/modals/LlcModal.tsx | 4 ++-- frontend/components/panels/StakePanel.tsx | 2 +- frontend/hooks/useJoinDaoLlcMutation.ts | 2 +- 3 files changed, 4 insertions(+), 4 deletions(-) diff --git a/frontend/components/modals/LlcModal.tsx b/frontend/components/modals/LlcModal.tsx index 7ca077b1..525432b2 100644 --- a/frontend/components/modals/LlcModal.tsx +++ b/frontend/components/modals/LlcModal.tsx @@ -79,7 +79,7 @@ export function LlcModal({

The Members of the Company have entered into that - {/* TODO: correct date */} + {/* TODO: put the right date here */} certain Operating Agreement, dated as of [__] (the “ Operating Agreement”), a copy of which is available at the following link:{' '} @@ -180,7 +180,7 @@ export function LlcModal({ onClick={onSignLlc} disabled={isSigning} > - {isSigning ? : 'Sign LLC'} + {isSigning ? : 'Sign LLC agreement'} diff --git a/frontend/components/panels/StakePanel.tsx b/frontend/components/panels/StakePanel.tsx index f2dd0d82..70fbfbbc 100644 --- a/frontend/components/panels/StakePanel.tsx +++ b/frontend/components/panels/StakePanel.tsx @@ -136,7 +136,7 @@ export function StakePanel({ mainStakeAccount }: StakePanelProps) { isLlcModalOpen={isLlcModalOpen} setIsLlcModalOpen={setIsLlcModalOpen} onSignLlc={() => { - // Once the user clicks sign llc + // Once the user clicks sign llc agreement // Sign and deposit will happen in the same transaction // We are handling the loading in the panel itself. deposit(amount) diff --git a/frontend/hooks/useJoinDaoLlcMutation.ts b/frontend/hooks/useJoinDaoLlcMutation.ts index ebbb4d13..98e723f4 100644 --- a/frontend/hooks/useJoinDaoLlcMutation.ts +++ b/frontend/hooks/useJoinDaoLlcMutation.ts @@ -13,7 +13,7 @@ export function useJoinDaoLlcMutation() { mainStakeAccount: StakeAccount }) => { await stakeConnection.joinDaoLlc(mainStakeAccount) - toast.success(`Successfully signed LLC!`) + toast.success(`Successfully signed LLC agreement!`) }, { onError(error: Error) { From 540301aa8c18f4b813a580a779f86e5d1092d4bb Mon Sep 17 00:00:00 2001 From: 0xfirefist Date: Wed, 6 Dec 2023 21:59:47 +0530 Subject: [PATCH 08/13] fix callback dependencies bug --- frontend/components/panels/StakePanel.tsx | 2 +- frontend/components/panels/WithdrawPanel.tsx | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/frontend/components/panels/StakePanel.tsx b/frontend/components/panels/StakePanel.tsx index 70fbfbbc..d3323723 100644 --- a/frontend/components/panels/StakePanel.tsx +++ b/frontend/components/panels/StakePanel.tsx @@ -56,7 +56,7 @@ export function StakePanel({ mainStakeAccount }: StakePanelProps) { // action is disabled below if these is undefined stakeConnection: stakeConnection!, }), - [] + [depositMutation.mutate, mainStakeAccount, stakeConnection] ) const [isLlcModalOpen, setIsLlcModalOpen] = useState(false) diff --git a/frontend/components/panels/WithdrawPanel.tsx b/frontend/components/panels/WithdrawPanel.tsx index 9296f671..2efdbd8a 100644 --- a/frontend/components/panels/WithdrawPanel.tsx +++ b/frontend/components/panels/WithdrawPanel.tsx @@ -48,7 +48,7 @@ export function WithdrawPanel({ mainStakeAccount }: WithdrawPanelProps) { mainStakeAccount: mainStakeAccount as StakeAccount, stakeConnection: stakeConnection!, }) - }, []) + }, [amount, mainStakeAccount, stakeConnection]) return ( From 143f8768f7bfdd90e131be1045c790214fdd6444 Mon Sep 17 00:00:00 2001 From: 0xfirefist Date: Wed, 6 Dec 2023 22:17:10 +0530 Subject: [PATCH 09/13] update error message --- frontend/components/modals/LockedModal.tsx | 2 +- frontend/components/panels/StakePanel.tsx | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/frontend/components/modals/LockedModal.tsx b/frontend/components/modals/LockedModal.tsx index 879a5961..f366bb35 100644 --- a/frontend/components/modals/LockedModal.tsx +++ b/frontend/components/modals/LockedModal.tsx @@ -205,7 +205,7 @@ function LockedModalButton({ }) else setIsLlcModalOpen(true) } catch { - toast.error('Error: staking') + toast.error('Connection error') } }, [stakeConnection, mainStakeAccount]) diff --git a/frontend/components/panels/StakePanel.tsx b/frontend/components/panels/StakePanel.tsx index d3323723..0ce9c6ec 100644 --- a/frontend/components/panels/StakePanel.tsx +++ b/frontend/components/panels/StakePanel.tsx @@ -73,7 +73,7 @@ export function StakePanel({ mainStakeAccount }: StakePanelProps) { if (isLlcMember === true) deposit(amount) else setIsLlcModalOpen(true) } catch { - toast.error('Error: depositing') + toast.error('Connection error') } } }, [deposit, amount, stakeConnection, mainStakeAccount]) From 19d1274cdc7caa965f8d23d605a7b0f2aa21a069 Mon Sep 17 00:00:00 2001 From: 0xfirefist Date: Wed, 6 Dec 2023 22:18:18 +0530 Subject: [PATCH 10/13] fix use callback bug --- frontend/components/panels/WithdrawPanel.tsx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/frontend/components/panels/WithdrawPanel.tsx b/frontend/components/panels/WithdrawPanel.tsx index 2efdbd8a..a5a85380 100644 --- a/frontend/components/panels/WithdrawPanel.tsx +++ b/frontend/components/panels/WithdrawPanel.tsx @@ -48,7 +48,7 @@ export function WithdrawPanel({ mainStakeAccount }: WithdrawPanelProps) { mainStakeAccount: mainStakeAccount as StakeAccount, stakeConnection: stakeConnection!, }) - }, [amount, mainStakeAccount, stakeConnection]) + }, [withdrawMutation.mutate, amount, mainStakeAccount, stakeConnection]) return ( From a4b1ad2919bef22f4ff46f68d96360dd7ffbed16 Mon Sep 17 00:00:00 2001 From: 0xfirefist Date: Thu, 7 Dec 2023 17:13:47 +0530 Subject: [PATCH 11/13] isLlcMember remove async --- staking/app/StakeConnection.ts | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/staking/app/StakeConnection.ts b/staking/app/StakeConnection.ts index 0a98bcd7..7b0b6429 100644 --- a/staking/app/StakeConnection.ts +++ b/staking/app/StakeConnection.ts @@ -463,7 +463,7 @@ export class StakeConnection { return stakeAccountKeypair; } - public async isLlcMember(stakeAccount: StakeAccount) { + public isLlcMember(stakeAccount: StakeAccount) { return ( stakeAccount.stakeAccountMetadata.signedAgreementHash == this.config.agreementHash @@ -580,7 +580,7 @@ export class StakeConnection { ); } - if (!(await this.isLlcMember(stakeAccount))) { + if (!this.isLlcMember(stakeAccount)) { await this.withJoinDaoLlc(transaction.instructions, stakeAccount.address); } @@ -671,7 +671,7 @@ export class StakeConnection { ); } - if (!stakeAccount || !(await this.isLlcMember(stakeAccount))) { + if (!stakeAccount || !this.isLlcMember(stakeAccount)) { await this.withJoinDaoLlc(ixs, stakeAccountAddress); } @@ -776,7 +776,7 @@ export class StakeConnection { ); } - if (!stakeAccount || !(await this.isLlcMember(stakeAccount))) { + if (!stakeAccount || !this.isLlcMember(stakeAccount)) { await this.withJoinDaoLlc(ixs, stakeAccountAddress); } From 6d4c72b18a80e653e3162edf37662dd584df2794 Mon Sep 17 00:00:00 2001 From: 0xfirefist Date: Thu, 7 Dec 2023 17:16:21 +0530 Subject: [PATCH 12/13] remove error and async from isllcmember calls --- frontend/components/modals/LockedModal.tsx | 18 +++++++----------- frontend/components/panels/StakePanel.tsx | 14 ++++---------- frontend/pages/index.tsx | 6 ++---- 3 files changed, 13 insertions(+), 25 deletions(-) diff --git a/frontend/components/modals/LockedModal.tsx b/frontend/components/modals/LockedModal.tsx index f366bb35..f8466fa0 100644 --- a/frontend/components/modals/LockedModal.tsx +++ b/frontend/components/modals/LockedModal.tsx @@ -195,18 +195,14 @@ function LockedModalButton({ const onStakeAll = useCallback(async () => { if (mainStakeAccount === 'NA' || mainStakeAccount === undefined) return - try { - const isLlcMember = await stakeConnection!.isLlcMember(mainStakeAccount) + const isLlcMember = stakeConnection!.isLlcMember(mainStakeAccount) - if (isLlcMember === true) - unvestedLockAll.mutate({ - mainStakeAccount: mainStakeAccount, - stakeConnection: stakeConnection!, - }) - else setIsLlcModalOpen(true) - } catch { - toast.error('Connection error') - } + if (isLlcMember === true) + unvestedLockAll.mutate({ + mainStakeAccount: mainStakeAccount, + stakeConnection: stakeConnection!, + }) + else setIsLlcModalOpen(true) }, [stakeConnection, mainStakeAccount]) if (mainStakeAccount === 'NA') return <> diff --git a/frontend/components/panels/StakePanel.tsx b/frontend/components/panels/StakePanel.tsx index 0ce9c6ec..04e06608 100644 --- a/frontend/components/panels/StakePanel.tsx +++ b/frontend/components/panels/StakePanel.tsx @@ -62,19 +62,13 @@ export function StakePanel({ mainStakeAccount }: StakePanelProps) { const [isLlcModalOpen, setIsLlcModalOpen] = useState(false) // This only executes if deposit action is enabled - const onAction = useCallback(async () => { + const onAction = useCallback(() => { if (mainStakeAccount === 'NA') setIsLlcModalOpen(true) else { - try { - const isLlcMember = await stakeConnection!.isLlcMember( - mainStakeAccount! - ) + const isLlcMember = stakeConnection!.isLlcMember(mainStakeAccount!) - if (isLlcMember === true) deposit(amount) - else setIsLlcModalOpen(true) - } catch { - toast.error('Connection error') - } + if (isLlcMember === true) deposit(amount) + else setIsLlcModalOpen(true) } }, [deposit, amount, stakeConnection, mainStakeAccount]) diff --git a/frontend/pages/index.tsx b/frontend/pages/index.tsx index 11e544d6..d866c671 100644 --- a/frontend/pages/index.tsx +++ b/frontend/pages/index.tsx @@ -105,10 +105,8 @@ const Staking: NextPage = () => { mainStakeAccount === 'NA' ) return - ;(async () => { - if (!(await stakeConnection.isLlcMember(mainStakeAccount))) - setIsLlcModalOpen(true) - })() + + if (!stakeConnection.isLlcMember(mainStakeAccount)) setIsLlcModalOpen(true) }, [stakeConnection, mainStakeAccount]) // First stake connection will load, then stake accounts, and From ff8e6be624862419f400c29f8518bd2df6502aeb Mon Sep 17 00:00:00 2001 From: guibescos <59208140+guibescos@users.noreply.github.com> Date: Fri, 15 Dec 2023 19:32:20 +0700 Subject: [PATCH 13/13] do It (#305) --- frontend/hooks/useJoinDaoLlcMutation.ts | 12 +++++++++++- staking/app/StakeConnection.ts | 2 +- 2 files changed, 12 insertions(+), 2 deletions(-) diff --git a/frontend/hooks/useJoinDaoLlcMutation.ts b/frontend/hooks/useJoinDaoLlcMutation.ts index 98e723f4..41471071 100644 --- a/frontend/hooks/useJoinDaoLlcMutation.ts +++ b/frontend/hooks/useJoinDaoLlcMutation.ts @@ -1,8 +1,11 @@ import { StakeAccount, StakeConnection } from '@pythnetwork/staking' import toast from 'react-hot-toast' -import { useMutation } from 'react-query' +import { useMutation, useQueryClient } from 'react-query' +import { StakeConnectionQueryKey } from './useStakeConnection' export function useJoinDaoLlcMutation() { + const queryClient = useQueryClient() + return useMutation( ['sign-llc-mutation'], async ({ @@ -16,6 +19,13 @@ export function useJoinDaoLlcMutation() { toast.success(`Successfully signed LLC agreement!`) }, { + onSuccess() { + // invalidate all except stake connection + queryClient.invalidateQueries({ + predicate: (query) => query.queryKey[0] !== StakeConnectionQueryKey, + }) + }, + onError(error: Error) { toast.error(error.message) }, diff --git a/staking/app/StakeConnection.ts b/staking/app/StakeConnection.ts index 5c63f070..1d3c0bbf 100644 --- a/staking/app/StakeConnection.ts +++ b/staking/app/StakeConnection.ts @@ -598,7 +598,7 @@ export class StakeConnection { } /** - * Join the DAO LLC for the give stake account. + * Join the DAO LLC for the given stake account. */ public async joinDaoLlc(stakeAccount: StakeAccount) { const transaction: Transaction = new Transaction();