-
Notifications
You must be signed in to change notification settings - Fork 27
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Merge pull request #153 from gnosis/manboy-eth/issue149
[Reality Module] Add monitoring for answers submitted for a proposal question at Reality.eth
- Loading branch information
Showing
9 changed files
with
433 additions
and
77 deletions.
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
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
95 changes: 95 additions & 0 deletions
95
packages/backend/lib/defender/autotasks/on_new_question_from_module.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,95 @@ | ||
const { SentinelClient } = require("defender-sentinel-client") | ||
|
||
const PROPOSAL_QUESTION_CREATED_EVENT_TOPIC = | ||
"0xa1f5047031a658827550a2c4be07648493f3ac88a09c857b3961d1336429a31f" // Keccak-256("ProposalQuestionCreated(bytes32,string)") | ||
|
||
// @param event: AutotaskEvent | ||
exports.handler = async function (event) { | ||
// variable from the event | ||
const evmEvent = event.request.body.transaction.logs.find( | ||
(log) => log.topics[0] === PROPOSAL_QUESTION_CREATED_EVENT_TOPIC, | ||
) | ||
const questionId = evmEvent.topics[1] | ||
console.log("QuestionId to monitor for:", questionId) | ||
const txHash = event.request.body.transaction.transactionHash | ||
const txFrom = event.request.body.transaction.from | ||
|
||
// variables from autotask creation | ||
const network = "{{network}}" | ||
const oracleAddress = "{{oracleAddress}}" | ||
const notificationChannels = "{{notificationChannels}}" | ||
const apiKey = "{{apiKey}}" | ||
const apiSecret = "{{apiSecret}}" | ||
|
||
const client = new SentinelClient({ | ||
apiKey, | ||
apiSecret, | ||
}) | ||
|
||
const requestParameters = { | ||
type: "BLOCK", | ||
network, | ||
name: `Answer submitted for a proposal question at Reality.eth for the Reality Module (on ${network})`, | ||
addresses: [oracleAddress], | ||
paused: false, | ||
abi: `[{ | ||
"anonymous": false, | ||
"inputs": [ | ||
{ | ||
"indexed": false, | ||
"internalType": "bytes32", | ||
"name": "answer", | ||
"type": "bytes32" | ||
}, | ||
{ | ||
"indexed": true, | ||
"internalType": "bytes32", | ||
"name": "question_id", | ||
"type": "bytes32" | ||
}, | ||
{ | ||
"indexed": false, | ||
"internalType": "bytes32", | ||
"name": "history_hash", | ||
"type": "bytes32" | ||
}, | ||
{ | ||
"indexed": true, | ||
"internalType": "address", | ||
"name": "user", | ||
"type": "address" | ||
}, | ||
{ | ||
"indexed": false, | ||
"internalType": "uint256", | ||
"name": "bond", | ||
"type": "uint256" | ||
}, | ||
{ | ||
"indexed": false, | ||
"internalType": "uint256", | ||
"name": "ts", | ||
"type": "uint256" | ||
}, | ||
{ | ||
"indexed": false, | ||
"internalType": "bool", | ||
"name": "is_commitment", | ||
"type": "bool" | ||
} | ||
], | ||
"name": "LogNewAnswer", | ||
"type": "event" | ||
}]`, | ||
eventConditions: [ | ||
{ | ||
eventSignature: | ||
"LogNewAnswer(bytes32,bytes32,bytes32,address,uint256,uint256,bool)", | ||
expression: `$1 == "${questionId}"`, | ||
}, | ||
], | ||
notificationChannels: notificationChannels, | ||
} | ||
|
||
return client.create(requestParameters) | ||
} |
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,117 @@ | ||
import { | ||
CreateSentinelRequest, | ||
NotificationType, | ||
SentinelClient, | ||
} from "defender-sentinel-client" | ||
import { AutotaskClient } from "defender-autotask-client" | ||
import { CreateAutotaskRequest } from "defender-autotask-client" | ||
import { Network } from "../../lib/types" | ||
import { packageCode, readFileAndReplace } from "../util" | ||
|
||
export { NotificationType } from "defender-sentinel-client" | ||
|
||
export const setupSentinelClient = ({ apiKey, apiSecret }) => | ||
new SentinelClient({ apiKey, apiSecret }) | ||
|
||
export const setupAutotaskClient = ({ apiKey, apiSecret }) => | ||
new AutotaskClient({ apiKey, apiSecret }) | ||
|
||
export const setupNewNotificationChannel = async ( | ||
client: SentinelClient, | ||
channel: NotificationType, | ||
config: any, | ||
) => { | ||
const notificationChannel = await client.createNotificationChannel({ | ||
type: channel, | ||
name: `ZodiacRealityModuleNotification-${channel}`, | ||
config, | ||
paused: false, | ||
}) | ||
console.log( | ||
"Created Notification Channel with ID: ", | ||
notificationChannel.notificationId, | ||
) | ||
|
||
return notificationChannel.notificationId | ||
} | ||
|
||
export const createSentinel = async ( | ||
client: SentinelClient, | ||
notificationChannels: string[], | ||
network: Network, | ||
realityModuleAddress: string, | ||
autotaskId: string, | ||
) => { | ||
const requestParameters: CreateSentinelRequest = { | ||
type: "BLOCK", | ||
network, | ||
name: `Proposal added to the Reality Module (${realityModuleAddress} on ${network})`, | ||
addresses: [realityModuleAddress], | ||
paused: false, | ||
abi: `[{ | ||
"anonymous": false, | ||
"inputs": [ | ||
{ | ||
"indexed": true, | ||
"internalType": "bytes32", | ||
"name": "questionId", | ||
"type": "bytes32" | ||
}, | ||
{ | ||
"indexed": true, | ||
"internalType": "string", | ||
"name": "proposalId", | ||
"type": "string" | ||
} | ||
], | ||
"name": "ProposalQuestionCreated", | ||
"type": "event" | ||
}]`, | ||
eventConditions: [ | ||
{ | ||
eventSignature: "ProposalQuestionCreated(bytes32,string)", | ||
}, | ||
], | ||
autotaskTrigger: autotaskId, | ||
notificationChannels: notificationChannels, | ||
} | ||
|
||
const sentinel = await client.create(requestParameters) | ||
console.log("Created Sentinel with subscriber ID: ", sentinel.subscriberId) | ||
|
||
return sentinel.subscriberId | ||
} | ||
|
||
export const createAutotask = async ( | ||
client: AutotaskClient, | ||
oracleAddress: string, | ||
notificationChannels: string[], | ||
network: string, | ||
apiKey: string, | ||
apiSecret: string, | ||
) => { | ||
const code = readFileAndReplace( | ||
"lib/defender/autotasks/on_new_question_from_module.js", | ||
{ | ||
"{{network}}": network, | ||
"{{oracleAddress}}": oracleAddress, | ||
'"{{notificationChannels}}"': JSON.stringify(notificationChannels), | ||
"{{apiKey}}": apiKey, | ||
"{{apiSecret}}": apiSecret, | ||
}, | ||
) | ||
|
||
const params: CreateAutotaskRequest = { | ||
name: "Setup Sentinel for new Reality.eth question", | ||
encodedZippedCode: await packageCode(code), | ||
trigger: { | ||
type: "webhook", | ||
}, | ||
paused: false, | ||
} | ||
|
||
const createdAutotask = await client.create(params) | ||
console.log("Created Autotask with ID: ", createdAutotask.autotaskId) | ||
|
||
return createdAutotask.autotaskId | ||
} |
Oops, something went wrong.