@moly-mcp/lido 1.0.5 → 1.0.7

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -0,0 +1,97 @@
1
+ #!/usr/bin/env node
2
+ import {
3
+ applySettingsUpdate,
4
+ getRuntime
5
+ } from "./chunk-EKZFGIVK.js";
6
+ import {
7
+ loadConfig,
8
+ redactedConfig
9
+ } from "./chunk-P6VFMSPM.js";
10
+
11
+ // src/tools/stake.ts
12
+ import { parseEther, formatEther } from "viem";
13
+ var SUBMIT_ABI = [
14
+ {
15
+ name: "submit",
16
+ type: "function",
17
+ inputs: [{ name: "_referral", type: "address" }],
18
+ outputs: [{ type: "uint256" }],
19
+ stateMutability: "payable"
20
+ }
21
+ ];
22
+ var REFERRAL = "0x0000000000000000000000000000000000000000";
23
+ async function stakeEth(amountEth, dryRun) {
24
+ const rt = getRuntime();
25
+ const value = parseEther(amountEth);
26
+ const account = rt.getAddress();
27
+ const lidoAddress = rt.chainAddresses.stETH;
28
+ const shouldDryRun = rt.config.mode === "simulation" ? dryRun !== false : !!dryRun;
29
+ if (shouldDryRun) {
30
+ let estimatedGas = "unavailable";
31
+ try {
32
+ const gas = await rt.publicClient.estimateContractGas({
33
+ address: lidoAddress,
34
+ abi: SUBMIT_ABI,
35
+ functionName: "submit",
36
+ args: [REFERRAL],
37
+ value,
38
+ account: "0x0000000000000000000000000000000000000001"
39
+ });
40
+ estimatedGas = gas.toString();
41
+ } catch {
42
+ }
43
+ return {
44
+ simulated: true,
45
+ mode: rt.config.mode,
46
+ network: rt.chainAddresses.name,
47
+ action: "stake",
48
+ amountEth,
49
+ estimatedGas,
50
+ expectedStETH: amountEth,
51
+ note: "stETH rebases daily \u2014 your balance grows automatically after staking."
52
+ };
53
+ }
54
+ const tx = await rt.sdk.stake.stakeEth({
55
+ value,
56
+ account: { address: account },
57
+ callback: () => {
58
+ }
59
+ });
60
+ return {
61
+ simulated: false,
62
+ mode: rt.config.mode,
63
+ network: rt.chainAddresses.name,
64
+ action: "stake",
65
+ amountEth,
66
+ txHash: tx.hash,
67
+ stethReceived: formatEther(tx.result?.stethReceived ?? 0n),
68
+ sharesReceived: formatEther(tx.result?.sharesReceived ?? 0n)
69
+ };
70
+ }
71
+
72
+ // src/tools/settings.ts
73
+ function getSettings() {
74
+ const cfg = loadConfig();
75
+ return {
76
+ ...redactedConfig(cfg),
77
+ note: "Use update_settings to change mode, network, or rpc. Private key and API keys can only be changed via: moly setup"
78
+ };
79
+ }
80
+ function updateSettings(patch) {
81
+ if (Object.keys(patch).length === 0) {
82
+ return { error: "No settings provided to update." };
83
+ }
84
+ const updated = applySettingsUpdate(patch);
85
+ return {
86
+ updated: true,
87
+ changes: patch,
88
+ current: redactedConfig(updated),
89
+ note: "Settings saved and applied. SDK reinitialized with new config."
90
+ };
91
+ }
92
+
93
+ export {
94
+ stakeEth,
95
+ getSettings,
96
+ updateSettings
97
+ };
@@ -0,0 +1,289 @@
1
+ #!/usr/bin/env node
2
+ import {
3
+ loadConfig,
4
+ saveConfig
5
+ } from "./chunk-P6VFMSPM.js";
6
+ import {
7
+ __require
8
+ } from "./chunk-PDX44BCA.js";
9
+
10
+ // src/server/runtime.ts
11
+ import { createPublicClient, createWalletClient, http, defineChain } from "viem";
12
+ import { mainnet, base, arbitrum } from "viem/chains";
13
+ import { privateKeyToAccount } from "viem/accounts";
14
+ import { LidoSDK } from "@lidofinance/lido-ethereum-sdk";
15
+
16
+ // src/config/types.ts
17
+ var L2_CHAINS = {
18
+ base: {
19
+ chainId: 8453,
20
+ name: "Base",
21
+ defaultRpc: "https://mainnet.base.org",
22
+ wstETH: "0xc1CBa3fCea344f92D9239c08C0568f6F2F0ee452"
23
+ },
24
+ arbitrum: {
25
+ chainId: 42161,
26
+ name: "Arbitrum One",
27
+ defaultRpc: "https://arb1.arbitrum.io/rpc",
28
+ wstETH: "0x5979D7b546E38E9Ab8049dCFAc0B5D35A8De3f6e"
29
+ }
30
+ };
31
+ var CHAIN_CONFIG = {
32
+ hoodi: {
33
+ chainId: 560048,
34
+ stETH: "0x3508A952176b3c15387C97BE809eaffB1982176a",
35
+ wstETH: "0x7E99eE3C66636DE415D2d7C880938F2f40f94De4",
36
+ voting: "0x49B3512c44891bef83F8967d075121Bd1b07a01B",
37
+ defaultRpc: "https://hoodi.drpc.org",
38
+ name: "Hoodi Testnet"
39
+ },
40
+ mainnet: {
41
+ chainId: 1,
42
+ stETH: "0xae7ab96520DE3A18E5e111B5EaAb095312D7fE84",
43
+ wstETH: "0x7f39C581F595B53c5cb19bD0b3f8dA6c935E2Ca0",
44
+ voting: "0x2e59A20f205bB85a89C53f1936454680651E618e",
45
+ defaultRpc: "https://eth.llamarpc.com",
46
+ name: "Ethereum Mainnet"
47
+ }
48
+ };
49
+
50
+ // src/server/runtime.ts
51
+ var hoodi = defineChain({
52
+ id: 560048,
53
+ name: "Hoodi Testnet",
54
+ nativeCurrency: { name: "Ether", symbol: "ETH", decimals: 18 },
55
+ rpcUrls: { default: { http: ["https://hoodi.drpc.org"] } }
56
+ });
57
+ var L2_VIEM_CHAINS = { base, arbitrum };
58
+ var _runtime = null;
59
+ function buildRuntime() {
60
+ const config = loadConfig();
61
+ const chainCfg = CHAIN_CONFIG[config.network];
62
+ const rpcUrl = config.rpc ?? chainCfg.defaultRpc;
63
+ const viemChain = config.network === "mainnet" ? mainnet : hoodi;
64
+ const publicClient = createPublicClient({
65
+ chain: viemChain,
66
+ transport: http(rpcUrl)
67
+ });
68
+ const sdk = new LidoSDK({
69
+ chainId: chainCfg.chainId,
70
+ rpcProvider: publicClient
71
+ });
72
+ let _wallet = null;
73
+ let _resolvedAccount = null;
74
+ function resolveAccount() {
75
+ if (_resolvedAccount) return _resolvedAccount;
76
+ if (config.ows) {
77
+ let exportWallet;
78
+ try {
79
+ exportWallet = __require("@open-wallet-standard/core").exportWallet;
80
+ } catch {
81
+ throw new Error("OWS SDK not installed. Run: npm install @open-wallet-standard/core");
82
+ }
83
+ const exported = exportWallet(config.ows.walletName, config.ows.passphrase);
84
+ const keyHex = exported.secp256k1 ?? exported;
85
+ const pk2 = keyHex.startsWith("0x") ? keyHex : "0x" + keyHex;
86
+ _resolvedAccount = privateKeyToAccount(pk2);
87
+ return _resolvedAccount;
88
+ }
89
+ const pk = config.privateKey;
90
+ if (!pk) throw new Error("No key configured. Run: moly setup");
91
+ _resolvedAccount = privateKeyToAccount(pk);
92
+ return _resolvedAccount;
93
+ }
94
+ function getWallet() {
95
+ if (_wallet) return _wallet;
96
+ const account = resolveAccount();
97
+ _wallet = createWalletClient({
98
+ account,
99
+ chain: viemChain,
100
+ transport: http(rpcUrl)
101
+ });
102
+ return _wallet;
103
+ }
104
+ function getAddress() {
105
+ return resolveAccount().address;
106
+ }
107
+ const _l2Clients = {};
108
+ const _l2Wallets = {};
109
+ function getL2PublicClient(chain) {
110
+ if (_l2Clients[chain]) return _l2Clients[chain];
111
+ const cfg = L2_CHAINS[chain];
112
+ const client = createPublicClient({ chain: L2_VIEM_CHAINS[chain], transport: http(cfg.defaultRpc) });
113
+ _l2Clients[chain] = client;
114
+ return client;
115
+ }
116
+ function getL2Wallet(chain) {
117
+ if (_l2Wallets[chain]) return _l2Wallets[chain];
118
+ const account = resolveAccount();
119
+ const cfg = L2_CHAINS[chain];
120
+ const wallet = createWalletClient({ account, chain: L2_VIEM_CHAINS[chain], transport: http(cfg.defaultRpc) });
121
+ _l2Wallets[chain] = wallet;
122
+ return wallet;
123
+ }
124
+ return {
125
+ config,
126
+ chainAddresses: chainCfg,
127
+ publicClient,
128
+ sdk,
129
+ getWallet,
130
+ getAddress,
131
+ getL2PublicClient,
132
+ getL2Wallet,
133
+ reload() {
134
+ _runtime = null;
135
+ }
136
+ };
137
+ }
138
+ function getRuntime() {
139
+ if (!_runtime) _runtime = buildRuntime();
140
+ return _runtime;
141
+ }
142
+ function applySettingsUpdate(patch) {
143
+ const current = loadConfig();
144
+ if (patch.network !== void 0) current.network = patch.network;
145
+ if (patch.mode !== void 0) current.mode = patch.mode;
146
+ if (patch.rpc !== void 0) current.rpc = patch.rpc;
147
+ if (patch.model !== void 0 && current.ai) current.ai.model = patch.model;
148
+ if (patch.chain_scope !== void 0) current.chainScope = patch.chain_scope;
149
+ saveConfig(current);
150
+ _runtime = null;
151
+ return current;
152
+ }
153
+
154
+ // src/tools/balance.ts
155
+ import { formatEther } from "viem";
156
+ async function getBalance(address) {
157
+ const rt = getRuntime();
158
+ const addr = address ?? rt.getAddress();
159
+ const [eth, steth, wsteth] = await Promise.all([
160
+ rt.sdk.core.balanceETH(addr),
161
+ rt.sdk.steth.balance(addr),
162
+ rt.sdk.wsteth.balance(addr)
163
+ ]);
164
+ return {
165
+ address: addr,
166
+ mode: rt.config.mode,
167
+ network: rt.chainAddresses.name,
168
+ balances: {
169
+ eth: formatEther(eth),
170
+ stETH: formatEther(steth),
171
+ wstETH: formatEther(wsteth)
172
+ }
173
+ };
174
+ }
175
+ async function getRewards(address, days = 7) {
176
+ const rt = getRuntime();
177
+ const addr = address ?? rt.getAddress();
178
+ const rewards = await rt.sdk.rewards.getRewardsFromChain({
179
+ address: addr,
180
+ stepBlock: 1e3,
181
+ back: { days: BigInt(days) }
182
+ });
183
+ return {
184
+ address: addr,
185
+ period: `${days} days`,
186
+ totalRewards: formatEther(rewards.totalRewards),
187
+ baseBalance: formatEther(rewards.baseBalance),
188
+ rewards: rewards.rewards.slice(0, 10).map((e) => ({
189
+ type: e.type,
190
+ change: formatEther(e.change),
191
+ balance: formatEther(e.balance)
192
+ }))
193
+ };
194
+ }
195
+
196
+ // src/tools/wrap.ts
197
+ import { parseEther, formatEther as formatEther2 } from "viem";
198
+ async function wrapSteth(amountSteth, dryRun) {
199
+ const rt = getRuntime();
200
+ const amount = parseEther(amountSteth);
201
+ const shouldDryRun = rt.config.mode === "simulation" ? dryRun !== false : !!dryRun;
202
+ const expectedWstETH = await rt.sdk.wrap.convertStethToWsteth(amount);
203
+ if (shouldDryRun) {
204
+ return {
205
+ simulated: true,
206
+ mode: rt.config.mode,
207
+ network: rt.chainAddresses.name,
208
+ action: "wrap_steth",
209
+ amountSteth,
210
+ expectedWstETH: formatEther2(expectedWstETH),
211
+ note: "wstETH is non-rebasing \u2014 balance stays fixed while value grows. Better for DeFi."
212
+ };
213
+ }
214
+ const account = rt.getAddress();
215
+ const tx = await rt.sdk.wrap.wrapSteth({
216
+ value: amount,
217
+ account,
218
+ callback: () => {
219
+ }
220
+ });
221
+ return {
222
+ simulated: false,
223
+ mode: rt.config.mode,
224
+ network: rt.chainAddresses.name,
225
+ action: "wrap_steth",
226
+ amountSteth,
227
+ txHash: tx.hash,
228
+ wstethReceived: formatEther2(tx.result?.wstethReceived ?? 0n)
229
+ };
230
+ }
231
+ async function unwrapWsteth(amountWsteth, dryRun) {
232
+ const rt = getRuntime();
233
+ const amount = parseEther(amountWsteth);
234
+ const shouldDryRun = rt.config.mode === "simulation" ? dryRun !== false : !!dryRun;
235
+ const expectedStETH = await rt.sdk.wrap.convertWstethToSteth(amount);
236
+ if (shouldDryRun) {
237
+ return {
238
+ simulated: true,
239
+ mode: rt.config.mode,
240
+ network: rt.chainAddresses.name,
241
+ action: "unwrap_wsteth",
242
+ amountWsteth,
243
+ expectedStETH: formatEther2(expectedStETH),
244
+ note: "Unwrapping gives rebasing stETH back. Balance updates daily with rewards."
245
+ };
246
+ }
247
+ const account = rt.getAddress();
248
+ const tx = await rt.sdk.wrap.unwrap({
249
+ value: amount,
250
+ account,
251
+ callback: () => {
252
+ }
253
+ });
254
+ return {
255
+ simulated: false,
256
+ mode: rt.config.mode,
257
+ network: rt.chainAddresses.name,
258
+ action: "unwrap_wsteth",
259
+ amountWsteth,
260
+ txHash: tx.hash,
261
+ stethReceived: formatEther2(tx.result?.stethReceived ?? 0n)
262
+ };
263
+ }
264
+ async function getConversionRate() {
265
+ const rt = getRuntime();
266
+ const oneEther = parseEther("1");
267
+ const [wstethPerSteth, stethPerWsteth] = await Promise.all([
268
+ rt.sdk.wrap.convertStethToWsteth(oneEther),
269
+ rt.sdk.wrap.convertWstethToSteth(oneEther)
270
+ ]);
271
+ return {
272
+ mode: rt.config.mode,
273
+ network: rt.chainAddresses.name,
274
+ "1_stETH_in_wstETH": formatEther2(wstethPerSteth),
275
+ "1_wstETH_in_stETH": formatEther2(stethPerWsteth),
276
+ note: "wstETH/stETH ratio increases over time as staking rewards accumulate."
277
+ };
278
+ }
279
+
280
+ export {
281
+ L2_CHAINS,
282
+ getRuntime,
283
+ applySettingsUpdate,
284
+ getBalance,
285
+ getRewards,
286
+ wrapSteth,
287
+ unwrapWsteth,
288
+ getConversionRate
289
+ };
@@ -0,0 +1,233 @@
1
+ #!/usr/bin/env node
2
+ import {
3
+ getRuntime
4
+ } from "./chunk-EKZFGIVK.js";
5
+
6
+ // src/tools/unstake.ts
7
+ import { parseEther, formatEther } from "viem";
8
+ async function requestWithdrawal(amountSteth, dryRun) {
9
+ const rt = getRuntime();
10
+ const amount = parseEther(amountSteth);
11
+ const shouldDryRun = rt.config.mode === "simulation" ? dryRun !== false : !!dryRun;
12
+ if (shouldDryRun) {
13
+ return {
14
+ simulated: true,
15
+ mode: rt.config.mode,
16
+ network: rt.chainAddresses.name,
17
+ action: "request_withdrawal",
18
+ amountSteth,
19
+ minWithdrawal: "0.1 stETH",
20
+ maxWithdrawal: "1000 stETH per request",
21
+ note: "Withdrawal requests enter a queue. Finalization can take hours to days depending on validator exits. You will receive an ERC-721 NFT representing your position."
22
+ };
23
+ }
24
+ const account = rt.getAddress();
25
+ const tx = await rt.sdk.withdraw.request.requestWithdrawal({
26
+ amount,
27
+ token: "stETH",
28
+ account,
29
+ callback: () => {
30
+ }
31
+ });
32
+ return {
33
+ simulated: false,
34
+ mode: rt.config.mode,
35
+ network: rt.chainAddresses.name,
36
+ action: "request_withdrawal",
37
+ amountSteth,
38
+ txHash: tx.hash,
39
+ requestIds: tx.result?.requests?.map((r) => r.requestId.toString()),
40
+ note: "Check status with get_withdrawal_status. Claim when finalized."
41
+ };
42
+ }
43
+ async function claimWithdrawals(requestIds, dryRun) {
44
+ const rt = getRuntime();
45
+ const ids = requestIds.map(BigInt);
46
+ const shouldDryRun = rt.config.mode === "simulation" ? dryRun !== false : !!dryRun;
47
+ if (shouldDryRun) {
48
+ return {
49
+ simulated: true,
50
+ mode: rt.config.mode,
51
+ network: rt.chainAddresses.name,
52
+ action: "claim_withdrawals",
53
+ requestIds,
54
+ note: "Claims can only be made after requests are finalized. Use get_withdrawal_status first."
55
+ };
56
+ }
57
+ const account = rt.getAddress();
58
+ const tx = await rt.sdk.withdraw.claim.claimRequests({
59
+ requestsIds: ids,
60
+ account,
61
+ callback: () => {
62
+ }
63
+ });
64
+ return {
65
+ simulated: false,
66
+ mode: rt.config.mode,
67
+ network: rt.chainAddresses.name,
68
+ action: "claim_withdrawals",
69
+ requestIds,
70
+ txHash: tx.hash
71
+ };
72
+ }
73
+ async function getWithdrawalRequests(address) {
74
+ const rt = getRuntime();
75
+ const addr = address ?? rt.getAddress();
76
+ const requests = await rt.sdk.withdraw.views.getWithdrawalRequestsIds({ account: addr });
77
+ return {
78
+ address: addr,
79
+ mode: rt.config.mode,
80
+ network: rt.chainAddresses.name,
81
+ requests: requests.map((id) => id.toString()),
82
+ count: requests.length
83
+ };
84
+ }
85
+ async function getWithdrawalStatus(requestIds) {
86
+ const rt = getRuntime();
87
+ const ids = requestIds.map(BigInt);
88
+ const statuses = await rt.sdk.withdraw.views.getWithdrawalStatus({ requestsIds: ids });
89
+ return {
90
+ mode: rt.config.mode,
91
+ network: rt.chainAddresses.name,
92
+ statuses: statuses.map((s, i) => ({
93
+ requestId: requestIds[i],
94
+ amountOfStETH: formatEther(s.amountOfStETH),
95
+ amountOfShares: formatEther(s.amountOfShares),
96
+ owner: s.owner,
97
+ isFinalized: s.isFinalized,
98
+ isClaimed: s.isClaimed
99
+ }))
100
+ };
101
+ }
102
+
103
+ // src/tools/governance.ts
104
+ import { createPublicClient, http, parseAbi, formatEther as formatEther2 } from "viem";
105
+ import { mainnet } from "viem/chains";
106
+ import { defineChain } from "viem";
107
+ var hoodi = defineChain({
108
+ id: 560048,
109
+ name: "Hoodi Testnet",
110
+ nativeCurrency: { name: "Ether", symbol: "ETH", decimals: 18 },
111
+ rpcUrls: { default: { http: ["https://hoodi.drpc.org"] } }
112
+ });
113
+ var VOTING_ABI = parseAbi([
114
+ "function vote(uint256 _voteId, bool _supports, bool _executesIfDecided) external",
115
+ "function getVote(uint256 _voteId) external view returns (bool open, bool executed, uint64 startDate, uint64 snapshotBlock, uint64 supportRequired, uint64 minAcceptQuorum, uint256 yea, uint256 nay, uint256 votingPower, bytes script)",
116
+ "function votesLength() external view returns (uint256)"
117
+ ]);
118
+ async function getProposals(count = 5) {
119
+ const rt = getRuntime();
120
+ const votingAddress = rt.chainAddresses.voting;
121
+ const rpcUrl = rt.config.rpc ?? rt.chainAddresses.defaultRpc;
122
+ const viemChain = rt.config.network === "mainnet" ? mainnet : hoodi;
123
+ const client = createPublicClient({ chain: viemChain, transport: http(rpcUrl) });
124
+ const totalVotes = await client.readContract({
125
+ address: votingAddress,
126
+ abi: VOTING_ABI,
127
+ functionName: "votesLength"
128
+ });
129
+ const latest = Number(totalVotes);
130
+ const from = Math.max(0, latest - count);
131
+ const ids = Array.from({ length: latest - from }, (_, i) => from + i);
132
+ const votes = await Promise.all(
133
+ ids.map(async (id) => {
134
+ const v = await client.readContract({
135
+ address: votingAddress,
136
+ abi: VOTING_ABI,
137
+ functionName: "getVote",
138
+ args: [BigInt(id)]
139
+ });
140
+ return {
141
+ id,
142
+ open: v[0],
143
+ executed: v[1],
144
+ startDate: new Date(Number(v[2]) * 1e3).toISOString(),
145
+ yea: formatEther2(v[6]),
146
+ nay: formatEther2(v[7]),
147
+ votingPower: formatEther2(v[8])
148
+ };
149
+ })
150
+ );
151
+ return {
152
+ mode: rt.config.mode,
153
+ network: rt.chainAddresses.name,
154
+ votingContract: votingAddress,
155
+ totalProposals: latest,
156
+ proposals: votes.reverse()
157
+ };
158
+ }
159
+ async function getProposal(proposalId) {
160
+ const rt = getRuntime();
161
+ const votingAddress = rt.chainAddresses.voting;
162
+ const rpcUrl = rt.config.rpc ?? rt.chainAddresses.defaultRpc;
163
+ const viemChain = rt.config.network === "mainnet" ? mainnet : hoodi;
164
+ const client = createPublicClient({ chain: viemChain, transport: http(rpcUrl) });
165
+ const v = await client.readContract({
166
+ address: votingAddress,
167
+ abi: VOTING_ABI,
168
+ functionName: "getVote",
169
+ args: [BigInt(proposalId)]
170
+ });
171
+ return {
172
+ mode: rt.config.mode,
173
+ network: rt.chainAddresses.name,
174
+ id: proposalId,
175
+ open: v[0],
176
+ executed: v[1],
177
+ startDate: new Date(Number(v[2]) * 1e3).toISOString(),
178
+ snapshotBlock: v[3].toString(),
179
+ supportRequired: `${(Number(v[4]) / 1e16).toFixed(1)}%`,
180
+ minAcceptQuorum: `${(Number(v[5]) / 1e16).toFixed(1)}%`,
181
+ yea: formatEther2(v[6]),
182
+ nay: formatEther2(v[7]),
183
+ votingPower: formatEther2(v[8])
184
+ };
185
+ }
186
+ async function castVote(proposalId, support, dryRun) {
187
+ const rt = getRuntime();
188
+ const votingAddress = rt.chainAddresses.voting;
189
+ const shouldDryRun = rt.config.mode === "simulation" ? dryRun !== false : !!dryRun;
190
+ if (shouldDryRun) {
191
+ const proposal = await getProposal(proposalId);
192
+ return {
193
+ simulated: true,
194
+ mode: rt.config.mode,
195
+ network: rt.chainAddresses.name,
196
+ action: "cast_vote",
197
+ proposalId,
198
+ vote: support ? "YEA" : "NAY",
199
+ proposal,
200
+ note: "You need LDO tokens to vote. Voting power is based on LDO balance at snapshot block."
201
+ };
202
+ }
203
+ const wallet = rt.getWallet();
204
+ const account = rt.getAddress();
205
+ const viemChain = rt.config.network === "mainnet" ? mainnet : hoodi;
206
+ const hash = await wallet.writeContract({
207
+ chain: viemChain,
208
+ address: votingAddress,
209
+ abi: VOTING_ABI,
210
+ functionName: "vote",
211
+ args: [BigInt(proposalId), support, false],
212
+ account
213
+ });
214
+ return {
215
+ simulated: false,
216
+ mode: rt.config.mode,
217
+ network: rt.chainAddresses.name,
218
+ action: "cast_vote",
219
+ proposalId,
220
+ vote: support ? "YEA" : "NAY",
221
+ txHash: hash
222
+ };
223
+ }
224
+
225
+ export {
226
+ requestWithdrawal,
227
+ claimWithdrawals,
228
+ getWithdrawalRequests,
229
+ getWithdrawalStatus,
230
+ getProposals,
231
+ getProposal,
232
+ castVote
233
+ };