-
Notifications
You must be signed in to change notification settings - Fork 5
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Colony metrics route #25
Merged
Merged
Changes from all commits
Commits
Show all changes
6 commits
Select commit
Hold shift + click to select a range
8b1c892
added route which returns farmer reputation and HX balance in colony
JonathanScialpi 5fabcd4
updating readme with blockchain integration architecture and diagram
JonathanScialpi e2cb43d
route for reputation stats
JonathanScialpi 1035daa
changing the name of the service and route
JonathanScialpi a95be6c
moving IFT and web3 under blockchain integration dir
JonathanScialpi 3d2359a
removing debug logs from new colony route
JonathanScialpi File filter
Filter by extension
Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
There are no files selected for viewing
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
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
File renamed without changes.
File renamed without changes.
File renamed without changes.
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
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
73 changes: 73 additions & 0 deletions
73
backend/src/integrations/Blockchain/web3/helper-functions.ts
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,73 @@ | ||
import { CropTemplate} from "../../../db/entities/cropTemplate"; | ||
import { Field, SubField, SubFieldCrop} from "../../../db/entities/field" | ||
|
||
// actionWeight * MaxPayout = NumOfHXToPay | ||
|
||
export const calculatePayment = (actionWeight, maxPayout) => { | ||
return Math.floor((actionWeight/100) * maxPayout); | ||
} | ||
|
||
// this function should receive a cropId and farmerId which can be used to find the proper SubFieldCrop | ||
// once found, we can set the action value to that of actionStatus arg. | ||
export function UpdateReputationActions( | ||
field: Field, | ||
cropId: string, | ||
farmer: string, | ||
actionName: string, | ||
actionStatus: boolean): [Field, CropTemplate, Boolean]{ | ||
let cropTemplate; | ||
let statusUpdated = false; | ||
const subFieldsArray: SubField[] = field.subFields; | ||
for(let subFieldIndex in subFieldsArray){ | ||
const subFieldCropsArray: SubFieldCrop[] = subFieldsArray[subFieldIndex].properties.crops; | ||
for(let subFieldCropIndex in subFieldCropsArray){ | ||
if(subFieldCropsArray[subFieldCropIndex].crop._id?.toString() === cropId && | ||
subFieldCropsArray[subFieldCropIndex].farmer === farmer && | ||
subFieldCropsArray[subFieldCropIndex].reputation_actions | ||
){ | ||
statusUpdated = (subFieldCropsArray[subFieldCropIndex].reputation_actions![actionName] != actionStatus); | ||
subFieldCropsArray[subFieldCropIndex].reputation_actions![actionName] = actionStatus; | ||
cropTemplate = subFieldCropsArray[subFieldCropIndex].crop_template!; | ||
} | ||
} | ||
} | ||
return [field, cropTemplate, statusUpdated]; | ||
} | ||
|
||
const calculateReputationEarned = (reputationActions: Record<string,boolean>, reputationWeights: Record<string, string>) => { | ||
let totalRepEarned = 0; | ||
for(const key in reputationActions){ | ||
totalRepEarned += calculatePayment(reputationActions[key], reputationWeights[key]); | ||
} | ||
return totalRepEarned; | ||
} | ||
|
||
/* | ||
given a field, return the max payout and total reputation earned per subfield | ||
[ | ||
crop_name : { | ||
id: ... | ||
max_reputation: ... | ||
reputation_earned: ... | ||
}, | ||
... | ||
] | ||
*/ | ||
export function getReputationReport(field: Field): any{ | ||
let reputationReportList: Record<string, any>[] = []; | ||
const subFieldsArray: SubField[] = field.subFields; | ||
|
||
for(let subFieldIndex in subFieldsArray){ | ||
const subFieldCropsArray: SubFieldCrop[] = subFieldsArray[subFieldIndex].properties.crops; | ||
for(let subFieldCropIndex in subFieldCropsArray){ | ||
reputationReportList.push({ | ||
[subFieldCropsArray[subFieldCropIndex].crop.name] : { | ||
id : subFieldCropsArray[subFieldCropIndex].crop._id!.toString(), | ||
max_reputation : subFieldCropsArray[subFieldCropIndex].crop.crop_template!.max_payout, | ||
reputation_earned : calculateReputationEarned(subFieldCropsArray[subFieldCropIndex].reputation_actions!, subFieldCropsArray[subFieldCropIndex].crop.crop_template!.action_weights!) | ||
} | ||
}); | ||
} | ||
} | ||
return reputationReportList; | ||
} |
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
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,46 @@ | ||
import { Request, Response, Router } from "express"; | ||
import { gnosisConnection } from "../integrations/Blockchain/web3/authentication-functions"; | ||
import { AwsKmsSigner } from "../integrations/Blockchain/web3/AwsKmsSigner"; | ||
import { ColonyNetwork } from '@colony/sdk'; | ||
import { getReputationReport } from "../integrations/Blockchain/web3/helper-functions"; | ||
import { FarmerModel } from "../db/entities/farmer"; | ||
|
||
var router = Router(); | ||
|
||
router.post("/", getReputationForFarmer); | ||
|
||
// This route expects a Farmer ID string. The farmer Id will be used to retrieve the Farmer object. | ||
// The farmer object's ethKeyID will be used to get the farmer's ethAddress and reputation. | ||
async function getReputationForFarmer(req: Request, res: Response){ | ||
try{ | ||
// get farmer object | ||
const farmer = await FarmerModel.findById(req.body.farmer_id).lean().exec(); | ||
|
||
if(!farmer){ | ||
throw new Error("Farmer not found."); | ||
}else{ | ||
// connect to Gnosis network with Farmer account | ||
const provider = gnosisConnection(); | ||
const farmerSigner = new AwsKmsSigner(farmer!.ethKeyID, provider); | ||
const farmerEthAddress = await farmerSigner.getAddress(); | ||
|
||
// connect to Heifer colony and retrieve farmer rep and HX balance | ||
const colonyNetwork = new ColonyNetwork(farmerSigner); | ||
const colony = await colonyNetwork.getColony(process.env.HEIFER_COLONY_CONTRACT_ADDRESS!); | ||
const balance = await colony.getBalance(); | ||
const reputation = await colony.getReputation(farmerEthAddress); | ||
res.json({ | ||
colony_balance : balance.toString(), | ||
reputation : reputation.toString(), | ||
farmer_eth_address: farmerEthAddress, | ||
reputation_report : getReputationReport(req.body) | ||
}); | ||
} | ||
|
||
}catch(e){ | ||
console.error(e); | ||
res.status(500).json(e); | ||
} | ||
} | ||
|
||
export default router; |
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
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
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
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
This file was deleted.
Oops, something went wrong.
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
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,12 @@ | ||
import axios from 'axios'; | ||
import { Field } from '../../../backend/src/db/entities/field'; | ||
|
||
export class ColonyAPI{ | ||
APIBase = "/api/colony/"; | ||
|
||
async getReputationForFarmer(field: Field): Promise<any> { | ||
const data = await axios.post(this.APIBase, field); | ||
console.log(data.data) | ||
return data.data; | ||
} | ||
} |
Oops, something went wrong.
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I don't want to create extra work for you, but would it possible to wrap anything related to colony into it's own class? It would make it easier to call from other places but also test and mock colony data. It would really come down to being another class in the web3 folder that wraps around colony's api calls.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Let's discuss further in a technical call and then I will create a new branch for this if needed. The reason why I'm not sure if its required is because the Colony SDK is already like a wrapper class which makes it easier to interact with colony so another class would be like a wrapper class on top of another wrapper class.