Skip to content

Commit cca9a96

Browse files
committed
feat(creator): add transfer restrictions label to hypercert component
- Introduced TransferRestrictionsLabel component to display transfer restrictions for hypercerts. - Updated Creator component to include the new label, enhancing the information presented to users.
1 parent 70762ee commit cca9a96

File tree

2 files changed

+115
-1
lines changed

2 files changed

+115
-1
lines changed

components/hypercert/creator.tsx

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,11 +3,12 @@ import { Cuboid } from "lucide-react";
33
import { SUPPORTED_CHAINS, SupportedChainIdType } from "@/configs/constants";
44
import CopyableHypercertId from "@/components/copyable-hypercert-id";
55
import { HypercertState } from "@/hypercerts/fragments/hypercert-state.fragment";
6+
import TransferRestrictionsLabel from "./transfer-restrictions-label";
67

78
export default function Creator({ hypercert }: { hypercert: HypercertState }) {
89
if (!hypercert) return null;
910
return (
10-
<div className="flex flex-wrap items-center space-x-1 text-sm text-slate-600 font-medium">
11+
<div className="flex flex-wrap items-center space-x-1 text-sm text-slate-600 font-medium space-y-1">
1112
{hypercert.hypercert_id && (
1213
<CopyableHypercertId id={hypercert.hypercert_id} />
1314
)}
@@ -17,6 +18,12 @@ export default function Creator({ hypercert }: { hypercert: HypercertState }) {
1718
<EthAddress address={hypercert.creator_address} showEnsName />
1819
</div>
1920
)}
21+
<div className="flex space-x-1 items-center">
22+
<TransferRestrictionsLabel
23+
hypercertId={hypercert.hypercert_id || ""}
24+
showSeparator
25+
/>
26+
</div>
2027
{hypercert.contract?.chain_id && (
2128
<div className="flex space-x-2 items-center">
2229
<span className="text-slate-400"></span>
Lines changed: 107 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,107 @@
1+
"use client";
2+
3+
import {
4+
parseClaimOrFractionId,
5+
TransferRestrictions,
6+
} from "@hypercerts-org/sdk";
7+
import { getAddress } from "viem";
8+
import { useReadContract } from "wagmi";
9+
import {
10+
Popover,
11+
PopoverContent,
12+
PopoverTrigger,
13+
} from "@/components/ui/popover";
14+
import { useState } from "react";
15+
16+
export default function TransferRestrictionsLabel({
17+
hypercertId,
18+
showSeparator = false,
19+
}: {
20+
hypercertId: string;
21+
showSeparator?: boolean;
22+
}) {
23+
const [isOpen, setIsOpen] = useState(false);
24+
const { contractAddress, id } = parseClaimOrFractionId(hypercertId);
25+
const { data: transferRestrictions } = useReadContract({
26+
abi: [
27+
{
28+
inputs: [{ internalType: "uint256", name: "tokenID", type: "uint256" }],
29+
name: "readTransferRestriction",
30+
outputs: [
31+
{
32+
internalType: "string",
33+
name: "",
34+
type: "string",
35+
},
36+
],
37+
stateMutability: "view",
38+
type: "function",
39+
},
40+
],
41+
address: getAddress(contractAddress || ""),
42+
functionName: "readTransferRestriction",
43+
args: [id],
44+
query: {
45+
enabled: !!contractAddress && !!id,
46+
select: (data) => {
47+
if (data === "AllowAll") {
48+
return TransferRestrictions.AllowAll;
49+
} else if (data === "DisallowAll") {
50+
return TransferRestrictions.DisallowAll;
51+
} else if (data === "FromCreatorOnly") {
52+
return TransferRestrictions.FromCreatorOnly;
53+
}
54+
},
55+
},
56+
});
57+
if (transferRestrictions === undefined) return null;
58+
return (
59+
<>
60+
{showSeparator && <span className="text-slate-400"></span>}
61+
<div className="flex items-center gap-2 content-center px-1 py-0.5 bg-slate-100 rounded-md w-max text-sm">
62+
<Popover open={isOpen} onOpenChange={setIsOpen}>
63+
<PopoverTrigger asChild>
64+
<span
65+
className="cursor-help"
66+
onMouseEnter={() => setIsOpen(true)}
67+
onMouseLeave={() => setIsOpen(false)}
68+
>
69+
{getTransferRestrictionsText(transferRestrictions)}
70+
</span>
71+
</PopoverTrigger>
72+
<PopoverContent className="w-80 p-3" side="top">
73+
<p className="text-sm text-slate-700">
74+
{getTransferRestrictionsLabel(transferRestrictions)}
75+
</p>
76+
</PopoverContent>
77+
</Popover>
78+
</div>
79+
</>
80+
);
81+
}
82+
83+
export const getTransferRestrictionsText = (
84+
transferRestrictions: TransferRestrictions,
85+
) => {
86+
switch (transferRestrictions) {
87+
case TransferRestrictions.AllowAll:
88+
return "Transferable";
89+
case TransferRestrictions.DisallowAll:
90+
return "Not transferable";
91+
case TransferRestrictions.FromCreatorOnly:
92+
return "Transferable-once";
93+
}
94+
};
95+
96+
export const getTransferRestrictionsLabel = (
97+
transferRestrictions: TransferRestrictions,
98+
) => {
99+
switch (transferRestrictions) {
100+
case TransferRestrictions.AllowAll:
101+
return "Fractions can be transferred without limitations.";
102+
case TransferRestrictions.DisallowAll:
103+
return "Fractions can not be transferred";
104+
case TransferRestrictions.FromCreatorOnly:
105+
return "Fractions can be transferred once from the creator to another user.";
106+
}
107+
};

0 commit comments

Comments
 (0)