Skip to content

Commit

Permalink
refactor: Update Agora class and related modules Auth & Projects
Browse files Browse the repository at this point in the history
  • Loading branch information
luisvid committed Oct 24, 2024
1 parent 3eccde5 commit 164d8b1
Show file tree
Hide file tree
Showing 5 changed files with 91 additions and 96 deletions.
57 changes: 42 additions & 15 deletions packages/ethernaut-optigov/src/internal/agora/Agora.js
Original file line number Diff line number Diff line change
@@ -1,35 +1,62 @@
const axios = require('axios')
const debug = require('ethernaut-common/src/ui/debug')
const EthernautCliError = require('ethernaut-common/src/error/error')
const Auth = require('./Auth')
const Projects = require('./Projects')
const debug = require('ethernaut-common/src/ui/debug')

const API_BASE_URL = 'https://vote.optimism.io/api/v1'
const AGORA_API_KEY = process.env.AGORA_API_KEY

class Agora {
constructor() {
this.auth = new Auth(this)
this.projects = new Projects(this)
this.apiKey = AGORA_API_KEY
this.apiBaseUrl = API_BASE_URL
this.bearerToken = null
}

async getSpec() {
try {
const response = await axios.get(`${API_BASE_URL}/spec`, {
headers: {
Authorization: `Bearer ${AGORA_API_KEY}`,
},
})
// Axios instance setup
createAxiosInstance() {
const headers = {
Authorization: this.bearerToken
? `Bearer ${this.bearerToken}`
: `Bearer ${this.apiKey}`,
}

debug.log(`Spec: ${response.data}`, 'ethernaut-optigov')
return response.data
} catch (error) {
return axios.create({
baseURL: this.apiBaseUrl,
headers,
})
}

// Handle common API errors
handleError(error) {
if (error.response) {
throw new EthernautCliError(
'ethernaut-optigov',
`Http status error: ${error.response.data}`,
)
} else {
throw new EthernautCliError(
'ethernaut-optigov',
`Http status error: ${error.message}`,
)
}
}

// common method for getting API spec
async getSpec() {
try {
const axiosInstance = this.createAxiosInstance()
const response = await axiosInstance.get('/spec')
debug.log(`Spec: ${response.data}`, 'ethernaut-optigov')
return response.data
} catch (error) {
this.handleError(error)
}
}

// Set the bearer token after authentication
setBearerToken(token) {
this.bearerToken = token
}
}

module.exports = Agora
54 changes: 15 additions & 39 deletions packages/ethernaut-optigov/src/internal/agora/Auth.js
Original file line number Diff line number Diff line change
@@ -1,62 +1,38 @@
const axios = require('axios')
const debug = require('ethernaut-common/src/ui/debug')
const EthernautCliError = require('ethernaut-common/src/error/error')

class Auth {
constructor(agora) {
this.agora = agora
}

// Get a nonce from the Agora API
async getNonce() {
try {
const response = await axios.get(`${this.agora.API_BASE_URL}/auth/nonce`)

const axiosInstance = this.agora.createAxiosInstance()
const response = await axiosInstance.get('/auth/nonce')
debug.log(`Nonce: ${response.data.nonce}`, 'ethernaut-optigov')
return response.data
return response.data.nonce
} catch (error) {
throw new EthernautCliError(
'ethernaut-optigov',
`Http status error: ${error.message}`,
)
this.agora.handleError(error)
}
}

// Authenticate with the Agora API
async authenticateWithAgora(message, signature, nonce) {
try {
const response = await axios.post(
`${this.agora.API_BASE_URL}/auth/verify`,
{
message,
signature,
nonce,
},
{
headers: {
'Content-Type': 'application/json',
},
},
)
const axiosInstance = this.agora.createAxiosInstance()
const response = await axiosInstance.post('/auth/verify', {
message,
signature,
nonce,
})

debug.log('Auth Response Status:', response.status)
// save the Bearer token
this.bearerToken = response.data.access_token

// Set the Bearer token for future requests
this.agora.setBearerToken(response.data.access_token)

return response.data.access_token
} catch (error) {
if (error.response) {
// Server responded with a status other than 2xx
throw new EthernautCliError(
'ethernaut-optigov',
`Http status error: ${error.response.data}`,
)
} else {
// Other errors (e.g., network issue)
throw new EthernautCliError(
'ethernaut-optigov',
`Http status error: ${error.message}`,
)
}
this.agora.handleError(error)
}
}
}
Expand Down
40 changes: 13 additions & 27 deletions packages/ethernaut-optigov/src/internal/agora/Projects.js
Original file line number Diff line number Diff line change
@@ -1,56 +1,42 @@
const axios = require('axios')
const debug = require('ethernaut-common/src/ui/debug')
const EthernautCliError = require('ethernaut-common/src/error/error')

class Projects {
constructor(agora) {
this.agora = agora
}

async getLatestRound() {
// TODO: Implement this
return 5
return 5 // Placeholder, you can implement this logic
}

async projects({ limit, offset } = { limit: 10, offset: 0 }) {
async getProjects({ limit = 10, offset = 0 } = {}) {
try {
const response = await axios.get(
`${this.agora.API_BASE_URL}/projects?limit=${limit}&?offset=${offset}`,
{
headers: {
Authorization: `Bearer ${this.agora.AGORA_API_KEY}`,
},
},
)
const axiosInstance = this.agora.createAxiosInstance()
const response = await axiosInstance.get('/projects', {
params: { limit, offset },
})

debug.log(`Projects: ${response.data}`, 'ethernaut-optigov')
return response.data.data
} catch (error) {
throw new EthernautCliError(
'ethernaut-optigov',
`Http status error: ${error.message}`,
)
this.agora.handleError(error)
}
}

async roundProjects({ roundId, limit = 10, offset = 0 }) {
async getRoundProjects({ roundId, limit = 10, offset = 0 }) {
try {
const response = await axios.get(
`${this.agora.API_BASE_URL}/retrofunding/rounds/${roundId}/projects?limit=${limit}&offset=${offset}`,
const axiosInstance = this.agora.createAxiosInstance()
const response = await axiosInstance.get(
`/retrofunding/rounds/${roundId}/projects`,
{
headers: {
Authorization: `Bearer ${this.apiKey}`,
},
params: { limit, offset },
},
)

debug.log(`Round Projects: ${response.data}`, 'ethernaut-optigov')
return response.data.data
} catch (error) {
throw new EthernautCliError(
'ethernaut-optigov',
`Http status error: ${error.message}`,
)
this.agora.handleError(error)
}
}
}
Expand Down
30 changes: 17 additions & 13 deletions packages/ethernaut-optigov/src/tasks/Projects.js
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
const types = require('ethernaut-common/src/validation/types')
const output = require('ethernaut-common/src/ui/output')
const Projects = require('../internal/agora/Projects')
const Agora = require('../internal/agora/Agora')

require('../scopes/optigov')
Expand Down Expand Up @@ -27,17 +28,11 @@ require('../scopes/optigov')
)
.setAction(async ({ round, name, category }) => {
try {
const agora = new Agora()
const projects = await getProjects(round)

let roundId
if (round === 'latest') roundId = agora.projects.getLatestRound()
else if (round === 'any') roundId = undefined
const filteredProjects = filterProjects(projects, name, category)

let projects = await getProjects(agora, roundId)

projects = filterProjects(projects, name, category)

return output.resultBox(printProjects(projects), 'Projects')
return output.resultBox(printProjects(filteredProjects), 'Projects')
} catch (err) {
return output.errorBox(err)
}
Expand Down Expand Up @@ -72,10 +67,19 @@ function printProjects(projects) {
return strs.join('\n\n')
}

async function getProjects(agora, roundId) {
if (roundId === undefined) {
return await agora.projects.projects()
async function getProjects(round) {
const agora = new Agora()
const projects = new Projects(agora)

let roundId

if (round === 'latest') {
roundId = await projects.getLatestRound()
}

if (!roundId) {
return await projects.getProjects()
}

return await agora.projects.roundProjects({ roundId })
return await projects.getRoundProjects({ roundId })
}
6 changes: 4 additions & 2 deletions packages/ethernaut-optigov/src/tasks/login.js
Original file line number Diff line number Diff line change
@@ -1,7 +1,8 @@
const Auth = require('../internal/agora/Auth')
const output = require('ethernaut-common/src/ui/output')
const { createSiweMessage } = require('../internal/Siwe')
const EthernautCliError = require('ethernaut-common/src/error/error')
const Auth = require('../internal/agora/Auth')
const Agora = require('../internal/agora/Agora')

require('../scopes/optigov')
.task(
Expand All @@ -24,7 +25,8 @@ require('../scopes/optigov')
'ethernaut-optigov',
)

const auth = new Auth()
const agora = new Agora()
const auth = new Auth(agora)

const statement = 'Log in to Agoras RetroPGF API with SIWE.'
const nonce = await auth.getNonce()
Expand Down

0 comments on commit 164d8b1

Please sign in to comment.