Skip to content

Commit

Permalink
Merge pull request #131 from Agoric/rs-fraz-ec-changes
Browse files Browse the repository at this point in the history
handle multiple econgov invitations due to ec changes
  • Loading branch information
frazarshad authored Oct 3, 2024
2 parents 6f09752 + d3360c2 commit ac03280
Show file tree
Hide file tree
Showing 6 changed files with 313 additions and 10 deletions.
4 changes: 3 additions & 1 deletion src/components/PsmPanel.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ import ProposeParamChange from './ProposeParamChange';
import ProposePauseOffers from './ProposePauseOffers';
import CharterGuidance from './CharterGuidance';
import { useAtomValue } from 'jotai';
import { walletUtilsAtom } from 'store/app';
import { rpcUtilsAtom, walletUtilsAtom } from 'store/app';

// TODO fetch list from RPC
const anchors = [
Expand Down Expand Up @@ -44,6 +44,7 @@ export default function PsmPanel() {
const [anchorName, setAnchorName] = useState(anchors[0]);
const [proposalType, setProposalType] = useState(ProposalTypes.paramChange);
const walletUtils = useAtomValue(walletUtilsAtom);
const rpcUtils = useAtomValue(rpcUtilsAtom);
const { data: walletCurrent, status } = usePublishedDatum(
walletUtils
? `wallet.${walletUtils.getWalletAddress()}.current`
Expand All @@ -54,6 +55,7 @@ export default function PsmPanel() {
status,
walletCurrent,
charterInvitationSpec.description,
rpcUtils?.agoricNames.instance.econCommitteeCharter,
);

const previousOfferId = invitationStatus.acceptedIn;
Expand Down
4 changes: 3 additions & 1 deletion src/components/VaultsPanel.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ import ChangeOracles, { ChangeOraclesMode } from './ChangeOracles';
import PauseLiquidations from './PauseLiquidations';
import AuctioneerParamChange from './AuctioneerParamChange';
import { useAtomValue } from 'jotai';
import { walletUtilsAtom } from 'store/app';
import { walletUtilsAtom, rpcUtilsAtom } from 'store/app';

const ProposalTypes = {
addOracles: 'Add Oracle Operators',
Expand All @@ -36,6 +36,7 @@ export default function VaultsPanel() {
ProposalTypes.managerParamChange,
);
const walletUtils = useAtomValue(walletUtilsAtom);
const rpcUtils = useAtomValue(rpcUtilsAtom);
const filterProposals = networkProposalFilter(walletUtils);

const { data: walletCurrent, status } = usePublishedDatum(
Expand All @@ -48,6 +49,7 @@ export default function VaultsPanel() {
status,
walletCurrent,
charterInvitationSpec.description,
rpcUtils?.agoricNames.instance.econCommitteeCharter,
);
const charterOfferId = charterInvitationStatus.acceptedIn;

Expand Down
11 changes: 8 additions & 3 deletions src/components/VotePanel.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ import { timestampPassed } from 'utils/helpers';
import AcceptInvitation from './AcceptInvitation';
import { OfferId, VoteOnQuestion } from './questions';
import { useAtomValue } from 'jotai';
import { walletUtilsAtom } from 'store/app';
import { rpcUtilsAtom, walletUtilsAtom } from 'store/app';

interface Props {}

Expand Down Expand Up @@ -90,6 +90,7 @@ function VoteOnQuestions(props: {

export default function VotePanel(_props: Props) {
const walletUtils = useAtomValue(walletUtilsAtom);
const rpcUtils = useAtomValue(rpcUtilsAtom);
const { data, status } = usePublishedDatum(
walletUtils
? `wallet.${walletUtils.getWalletAddress()}.current`
Expand All @@ -98,8 +99,12 @@ export default function VotePanel(_props: Props) {
const { status: instanceStatus, data: instance } = usePublishedDatum(
'agoricNames.instance',
);

const invitationStatus = inferInvitationStatus(status, data, 'Voter');
const invitationStatus = inferInvitationStatus(
status,
data,
'Voter',
rpcUtils?.agoricNames.instance.economicCommittee,
);
const previousOfferId = invitationStatus.acceptedIn;

return (
Expand Down
288 changes: 288 additions & 0 deletions src/lib/wallet.test.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,288 @@
import '../../src/installSesLockdown';
import { test, expect, describe, vi } from 'vitest';

vi.stubGlobal('window', {
location: { search: '' },
alert: vi.fn(),
keplr: {
experimentalSuggestChain: vi.fn(),
enable: vi.fn(),
getKey: () => ({ isNanoLedger: true }),
getOfflineSignerOnlyAmino: () => ({
getAccounts: () => [{ address: 1 }],
}),
},
});

import { inferInvitationStatus } from './wallet';
import { LoadStatus } from './rpc';

const createMockWallet = ({
usedCharterInviations = 0,
charterInvitations = 0,
usedCommitteeInvitations = 0,
committeeInvitations = 0,
}) => ({
brands: [],
liveOffers: [],
offerToPublicSubscriberPaths: [],
offerToUsedInvitation: [
...[...Array(usedCharterInviations)].map((_, idx) => [
`econgov-${1_000_000 + idx}`,
{
brand: 'Zoe Invitation Brand',
value: [
{
description: 'charter member invitation',
handle: null,
installation: null,
instance: `instance${idx}`,
},
],
},
]),
...[...Array(usedCommitteeInvitations)].map((_, idx) => [
`econgov-${2_000_000 + idx}`,
{
brand: 'Zoe Invitation Brand',
value: [
{
description: 'Voter0',
handle: null,
installation: null,
instance: `instance${idx}`,
},
],
},
]),
],
purses: [
{
balance: {
brand: 'Zoe Invitation Brand',
value: [
...[...Array(charterInvitations)].map((_, idx) => ({
description: 'charter member invitation',
handle: null,
installation: null,
instance: `instance${idx}`,
})),
...[...Array(committeeInvitations)].map((_, idx) => ({
description: 'Voter0',
handle: null,
installation: null,
instance: `instance${idx}`,
})),
],
},
brand: 'Zoe Invitation Brand',
},
],
});

describe('inferInvitationStatus', () => {
test('should find one accepted charter and committee invitation', () => {
const mockWallet = createMockWallet({
usedCharterInviations: 1,
usedCommitteeInvitations: 1,
});

const charterInvitationStatus = inferInvitationStatus(
LoadStatus.Received,
mockWallet,
'charter member invitation',
'instance0',
);

const voterInvitationStatus = inferInvitationStatus(
LoadStatus.Received,
mockWallet,
'Voter',
'instance0',
);

expect(charterInvitationStatus).toStrictEqual({
acceptedIn: 'econgov-1000000',
status: 'accepted',
});

expect(voterInvitationStatus).toStrictEqual({
acceptedIn: 'econgov-2000000',
status: 'accepted',
});
});

test('should not find any accepted charter and committee invitation', () => {
const mockWallet = createMockWallet({});

const charterInvitationStatus = inferInvitationStatus(
LoadStatus.Received,
mockWallet,
'charter member invitation',
'instance0',
);

const voterInvitationStatus = inferInvitationStatus(
LoadStatus.Received,
mockWallet,
'Voter',
'instance0',
);

expect(charterInvitationStatus).toStrictEqual({
status: 'missing',
});

expect(voterInvitationStatus).toStrictEqual({
status: 'missing',
});
});

test('should find unused charter and committee invitation', () => {
const mockWallet = createMockWallet({
charterInvitations: 1,
committeeInvitations: 1,
});

const charterInvitationStatus = inferInvitationStatus(
LoadStatus.Received,
mockWallet,
'charter member invitation',
'instance0',
);

const voterInvitationStatus = inferInvitationStatus(
LoadStatus.Received,
mockWallet,
'Voter',
'instance0',
);

expect(charterInvitationStatus).toStrictEqual({
invitation: {
description: 'charter member invitation',
handle: null,
installation: null,
instance: 'instance0',
},
status: 'available',
});

expect(voterInvitationStatus).toStrictEqual({
invitation: {
description: 'Voter0',
handle: null,
installation: null,
instance: 'instance0',
},
status: 'available',
});
});

test('should find new unused invitations before old used ones', () => {
const mockWallet = createMockWallet({
charterInvitations: 2,
committeeInvitations: 2,
usedCharterInviations: 1,
usedCommitteeInvitations: 1,
});

const charterInvitationStatus = inferInvitationStatus(
LoadStatus.Received,
mockWallet,
'charter member invitation',
'instance1',
);

const voterInvitationStatus = inferInvitationStatus(
LoadStatus.Received,
mockWallet,
'Voter',
'instance1',
);

expect(charterInvitationStatus).toStrictEqual({
invitation: {
description: 'charter member invitation',
handle: null,
installation: null,
instance: 'instance1',
},
status: 'available',
});

expect(voterInvitationStatus).toStrictEqual({
invitation: {
description: 'Voter0',
handle: null,
installation: null,
instance: 'instance1',
},
status: 'available',
});
});

test('should find newer used charter and committee invitation before old ones', () => {
const mockWallet = createMockWallet({
usedCharterInviations: 2,
usedCommitteeInvitations: 2,
});

const charterInvitationStatus = inferInvitationStatus(
LoadStatus.Received,
mockWallet,
'charter member invitation',
'instance1',
);

const voterInvitationStatus = inferInvitationStatus(
LoadStatus.Received,
mockWallet,
'Voter',
'instance1',
);

// newer invitations will have the last digit as 1
expect(charterInvitationStatus).toStrictEqual({
acceptedIn: 'econgov-1000001',
status: 'accepted',
});

expect(voterInvitationStatus).toStrictEqual({
acceptedIn: 'econgov-2000001',
status: 'accepted',
});
});

test('should not find old charter and committee invitation (used or unused) when new instance is available', () => {
const mockWallet = createMockWallet({
charterInvitations: 1,
committeeInvitations: 1,
usedCharterInviations: 1,
usedCommitteeInvitations: 1,
});

const charterInvitationStatus = inferInvitationStatus(
LoadStatus.Received,
mockWallet,
'charter member invitation',
'instance1',
);

const voterInvitationStatus = inferInvitationStatus(
LoadStatus.Received,
mockWallet,
'Voter',
'instance1',
);

// newer invitations will have the last digit as 1
expect(charterInvitationStatus).toStrictEqual({
status: 'missing',
});

expect(voterInvitationStatus).toStrictEqual({
status: 'missing',
});
});
});
Loading

0 comments on commit ac03280

Please sign in to comment.