Doing external HTTP Calls with Relay

Hello I was looking at the workshop at https://blog.openzeppelin.com/workshop-recap-service-monitoring-and-emergency-response/

I do see sendLossAlert but im not sure how it’s implemented, im looking to query external data (not blockchain)

1 Like

Hi @Elyx0,

Welcome to the forum :wave:

The autotask with the slack notification is as follows.

Note: The webhook is obtained from an Autotask secret: https://docs.openzeppelin.com/defender/autotasks#secrets

const { Relayer } = require('defender-relay-client');
const { ethers } = require("ethers");
const axios = require('axios');
const { DefenderRelaySigner, DefenderRelayProvider } = require('defender-relay-client/lib/ethers');
const divider = { type: 'divider' };
function markdown(msg) {
    return {
        type: 'section',
        text: {
            type: 'mrkdwn',
            text: msg,
        },
    }
}
function txLink(hash) {
    return `https://etherscan.io/tx/${hash}`
}
// sends a slack message using a webhook endpoint (configured as autotask secret)
async function sendLossAlert(payload, sentinelEvent, loss) {
    const notification = {
        blocks: [divider, markdown('❗*VAULT LOSS DETECTED*❗'), divider, markdown(`Address: ${sentinelEvent.sentinel.address}`), markdown(`Amount: ${loss}`), markdown(`Risky Transaction: ${txLink(sentinelEvent.transaction.transactionHash)}`)],
    };
    const url = payload.secrets.slackWebhookUrl;
    await axios.post(url, notification, {
        headers: {
            'Content-Type': 'application/json'
        }
    });
}
// 1 Million DAI
const threshold = ethers.BigNumber.from("-1000000000000000000000000")
// receives event from sentinel
exports.handler = async function(payload) {
  // init
  const provider = new DefenderRelayProvider(payload);
  const evt = payload.request.body;
  // init vault contract
  const abi = evt.sentinel.abi;
  const address = evt.sentinel.address;
  const yVault = new ethers.Contract(address, abi, provider);
  // get balance for this block and previous block
  const block = await provider.getBlock(evt.blockHash)
  const currentBlockBalance = await yVault.balance({blockTag: block.number});
  const prevBlockBalance = await yVault.balance({blockTag: block.number-1})
  // send alert if loss exceeds threshold
  const delta = currentBlockBalance.sub(prevBlockBalance);
  const exceedsThreshold = delta.lte(threshold);
  if(exceedsThreshold) {
    await sendLossAlert(payload, evt, delta);
  }
  // for logging
  return {currentBlockBalance, prevBlockBalance, delta, exceedsThreshold }
}

just to double check @abcoathup, autotasks can not trigger notifications out of the box (like Sentinels do)? for now, it would be as in the example above, where one would make an HTTP call to some external service (Slack, Sentry, etc).

autotasks can not trigger notifications out of the box (like Sentinels do)? for now

Correct, it is not yet possible to trigger notifications from an autotask but it is something we are interested in supporting. You can use a standard HTTP call to some service, or you could use a third party library and bundle it for the autotask like in this example.

1 Like