Skip to content

Commit c4467bd

Browse files
committed
prep staking tab.
1 parent 7bf83ee commit c4467bd

File tree

12 files changed

+603
-479
lines changed

12 files changed

+603
-479
lines changed

package-lock.json

Lines changed: 0 additions & 445 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

src/components/pages/wallet/governance/proposal/voteButtton.tsx

Lines changed: 51 additions & 32 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,7 @@ import {
1717
SelectValue,
1818
} from "@/components/ui/select";
1919
import { ToastAction } from "@/components/ui/toast";
20+
import useMultisigWallet from "@/hooks/useMultisigWallet";
2021

2122
interface VoteButtonProps {
2223
appWallet: Wallet;
@@ -38,7 +39,7 @@ export default function VoteButton({
3839
const setAlert = useSiteStore((state) => state.setAlert);
3940
const network = useSiteStore((state) => state.network);
4041
const { newTransaction } = useTransaction();
41-
42+
const { multisigWallet } = useMultisigWallet();
4243
async function vote() {
4344
if (drepInfo === undefined) {
4445
setAlert("DRep not found");
@@ -60,11 +61,14 @@ export default function VoteButton({
6061
setLoading(false);
6162
return;
6263
}
63-
64+
if (!multisigWallet)
65+
throw new Error("Multisig Wallet could not be built.");
6466
const dRepId = appWallet.dRepId;
6567
const txBuilder = getTxBuilder(network);
6668
const blockchainProvider = getProvider(network);
67-
const utxos = await blockchainProvider.fetchAddressUTxOs(appWallet.address);
69+
const utxos = await blockchainProvider.fetchAddressUTxOs(
70+
appWallet.address,
71+
);
6872

6973
const assetMap = new Map<Unit, Quantity>();
7074
assetMap.set("lovelace", "5000000");
@@ -76,11 +80,10 @@ export default function VoteButton({
7680
utxo.input.txHash,
7781
utxo.input.outputIndex,
7882
utxo.output.amount,
79-
utxo.output.address
83+
utxo.output.address,
8084
)
8185
.txInScript(appWallet.scriptCbor);
8286
}
83-
console.log(certIndex)
8487
txBuilder
8588
.vote(
8689
{
@@ -93,12 +96,23 @@ export default function VoteButton({
9396
},
9497
{
9598
voteKind: voteKind,
96-
}
99+
},
97100
)
98101
.voteScript(appWallet.scriptCbor)
99102
.selectUtxosFrom(utxos)
100103
.changeAddress(appWallet.address);
104+
105+
const paymentKeys = multisigWallet.getKeysByRole(0) ?? [];
106+
for (const key of paymentKeys) {
107+
txBuilder.requiredSignerHash(key.keyHash);
108+
}
101109

110+
if (multisigWallet.stakingEnabled()) {
111+
const stakingKeys = multisigWallet.getKeysByRole(2) ?? [];
112+
for (const key of stakingKeys) {
113+
txBuilder.requiredSignerHash(key.keyHash);
114+
}
115+
}
102116
await newTransaction({
103117
txBuilder,
104118
description: `Vote: ${voteKind} - ${description}`,
@@ -113,7 +127,10 @@ export default function VoteButton({
113127

114128
setAlert("Vote transaction successfully created!");
115129
} catch (error) {
116-
if (error instanceof Error && error.message.includes("User rejected transaction")) {
130+
if (
131+
error instanceof Error &&
132+
error.message.includes("User rejected transaction")
133+
) {
117134
toast({
118135
title: "Transaction Aborted",
119136
description: "You canceled the vote transaction.",
@@ -149,30 +166,32 @@ export default function VoteButton({
149166
}
150167

151168
return (
152-
<div className="flex flex-col items-center justify-center w-full max-w-sm space-y-2">
153-
<Select
154-
value={voteKind}
155-
onValueChange={(value) => setVoteKind(value as "Yes" | "No" | "Abstain")}
156-
>
157-
<SelectTrigger className="w-full px-4 py-2 border border-gray-300 rounded-md focus:ring-2 focus:ring-blue-500">
158-
<SelectValue placeholder="Select Vote Kind" />
159-
</SelectTrigger>
160-
<SelectContent>
161-
<SelectGroup>
162-
<SelectItem value="Yes">Yes</SelectItem>
163-
<SelectItem value="No">No</SelectItem>
164-
<SelectItem value="Abstain">Abstain</SelectItem>
165-
</SelectGroup>
166-
</SelectContent>
167-
</Select>
169+
<div className="flex w-full max-w-sm flex-col items-center justify-center space-y-2">
170+
<Select
171+
value={voteKind}
172+
onValueChange={(value) =>
173+
setVoteKind(value as "Yes" | "No" | "Abstain")
174+
}
175+
>
176+
<SelectTrigger className="w-full rounded-md border border-gray-300 px-4 py-2 focus:ring-2 focus:ring-blue-500">
177+
<SelectValue placeholder="Select Vote Kind" />
178+
</SelectTrigger>
179+
<SelectContent>
180+
<SelectGroup>
181+
<SelectItem value="Yes">Yes</SelectItem>
182+
<SelectItem value="No">No</SelectItem>
183+
<SelectItem value="Abstain">Abstain</SelectItem>
184+
</SelectGroup>
185+
</SelectContent>
186+
</Select>
168187

169-
<Button
170-
onClick={vote}
171-
disabled={loading || proposalId.length !== 66}
172-
className="w-full px-6 py-2 bg-blue-600 hover:bg-blue-700 text-white font-semibold rounded-md shadow"
173-
>
174-
{loading ? "Voting..." : "Vote"}
175-
</Button>
176-
</div>
188+
<Button
189+
onClick={vote}
190+
disabled={loading || proposalId.length !== 66}
191+
className="w-full rounded-md bg-blue-600 px-6 py-2 font-semibold text-white shadow hover:bg-blue-700"
192+
>
193+
{loading ? "Voting..." : "Vote"}
194+
</Button>
195+
</div>
177196
);
178-
}
197+
}

src/components/pages/wallet/new-transaction/index.tsx

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -100,8 +100,6 @@ export default function PageNewTransaction() {
100100
if (!connected) throw new Error("Wallet not connected");
101101
if (!appWallet) throw new Error("Wallet not found");
102102
if (!userAddress) throw new Error("User address not found");
103-
console.log(amounts)
104-
console.log(assets)
105103
setLoading(true);
106104
setError(undefined);
107105

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,22 @@
1+
import { Button } from "@/components/ui/button";
2+
import { StakingInfo } from "../stakingInfoCard";
3+
import { Wallet } from "@/types/wallet";
4+
import { UTxO } from "@meshsdk/core";
5+
6+
export default function DelegateButton({
7+
stakingInfo,
8+
appWallet,
9+
utxos,
10+
manualSelected,
11+
}: {
12+
stakingInfo: StakingInfo;
13+
appWallet: Wallet;
14+
utxos: UTxO[];
15+
manualSelected: boolean;
16+
}) {
17+
return (
18+
<Button variant="outline">
19+
Delegate ({utxos.length} UTxOs)
20+
</Button>
21+
);
22+
}
Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,22 @@
1+
import { Button } from "@/components/ui/button";
2+
import { StakingInfo } from "../stakingInfoCard";
3+
import { Wallet } from "@/types/wallet";
4+
import { UTxO } from "@meshsdk/core";
5+
6+
export default function DeregisterButton({
7+
stakingInfo,
8+
appWallet,
9+
utxos,
10+
manualSelected,
11+
}: {
12+
stakingInfo: StakingInfo;
13+
appWallet: Wallet;
14+
utxos: UTxO[];
15+
manualSelected: boolean;
16+
}) {
17+
return (
18+
<Button variant="outline">
19+
Deregister ({utxos.length} UTxOs)
20+
</Button>
21+
);
22+
}
Lines changed: 127 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,127 @@
1+
import { useState } from "react";
2+
import { Button } from "@/components/ui/button";
3+
import { Loader } from "lucide-react";
4+
import { StakingInfo } from "../stakingInfoCard";
5+
import { Wallet } from "@/types/wallet";
6+
import { deserializePoolId, UTxO } from "@meshsdk/core";
7+
import { MultisigWallet } from "@/utils/multisigSDK";
8+
import { ToastAction } from "@radix-ui/react-toast";
9+
import { toast } from "@/hooks/use-toast";
10+
import { getTxBuilder } from "@/utils/get-tx-builder";
11+
import { getProvider } from "@/utils/get-provider";
12+
import useTransaction from "@/hooks/useTransaction";
13+
export default function RegisterButton({
14+
stakingInfo,
15+
appWallet,
16+
mWallet,
17+
utxos,
18+
network,
19+
poolHex,
20+
}: {
21+
stakingInfo: StakingInfo;
22+
appWallet: Wallet;
23+
mWallet: MultisigWallet;
24+
utxos: UTxO[];
25+
network: number;
26+
poolHex: string;
27+
}) {
28+
const { newTransaction } = useTransaction();
29+
const [loading, setLoading] = useState(false);
30+
31+
async function register() {
32+
setLoading(true);
33+
try {
34+
if (!mWallet) throw new Error("Multisig Wallet could not be built.");
35+
const rewardAddress = mWallet.getStakeAddress();
36+
if (!rewardAddress)
37+
throw new Error("Reward Address could not be built.");
38+
39+
const txBuilder = getTxBuilder(network);
40+
const selectedUtxos = utxos;
41+
42+
for (const utxo of selectedUtxos) {
43+
txBuilder
44+
.txIn(
45+
utxo.input.txHash,
46+
utxo.input.outputIndex,
47+
utxo.output.amount,
48+
utxo.output.address,
49+
)
50+
.txInScript(appWallet.scriptCbor);
51+
}
52+
txBuilder
53+
.selectUtxosFrom(utxos)
54+
.changeAddress(appWallet.address)
55+
//.registerStakeCertificate(rewardAddress)
56+
.delegateStakeCertificate(rewardAddress, poolHex);
57+
58+
59+
const paymentKeys = mWallet.getKeysByRole(0) ?? [];
60+
for (const key of paymentKeys) {
61+
txBuilder.requiredSignerHash(key.keyHash);
62+
}
63+
64+
const stakingKeys = mWallet.getKeysByRole(2) ?? [];
65+
for (const key of stakingKeys) {
66+
txBuilder.requiredSignerHash(key.keyHash);
67+
}
68+
69+
await newTransaction({
70+
txBuilder,
71+
description: `Register stake.`,
72+
});
73+
74+
toast({
75+
title: "Transaction Successful",
76+
description: `Your Registration has been recorded.`,
77+
duration: 5000,
78+
});
79+
80+
} catch (error) {
81+
if (
82+
error instanceof Error &&
83+
error.message.includes("User rejected transaction")
84+
) {
85+
toast({
86+
title: "Transaction Aborted",
87+
description: "You canceled the registration transaction.",
88+
duration: 5000,
89+
});
90+
} else {
91+
toast({
92+
title: "Transaction Failed",
93+
description: `Error: ${error}`,
94+
duration: 10000,
95+
action: (
96+
<ToastAction
97+
altText="Copy error"
98+
onClick={() => {
99+
navigator.clipboard.writeText(JSON.stringify(error));
100+
toast({
101+
title: "Error Copied",
102+
description: "Error details copied to clipboard.",
103+
duration: 5000,
104+
});
105+
}}
106+
>
107+
Copy Error
108+
</ToastAction>
109+
),
110+
variant: "destructive",
111+
});
112+
console.error("Transaction error:", error);
113+
}
114+
} finally {
115+
setLoading(false);
116+
}
117+
}
118+
119+
return (
120+
<Button variant="outline" onClick={register} disabled={loading}>
121+
{loading ? (
122+
<Loader className="mr-2 h-4 w-4 animate-spin" />
123+
) : null}
124+
Register
125+
</Button>
126+
);
127+
}

0 commit comments

Comments
 (0)