-
Notifications
You must be signed in to change notification settings - Fork 5
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
Showing
2 changed files
with
155 additions
and
0 deletions.
There are no files selected for viewing
58 changes: 58 additions & 0 deletions
58
packages/ethernaut-optigov/src/internal/agora/Proposals.js
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,58 @@ | ||
const debug = require('ethernaut-common/src/ui/debug') | ||
|
||
class Proposals { | ||
constructor(agora) { | ||
this.agora = agora | ||
} | ||
|
||
// Get a list of proposals with pagination | ||
async getProposals({ limit = 10, offset = 0 } = {}) { | ||
try { | ||
const axiosInstance = this.agora.createAxiosInstance() | ||
const response = await axiosInstance.get('/proposals', { | ||
params: { limit, offset }, | ||
}) | ||
|
||
debug.log(`Proposals: ${response.data}`, 'ethernaut-optigov') | ||
return response.data.data | ||
} catch (error) { | ||
this.agora.handleError(error) | ||
} | ||
} | ||
|
||
// Get a specific proposal by proposalId | ||
async getProposalById(proposalId) { | ||
try { | ||
const axiosInstance = this.agora.createAxiosInstance() | ||
const response = await axiosInstance.get(`/proposals/${proposalId}`) | ||
|
||
debug.log(`Proposal: ${response.data}`, 'ethernaut-optigov') | ||
return response.data | ||
} catch (error) { | ||
this.agora.handleError(error) | ||
} | ||
} | ||
|
||
// Get a paginated list of votes for a specific proposal | ||
async getProposalVotes({ proposalId, limit = 10, offset = 0 }) { | ||
try { | ||
const axiosInstance = this.agora.createAxiosInstance() | ||
const response = await axiosInstance.get( | ||
`/proposals/${proposalId}/votes`, | ||
{ | ||
params: { limit, offset }, | ||
}, | ||
) | ||
|
||
debug.log( | ||
`Votes for Proposal ${proposalId}: ${response.data}`, | ||
'ethernaut-optigov', | ||
) | ||
return response.data.data | ||
} catch (error) { | ||
this.agora.handleError(error) | ||
} | ||
} | ||
} | ||
|
||
module.exports = Proposals |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,97 @@ | ||
const types = require('ethernaut-common/src/validation/types') | ||
const output = require('ethernaut-common/src/ui/output') | ||
const Proposals = require('../internal/agora/Proposals') | ||
const Agora = require('../internal/agora/Agora') | ||
|
||
require('../scopes/optigov') | ||
.task( | ||
'proposals', | ||
'Prints a list of proposals registered in RetroPGF, given specified filters', | ||
) | ||
.addOptionalParam( | ||
'limit', | ||
'The maximum number of proposals to fetch. Defaults to 10.', | ||
10, | ||
types.int, | ||
) | ||
.addOptionalParam( | ||
'offset', | ||
'The number of proposals to skip before starting to fetch. Defaults to 0.', | ||
0, | ||
types.int, | ||
) | ||
.addOptionalParam( | ||
'proposalId', | ||
'The ID of a specific proposal to query.', | ||
undefined, | ||
types.string, | ||
) | ||
.addOptionalParam( | ||
'votes', | ||
'If specified, fetch votes for the given proposalId.', | ||
false, | ||
types.string, | ||
) | ||
.setAction(async ({ limit, offset, proposalId, votes }) => { | ||
try { | ||
// Instantiate Agora and Proposals | ||
const agora = new Agora() | ||
const proposals = new Proposals(agora) | ||
|
||
// If proposalId is provided, fetch specific proposal or votes | ||
if (proposalId) { | ||
if (votes) { | ||
// Get votes for the specified proposal | ||
const proposalVotes = await proposals.getProposalVotes({ | ||
proposalId, | ||
limit, | ||
offset, | ||
}) | ||
return output.resultBox( | ||
printVotes(proposalVotes), | ||
`Votes for Proposal ${proposalId}`, | ||
) | ||
} else { | ||
// Get the specific proposal by ID | ||
const proposal = await proposals.getProposalById(proposalId) | ||
return output.resultBox( | ||
printProposal(proposal), | ||
`Proposal ${proposalId}`, | ||
) | ||
} | ||
} | ||
|
||
// If no specific proposalId is given, fetch the list of proposals | ||
const proposalList = await proposals.getProposals({ limit, offset }) | ||
return output.resultBox(printProposals(proposalList), 'Proposals') | ||
} catch (err) { | ||
return output.errorBox(err) | ||
} | ||
}) | ||
|
||
// Utility function to print a list of proposals | ||
function printProposals(proposals) { | ||
const strs = [] | ||
|
||
for (const proposal of proposals) { | ||
strs.push(` - ${proposal.title}: ${proposal.summary}`) | ||
} | ||
|
||
return strs.join('\n\n') | ||
} | ||
|
||
// Utility function to print a specific proposal | ||
function printProposal(proposal) { | ||
return `Title: ${proposal.title}\nSummary: ${proposal.summary}\nDetails: ${proposal.details}` | ||
} | ||
|
||
// Utility function to print votes for a proposal | ||
function printVotes(votes) { | ||
const strs = [] | ||
|
||
for (const vote of votes) { | ||
strs.push(` - Voter: ${vote.voter}, Choice: ${vote.choice}`) | ||
} | ||
|
||
return strs.join('\n\n') | ||
} |