From 9097456dc2c084d038c4ab06e260c390dacf6e98 Mon Sep 17 00:00:00 2001 From: "Hong Jing (Jingles)" Date: Thu, 26 Sep 2024 01:16:17 +0800 Subject: [PATCH] add docs and demo for delegation --- .../pages/apis/txbuilder/governance/index.tsx | 3 + .../txbuilder/governance/registration.tsx | 7 - .../txbuilder/governance/vote-delegation.tsx | 204 ++++++++++++++++++ 3 files changed, 207 insertions(+), 7 deletions(-) create mode 100644 apps/playground/src/pages/apis/txbuilder/governance/vote-delegation.tsx diff --git a/apps/playground/src/pages/apis/txbuilder/governance/index.tsx b/apps/playground/src/pages/apis/txbuilder/governance/index.tsx index 8414350a..a9f5574f 100644 --- a/apps/playground/src/pages/apis/txbuilder/governance/index.tsx +++ b/apps/playground/src/pages/apis/txbuilder/governance/index.tsx @@ -9,11 +9,13 @@ import { metaTxbuilderGovernance } from "~/data/links-txbuilders"; import { Intro } from "../common"; import GovernanceDeregistration from "./deregistration"; import GovernanceRegistration from "./registration"; +import GovernanceVoteDelegation from "./vote-delegation"; const ReactPage: NextPage = () => { const sidebarItems = [ { label: "DRep Registration", to: "registration" }, { label: "DRep Deregistration", to: "deregistration" }, + { label: "Vote Delegation", to: "delegation" }, ]; return ( @@ -46,6 +48,7 @@ const ReactPage: NextPage = () => { + ); diff --git a/apps/playground/src/pages/apis/txbuilder/governance/registration.tsx b/apps/playground/src/pages/apis/txbuilder/governance/registration.tsx index 6efe1ebd..672e2ba7 100644 --- a/apps/playground/src/pages/apis/txbuilder/governance/registration.tsx +++ b/apps/playground/src/pages/apis/txbuilder/governance/registration.tsx @@ -9,19 +9,12 @@ import { } from "@meshsdk/core"; import { useWallet } from "@meshsdk/react"; -import Button from "~/components/button/button"; import Input from "~/components/form/input"; import InputTable from "~/components/sections/input-table"; import LiveCodeDemo from "~/components/sections/live-code-demo"; import TwoColumnsScroll from "~/components/sections/two-columns-scroll"; import Codeblock from "~/components/text/codeblock"; import { getTxBuilder } from "../common"; -import { - deregisterDRep, - getNativeScript, - makePayment, - registerDRep, -} from "./test-native-script"; export default function GovernanceRegistration() { return ( diff --git a/apps/playground/src/pages/apis/txbuilder/governance/vote-delegation.tsx b/apps/playground/src/pages/apis/txbuilder/governance/vote-delegation.tsx new file mode 100644 index 00000000..fbda0819 --- /dev/null +++ b/apps/playground/src/pages/apis/txbuilder/governance/vote-delegation.tsx @@ -0,0 +1,204 @@ +import { useState } from "react"; + +import { keepRelevant, Quantity, Unit } from "@meshsdk/core"; +import { useWallet } from "@meshsdk/react"; + +import Input from "~/components/form/input"; +import InputTable from "~/components/sections/input-table"; +import LiveCodeDemo from "~/components/sections/live-code-demo"; +import TwoColumnsScroll from "~/components/sections/two-columns-scroll"; +import Codeblock from "~/components/text/codeblock"; +import { getTxBuilder } from "../common"; + +export default function GovernanceVoteDelegation() { + return ( + + ); +} + +function Left() { + let codeGetWalletInfo = ``; + codeGetWalletInfo += `const utxos = await wallet.getUtxos();\n`; + codeGetWalletInfo += `const rewardAddresses = await wallet.getRewardAddresses();\n`; + codeGetWalletInfo += `const rewardAddress = rewardAddresses[0];\n`; + codeGetWalletInfo += `const changeAddress = await wallet.getChangeAddress();\n`; + + let codeUtxo = ``; + codeUtxo += `const assetMap = new Map();\n`; + codeUtxo += `assetMap.set("lovelace", "5000000");\n`; + codeUtxo += `const selectedUtxos = keepRelevant(assetMap, utxos);\n`; + + let codeTx = ``; + codeTx += `for (const utxo of selectedUtxos) {\n`; + codeTx += ` txBuilder.txIn(\n`; + codeTx += ` utxo.input.txHash,\n`; + codeTx += ` utxo.input.outputIndex,\n`; + codeTx += ` utxo.output.amount,\n`; + codeTx += ` utxo.output.address,\n`; + codeTx += ` );\n`; + codeTx += `}\n`; + codeTx += `\n`; + codeTx += `txBuilder\n`; + codeTx += ` .voteDelegationCertificate(\n`; + codeTx += ` {\n`; + codeTx += ` dRepId: drepid,\n`; + codeTx += ` },\n`; + codeTx += ` rewardAddress,\n`; + codeTx += ` )\n`; + codeTx += ` .changeAddress(changeAddress);\n`; + + let codeBuildSign = ``; + codeBuildSign += `const unsignedTx = await txBuilder.complete();\n`; + codeBuildSign += `const signedTx = await wallet.signTx(unsignedTx);\n`; + codeBuildSign += `const txHash = await wallet.submitTx(signedTx);\n`; + + return ( + <> +

+ Any wallet can delegate its voting power to another DRep. This is done + by creating a vote delegation certificate and submitting it to the + blockchain. +

+

+ First we need to get the wallet information. This includes the UTXOs, + the reward address, and the change address. +

+ +

+ Next we need to select the UTXOs to use to pay for the transaction. We + will select the UTXOs that have at least 5 ADA. Though the fee is less + than 1 ADA. +

+ +

+ We can now start building the transaction. We will add the selected + UTXOs as inputs to the transaction. We will also add the vote delegation + certificate to the transaction. The vote delegation certificate requires + the DRep ID of the DRep to delegate to and the reward address of the + delegator. +

+ +

+ Finally we can build, sign the transaction and submit it to the + blockchain. +

+ +

+ The transaction will be submitted to the blockchain and the DRep will be + registered. The deposit will be taken from the DRep owner and the DRep + will be added to the list of registered DReps. +

+ + ); +} + +function Right() { + const { wallet, connected } = useWallet(); + const [drepid, setDrepid] = useState(""); + + async function runDemo() { + if (!connected) throw new Error("Wallet not connected"); + + const utxos = await wallet.getUtxos(); + const rewardAddresses = await wallet.getRewardAddresses(); + const rewardAddress = rewardAddresses[0]; + if (rewardAddress === undefined) throw new Error("No reward address found"); + + const changeAddress = await wallet.getChangeAddress(); + + const assetMap = new Map(); + assetMap.set("lovelace", "5000000"); + const selectedUtxos = keepRelevant(assetMap, utxos); + + const txBuilder = getTxBuilder(); + + for (const utxo of selectedUtxos) { + txBuilder.txIn( + utxo.input.txHash, + utxo.input.outputIndex, + utxo.output.amount, + utxo.output.address, + ); + } + + txBuilder + .voteDelegationCertificate( + { + dRepId: drepid, + }, + rewardAddress, + ) + .changeAddress(changeAddress); + + const unsignedTx = await txBuilder.complete(); + const signedTx = await wallet.signTx(unsignedTx); + const txHash = await wallet.submitTx(signedTx); + return txHash; + } + + let codeSnippet = ``; + codeSnippet += `const utxos = await wallet.getUtxos();\n`; + codeSnippet += `const rewardAddresses = await wallet.getRewardAddresses();\n`; + codeSnippet += `const rewardAddress = rewardAddresses[0];\n`; + codeSnippet += `\n`; + codeSnippet += `const changeAddress = await wallet.getChangeAddress();\n`; + codeSnippet += `\n`; + codeSnippet += `const assetMap = new Map();\n`; + codeSnippet += `assetMap.set("lovelace", "5000000");\n`; + codeSnippet += `const selectedUtxos = keepRelevant(assetMap, utxos);\n`; + codeSnippet += `\n`; + codeSnippet += `const txBuilder = getTxBuilder();\n`; + codeSnippet += `\n`; + codeSnippet += `for (const utxo of selectedUtxos) {\n`; + codeSnippet += ` txBuilder.txIn(\n`; + codeSnippet += ` utxo.input.txHash,\n`; + codeSnippet += ` utxo.input.outputIndex,\n`; + codeSnippet += ` utxo.output.amount,\n`; + codeSnippet += ` utxo.output.address,\n`; + codeSnippet += ` );\n`; + codeSnippet += `}\n`; + codeSnippet += `\n`; + codeSnippet += `txBuilder\n`; + codeSnippet += ` .voteDelegationCertificate(\n`; + codeSnippet += ` {\n`; + codeSnippet += ` dRepId: drepid,\n`; + codeSnippet += ` },\n`; + codeSnippet += ` rewardAddress,\n`; + codeSnippet += ` )\n`; + codeSnippet += ` .changeAddress(changeAddress);\n`; + codeSnippet += `\n`; + codeSnippet += `const unsignedTx = await txBuilder.complete();\n`; + codeSnippet += `const signedTx = await wallet.signTx(unsignedTx);\n`; + codeSnippet += `const txHash = await wallet.submitTx(signedTx);\n`; + + return ( + + setDrepid(e.target.value)} + placeholder="drep..." + label="DRep ID" + key={0} + />, + ]} + /> + + ); +}