Skip to content

Commit

Permalink
wip
Browse files Browse the repository at this point in the history
  • Loading branch information
carina-akaia committed Nov 28, 2024
1 parent a302f32 commit f6f0cbd
Show file tree
Hide file tree
Showing 13 changed files with 271 additions and 97 deletions.
3 changes: 3 additions & 0 deletions src/common/constants.ts
Original file line number Diff line number Diff line change
Expand Up @@ -46,6 +46,9 @@ export const APP_METADATA: Metadata & {
export const NATIVE_TOKEN_ID = "near";
export const NATIVE_TOKEN_DECIMALS = 24;

export const MPDAO_TOKEN_CONTRACT_ACCOUNT_ID =
NETWORK === "mainnet" ? "mpdao-token.near" : "mpdao-token.testnet";

// List ID of PotLock Public Goods Registry
export const PUBLIC_GOODS_REGISTRY_LIST_ID = 1;

Expand Down
1 change: 1 addition & 0 deletions src/common/contracts/metapool/index.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
export * from "./vote";
1 change: 1 addition & 0 deletions src/common/contracts/metapool/vote/index.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
export * from "./interface";
23 changes: 23 additions & 0 deletions src/common/contracts/metapool/vote/interface.d.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
export type MpDaoVoter = {
voter_id: string;
balance_in_contract: string;

locking_positions: {
index: number;
amount: string;
locking_period: number;
voting_power: string;
unlocking_started_at: number | null;
is_unlocked: boolean;
is_unlocking: boolean;
is_locked: boolean;
}[];

voting_power: string;

vote_positions: {
votable_address: string;
votable_object_id: string;
voting_power: string;
}[];
};
4 changes: 4 additions & 0 deletions src/common/services/ft/constants.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
import { MPDAO_TOKEN_CONTRACT_ACCOUNT_ID } from "@/common/constants";
import { AccountId } from "@/common/types";

export const MANUALLY_LISTED_ACCOUNT_IDS: AccountId[] = [MPDAO_TOKEN_CONTRACT_ACCOUNT_ID];
66 changes: 35 additions & 31 deletions src/common/services/ft/models.ts
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,8 @@ import { refExchangeClient } from "@/common/contracts/ref-finance";
import { bigStringToFloat } from "@/common/lib";
import { AccountId, FungibleTokenMetadata, TokenId } from "@/common/types";

import { MANUALLY_LISTED_ACCOUNT_IDS } from "./constants";

export type FtRegistryEntry = {
contract_account_id: TokenId;
metadata: FungibleTokenMetadata;
Expand Down Expand Up @@ -74,38 +76,40 @@ export const useFtRegistryStore = create<FtRegistryStore>()(
] as [TokenId, FtRegistryEntry],
),

...tokenContractAccountIds.map(async (contract_account_id) => {
const ftClient = naxiosInstance.contractApi({
contractId: contract_account_id,
cache: new MemoryCache({ expirationTime: 600 }),
});

const metadata = await ftClient
.view<{}, FungibleTokenMetadata>("ft_metadata")
.catch(() => undefined);

const balance = await ftClient
.view<{ account_id: AccountId }, string>("ft_balance_of", {
args: { account_id: walletApi.accountId ?? "unknown" },
})
.catch(() => undefined);

return metadata === undefined
? null
: ([
contract_account_id,
{
...MANUALLY_LISTED_ACCOUNT_IDS.concat(tokenContractAccountIds).map(
async (contract_account_id) => {
const ftClient = naxiosInstance.contractApi({
contractId: contract_account_id,
cache: new MemoryCache({ expirationTime: 600 }),
});

const metadata = await ftClient
.view<{}, FungibleTokenMetadata>("ft_metadata")
.catch(() => undefined);

const balance = await ftClient
.view<{ account_id: AccountId }, string>("ft_balance_of", {
args: { account_id: walletApi.accountId ?? "unknown" },
})
.catch(() => undefined);

return metadata === undefined
? null
: ([
contract_account_id,
metadata,
balance,

balanceFloat:
balance === undefined
? balance
: bigStringToFloat(balance, metadata.decimals),
},
] as [TokenId, FtRegistryEntry]);
}),
{
contract_account_id,
metadata,
balance,

balanceFloat:
balance === undefined
? balance
: bigStringToFloat(balance, metadata.decimals),
},
] as [TokenId, FtRegistryEntry]);
},
),
]).then(
piped(
filter(isNonNull),
Expand Down
60 changes: 35 additions & 25 deletions src/common/ui/components/molecules/checklist.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -11,11 +11,17 @@ import { cn } from "../../utils";

export type ChecklistProps = {
title: string;
breakdown: BasicRequirement[];
requirements: BasicRequirement[];
isFinalized?: boolean;
error?: Error;
};

export const Checklist: React.FC<ChecklistProps> = ({ title, breakdown, isFinalized = true }) => (
export const Checklist: React.FC<ChecklistProps> = ({
title,
requirements,
isFinalized = true,
error,
}) => (
<div
className={cn(
"xl:w-126.5 min-w-87.5 lg:w-fit flex h-fit w-full flex-col items-start justify-start",
Expand All @@ -34,29 +40,33 @@ export const Checklist: React.FC<ChecklistProps> = ({ title, breakdown, isFinali
</span>
</div>

<div
className={cn(
"flex h-fit flex-col items-start justify-start gap-4 self-stretch",
"rounded-lg bg-white p-4 shadow",
)}
>
{breakdown.map(({ title, isSatisfied }) => (
<div className="inline-flex items-center justify-start gap-2 self-stretch" key={title}>
{isSatisfied ? (
<MdCheckCircleOutline className="color-success relative h-6 w-6" />
) : (
<>
{isFinalized ? (
<MdOutlineCircle className="color-gray h-6 w-6" />
) : (
<MdOutlinePending className="h-6 w-6" />
)}
</>
)}
{error ? (
<span className="text-destructive text-xl">{error.message}</span>
) : (
<ul
className={cn(
"flex h-fit flex-col items-start justify-start gap-4 self-stretch",
"rounded-lg bg-white p-4 shadow",
)}
>
{requirements.map(({ title, isSatisfied }) => (
<li className="inline-flex items-center justify-start gap-2 self-stretch" key={title}>
{isSatisfied ? (
<MdCheckCircleOutline className="color-success relative h-6 w-6" />
) : (
<>
{isFinalized ? (
<MdOutlineCircle className="color-gray h-6 w-6" />
) : (
<MdOutlinePending className="h-6 w-6" />
)}
</>
)}

<span className="text-sm font-normal leading-tight text-neutral-600">{title}</span>
</div>
))}
</div>
<span className="text-sm font-normal leading-tight text-neutral-600">{title}</span>
</li>
))}
</ul>
)}
</div>
);
1 change: 1 addition & 0 deletions src/modules/access-control/index.ts
Original file line number Diff line number Diff line change
@@ -1 +1,2 @@
export * from "./components/AccessControlList";
export * from "./types";
5 changes: 5 additions & 0 deletions src/modules/access-control/types.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
import { BasicRequirement } from "@/common/types";

export type AccessControlClearanceCheckResult =
| { requirements: BasicRequirement[]; isEveryRequirementSatisfied: boolean; error: null }
| { requirements: null; isEveryRequirementSatisfied: false; error: Error };
26 changes: 17 additions & 9 deletions src/modules/pot/components/PotHero.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -21,22 +21,20 @@ import NewApplicationModal from "./NewApplicationModal";
import { PotStats } from "./PotStats";
import { PotTimeline } from "./PotTimeline";
import {
usePotUserApplicationRequirements,
usePotUserApplicationClearance,
usePotUserPermissions,
usePotUserVotingRequirements,
usePotUserVotingClearance,
} from "../hooks/clearance";
import { isPotVotingBased } from "../utils/voting";

export type PotHeroProps = ByPotId & {};

export const PotHero: React.FC<PotHeroProps> = ({ potId }) => {
const router = useRouter();
const isOnVotingPage = router.pathname.includes("votes");
const { data: pot } = indexer.usePot({ potId });
const isVotingBasedPot = isPotVotingBased({ potId });
const { isSignedIn, accountId } = useAuthSession();
const applicationClearanceBreakdown = usePotUserApplicationRequirements();
const votingClearanceBreakdown = usePotUserVotingRequirements();
const applicationClearance = usePotUserApplicationClearance({ potId });
const votingClearance = usePotUserVotingClearance({ potId });

const { canApply, canDonate, canFund, canChallengePayouts, existingChallengeForUser } =
usePotUserPermissions({ potId });
Expand All @@ -62,6 +60,13 @@ export const PotHero: React.FC<PotHeroProps> = ({ potId }) => {
} else return [pot?.description ?? null, null];
}, [pot?.description]);

// TODO: Implement proper voting stage check
const isVotingStage = useMemo(() => {
if (!pot) return false;
// Add proper voting stage logic here
return false;
}, [pot]);

return (
<>
{pot && (
Expand Down Expand Up @@ -156,12 +161,15 @@ export const PotHero: React.FC<PotHeroProps> = ({ potId }) => {
<div className="lg:w-a flex w-full flex-col gap-6">
{isVotingBasedPot ? (
<>
{isOnVotingPage ? (
<Checklist title="Voting Requirements" breakdown={votingClearanceBreakdown} />
{isVotingStage ? (
<Checklist
title="Voting Requirements"
requirements={votingClearance.requirements ?? []}
/>
) : (
<Checklist
title="Application Requirements"
breakdown={applicationClearanceBreakdown}
requirements={applicationClearance.requirements ?? []}
/>
)}
</>
Expand Down
Loading

0 comments on commit f6f0cbd

Please sign in to comment.