mirror of https://github.com/certusone/oyster.git
fix: show uo to date voting records
This commit is contained in:
parent
be911a89f7
commit
f9fec80e08
|
@ -0,0 +1,63 @@
|
||||||
|
import { useEffect, useState } from 'react';
|
||||||
|
|
||||||
|
import { PublicKey } from '@solana/web3.js';
|
||||||
|
import {
|
||||||
|
ParsedAccount,
|
||||||
|
useConnection,
|
||||||
|
useConnectionConfig,
|
||||||
|
utils,
|
||||||
|
} from '@oyster/common';
|
||||||
|
import {
|
||||||
|
GovernanceVotingRecord,
|
||||||
|
GovernanceVotingRecordLayout,
|
||||||
|
GovernanceVotingRecordParser,
|
||||||
|
} from '../models/timelock';
|
||||||
|
import { getGovernanceVotingRecords } from '../utils/lookups';
|
||||||
|
|
||||||
|
export function useVotingRecords(proposal: PublicKey) {
|
||||||
|
const [votingRecords, setVotingRecords] = useState<
|
||||||
|
Record<string, ParsedAccount<GovernanceVotingRecord>>
|
||||||
|
>({});
|
||||||
|
|
||||||
|
const { endpoint } = useConnectionConfig();
|
||||||
|
const connection = useConnection();
|
||||||
|
|
||||||
|
const { timelock } = utils.programIds();
|
||||||
|
|
||||||
|
useEffect(() => {
|
||||||
|
if (!proposal) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
const sub = (async () => {
|
||||||
|
const records = await getGovernanceVotingRecords(proposal, endpoint);
|
||||||
|
setVotingRecords(records);
|
||||||
|
|
||||||
|
return connection.onProgramAccountChange(timelock.programId, info => {
|
||||||
|
if (
|
||||||
|
info.accountInfo.data.length === GovernanceVotingRecordLayout.span
|
||||||
|
) {
|
||||||
|
const votingRecord = GovernanceVotingRecordParser(
|
||||||
|
info.accountId,
|
||||||
|
info.accountInfo,
|
||||||
|
) as ParsedAccount<GovernanceVotingRecord>;
|
||||||
|
|
||||||
|
if (votingRecord.info.proposal.toBase58() !== proposal.toBase58()) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
setVotingRecords(vrs => ({
|
||||||
|
...vrs,
|
||||||
|
[votingRecord.info.owner.toBase58()]: votingRecord,
|
||||||
|
}));
|
||||||
|
}
|
||||||
|
});
|
||||||
|
})();
|
||||||
|
|
||||||
|
return () => {
|
||||||
|
sub.then(id => connection.removeProgramAccountChangeListener(id));
|
||||||
|
};
|
||||||
|
}, [proposal]);
|
||||||
|
|
||||||
|
return votingRecords;
|
||||||
|
}
|
|
@ -320,9 +320,8 @@ export const GovernanceVotingRecordParser = (
|
||||||
pubKey: PublicKey,
|
pubKey: PublicKey,
|
||||||
info: AccountInfo<Buffer>,
|
info: AccountInfo<Buffer>,
|
||||||
) => {
|
) => {
|
||||||
const buffer = Buffer.from(info.data);
|
const data = GovernanceVotingRecordLayout.decode(info.data);
|
||||||
const data = GovernanceVotingRecordLayout.decode(buffer);
|
|
||||||
console.log('Data', data);
|
|
||||||
const details = {
|
const details = {
|
||||||
pubkey: pubKey,
|
pubkey: pubKey,
|
||||||
account: {
|
account: {
|
||||||
|
|
|
@ -1,10 +1,9 @@
|
||||||
import { Card, Col, Grid, Row, Spin, Statistic, Tabs } from 'antd';
|
import { Card, Col, Grid, Row, Spin, Statistic, Tabs } from 'antd';
|
||||||
import React, { useEffect, useMemo, useState } from 'react';
|
import React, { useMemo, useState } from 'react';
|
||||||
import { LABELS } from '../../constants';
|
import { LABELS } from '../../constants';
|
||||||
import { ParsedAccount, TokenIcon } from '@oyster/common';
|
import { ParsedAccount, TokenIcon } from '@oyster/common';
|
||||||
import {
|
import {
|
||||||
ConsensusAlgorithm,
|
ConsensusAlgorithm,
|
||||||
GovernanceVotingRecord,
|
|
||||||
INSTRUCTION_LIMIT,
|
INSTRUCTION_LIMIT,
|
||||||
TimelockConfig,
|
TimelockConfig,
|
||||||
TimelockSet,
|
TimelockSet,
|
||||||
|
@ -14,7 +13,7 @@ import {
|
||||||
} from '../../models/timelock';
|
} from '../../models/timelock';
|
||||||
import { useParams } from 'react-router-dom';
|
import { useParams } from 'react-router-dom';
|
||||||
import ReactMarkdown from 'react-markdown';
|
import ReactMarkdown from 'react-markdown';
|
||||||
import { useConfig, useProposals } from '../../contexts/proposals';
|
import { useProposals } from '../../contexts/proposals';
|
||||||
import { StateBadge } from '../../components/Proposal/StateBadge';
|
import { StateBadge } from '../../components/Proposal/StateBadge';
|
||||||
import { contexts, hooks } from '@oyster/common';
|
import { contexts, hooks } from '@oyster/common';
|
||||||
import { MintInfo } from '@solana/spl-token';
|
import { MintInfo } from '@solana/spl-token';
|
||||||
|
@ -26,7 +25,7 @@ import MintSourceTokens from '../../components/Proposal/MintSourceTokens';
|
||||||
import { Vote } from '../../components/Proposal/Vote';
|
import { Vote } from '../../components/Proposal/Vote';
|
||||||
import { WithdrawVote } from '../../components/Proposal/WithdrawVote';
|
import { WithdrawVote } from '../../components/Proposal/WithdrawVote';
|
||||||
import './style.less';
|
import './style.less';
|
||||||
import { getGovernanceVotingRecords } from '../../utils/lookups';
|
import { useVotingRecords } from '../../hooks/useVotingRecords';
|
||||||
import BN from 'bn.js';
|
import BN from 'bn.js';
|
||||||
import { VoterBubbleGraph } from '../../components/Proposal/VoterBubbleGraph';
|
import { VoterBubbleGraph } from '../../components/Proposal/VoterBubbleGraph';
|
||||||
import { VoterTable } from '../../components/Proposal/VoterTable';
|
import { VoterTable } from '../../components/Proposal/VoterTable';
|
||||||
|
@ -58,12 +57,8 @@ export const ProposalView = () => {
|
||||||
const yesVotingMint = useMint(proposal?.info.yesVotingMint);
|
const yesVotingMint = useMint(proposal?.info.yesVotingMint);
|
||||||
const noVotingMint = useMint(proposal?.info.noVotingMint);
|
const noVotingMint = useMint(proposal?.info.noVotingMint);
|
||||||
|
|
||||||
const [votingDisplayData, setVotingDisplayData] = useState<any>({});
|
const votingRecords = useVotingRecords(proposal?.pubkey);
|
||||||
useEffect(() => {
|
|
||||||
getGovernanceVotingRecords(proposal?.pubkey, endpoint).then(records =>
|
|
||||||
setVotingDisplayData(voterDisplayData(records)),
|
|
||||||
);
|
|
||||||
}, [proposal]);
|
|
||||||
return (
|
return (
|
||||||
<div className="flexColumn">
|
<div className="flexColumn">
|
||||||
{proposal &&
|
{proposal &&
|
||||||
|
@ -80,7 +75,7 @@ export const ProposalView = () => {
|
||||||
votingMint={votingMint}
|
votingMint={votingMint}
|
||||||
yesVotingMint={yesVotingMint}
|
yesVotingMint={yesVotingMint}
|
||||||
noVotingMint={noVotingMint}
|
noVotingMint={noVotingMint}
|
||||||
votingDisplayData={votingDisplayData}
|
votingDisplayData={voterDisplayData(votingRecords)}
|
||||||
sigMint={sigMint}
|
sigMint={sigMint}
|
||||||
instructions={context.transactions}
|
instructions={context.transactions}
|
||||||
endpoint={endpoint}
|
endpoint={endpoint}
|
||||||
|
|
Loading…
Reference in New Issue