Skip to content

Commit

Permalink
fix(addresses): fix address structure for three chains
Browse files Browse the repository at this point in the history
  • Loading branch information
hamidroohi92 committed Nov 8, 2024
1 parent ea79003 commit 23211b4
Show file tree
Hide file tree
Showing 21 changed files with 358 additions and 61 deletions.
4 changes: 3 additions & 1 deletion components/nav/navbar.tsx
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import WalletContainer from "@/components/WalletContainer";
import { plugins } from "@/plugins";
// import { plugins } from "@/plugins";
import { AvatarIcon, IconType } from "@aragon/ods";
import classNames from "classnames";
import Image from "next/image";
Expand All @@ -8,12 +8,14 @@ import { useState } from "react";
import { MobileNavDialog } from "./mobileNavDialog";
import { NavLink, type INavLink } from "./navLink";
import { useChainId } from "wagmi";
import usePlugins from "@/hooks/usePlugins";

export const Navbar: React.FC = () => {
const [open, setOpen] = useState(false);
const chainId = useChainId();

console.log("chain id", chainId);
const plugins = usePlugins();

const navLinks: INavLink[] = [
// { path: "/", id: "dashboard", name: "Dashboard", icon: IconType.APP_DASHBOARD },
Expand Down
47 changes: 47 additions & 0 deletions hooks/ethers.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,47 @@
"use client";

import { FallbackProvider, JsonRpcProvider, BrowserProvider, JsonRpcSigner } from "ethers";
import { useMemo } from "react";
import type { Chain, Client, Transport, Account } from "viem";
import { type Config, useClient, useConnectorClient } from "wagmi";

export function clientToProvider(client: Client<Transport, Chain>) {
const { chain, transport } = client;
const network = {
chainId: chain.id,
name: chain.name,
ensAddress: chain.contracts?.ensRegistry?.address,
};
if (transport.type === "fallback") {
const providers = (transport.transports as ReturnType<Transport>[]).map(
({ value }) => new JsonRpcProvider(value?.url, network)
);
if (providers.length === 1) return providers[0];
return new FallbackProvider(providers);
}
return new JsonRpcProvider(transport.url, network);
}

/** Action to convert a viem Client to an ethers.js Provider. */
export function useEthersProvider({ chainId }: { chainId?: number } = {}) {
const client = useClient<Config>({ chainId });
return useMemo(() => (client ? clientToProvider(client) : undefined), [client]);
}

export function clientToSigner(client: Client<Transport, Chain, Account>) {
const { account, chain, transport } = client;
const network = {
chainId: chain.id,
name: chain.name,
ensAddress: chain.contracts?.ensRegistry?.address,
};
const provider = new BrowserProvider(transport, network);
const signer = new JsonRpcSigner(provider, account.address);
return signer;
}

/** Hook to convert a viem Wallet Client to an ethers.js Signer. */
export function useEthersSigner({ chainId }: { chainId?: number } = {}) {
const { data: client } = useConnectorClient<Config>({ chainId });
return useMemo(() => (client ? clientToSigner(client) : undefined), [client]);
}
80 changes: 80 additions & 0 deletions hooks/useConstant.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,80 @@
import { useEffect, useState } from "react";
import { crab, darwinia } from "viem/chains";
import { useChainId } from "wagmi";

export default function useConstant() {
const [publicDaoAddress, setPublicDaoAddress] = useState<string>("");
const [publicTokenAddress, setPublicTokenAddress] = useState<string>("");
const [publicTokenVotingPluginAddress, setPublicTokenVotingPluginAddress] = useState<string>("");
const [publicDelegationContractAddress, setPublicDelegationContractAddress] = useState<string>("");
const [publicDelegationAnnouncementsStartBlock, setPublicDelegationAnnouncementsStartBlock] = useState<string>("");

const chainId = useChainId();

useEffect(() => {
if (chainId === darwinia.id) {
console.log("switched to darwinia");
setPublicDaoAddress(process.env.NEXT_PUBLIC_DAO_ADDRESS ? process.env.NEXT_PUBLIC_DAO_ADDRESS : "");
setPublicTokenAddress(process.env.NEXT_PUBLIC_TOKEN_ADDRESS ? process.env.NEXT_PUBLIC_TOKEN_ADDRESS : "");
setPublicTokenVotingPluginAddress(
process.env.NEXT_PUBLIC_TOKEN_VOTING_PLUGIN_ADDRESS ? process.env.NEXT_PUBLIC_TOKEN_VOTING_PLUGIN_ADDRESS : ""
);
setPublicDelegationContractAddress(
process.env.NEXT_PUBLIC_DELEGATION_CONTRACT_ADDRESS ? process.env.NEXT_PUBLIC_DELEGATION_CONTRACT_ADDRESS : ""
);
setPublicDelegationAnnouncementsStartBlock(
process.env.NEXT_PUBLIC_DELEGATION_ANNOUNCEMENTS_START_BLOCK
? process.env.NEXT_PUBLIC_DELEGATION_ANNOUNCEMENTS_START_BLOCK
: ""
);
} else if (chainId === crab.id) {
console.log("switched to crab");
setPublicDaoAddress(process.env.NEXT_PUBLIC_DAO_ADDRESS_CRAD ? process.env.NEXT_PUBLIC_DAO_ADDRESS_CRAD : "");
setPublicTokenAddress(
process.env.NEXT_PUBLIC_TOKEN_ADDRESS_CRAD ? process.env.NEXT_PUBLIC_TOKEN_ADDRESS_CRAD : ""
);
setPublicTokenVotingPluginAddress(
process.env.NEXT_PUBLIC_TOKEN_VOTING_PLUGIN_ADDRESS_CRAD
? process.env.NEXT_PUBLIC_TOKEN_VOTING_PLUGIN_ADDRESS_CRAD
: ""
);
setPublicDelegationContractAddress(
process.env.NEXT_PUBLIC_DELEGATION_CONTRACT_ADDRESS_CRAD
? process.env.NEXT_PUBLIC_DELEGATION_CONTRACT_ADDRESS_CRAD
: ""
);
setPublicDelegationAnnouncementsStartBlock(
process.env.NEXT_PUBLIC_DELEGATION_ANNOUNCEMENTS_START_BLOCK_CRAD
? process.env.NEXT_PUBLIC_DELEGATION_ANNOUNCEMENTS_START_BLOCK_CRAD
: ""
);
} else if (chainId === 701) {
console.log("switched to koi");
setPublicDaoAddress(process.env.NEXT_PUBLIC_DAO_ADDRESS_KOI ? process.env.NEXT_PUBLIC_DAO_ADDRESS_KOI : "");
setPublicTokenAddress(process.env.NEXT_PUBLIC_TOKEN_ADDRESS_KOI ? process.env.NEXT_PUBLIC_TOKEN_ADDRESS_KOI : "");
setPublicTokenVotingPluginAddress(
process.env.NEXT_PUBLIC_TOKEN_VOTING_PLUGIN_ADDRESS_KOI
? process.env.NEXT_PUBLIC_TOKEN_VOTING_PLUGIN_ADDRESS_KOI
: ""
);
setPublicDelegationContractAddress(
process.env.NEXT_PUBLIC_DELEGATION_CONTRACT_ADDRESS_KOI
? process.env.NEXT_PUBLIC_DELEGATION_CONTRACT_ADDRESS_KOI
: ""
);
setPublicDelegationAnnouncementsStartBlock(
process.env.NEXT_PUBLIC_DELEGATION_ANNOUNCEMENTS_START_BLOCK_KOI
? process.env.NEXT_PUBLIC_DELEGATION_ANNOUNCEMENTS_START_BLOCK_KOI
: ""
);
}
}, [chainId]);

return {
publicDaoAddress,
publicTokenAddress,
publicTokenVotingPluginAddress,
publicDelegationContractAddress,
publicDelegationAnnouncementsStartBlock,
};
}
9 changes: 6 additions & 3 deletions hooks/usePermit.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,14 +3,17 @@ import { useReadContracts, useSignTypedData, useAccount } from "wagmi";
import { hexToSignature, Address } from "viem";
import { ERC20PermitAbi } from "@/artifacts/ERC20Permit.sol";
import { useAlerts, AlertContextProps } from "@/context/Alerts";
import { PUB_CHAIN, PUB_TOKEN_ADDRESS } from "@/constants";
import { PUB_CHAIN } from "@/constants";
import useConstant from "./useConstant";

export function usePermit() {
const { addAlert } = useAlerts() as AlertContextProps;

const { publicTokenAddress } = useConstant();

const account_address = useAccount().address!;
const erc20Contract = {
address: PUB_TOKEN_ADDRESS,
address: publicTokenAddress as Address,
abi: ERC20PermitAbi,
};
const { data: erc20data, refetch: erc20refetch } = useReadContracts({
Expand Down Expand Up @@ -70,7 +73,7 @@ export function usePermit() {
chainId: PUB_CHAIN.id,
name: erc20_name,
version: versionFromContract,
verifyingContract: PUB_TOKEN_ADDRESS,
verifyingContract: publicTokenAddress as Address,
};

const types = {
Expand Down
84 changes: 84 additions & 0 deletions hooks/usePlugins.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,84 @@
import { useEffect, useState } from "react";
import { useChainId } from "wagmi";
import { IconType } from "@aragon/ods";
import { Address } from "viem";
import { crab, darwinia } from "viem/chains";

type PluginItem = {
/** The URL fragment after /plugins */
id: string;
/** The name of the folder within `/plugins` */
folderName: string;
/** Title on menu */
title: string;
icon: IconType;
pluginAddress: string;
};

const darwiniaPlugins: PluginItem[] = [
{
id: "community-proposals",
folderName: "tokenVoting",
title: "Community proposals",
icon: IconType.BLOCKCHAIN_BLOCKCHAIN,
pluginAddress: (process.env.NEXT_PUBLIC_TOKEN_VOTING_PLUGIN_ADDRESS ?? "") as Address,
},
{
id: "delegate-wall",
folderName: "delegateAnnouncer",
title: "Delegation",
icon: IconType.FEEDBACK,
pluginAddress: (process.env.NEXT_PUBLIC_DELEGATION_CONTRACT_ADDRESS ?? "") as Address,
},
];

const carbPlugins: PluginItem[] = [
{
id: "community-proposals",
folderName: "tokenVoting",
title: "Community proposals",
icon: IconType.BLOCKCHAIN_BLOCKCHAIN,
pluginAddress: (process.env.NEXT_PUBLIC_TOKEN_VOTING_PLUGIN_ADDRESS_CRAB ?? "") as Address,
},
{
id: "delegate-wall",
folderName: "delegateAnnouncer",
title: "Delegation",
icon: IconType.FEEDBACK,
pluginAddress: (process.env.NEXT_PUBLIC_DELEGATION_CONTRACT_ADDRESS_CRAB ?? "") as Address,
},
];

const koiPlugins: PluginItem[] = [
{
id: "community-proposals",
folderName: "tokenVoting",
title: "Community proposals",
icon: IconType.BLOCKCHAIN_BLOCKCHAIN,
pluginAddress: (process.env.NEXT_PUBLIC_TOKEN_VOTING_PLUGIN_ADDRESS_KOI ?? "") as Address,
},
{
id: "delegate-wall",
folderName: "delegateAnnouncer",
title: "Delegation",
icon: IconType.FEEDBACK,
pluginAddress: (process.env.NEXT_PUBLIC_DELEGATION_CONTRACT_ADDRESS_KOI ?? "") as Address,
},
];

export default function usePlugins() {
const chainId = useChainId();
const [plugins, setPlugins] = useState<PluginItem[]>(darwiniaPlugins);

useEffect(() => {
if (chainId === darwinia.id) {
setPlugins([...darwiniaPlugins]);
} else if (chainId === crab.id) {
setPlugins([...carbPlugins]);
} else if (chainId === 701) {
setPlugins([...koiPlugins]);
}
}, [chainId]);

return plugins;
}
1 change: 1 addition & 0 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,7 @@
"classnames": "^2.5.1",
"dayjs": "^1.11.10",
"dompurify": "^3.0.11",
"ethers": "^6.13.4",
"ipfs-http-client": "51.0.0",
"next": "14.1.4",
"react": "^18.2.0",
Expand Down
5 changes: 4 additions & 1 deletion pages/plugins/[id].tsx
Original file line number Diff line number Diff line change
Expand Up @@ -3,15 +3,18 @@ import { useRouter } from "next/router";
import { PleaseWaitSpinner } from "@/components/please-wait";
import { resolveQueryParam } from "@/utils/query";
import { NotFound } from "@/components/not-found";
import { plugins } from "@/plugins";
// import { plugins } from "@/plugins";
import { logger } from "@/services/logger";
import usePlugins from "@/hooks/usePlugins";

const PluginLoader: FC = () => {
const { query } = useRouter();
const pluginId = resolveQueryParam(query.id);
const [PageComponent, setPageComponent] = useState<FC | null>(null);
const [componentLoading, setComponentLoading] = useState(true);

const plugins = usePlugins();

useEffect(() => {
if (!pluginId) return;

Expand Down
8 changes: 5 additions & 3 deletions plugins/delegateAnnouncer/components/UserDelegateCard.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ import { iVotesAbi } from "../artifacts/iVotes.sol";
import { formatHexString } from "@/utils/evm";
import { DelegateAnnouncerAbi } from "@/plugins/delegateAnnouncer/artifacts/DelegateAnnouncer.sol";
import * as DOMPurify from "dompurify";
import { PUB_DAO_ADDRESS, PUB_DELEGATION_CONTRACT_ADDRESS } from "@/constants";
import useConstant from "@/hooks/useConstant";

type SelfDelegationProfileCardProps = {
address: Address;
Expand Down Expand Up @@ -56,12 +56,14 @@ export const SelfDelegationProfileCard = ({
});
};

const { publicDaoAddress, publicDelegationContractAddress } = useConstant();

const announceDelegate = () => {
delegateAnnouncementWrite({
abi: DelegateAnnouncerAbi,
address: PUB_DELEGATION_CONTRACT_ADDRESS,
address: publicDelegationContractAddress as Address,
functionName: "announceDelegation",
args: [PUB_DAO_ADDRESS, toHex(inputDescription!)],
args: [publicDaoAddress as Address, toHex(inputDescription!)],
});
};

Expand Down
5 changes: 3 additions & 2 deletions plugins/delegateAnnouncer/hooks/useDelegateAnnouncements.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -2,13 +2,14 @@ import { useEffect, useState } from "react";
import { DelegateAnnouncerAbi } from "@/plugins/delegateAnnouncer/artifacts/DelegateAnnouncer.sol";
import { Address, PublicClient, getAbiItem, fromHex } from "viem";
import { DelegateAnnounce } from "../utils/types";
import { PUB_DELEGATION_ANNOUNCEMENTS_START_BLOCK } from "@/constants";
import useConstant from "@/hooks/useConstant";

const AnnounceDelegationEvent = getAbiItem({ abi: DelegateAnnouncerAbi, name: "AnnounceDelegation" });

export function useDelegateAnnouncements(publicClient: PublicClient, delegationContract: Address, daoAddress: Address) {
const [delegateAnnouncements, setDelegateAnnouncements] = useState<DelegateAnnounce[]>([]);
const [isLoading, setIsLoading] = useState<boolean>(true);
const { publicDelegationAnnouncementsStartBlock } = useConstant();

useEffect(() => {
setIsLoading(true);
Expand All @@ -19,7 +20,7 @@ export function useDelegateAnnouncements(publicClient: PublicClient, delegationC
args: {
dao: daoAddress,
} as any,
fromBlock: PUB_DELEGATION_ANNOUNCEMENTS_START_BLOCK,
fromBlock: BigInt(publicDelegationAnnouncementsStartBlock),
toBlock: "latest",
})
.then((logs) => {
Expand Down
17 changes: 9 additions & 8 deletions plugins/delegateAnnouncer/pages/index.tsx
Original file line number Diff line number Diff line change
@@ -1,27 +1,28 @@
import { usePublicClient, useReadContract } from "wagmi";
import { useAccount } from "wagmi";
import { PublicClient, parseAbi } from "viem";
import { ReactNode } from "react";
import { Address, PublicClient, parseAbi } from "viem";
import { ReactNode, useState } from "react";
import { Else, ElseIf, If, Then } from "@/components/if";
import { PleaseWaitSpinner } from "@/components/please-wait";
import { useDelegateAnnouncements } from "../hooks/useDelegateAnnouncements";
import { DelegateCard } from "@/plugins/delegateAnnouncer/components/DelegateCard";
import { SelfDelegationProfileCard } from "../components/UserDelegateCard";
import { PUB_DAO_ADDRESS, PUB_DELEGATION_CONTRACT_ADDRESS, PUB_TOKEN_ADDRESS } from "@/constants";
import useConstant from "@/hooks/useConstant";

export default function DelegateAnnouncements() {
const publicClient = usePublicClient();
const account = useAccount();
const { publicDaoAddress, publicDelegationContractAddress, publicTokenAddress } = useConstant();
const { data: delegates, status } = useReadContract({
abi: iVotesAbi,
address: PUB_TOKEN_ADDRESS,
address: publicTokenAddress as Address,
functionName: "delegates",
args: [account.address!],
});
const { delegateAnnouncements, isLoading: delegateAnnouncementsIsLoading } = useDelegateAnnouncements(
publicClient as PublicClient,
PUB_DELEGATION_CONTRACT_ADDRESS,
PUB_DAO_ADDRESS
publicDelegationContractAddress as Address,
publicDaoAddress as Address
);

return (
Expand All @@ -31,7 +32,7 @@ export default function DelegateAnnouncements() {
<h2 className="pb-3 text-xl font-semibold text-[#fff]">Your profile</h2>
<SelfDelegationProfileCard
address={account.address!}
tokenAddress={PUB_TOKEN_ADDRESS}
tokenAddress={publicTokenAddress as Address}
delegates={delegates!}
loading={status === "pending"}
message={delegateAnnouncements.findLast((an) => an.delegate === account.address)?.message}
Expand All @@ -49,7 +50,7 @@ export default function DelegateAnnouncements() {
delegates={delegates!}
delegate={announcement.delegate}
message={announcement.message}
tokenAddress={PUB_TOKEN_ADDRESS}
tokenAddress={publicTokenAddress as Address}
/>
))}
</div>
Expand Down
Loading

0 comments on commit 23211b4

Please sign in to comment.