Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

chore: remove ipfs dependencies #167

Open
wants to merge 1 commit into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
33 changes: 27 additions & 6 deletions components/groups/components/myGroups.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -54,9 +54,16 @@ export function YourGroups({
const router = useRouter();
const { address } = useChain('manifest');

const filteredGroups = groups.groups.filter(group =>
(group.ipfsMetadata?.title || 'Untitled Group').toLowerCase().includes(searchTerm.toLowerCase())
);
const filteredGroups = groups.groups.filter(group => {
try {
const metadata = group.metadata ? JSON.parse(group.metadata) : null;
const groupTitle = metadata?.title || 'Untitled Group';
return groupTitle.toLowerCase().includes(searchTerm.toLowerCase());
} catch (e) {
console.warn('Failed to parse group metadata:', e);
return 'Untitled Group'.toLowerCase().includes(searchTerm.toLowerCase());
}
});

const totalPages = Math.ceil(filteredGroups.length / pageSize);
const paginatedGroups = filteredGroups.slice(
Expand All @@ -72,9 +79,18 @@ export function YourGroups({
g => g.policies && g.policies.length > 0 && g.policies[0]?.address === policyAddress
);
if (group) {
let groupName = 'Untitled Group';
try {
const metadata = group.metadata ? JSON.parse(group.metadata) : null;
groupName = metadata?.title ?? 'Untitled Group';
} catch (e) {
// If JSON parsing fails, fall back to default name
console.warn('Failed to parse group metadata:', e);
}

setSelectedGroup({
policyAddress,
name: group.ipfsMetadata?.title ?? 'Untitled Group',
name: groupName,
threshold:
(group.policies[0]?.decision_policy as ThresholdDecisionPolicySDKType)?.threshold ??
'0',
Expand Down Expand Up @@ -451,8 +467,13 @@ function GroupRow({
setActiveInfoModalId: (id: string | null) => void;
}) {
const policyAddress = (group.policies && group.policies[0]?.address) || '';
const groupName = group.ipfsMetadata?.title || 'Untitled Group';

let groupName = 'Untitled Group';
try {
const metadata = group.metadata ? JSON.parse(group.metadata) : null;
groupName = metadata?.title || 'Untitled Group';
} catch (e) {
console.warn('Failed to parse group metadata:', e);
}
const filterActiveProposals = (proposals: ProposalSDKType[]) => {
return proposals?.filter(
proposal =>
Expand Down
10 changes: 1 addition & 9 deletions components/groups/forms/groups/ConfirmationForm.tsx
Original file line number Diff line number Diff line change
@@ -1,8 +1,6 @@
import { useEffect, useState } from 'react';
import { TruncatedAddressWithCopy } from '@/components/react/addressCopy';
import { FormData } from '@/helpers/formReducer';
import { useFeeEstimation } from '@/hooks/useFeeEstimation';
import { uploadJsonToIPFS } from '@/hooks/useIpfs';
import { useTx } from '@/hooks/useTx';
import { cosmos } from '@liftedinit/manifestjs';
import { ThresholdDecisionPolicy } from '@liftedinit/manifestjs/dist/codegen/cosmos/group/v1/types';
Expand Down Expand Up @@ -35,11 +33,6 @@ export default function ConfirmationForm({
const { tx, isSigning, setIsSigning } = useTx('manifest');
const { estimateFee } = useFeeEstimation('manifest');

const uploadMetaDataToIPFS = async () => {
const CID = await uploadJsonToIPFS(jsonString);
return CID;
};

const minExecutionPeriod: Duration = {
seconds: BigInt(0),
nanos: 0,
Expand All @@ -62,7 +55,6 @@ export default function ConfirmationForm({
const handleConfirm = async () => {
setIsSigning(true);
try {
const CID = await uploadMetaDataToIPFS();
const msg = createGroupWithPolicy({
admin: address ?? '',
members: formData.members.map(member => ({
Expand All @@ -71,7 +63,7 @@ export default function ConfirmationForm({
metadata: member.name,
added_at: new Date(),
})),
groupMetadata: CID,
groupMetadata: jsonString,
groupPolicyMetadata: '',
groupPolicyAsAdmin: true,
decisionPolicy: {
Expand Down
1 change: 1 addition & 0 deletions components/groups/forms/groups/MemberInfoForm.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -247,6 +247,7 @@ export default function MemberInfoForm({
isOpen={isContactsOpen}
setOpen={setIsContactsOpen}
showContacts={true}
currentAddress={address}
onSelect={(selectedAddress: string) => {
if (activeMemberIndex !== null) {
setFieldValue(`members.${activeMemberIndex}.address`, selectedAddress);
Expand Down
54 changes: 32 additions & 22 deletions components/groups/modals/groupDetailsModal.tsx
Original file line number Diff line number Diff line change
@@ -1,15 +1,17 @@
import { TruncatedAddressWithCopy } from '@/components/react/addressCopy';
import { IPFSMetadata } from '@/hooks/useQueries';
import ProfileAvatar from '@/utils/identicon';
import {
GroupMemberSDKType,
GroupPolicyInfoSDKType,
ThresholdDecisionPolicySDKType,
} from '@liftedinit/manifestjs/dist/codegen/cosmos/group/v1/types';
import { PiXCircleLight } from 'react-icons/pi';

interface Group {
group: {
admin: string;
metadata: string;
ipfsMetadata: IPFSMetadata | null;
members: any[];
policies: any[];
members: GroupMemberSDKType[];
policies: GroupPolicyInfoSDKType[];
};
}

Expand All @@ -24,6 +26,13 @@ export function GroupDetailsModal({ group, modalId }: Group & { modalId: string
return adminAddresses.includes(address);
};

const metadata = group.metadata ? JSON.parse(group.metadata) : null;

Comment on lines +29 to +30
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🛠️ Refactor suggestion

Guard JSON Parsing with Try-Catch
Consider enclosing JSON.parse in a try-catch to gracefully handle malformed metadata.

const authors = metadata?.authors || 'No authors available';
const summary = metadata?.summary || 'No summary available';
const details = metadata?.details || 'No details available';
const proposalForumURL = metadata?.proposalForumURL || 'No forum URL available';

return (
<dialog id={modalId} className="modal">
<div className="modal-box absolute max-w-4xl mx-auto rounded-lg md:ml-20 shadow-lg">
Expand All @@ -37,29 +46,25 @@ export function GroupDetailsModal({ group, modalId }: Group & { modalId: string
<div>
<p className="text-sm font-light mt-4 ">AUTHORS</p>
<div className="bg-base-200 shadow rounded-lg p-4 mt-2 mb-2">
<p className="text-md ">{group?.ipfsMetadata?.authors ?? 'No authors available'}</p>
<p className="text-md ">{authors}</p>
</div>
</div>
<div>
<p className="text-sm font-light mt-4 ">SUMMARY</p>
<div className="bg-base-200 shadow rounded-lg p-4 mt-2 mb-2">
<p className="text-md ">{group?.ipfsMetadata?.summary ?? 'No summary available'}</p>
<p className="text-md ">{summary}</p>
</div>
</div>
<div>
<p className="text-sm font-light mt-4 ">DETAILS</p>
<div className="bg-base-200 shadow rounded-lg p-4 mt-2 mb-2 max-h-[9.53rem] overflow-y-auto">
<p className="text-md text-wrap ">
{group?.ipfsMetadata?.details ?? 'No details available'}
</p>
<p className="text-md text-wrap ">{details}</p>
</div>
</div>
<div>
<p className="text-sm font-light mt-4 ">FORUM</p>
<div className="bg-base-200 shadow rounded-lg p-4 mt-2 mb-2">
<p className="text-md ">
{group?.ipfsMetadata?.proposalForumURL ?? 'No forum URL available'}
</p>
<p className="text-md ">{proposalForumURL}</p>
</div>
</div>
</div>
Expand All @@ -82,10 +87,14 @@ export function GroupDetailsModal({ group, modalId }: Group & { modalId: string
<p className="text-sm font-light mt-4 ">VOTING WINDOW</p>
<div className="bg-base-200 shadow rounded-lg p-4 mt-2 mb-2">
<p className="text-md ">
{policy?.decision_policy?.windows?.voting_period
{(policy?.decision_policy as ThresholdDecisionPolicySDKType)?.windows
?.voting_period
? Math.floor(
parseInt(policy.decision_policy.windows.voting_period.slice(0, -1)) /
86400
parseInt(
(
policy?.decision_policy as ThresholdDecisionPolicySDKType
)?.windows?.voting_period.seconds.toString() ?? '0'
) / 86400
)
: 'No voting period available'}{' '}
days
Expand All @@ -96,8 +105,9 @@ export function GroupDetailsModal({ group, modalId }: Group & { modalId: string
<p className="text-sm font-light mt-4 ">THRESHOLD</p>
<div className="bg-base-200 shadow rounded-lg p-4 mt-2 mb-2">
<p className="text-md ">
{policy?.decision_policy?.threshold ?? 'No threshold available'} /
{group?.members.length ?? 'No members available'}
{(policy?.decision_policy as ThresholdDecisionPolicySDKType)?.threshold ??
'No threshold available'}{' '}
/ {group?.members.length ?? 'No members available'}
</p>
</div>
</div>
Expand Down Expand Up @@ -152,12 +162,12 @@ export function GroupDetailsModal({ group, modalId }: Group & { modalId: string
/>
</td>
<td>
{isPolicyAdmin(member?.member?.address) &&
isAdmin(member?.member?.address) ? (
{isPolicyAdmin(member?.member?.address ?? '') &&
isAdmin(member?.member?.address ?? '') ? (
'Super Admin'
) : isPolicyAdmin(member?.member?.address) ? (
) : isPolicyAdmin(member?.member?.address ?? '') ? (
'Policy'
) : isAdmin(member?.member?.address) ? (
) : isAdmin(member?.member?.address ?? '') ? (
'Group'
) : (
<PiXCircleLight className="text-red-500 h-5 w-5" />
Expand Down
77 changes: 49 additions & 28 deletions components/groups/modals/groupInfo.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -84,39 +84,53 @@ export function GroupInfo({
'No threshold available';

function renderAuthors() {
const authors = group?.ipfsMetadata?.authors;
let metadata = null;
let authors: string | string[] = 'No authors available';

try {
metadata = group?.metadata ? JSON.parse(group.metadata) : null;
authors = metadata?.authors || 'No authors available';
} catch (e) {
console.warn('Failed to parse group metadata for authors:', e);
}

if (!authors) {
return <InfoItem label="Author" value="No author information" />;
}

const formatAddress = (author: string, index: number) => (
<InfoItem key={index} label="Address" value={author} isAddress={true} />
);
try {
const formatAddress = (author: string, index: number) => (
<InfoItem key={index} label="Address" value={author} isAddress={true} />
);

const formatAuthor = (author: string, index: number) => (
<InfoItem key={index} label={`Author ${index + 1}`} value={author} />
);
const formatAuthor = (author: string, index: number) => (
<InfoItem key={index} label={`Author ${index + 1}`} value={author} />
);

if (typeof authors === 'string') {
if (authors.startsWith('manifest1')) {
return <div className="grid grid-cols-2 gap-4">{formatAddress(authors, 0)}</div>;
if (typeof authors === 'string') {
if (authors.startsWith('manifest1')) {
return <div className="grid grid-cols-2 gap-4">{formatAddress(authors, 0)}</div>;
}
return formatAuthor(authors, 0);
}
return formatAuthor(authors, 0);
}

if (Array.isArray(authors)) {
const manifestAddresses = authors.filter(author => author.startsWith('manifest1'));

if (manifestAddresses.length > 0) {
return (
<div className="grid grid-cols-2 gap-4">
{manifestAddresses.map((author, index) => formatAddress(author, index))}
</div>
if (Array.isArray(authors)) {
const manifestAddresses = authors.filter(
(author): author is string => typeof author === 'string' && author.startsWith('manifest1')
);
}

return <div>{authors.map((author, index) => formatAuthor(author, index))}</div>;
if (manifestAddresses.length > 0) {
return (
<div className="grid grid-cols-2 gap-4">
{manifestAddresses.map((author, index) => formatAddress(author, index))}
</div>
);
}

return <div>{authors.map((author, index) => formatAuthor(String(author), index))}</div>;
}
} catch (e) {
console.warn('Failed to process authors data:', e);
}

return <InfoItem label="Author" value="Invalid author information" />;
Expand Down Expand Up @@ -147,6 +161,17 @@ export function GroupInfo({
}
};

let title = 'Untitled Group';
let details = 'No description';

try {
const metadata = group.metadata ? JSON.parse(group.metadata) : null;
title = metadata?.title || 'Untitled Group';
details = metadata?.details || 'No description';
} catch (e) {
console.warn('Failed to parse group metadata:', e);
}

const modalContent = (
<dialog
id={modalId}
Expand Down Expand Up @@ -175,7 +200,7 @@ export function GroupInfo({
<div className="flex items-center justify-between mb-6">
<div className="flex items-center space-x-4">
<ProfileAvatar walletAddress={policyAddress} size={40} />
<h3 className="font-bold text-lg">{group.ipfsMetadata?.title ?? 'No title'}</h3>
<h3 className="font-bold text-lg">{title}</h3>
</div>
<form method="dialog">
<button
Expand Down Expand Up @@ -216,11 +241,7 @@ export function GroupInfo({
<InfoItem label="Voting period" value={votingPeriodDisplay} />
<InfoItem label="Qualified Majority" value={threshold} />

<InfoItem
label="Description"
value={group.ipfsMetadata?.details ?? 'No description'}
isProposal={true}
/>
<InfoItem label="Description" value={details} isProposal={true} />
<InfoItem label="Policy Address" value={policyAddress} isAddress={true} />
<h4 className="font-semibold mt-6 text-secondary-content">Authors</h4>
{renderAuthors()}
Expand Down
18 changes: 12 additions & 6 deletions components/groups/modals/updateGroupModal.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -31,12 +31,18 @@ export function UpdateGroupModal({
const { tx, isSigning, setIsSigning } = useTx(env.chain);
const { estimateFee } = useFeeEstimation(env.chain);

const maybeIpfsMetadata = group?.ipfsMetadata;
const maybeTitle = maybeIpfsMetadata?.title ?? '';
const maybeAuthors = maybeIpfsMetadata?.authors ?? '';
const maybeSummary = maybeIpfsMetadata?.summary ?? '';
const maybeProposalForumURL = maybeIpfsMetadata?.proposalForumURL ?? '';
const maybeDetails = maybeIpfsMetadata?.details ?? '';
let maybeMetadata = null;
try {
maybeMetadata = group.metadata ? JSON.parse(group.metadata) : null;
} catch (e) {
console.warn('Failed to parse group metadata:', e);
}

const maybeTitle = maybeMetadata?.title ?? '';
const maybeAuthors = maybeMetadata?.authors ?? '';
const maybeSummary = maybeMetadata?.summary ?? '';
const maybeProposalForumURL = maybeMetadata?.proposalForumURL ?? '';
const maybeDetails = maybeMetadata?.details ?? '';
const maybePolicies = group?.policies?.[0];
const maybeDecisionPolicy = maybePolicies?.decision_policy;
const maybeThreshold = (maybeDecisionPolicy as ThresholdDecisionPolicySDKType)?.threshold ?? '';
Expand Down
2 changes: 1 addition & 1 deletion components/groups/modals/voteDetailsModal.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -556,7 +556,7 @@ function VoteDetailsModal({
</button>
</div>
<div
className={`bg-base-300 rounded-[12px] p-4 overflow-y-auto ${
className={`bg-base-300 rounded-[12px] p-4 overflow-y-auto max-w-[22rem] overflow-x-auto ${
proposal.summary ? 'max-h-[10rem]' : 'max-h-[17rem]'
}`}
>
Expand Down
8 changes: 2 additions & 6 deletions components/wallet.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -213,12 +213,8 @@ export const IconWallet: React.FC<WalletSectionProps> = ({ chainName }) => {
return (
<div className="relative group">
<button
onClick={
status === WalletStatus.Disconnected || status === WalletStatus.Rejected
? onClick
: () => {}
}
className={`flex justify-center items-center w-8 h-8 hover:text-primary duration-200 ease-in-out ${status === WalletStatus.Disconnected || status === WalletStatus.Rejected ? 'cursor-pointer' : 'cursor-default'}`}
onClick={onClick}
className={`flex justify-center items-center w-8 h-8 hover:text-primary duration-200 ease-in-out`}
>
<buttonData.icon className="w-8 h-8" />
</button>
Expand Down
1 change: 0 additions & 1 deletion hooks/index.tsx
Original file line number Diff line number Diff line change
@@ -1,5 +1,4 @@
export * from './useFeeEstimation';
export * from './useIpfs';
export * from './useLcdQueryClient';
export * from './usePoaLcdQueryClient';
export * from './useQueries';
Expand Down
Loading
Loading