GithubHelp home page GithubHelp logo

conditional-tokens-bot's Introduction

Conditional Tokens bot

This is a bot to get events from Omen contiditional tokens smart contract and from Omen thengraph explorer and push them into social networks.

The bot supports mainnet and rinkeby Ethereum networks.

Configure

  • ETH_NODE: The Ethereum websocket to watch contracts.
  • BLOCK_REORG_LIMIT: Previous number of blocks to process to avoid reorgs.
  • AVERAGE_BLOCK_TIME: Average block time to look for previous blocks on timestamp queries.
  • CT_ADDRESS: The Conditional Tokens contract address for resolved markets events.
  • FIXED_PRODUCT_MM_FACTORY_ADDRESS: The Fixed Product Market Maker factory contract address for new markets creation events.
  • REALITIO_CONTRACT_ADDRESS: The Realitio contract address for arbitration requests notification events.
  • THE_GRAPH_OMEN: The Omen subgraph API endpoint.
  • SLACK_WEBHOOK_URL (optional): Your Slack Incomming Webhook endpoint to push messages. If it's not setted the message will be send to the standard output.
  • TWITTER_CONSUMER_KEY (optional): The Consumer Twitter Api key.
  • TWITTER_CONSUMER_SECRET (optional): The Consumer Twitter Api secret.
  • TWITTER_ACCESS_TOKEN (optional): The Twitter API Access Token.
  • TWITTER_ACCESS_TOKEN_SECRET (optional): The Twitter API Access Token Secret.
  • JOB_GET_TRADE_MINUTES (optional): The number of minutes for the job to ask for new trades on every Market Makers events. Default value 5 minutes.

conditional-tokens-bot's People

Contributors

davidalbela avatar

Stargazers

 avatar

Watchers

 avatar  avatar  avatar

conditional-tokens-bot's Issues

Get Market events between blocks

To avoid lost or send same message after a restart replace the event watcher to pull events between fromBlock: lastUsedBlock and toBlock: nodeLastBlock-5:

  • lastUsedBlock: the value of nodeLastBlock-5 from the last loop execution.
  • nodeLastBlock-5: the last block number of the node minus 5 blocks to avoid reorgs.

Check error "One of the blocks specified in filter cannot be found"

Sometimes the node returns the following error:

Error: Returned error: One of the blocks specified in filter (fromBlock, toBlock or blockHash) cannot be found
    at Object.ErrorResponse (/usr/src/app/node_modules/web3-core-helpers/lib/errors.js:28:19)
    at /usr/src/app/node_modules/web3-core-requestmanager/lib/index.js:288:36
    at XMLHttpRequest.request.onreadystatechange (/usr/src/app/node_modules/web3-providers-http/lib/index.js:98:13)
    at XMLHttpRequestEventTarget.dispatchEvent (/usr/src/app/node_modules/xhr2-cookies/dist/xml-http-request-event-target.js:34:22)
    at XMLHttpRequest._setReadyState (/usr/src/app/node_modules/xhr2-cookies/dist/xml-http-request.js:208:14)
    at XMLHttpRequest._onHttpResponseEnd (/usr/src/app/node_modules/xhr2-cookies/dist/xml-http-request.js:318:14)
    at IncomingMessage.<anonymous> (/usr/src/app/node_modules/xhr2-cookies/dist/xml-http-request.js:289:61)
    at IncomingMessage.emit (events.js:326:22)
    at endReadableNT (_stream_readable.js:1244:12)
    at processTicksAndRejections (internal/process/task_queues.js:80:21) {
  data: '0xaed286'
}

Remove nested then

Remove the nested then Promises that depends on each other. The nesting is unnecessary a difficult read and maintain the code.

Add check last reported event by block number

When the bot is restarted the events will be sent again to the channels from the configured block number. This feature will check for the lasted reported block number to start with.

Check websocket connection

Websocket connections shutdown sometimes on Infura mainnet websocket.

  • Add a check to the liveness heartbeat endpoint to check if the websocket is running.
  • Test other node websocket endpoints.

Fix outcomes message on Slack

There is a wrong format on the list of outcomes when a new market message is created.

Eg:

> Outcomes:
> 50.00% - l2f,> 50.00% - Cng

The right message is:

> Outcomes:
> 50.00% - l2f
> 50.00% - Cng

Conditional Tokens Activity Bot

We would like to build a bot that posts timely updates on activity in the conditional tokens contracts, it should post when (in order of priority):

  1. a market is created
New market created! :tada: 
**Title:** {market title}
**Outcomes:**
- {outcome 1} - {outcome 1 odds}
- {outcome n} - {outcome n odds}
**Collateral:** {collateral token}
**Liquidity: {amount of liquidity provided} {token ticker symbol}
**Omen URL:** {Omen URL for market}
**Created by:** {ethereum or ENS address of creator}
  1. a trade is made on a market
    If less than $1,000 value:
{trade amount} {token ticker} of {outcome} {"purchased" | "sold"} in "{market title}".
Outcome odds: {odds before trade} --> {odds after trade}
**Omen URL:** {Omen URL for market}
**User by:** {ethereum or ENS address of creator}

If greater than $1,000 value

@channel
{trade amount} {token ticker} of {outcome} {"purchased" | "sold"} in "{market title}".
Outcome odds: {odds before trade} --> {odds after trade}
**Omen URL:** {Omen URL for market}
**User by:** {ethereum or ENS address of creator}
  1. liquidity is added/removed from a market
{trade amount} {token ticker} of liquidity {"added" | "removed"} in "{market title}", total liquidity is now {total market liquidity} {token ticker}
**Omen URL:** {Omen URL for market}
**User by:** {ethereum or ENS address of creator}
  1. a market is ready to be resolved
Market ready for resolution
**Title:** {market title}
**Omen URL: {Omen URL for market}
  1. a market is resolved
Market resolved
**Title:** {market title}
**Omen URL: {Omen URL for market}
  1. a market goes into arbitration
@channel
Market is in arbitration
**Title:** {market title}
**Omen URL: {Omen URL for market}

We would like to use the bot internally in our slack, but we should ideally build it in such a way that anyone can add it to their Slack, Telegram, or Discord servers.

Add Omen FixedProductMarketMaker contract to bot

Right now, the bot is watching PositionSplit events from Conditional Tokens to see if a new general Market was created, but this will not make differences from a new given Market or a new trade, besides it could be any Market Maker.

To watch new created Omen Market Marker, the bot requires to watch FixedProductMarketMakerFactory on FixedProductMarketMakerCreation event and look for the condition and questions using the right thegraph subgraph endpoint. This feature will allow to get the right information from a new Market created on Omen.

Fix duplicated Tweet messages

Sometimes the Omen subgraph contains same market with the same title but that comes from different markets. When the bot tries to send the messages from different markets with the same title will return an error.

eg:

Error: Status is a duplicate.
  code: 187,
  allErrors: [ { code: 187, message: 'Status is a duplicate.' } ],
  twitterReply: { errors: [ [Object] ] },
  statusCode: 403

Add Liquidity is added/removed from a market

Push a message when liquidity is added or removed from a Market:

{trade amount} {token ticker} of liquidity {"added" | "removed"} in "{market title}", total liquidity is now {total market liquidity} {token ticker}
**Omen URL:** {Omen URL for market}
**Created by:** {ethereum or ENS address of creator}

External Dependency: protofire/omen-subgraph#71

Support new trade on market

Get trades information from a given Market. Could there are two options:

  • Listen a created contract FixedProductMarketMaker on the FPMMBuy and FPMMSell events from a given market address (returned by FixedProductMarketMakerCreation event). This will require to persist or get every created market address and watch it again after any restart.

  • Query subgraph on a scheduled task to query for latest new trades. This will require a Trade entity to [subgrap] schema (https://github.com/protofire/omen-subgraph/blob/master/schema.graphql):
    e.g:

{
  fixedProductMarketMakers(first: 10, orderBy: creationTimestamp, orderDirection: desc, where: {currentAnswer: null}) {
    id
    creationTimestamp
    scaledLiquidityMeasure
    collateralToken
    title
    outcomes
    currentAnswer
    participants {
      id
      
    }
  }
}

Define structure project

Refactor the structure of the project. Eg:

app.js           # App entry point
config           # Environment variables and configuration
jobs              # Jobs definitions for 
services       # the Business logic
subscribers  # Even handlers for async tasks
types            # Type declaration files
utils              # Custom utils

Maybe you can move this function to some utils file ?

Originally posted by @mariano-aguero in #26 (comment)

Repeat tries when service is overloaded

Sometimes the Ethereum or thegraph queries return errors.

Eg:

(node:19) UnhandledPromiseRejectionWarning: Error: service is overloaded and can not run the query right now. Please try again in a few minutes
    at /usr/src/app/src/services/getTrade.js:25:13
    at runMicrotasks (<anonymous>)

The bot should consider this error and repeat tries with the same timestamp values for the queries or increasing the time to not loose possible events in the middle.

Escape special chars from linked texts

Some characters are reserved in HTML. When titles includes special chars like ">" or "<" the link on message is broken. Eg:

Is this an example? > 100 GWEI?

Replace them by the entity name (&gt; or &lt;).

Fix fromBlock greather than toBlock on getPastEvents

Events from getPastEvents method sometimes receive wrong values fromBlock greather than toBlock.

The bot will fail returning the following error:

Error: Returned error: One of the blocks specified in filter (fromBlock, toBlock or blockHash) cannot be found.

Remove lodash dependency

Replace lodash dependency that is using collection forEach method. In many cases can be perform with a map.

Add gql and get info from Omen graph

Add a gql library to query from the retrieved events and obtain the related data. Data can be obtained from thegraph Omen endpoints with the given questionId by the events.

e.g:

# https://thegraph.com/explorer/subgraph/cag/hg
HASH_ID=`curl -s 'https://api.thegraph.com/subgraphs/name/cag/hg' \
 -H 'content-type: application/json' \
 --data-binary '{"query":"{ conditions(where : { id: \"'${CONDITION_ID}'\"}) { id oracle questionId }}"}' | jq '.data["conditions"][].questionId' | cut -d'"' -f 2`

# https://thegraph.com/explorer/subgraph/protofire/omen
echo "questionID: $HASH_ID"
curl 'https://api.thegraph.com/subgraphs/name/protofire/omen' \
  -H 'content-type: application/json' \
  -d '{"query":"{  questions(  where: {    id: \"'${HASH_ID}'\"  }  ) {    id    templateId    data    title  }}"}'

Add push messages to alert channels

Implement a alert messages to developers channel:

  • Push message when a bot is restarted
  • Check errors from the bot
  • Check errors from the graph monitoring
  • Check errors from a bad Ethereum connection

Liquidity message is pushed before new created Market message

When a new market is created, the bot system push a message of the triggered event add liquidity called by the creation market when liquidity is added.

To avoid to send first the message of liquidity, the bot should take that in account and manage the double situation when a new Market is created, making sure the liquidity does not come from a new market.

Fix amount format

When the collateral amout is too low the trade message will not show the amount.

Eg:

0.00 ERC-20 token of *No* purchased in "Will at least n ERC-20 tokens will do action untill end of date?".

Fix setting the fixed decimal for each case.

Add support multiple conditional markets

The bot supports one condition id for event FixedProductMarketMakerCreation on new market created message. It would be great to support when a new market is created with several condition ids.

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.