diff --git a/governance/xc_admin/packages/xc_admin_frontend/components/InstructionViews/WormholeInstructionView.tsx b/governance/xc_admin/packages/xc_admin_frontend/components/InstructionViews/WormholeInstructionView.tsx index d8b666c7..8cbb50c9 100644 --- a/governance/xc_admin/packages/xc_admin_frontend/components/InstructionViews/WormholeInstructionView.tsx +++ b/governance/xc_admin/packages/xc_admin_frontend/components/InstructionViews/WormholeInstructionView.tsx @@ -24,6 +24,7 @@ import { ParsedAccountPubkeyRow, SignerTag, WritableTag } from './AccountUtils' import { usePythContext } from '../../contexts/PythContext' import { getMappingCluster, isPubkey } from './utils' +import { PythCluster } from '@pythnetwork/client' const GovernanceInstructionView = ({ instruction, @@ -48,10 +49,11 @@ const GovernanceInstructionView = ({ } export const WormholeInstructionView = ({ instruction, + cluster, }: { instruction: WormholeMultisigInstruction + cluster: PythCluster }) => { - const { cluster } = useContext(ClusterContext) const { priceAccountKeyToSymbolMapping, productAccountKeyToSymbolMapping, diff --git a/governance/xc_admin/packages/xc_admin_frontend/components/tabs/Proposals.tsx b/governance/xc_admin/packages/xc_admin_frontend/components/tabs/Proposals.tsx index c2b12ca9..7ab68ce3 100644 --- a/governance/xc_admin/packages/xc_admin_frontend/components/tabs/Proposals.tsx +++ b/governance/xc_admin/packages/xc_admin_frontend/components/tabs/Proposals.tsx @@ -51,6 +51,7 @@ import { } from '../InstructionViews/AccountUtils' import { getMappingCluster, isPubkey } from '../InstructionViews/utils' +import { getPythProgramKeyForCluster, PythCluster } from '@pythnetwork/client' const ProposalRow = ({ proposal, multisig, @@ -94,15 +95,39 @@ const ProposalRow = ({ proposal.publicKey.toBase58().slice(-6)} {' '} -
- +
+ {proposal.approved.length > 0 && status === 'active' && ( +
+ +
+ )} + {proposal.rejected.length > 0 && status === 'active' && ( +
+ +
+ )} +
+ +
) } -const StatusTag = ({ proposalStatus }: { proposalStatus: string }) => { +const StatusTag = ({ + proposalStatus, + text, +}: { + proposalStatus: string + text?: string +}) => { return (
{ : 'bg-pythPurple' } py-1 px-2 text-xs`} > - {proposalStatus} + {text || proposalStatus}
) } @@ -230,7 +255,40 @@ const Proposal = ({ }) => { const [instructions, setInstructions] = useState([]) const [isTransactionLoading, setIsTransactionLoading] = useState(false) - const { cluster } = useContext(ClusterContext) + const { cluster: contextCluster } = useContext(ClusterContext) + const multisigCluster = getMultisigCluster(contextCluster) + const targetClusters: (PythCluster | 'unknown')[] = [] + instructions.map((ix) => { + if (ix instanceof PythMultisigInstruction) { + targetClusters.push(multisigCluster) + } else if ( + ix instanceof WormholeMultisigInstruction && + ix.governanceAction instanceof ExecutePostedVaa + ) { + ix.governanceAction.instructions.map((ix) => { + const remoteClusters: PythCluster[] = [ + 'pythnet', + 'pythtest-conformance', + 'pythtest-crosschain', + ] + for (const remoteCluster of remoteClusters) { + if ( + multisigCluster === getMultisigCluster(remoteCluster) && + ix.programId.equals(getPythProgramKeyForCluster(remoteCluster)) + ) { + targetClusters.push(remoteCluster) + } + } + }) + } else { + targetClusters.push('unknown') + } + }) + const uniqueTargetCluster = new Set(targetClusters).size === 1 + const cluster = + uniqueTargetCluster && targetClusters[0] !== 'unknown' + ? targetClusters[0] + : contextCluster const { voteSquads, @@ -243,6 +301,7 @@ const Proposal = ({ productAccountKeyToSymbolMapping, publisherKeyToNameMapping, } = usePythContext() + const publisherKeyToNameMappingCluster = publisherKeyToNameMapping[getMappingCluster(cluster)] const { publicKey: signerPublicKey } = useWallet() @@ -367,6 +426,17 @@ const Proposal = ({ multisig !== undefined && !isMultisigLoading ? (
+
+

+ {uniqueTargetCluster + ? `Target Pyth Program: ${targetClusters[0]}` + : targetClusters.length == 0 + ? 'No target Pyth program detected' + : `Multiple target Pyth programs detected ${targetClusters.join( + ' ' + )}`} +

+

Info

@@ -689,7 +759,10 @@ const Proposal = ({ ) : null} {instruction instanceof WormholeMultisigInstruction && ( - + )} {index !== instructions.length - 1 ? ( diff --git a/governance/xc_admin/packages/xc_admin_frontend/contexts/PythContext.tsx b/governance/xc_admin/packages/xc_admin_frontend/contexts/PythContext.tsx index bc1f0d7a..23307416 100644 --- a/governance/xc_admin/packages/xc_admin_frontend/contexts/PythContext.tsx +++ b/governance/xc_admin/packages/xc_admin_frontend/contexts/PythContext.tsx @@ -86,6 +86,8 @@ export const PythContextProvider: React.FC = ({ connection, publisherKeyToNameMapping, multisigSignerKeyToNameMapping, + priceAccountKeyToSymbolMapping, + productAccountKeyToSymbolMapping, ] )