Skip to content

Commit 3982f07

Browse files
committed
Add OpenGov Operations Example
- Create OpenGovExample.ts demonstrating OpenGov operations - Shows referendum submission, voting, decision deposits - Includes whitelisted caller operations and track information - Advanced level example with governance, opengov, voting, referenda categories - Registered the example in the example registry
1 parent 14b86b6 commit 3982f07

2 files changed

Lines changed: 173 additions & 0 deletions

File tree

src/lib/examples/OpenGovExample.ts

Lines changed: 169 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,169 @@
1+
import type { Network } from "../types/network";
2+
import { ExampleFactory } from "./factory";
3+
4+
export class OpenGovExample extends ExampleFactory {
5+
constructor() {
6+
super({
7+
id: "opengov-operations",
8+
name: "OpenGov Operations",
9+
description: "Demonstrate OpenGov operations: tracks, referenda, voting, and submission deposits",
10+
level: "advanced",
11+
categories: ["governance", "opengov", "voting", "referenda"],
12+
});
13+
}
14+
15+
generateCode(network: Network): string {
16+
return `// OpenGov Operations Example on ${network.name}
17+
${this.getImports(network, true)}
18+
19+
// Connect to ${network.name}
20+
const client = createClient(
21+
withPolkadotSdkCompat(
22+
getWsProvider("${network.endpoint}")
23+
)
24+
);
25+
26+
// Get the typed API using the descriptors
27+
const typedApi = client.getTypedApi(${network.descriptorKey});
28+
29+
// OpenGov operations demonstration
30+
const demonstrateOpenGovOperations = async () => {
31+
try {
32+
console.log("🏛️ Starting OpenGov operations demonstration...");
33+
34+
// 1. Query current referenda
35+
console.log("\\n📋 Querying active referenda:");
36+
const referenda = await typedApi.query.Referenda.ReferendumInfoFor.getEntries();
37+
console.log("Found", referenda.length, "active referenda");
38+
39+
if (referenda.length > 0) {
40+
const firstReferendum = referenda[0];
41+
console.log("First referendum:", {
42+
id: firstReferendum.key?.args?.[0]?.toString(),
43+
info: firstReferendum.value
44+
});
45+
}
46+
47+
// 2. Query referendum tracks
48+
console.log("\\n🎯 Querying referendum tracks:");
49+
try {
50+
const tracks = await typedApi.query.Referenda.Tracks.getValue();
51+
console.log("Available tracks:", tracks?.map(track => ({
52+
id: track?.[0]?.toString(),
53+
info: track?.[1]
54+
})));
55+
} catch (error) {
56+
console.log("Tracks query not available in current version");
57+
}
58+
59+
// 3. Demonstrate referendum submission
60+
console.log("\\n📝 Referendum Submission Example:");
61+
console.log("This would submit a referendum to a specific track:");
62+
const submissionTx = typedApi.tx.Referenda.submit({
63+
proposalOrigin: {
64+
Origins: "GeneralAdmin" // Track name
65+
},
66+
proposal: {
67+
Lookup: {
68+
hash: "0x0000000000000000000000000000000000000000000000000000000000000000", // Example hash
69+
len: 0
70+
}
71+
},
72+
enactmentMoment: {
73+
After: 100 // Blocks after approval
74+
}
75+
});
76+
console.log("Referendum submission transaction created (not submitted in simulator)");
77+
78+
// 4. Demonstrate voting on referendum
79+
console.log("\\n🗳️ Voting on Referendum Example:");
80+
console.log("This would vote on an active referendum:");
81+
const voteTx = typedApi.tx.ConvictionVoting.vote({
82+
poll_index: 0, // Referendum ID
83+
vote: {
84+
Standard: {
85+
vote: {
86+
aye: true,
87+
conviction: "Locked4x" // 4x conviction
88+
},
89+
balance: 1000000000000n // Vote amount
90+
}
91+
}
92+
});
93+
console.log("Vote transaction created for referendum #0 (not submitted in simulator)");
94+
95+
// 5. Query conviction voting state
96+
console.log("\\n📊 Querying conviction voting state:");
97+
const aliceAddress = "${this.getTestAccount("alice")}";
98+
try {
99+
const votingFor = await typedApi.query.ConvictionVoting.VotingFor.getValue(aliceAddress, 0);
100+
console.log("Alice's vote on referendum 0:", votingFor);
101+
} catch (error) {
102+
console.log("Conviction voting query not available");
103+
}
104+
105+
// 6. Demonstrate proposal deposit
106+
console.log("\\n💰 Proposal Deposit Example:");
107+
console.log("This would place a decision deposit on a referendum:");
108+
const depositTx = typedApi.tx.Referenda.placeDecisionDeposit({
109+
index: 0 // Referendum ID
110+
});
111+
console.log("Decision deposit transaction created (not submitted in simulator)");
112+
113+
// 7. Query decision deposits
114+
console.log("\\n🏦 Querying decision deposits:");
115+
try {
116+
const deposits = await typedApi.query.Referenda.DecisionDeposits.getValue(0);
117+
console.log("Decision deposits for referendum 0:", deposits);
118+
} catch (error) {
119+
console.log("Decision deposits query not available");
120+
}
121+
122+
// 8. Demonstrate whitelisted caller operation
123+
console.log("\\n⭐ Whitelisted Caller Example:");
124+
console.log("This would execute a whitelisted operation:");
125+
const whitelistTx = typedApi.tx.WhitelistedCaller.dispatchAs({
126+
asOrigin: {
127+
Origins: "WhitelistedCaller"
128+
},
129+
call: {
130+
system: {
131+
remark: {
132+
remark: "0x48656c6c6f20506f6c6b61646f7421" // "Hello Polkadot!"
133+
}
134+
}
135+
}
136+
});
137+
console.log("Whitelisted caller transaction created (not submitted in simulator)");
138+
139+
// 9. Query fellowship information (if available)
140+
console.log("\\n👥 Fellowship Information:");
141+
try {
142+
const fellowship = await typedApi.query.FellowshipCollective.Members.getValue(aliceAddress);
143+
console.log("Alice's fellowship rank:", fellowship?.toString());
144+
} catch (error) {
145+
console.log("Fellowship queries not available on this network");
146+
}
147+
148+
// 10. Query current block for timing
149+
console.log("\\n⏰ Current Block Information:");
150+
const currentBlock = await typedApi.query.System.Number.getValue();
151+
console.log("Current block:", currentBlock?.toString());
152+
153+
console.log("\\n✅ OpenGov operations demonstration completed!");
154+
console.log("Note: OpenGov operations require:");
155+
console.log("- Understanding of different tracks and their requirements");
156+
console.log("- Proper deposit amounts for proposal submission");
157+
console.log("- Sufficient conviction voting power");
158+
console.log("- In a real application, you would sign and submit these transactions");
159+
console.log("- Consider the lock periods for conviction voting");
160+
161+
} catch (error) {
162+
console.error("❌ Error in OpenGov operations:", error);
163+
}
164+
};
165+
166+
demonstrateOpenGovOperations().catch(console.error);
167+
`;
168+
}
169+
}

src/lib/examples/index.ts

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,8 @@
22
import { exampleRegistry } from "./factory";
33
import { StakingOperationsExample } from "./StakingOperationsExample";
44
import { AssetHubExample } from "./AssetHubExample";
5+
import { OpenGovExample } from "./OpenGovExample";
6+
57

68

79
import { SimpleTransferExample } from "./SimpleTransferExample";
@@ -11,6 +13,8 @@ import { WalletTransferExample } from "./WalletTransferExample";
1113
import { AcalaDeFiExample } from "./AcalaDeFiExample";
1214
import type { Example, ExampleLevel } from "../types/example";
1315
import { PolkadotGovernanceExample } from "./PolkadotGovernanceExample";
16+
new OpenGovExample(),
17+
1418

1519
new AssetHubExample(),
1620

0 commit comments

Comments
 (0)