@@ -1667,7 +1667,7 @@ function BallotOverviewTable({
@@ -185,7 +185,7 @@ export default function VoteCC({
if (!isDisabled) toggleCandidate(candidate.id);
}}
className={`cursor-pointer rounded border p-4 text-sm transition
- ${isSelected ? "border-blue-500 bg-blue-100 dark:bg-blue-900 dark:border-blue-400 font-semibold ring-2 ring-blue-400 dark:ring-blue-300 shadow-md" : ""}
+ ${isSelected ? "border-gray-500 bg-gray-100 dark:bg-gray-800 dark:border-gray-400 font-semibold ring-2 ring-gray-400 dark:ring-gray-300 shadow-md" : ""}
${isDisabled ? "cursor-not-allowed opacity-50" : "border-gray-300 dark:border-gray-600 bg-white dark:bg-gray-800 hover:shadow"}`}
>
{candidate.name}
diff --git a/src/components/pages/wallet/governance/card-info.tsx b/src/components/pages/wallet/governance/card-info.tsx
index 253c7db8..13329ec8 100644
--- a/src/components/pages/wallet/governance/card-info.tsx
+++ b/src/components/pages/wallet/governance/card-info.tsx
@@ -2,6 +2,8 @@ import { Wallet } from "@/types/wallet";
import { useWalletsStore } from "@/lib/zustand/wallets";
import Retire from "./drep/retire";
import Link from "next/link";
+import RegisterDrepModal from "./drep/RegisterDrepModal";
+import UpdateDrepModal from "./drep/UpdateDrepModal";
import {
DropdownMenu,
DropdownMenuContent,
@@ -31,6 +33,7 @@ import {
CollapsibleContent,
CollapsibleTrigger,
} from "@/components/ui/collapsible";
+import CardUI from "@/components/ui/card-content";
export default function CardInfo({ appWallet, manualUtxos }: { appWallet: Wallet; manualUtxos: UTxO[] }) {
const drepInfo = useWalletsStore((state) => state.drepInfo);
@@ -162,51 +165,58 @@ export default function CardInfo({ appWallet, manualUtxos }: { appWallet: Wallet
// Show loading or error state if no DRep ID
if (!displayDrepId) {
return (
-
- {/* Header */}
-
-
-
-
-
-
-
- {hasValidProxyData ? "Proxy DRep Information" : "DRep Information"}
-
-
- Note: governance features are currently in alpha as Blockfrost and CIPs standards are work in progress.
-
-
-
-
-
- {/* Loading or Error State */}
-
+
+
+
+ Toggle menu
+
+
+
+
+
+ gov.tools
+
+
+
+
+ }
+ >
+
{loadingProxyDrep ? (
-
-
+
+
Loading proxy DRep information...
) : proxyDrepError ? (
-
+
- Error loading proxy DRep
- {proxyDrepError}
+ Error loading proxy DRep
+ {proxyDrepError}
) : (
-
-
+
+
{hasValidProxyData ? "No proxy DRep information available" : "No DRep information available"}
)}
-
+
);
}
@@ -214,6 +224,8 @@ export default function CardInfo({ appWallet, manualUtxos }: { appWallet: Wallet
const isDRepRegistered = displayDrepInfo?.active === true;
const [isDRepManagementOpen, setIsDRepManagementOpen] = useState(false);
const [showProxySelector, setShowProxySelector] = useState(!!selectedProxyId);
+ const [registerModalOpen, setRegisterModalOpen] = useState(false);
+ const [updateModalOpen, setUpdateModalOpen] = useState(false);
// Sync showProxySelector when a proxy is selected
useEffect(() => {
@@ -223,26 +235,13 @@ export default function CardInfo({ appWallet, manualUtxos }: { appWallet: Wallet
}, [selectedProxyId]);
return (
-
- {/* Header */}
-
-
-
-
-
-
-
- {hasValidProxyData ? "Proxy DRep Information" : "DRep Information"}
-
-
- Note: governance features are currently in alpha as Blockfrost and CIPs standards are work in progress.
-
-
-
-
+
@@ -260,34 +259,20 @@ export default function CardInfo({ appWallet, manualUtxos }: { appWallet: Wallet
-
-
- {/* Combined DRep Card with Collapsible Management */}
-
- {/* Header */}
-
-
-
-
-
- {hasValidProxyData ? "Proxy DRep Information" : "DRep Information"}
-
-
- {hasValidProxyData ? "Using proxy for governance operations" : "Standard DRep governance mode"}
-
-
-
-
- {/* Improved Proxy Control - Only show when proxies exist */}
- {proxies && proxies.length > 0 && (
-
+ }
+ >
+
+ {/* Proxy Control Section - Only show when proxies exist */}
+ {proxies && proxies.length > 0 && (
+
+
{/* Toggle Row */}
Proxy Mode
{isProxyEnabled && selectedProxyId && (
-
+
Active
)}
@@ -309,8 +294,8 @@ export default function CardInfo({ appWallet, manualUtxos }: { appWallet: Wallet
setShowProxySelector(true);
}
}}
- className={`relative inline-flex h-6 w-11 items-center rounded-full transition-colors flex-shrink-0 focus:outline-none focus:ring-2 focus:ring-blue-500 focus:ring-offset-2 ${
- isProxyEnabled && selectedProxyId ? 'bg-blue-600' : 'bg-gray-200 dark:bg-gray-700'
+ className={`relative inline-flex h-6 w-11 items-center rounded-full transition-colors flex-shrink-0 focus:outline-none focus:ring-2 focus:ring-gray-500 focus:ring-offset-2 ${
+ isProxyEnabled && selectedProxyId ? 'bg-gray-600 dark:bg-gray-500' : 'bg-gray-200 dark:bg-gray-800'
}`}
type="button"
aria-label={isProxyEnabled && selectedProxyId ? "Disable proxy mode" : "Enable proxy mode"}
@@ -387,20 +372,21 @@ export default function CardInfo({ appWallet, manualUtxos }: { appWallet: Wallet
)}
- )}
-
+
+ )}
{/* DRep Information Content */}
-
+
+
{/* DRep ID */}
-
+
DRep ID
-
+
{loadingProxyDrep ? "..." : displayDrepId}
@@ -429,14 +415,14 @@ export default function CardInfo({ appWallet, manualUtxos }: { appWallet: Wallet
{/* DRep Status */}
{loadingProxyDrep ? (
-
- Loading...
+
+ Loading...
) : (
@@ -462,7 +448,7 @@ export default function CardInfo({ appWallet, manualUtxos }: { appWallet: Wallet
{/* Voting Power */}
-
+
Voting Power
@@ -483,16 +469,17 @@ export default function CardInfo({ appWallet, manualUtxos }: { appWallet: Wallet
+
{/* Collapsible DRep Management Section */}
-
+
-
+
-
-
+
DRep Management
@@ -506,7 +493,7 @@ export default function CardInfo({ appWallet, manualUtxos }: { appWallet: Wallet
-
+
{/* Primary Actions - Registration & Update */}
@@ -514,21 +501,19 @@ export default function CardInfo({ appWallet, manualUtxos }: { appWallet: Wallet
className="w-full justify-start gap-3 h-auto py-3.5 px-4 text-sm sm:text-base font-medium"
disabled={isDRepRegistered}
variant={isDRepRegistered ? "outline" : "default"}
+ onClick={() => setRegisterModalOpen(true)}
>
-
- Register DRep
-
+ Register DRep
@@ -550,7 +535,19 @@ export default function CardInfo({ appWallet, manualUtxos }: { appWallet: Wallet
-
+
+ {/* Register DRep Modal */}
+
+
+ {/* Update DRep Modal */}
+
+
);
}
diff --git a/src/components/pages/wallet/governance/clarity/card-clarity.tsx b/src/components/pages/wallet/governance/clarity/card-clarity.tsx
index 002a3e60..985c020d 100644
--- a/src/components/pages/wallet/governance/clarity/card-clarity.tsx
+++ b/src/components/pages/wallet/governance/clarity/card-clarity.tsx
@@ -1,6 +1,6 @@
import { useState } from "react";
import { Wallet } from "@/types/wallet";
-import CardUI from "@/components/common/card-content";
+import CardUI from "@/components/ui/card-content";
import { api } from "@/utils/api";
// import { CheckCircleIcon } from "@heroicons/react/24/solid";
import { Button } from "@/components/ui/button";
@@ -50,13 +50,13 @@ export default function ClarityCard({ appWallet }: ClarityCardProps) {
return (
-
+
{appWallet.clarityApiKey ? (
- Clarity API:
-
- Connected
+ Clarity API:
+
+ Connected
) : (
-
+
No Clarity API Key associated with this wallet.
diff --git a/src/components/pages/wallet/governance/drep/RegisterDrepModal.tsx b/src/components/pages/wallet/governance/drep/RegisterDrepModal.tsx
new file mode 100644
index 00000000..06c94876
--- /dev/null
+++ b/src/components/pages/wallet/governance/drep/RegisterDrepModal.tsx
@@ -0,0 +1,33 @@
+import {
+ Dialog,
+ DialogContent,
+ DialogHeader,
+ DialogTitle,
+} from "@/components/ui/dialog";
+import RegisterDRep from "./registerDrep";
+import { Plus } from "lucide-react";
+
+interface RegisterDrepModalProps {
+ open: boolean;
+ onOpenChange: (open: boolean) => void;
+}
+
+export default function RegisterDrepModal({
+ open,
+ onOpenChange,
+}: RegisterDrepModalProps) {
+ return (
+
+ );
+}
+
diff --git a/src/components/pages/wallet/governance/drep/UpdateDrepModal.tsx b/src/components/pages/wallet/governance/drep/UpdateDrepModal.tsx
new file mode 100644
index 00000000..264aeb40
--- /dev/null
+++ b/src/components/pages/wallet/governance/drep/UpdateDrepModal.tsx
@@ -0,0 +1,33 @@
+import {
+ Dialog,
+ DialogContent,
+ DialogHeader,
+ DialogTitle,
+} from "@/components/ui/dialog";
+import UpdateDRep from "./updateDrep";
+import { Minus } from "lucide-react";
+
+interface UpdateDrepModalProps {
+ open: boolean;
+ onOpenChange: (open: boolean) => void;
+}
+
+export default function UpdateDrepModal({
+ open,
+ onOpenChange,
+}: UpdateDrepModalProps) {
+ return (
+
+ );
+}
+
diff --git a/src/components/pages/wallet/governance/drep/registerDrep.tsx b/src/components/pages/wallet/governance/drep/registerDrep.tsx
index 0f2ddf35..11edfac2 100644
--- a/src/components/pages/wallet/governance/drep/registerDrep.tsx
+++ b/src/components/pages/wallet/governance/drep/registerDrep.tsx
@@ -24,7 +24,11 @@ interface PutResponse {
url: string;
}
-export default function RegisterDRep() {
+interface RegisterDRepProps {
+ onClose?: () => void;
+}
+
+export default function RegisterDRep({ onClose }: RegisterDRepProps = {}) {
const { appWallet } = useAppWallet();
const { connected, wallet } = useWallet();
const userAddress = useUserStore((state) => state.userAddress);
@@ -115,18 +119,17 @@ export default function RegisterDRep() {
setLoading(true);
const txBuilder = getTxBuilder(network);
- const dRepId = multisigWallet?.getKeysByRole(3) ? multisigWallet?.getDRepId() : appWallet?.dRepId;
- if (!dRepId) {
+
+ const drepData = multisigWallet?.getDRep(appWallet);
+ if (!drepData) {
throw new Error("DRep not found");
}
+ const { dRepId, drepCbor } = drepData;
+
const scriptCbor = multisigWallet?.getKeysByRole(3) ? multisigWallet?.getScript().scriptCbor : appWallet.scriptCbor;
- const drepCbor = multisigWallet?.getKeysByRole(3) ? multisigWallet?.getDRepScript() : appWallet.scriptCbor;
if (!scriptCbor) {
throw new Error("Script not found");
}
- if (!drepCbor) {
- throw new Error("DRep script not found");
- }
try {
const { anchorUrl, anchorHash } = await createAnchor();
@@ -163,10 +166,14 @@ export default function RegisterDRep() {
description: "DRep registration",
toastMessage: "DRep registration transaction has been created",
});
+ if (onClose) {
+ onClose();
+ } else {
+ router.push(`/wallets/${appWallet.id}/governance`);
+ }
} catch (e) {
console.error(e);
}
- router.push(`/wallets/${appWallet.id}/governance`);
setLoading(false);
}
@@ -217,87 +224,27 @@ export default function RegisterDRep() {
description: "Proxy DRep registration",
toastMessage: "Proxy DRep registration transaction has been created",
});
+ if (onClose) {
+ onClose();
+ } else {
+ router.push(`/wallets/${appWallet.id}/governance`);
+ }
} catch (e) {
console.error(e);
}
- router.push(`/wallets/${appWallet.id}/governance`);
setLoading(false);
}
return (
-
-
-
-
- Register DRep
-
-
- {/* Global Proxy Status - Only show when proxies exist */}
- {proxies && proxies.length > 0 && (
-
-
-
-
- {isProxyEnabled ? 'Proxy Mode Enabled' : 'Standard Mode'}
-
-
-
- {isProxyEnabled
- ? 'DRep will be registered using a proxy contract'
- : 'DRep will be registered directly'
- }
-
-
- )}
-
- {/* Proxy Configuration - Only show when proxies exist */}
- {isProxyEnabled && proxies && proxies.length > 0 && (
-
-
- This will register the DRep using a proxy contract, allowing for more flexible governance control.
-
- {proxies && proxies.length > 0 ? (
-
-
-
-
- ) : (
-
- {proxiesLoading ? "Loading proxies..." : "No proxies available. Please create a proxy first."}
-
- )}
-
- )}
-
- {/* Standard Mode Info */}
- {!isProxyEnabled && (
-
-
- DRep will be registered directly to your multisig wallet.
- To use proxy registration, enable proxy mode in the Proxy Control panel.
-
-
- )}
+
+ )}
{appWallet && (
void;
+}
+
+export default function UpdateDRep({ onClose }: UpdateDRepProps = {}) {
const { appWallet } = useAppWallet();
const { wallet, connected } = useWallet();
const userAddress = useUserStore((state) => state.userAddress);
@@ -157,7 +161,11 @@ export default function UpdateDRep() {
toastMessage: "Proxy DRep update transaction has been created",
});
- router.push(`/wallets/${appWallet.id}/governance`);
+ if (onClose) {
+ onClose();
+ } else {
+ router.push(`/wallets/${appWallet.id}/governance`);
+ }
} catch (error) {
console.error("Proxy DRep update error:", error);
throw error;
@@ -172,18 +180,17 @@ export default function UpdateDRep() {
setLoading(true);
const txBuilder = getTxBuilder(network);
- const dRepId = multisigWallet?.getKeysByRole(3) ? multisigWallet?.getDRepId() : appWallet?.dRepId;
- if (!dRepId) {
+
+ const drepData = multisigWallet?.getDRep(appWallet);
+ if (!drepData) {
throw new Error("DRep not found");
}
+ const { dRepId, drepCbor } = drepData;
+
const scriptCbor = multisigWallet?.getKeysByRole(3) ? multisigWallet?.getScript().scriptCbor : appWallet.scriptCbor;
- const drepCbor = multisigWallet?.getKeysByRole(3) ? multisigWallet?.getDRepScript() : appWallet.scriptCbor;
if (!scriptCbor) {
throw new Error("Script not found");
}
- if (!drepCbor) {
- throw new Error("DRep script not found");
- }
const changeAddress = multisigWallet?.getKeysByRole(3) ? multisigWallet?.getScript().address : appWallet.address;
if (!changeAddress) {
throw new Error("Change address not found");
@@ -213,30 +220,42 @@ export default function UpdateDRep() {
.drepUpdateCertificate(dRepId, {
anchorUrl: anchorUrl,
anchorDataHash: anchorHash,
- })
- .certificateScript(drepCbor)
- .changeAddress(changeAddress);
+ });
+
+ // Only add certificateScript if it's different from the spending script
+ // to avoid "extraneous scripts" error
+ if (drepCbor !== scriptCbor) {
+ txBuilder.certificateScript(drepCbor);
+ }
+
+ txBuilder.changeAddress(changeAddress);
await newTransaction({
txBuilder,
description: "DRep update",
toastMessage: "DRep update transaction has been created",
});
+ if (onClose) {
+ onClose();
+ } else {
+ router.push(`/wallets/${appWallet.id}/governance`);
+ }
} catch (e) {
console.error(e);
}
- router.push(`/wallets/${appWallet.id}/governance`);
setLoading(false);
}
return (
-
-
-
-
- Update DRep
-
-
+
+ {!onClose && (
+
+
+
+ Update DRep
+
+
+ )}
{appWallet && (
{/* Abstract */}
-
+
Abstract
@@ -295,7 +295,7 @@ function WalletGovernanceProposalContent({ id }: { id: string }) {
{/* Motivation */}
{proposalMetadata.json_metadata.body.motivation && (
-
+
Motivation
@@ -311,7 +311,7 @@ function WalletGovernanceProposalContent({ id }: { id: string }) {
{/* Rationale */}
{proposalMetadata.json_metadata.body.rationale && (
-
+
Rationale
@@ -327,7 +327,7 @@ function WalletGovernanceProposalContent({ id }: { id: string }) {
{/* References */}
{proposalMetadata.json_metadata.body.references && proposalMetadata.json_metadata.body.references.length > 0 && (
-
+
References
@@ -413,7 +413,7 @@ function WalletGovernanceProposalContent({ id }: { id: string }) {
))}
-
+
Total Amount:
diff --git a/src/components/pages/wallet/governance/proposal/voteButtton.tsx b/src/components/pages/wallet/governance/proposal/voteButtton.tsx
index 39de979e..e1c9fa5d 100644
--- a/src/components/pages/wallet/governance/proposal/voteButtton.tsx
+++ b/src/components/pages/wallet/governance/proposal/voteButtton.tsx
@@ -372,7 +372,7 @@ export default function VoteButton({
setVoteKind(value as "Yes" | "No" | "Abstain")
}
>
-
+
@@ -403,7 +403,7 @@ export default function VoteButton({
|