Skip to content

Commit 813ad34

Browse files
authored
[xc-admin-frontend] XC admin frontend fix part2 (#970)
* Add some missing hook dependencies * Smarter target cluster detection * Show approved/rejected count for active proposals
1 parent fbd004f commit 813ad34

File tree

3 files changed

+84
-7
lines changed

3 files changed

+84
-7
lines changed

governance/xc_admin/packages/xc_admin_frontend/components/InstructionViews/WormholeInstructionView.tsx

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,7 @@ import { ParsedAccountPubkeyRow, SignerTag, WritableTag } from './AccountUtils'
2424
import { usePythContext } from '../../contexts/PythContext'
2525

2626
import { getMappingCluster, isPubkey } from './utils'
27+
import { PythCluster } from '@pythnetwork/client'
2728

2829
const GovernanceInstructionView = ({
2930
instruction,
@@ -48,10 +49,11 @@ const GovernanceInstructionView = ({
4849
}
4950
export const WormholeInstructionView = ({
5051
instruction,
52+
cluster,
5153
}: {
5254
instruction: WormholeMultisigInstruction
55+
cluster: PythCluster
5356
}) => {
54-
const { cluster } = useContext(ClusterContext)
5557
const {
5658
priceAccountKeyToSymbolMapping,
5759
productAccountKeyToSymbolMapping,

governance/xc_admin/packages/xc_admin_frontend/components/tabs/Proposals.tsx

Lines changed: 79 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -51,6 +51,7 @@ import {
5151
} from '../InstructionViews/AccountUtils'
5252

5353
import { getMappingCluster, isPubkey } from '../InstructionViews/utils'
54+
import { getPythProgramKeyForCluster, PythCluster } from '@pythnetwork/client'
5455
const ProposalRow = ({
5556
proposal,
5657
multisig,
@@ -94,15 +95,39 @@ const ProposalRow = ({
9495
proposal.publicKey.toBase58().slice(-6)}
9596
</span>{' '}
9697
</div>
97-
<div>
98-
<StatusTag proposalStatus={status} />
98+
<div className="flex space-x-2">
99+
{proposal.approved.length > 0 && status === 'active' && (
100+
<div>
101+
<StatusTag
102+
proposalStatus="executed"
103+
text={`Approved: ${proposal.approved.length}`}
104+
/>
105+
</div>
106+
)}
107+
{proposal.rejected.length > 0 && status === 'active' && (
108+
<div>
109+
<StatusTag
110+
proposalStatus="rejected"
111+
text={`Rejected: ${proposal.rejected.length}`}
112+
/>
113+
</div>
114+
)}
115+
<div>
116+
<StatusTag proposalStatus={status} />
117+
</div>
99118
</div>
100119
</div>
101120
</div>
102121
)
103122
}
104123

105-
const StatusTag = ({ proposalStatus }: { proposalStatus: string }) => {
124+
const StatusTag = ({
125+
proposalStatus,
126+
text,
127+
}: {
128+
proposalStatus: string
129+
text?: string
130+
}) => {
106131
return (
107132
<div
108133
className={`flex items-center justify-center rounded-full ${
@@ -119,7 +144,7 @@ const StatusTag = ({ proposalStatus }: { proposalStatus: string }) => {
119144
: 'bg-pythPurple'
120145
} py-1 px-2 text-xs`}
121146
>
122-
{proposalStatus}
147+
{text || proposalStatus}
123148
</div>
124149
)
125150
}
@@ -230,7 +255,40 @@ const Proposal = ({
230255
}) => {
231256
const [instructions, setInstructions] = useState<MultisigInstruction[]>([])
232257
const [isTransactionLoading, setIsTransactionLoading] = useState(false)
233-
const { cluster } = useContext(ClusterContext)
258+
const { cluster: contextCluster } = useContext(ClusterContext)
259+
const multisigCluster = getMultisigCluster(contextCluster)
260+
const targetClusters: (PythCluster | 'unknown')[] = []
261+
instructions.map((ix) => {
262+
if (ix instanceof PythMultisigInstruction) {
263+
targetClusters.push(multisigCluster)
264+
} else if (
265+
ix instanceof WormholeMultisigInstruction &&
266+
ix.governanceAction instanceof ExecutePostedVaa
267+
) {
268+
ix.governanceAction.instructions.map((ix) => {
269+
const remoteClusters: PythCluster[] = [
270+
'pythnet',
271+
'pythtest-conformance',
272+
'pythtest-crosschain',
273+
]
274+
for (const remoteCluster of remoteClusters) {
275+
if (
276+
multisigCluster === getMultisigCluster(remoteCluster) &&
277+
ix.programId.equals(getPythProgramKeyForCluster(remoteCluster))
278+
) {
279+
targetClusters.push(remoteCluster)
280+
}
281+
}
282+
})
283+
} else {
284+
targetClusters.push('unknown')
285+
}
286+
})
287+
const uniqueTargetCluster = new Set(targetClusters).size === 1
288+
const cluster =
289+
uniqueTargetCluster && targetClusters[0] !== 'unknown'
290+
? targetClusters[0]
291+
: contextCluster
234292

235293
const {
236294
voteSquads,
@@ -243,6 +301,7 @@ const Proposal = ({
243301
productAccountKeyToSymbolMapping,
244302
publisherKeyToNameMapping,
245303
} = usePythContext()
304+
246305
const publisherKeyToNameMappingCluster =
247306
publisherKeyToNameMapping[getMappingCluster(cluster)]
248307
const { publicKey: signerPublicKey } = useWallet()
@@ -367,6 +426,17 @@ const Proposal = ({
367426
multisig !== undefined &&
368427
!isMultisigLoading ? (
369428
<div className="grid grid-cols-3 gap-4">
429+
<div className="col-span-3 my-2 space-y-4 bg-[#1E1B2F] p-4">
430+
<h4 className="h4 font-semibold">
431+
{uniqueTargetCluster
432+
? `Target Pyth Program: ${targetClusters[0]}`
433+
: targetClusters.length == 0
434+
? 'No target Pyth program detected'
435+
: `Multiple target Pyth programs detected ${targetClusters.join(
436+
' '
437+
)}`}
438+
</h4>
439+
</div>
370440
<div className="col-span-3 my-2 space-y-4 bg-[#1E1B2F] p-4 lg:col-span-2">
371441
<div className="flex justify-between">
372442
<h4 className="h4 font-semibold">Info</h4>
@@ -689,7 +759,10 @@ const Proposal = ({
689759
</>
690760
) : null}
691761
{instruction instanceof WormholeMultisigInstruction && (
692-
<WormholeInstructionView instruction={instruction} />
762+
<WormholeInstructionView
763+
cluster={cluster}
764+
instruction={instruction}
765+
/>
693766
)}
694767

695768
{index !== instructions.length - 1 ? (

governance/xc_admin/packages/xc_admin_frontend/contexts/PythContext.tsx

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -86,6 +86,8 @@ export const PythContextProvider: React.FC<PythContextProviderProps> = ({
8686
connection,
8787
publisherKeyToNameMapping,
8888
multisigSignerKeyToNameMapping,
89+
priceAccountKeyToSymbolMapping,
90+
productAccountKeyToSymbolMapping,
8991
]
9092
)
9193

0 commit comments

Comments
 (0)