Executor Guide
Building your own executor can be a profitable endeavor that also provides a public good. Below you will find a high-level guide to building your own executor.
Brink Order Execution
The role of an executor is to execute signed messages that have been created either through our API, brink.trade, or by a third party utilizing our smart contracts and network. When you go on the journey of building your own executor, you not only help to maintain the availability of automated order execution, but can also earn a profit while doing so.
Adapter Contracts
Building an Executor
Below you will find the high level steps you should take in order to build your own executor.
Load an Ethereum Wallet with Funds
In order to execute signed messages, you will need to have a wallet loaded with Ether. The amount is up to you, but this will be paying for the gas of the transactions you execute. Note that your executor may or may not take profit in tokens other than Ether depending on how you build it. If built to take profit in tokens, you will definitely want to monitor the balance of Ether in your executor wallet.
Setup your project
The team at Brink has built an SDK in order to make it easier to sign and execute orders. It is written in Node.js, and as such, we recommend starting off with a Node.js project base, our SDK, and Ethers. You will also want to install Brink Utils.
Obtain and Store Messages
Once you have your project setup, you need to be able to retrieve the signed messages through our API, we also recommend storing them in a database of your choice and keeping track of their states, but this is not absolutely necessary and we publicize our own internally tracked states via our API. Our goal is to decentralize this order book in the future, but for now they are only available through our data store. The two APIs you will want to take note of are:
This API allows you to filter signed messages by our own internal state. We recommend you use this API to initialize your datastore and do not use this for continual polling which is provided by the next API.
This API is a SSE get endpoint which will maintain a connection with our API server and continually notify new events as they are created. We recommend using this API to maintain the accuracy of your data store and to give your executor access to the most up-to-date signed messages.
An example below shows how to easily add event notifications to your Node.js application:
Evaluate and Execute Message
The next steps once you have a datastore setup and new events are flowing in is to evaluate the profitability of messages, and optionally update their state in your datastore in order to filter out ones that are not executable or unlikely to be profitable. Once you have evaluated an order and have deemed it profitable, it is time to execute and make that sweet sweet profit.
Setup
Instantiate the Brink SDK and Ethers, you will need both to evaluate and execute messages. (Note you will need to setup your own Ethereum node or use a service like Infura to populate The ETH_NODE_RPC_URL
field when instantiating the ethers provider. We also recommend you NEVER use your private key straight in your code, use a config solution instead)
Evaluation
You will not want to try and execute all signed messages that come into your system, many will fail and cost you gas. It is upon you to evaluate the profitability of each signed message and keep an updated state in order to have less failed transaction, and a higher profit output. Below are our recommendations for things to check when evaluating a signed message and helpful tools you can use. We recommend you think of your own and build you own adapter contracts in order to achieve the highest profits. Be creative!
Example Signed Message
1. Get an Instance of the Account
2. Check for expiration
Brink messages have an expiration block. If the expiration block is lower than the current block the message is expired then you should not execute the message, and you should also note this in your datastore.
3. Check for Cancelled Message
Brink messages can be cancelled by the creator of the message by flipping a bit. You can check if it has been cancelled using our SDK. If the message is cancelled you should not execute the message, and you should also note this in your datastore.
(bitmapIndex and bit can be found in the callData params in the above example message)
4. Check the Account's Balance
Before executing a message, you should check the account balance of the address that signed the message. If they do not have the required token or ETH funds for the message, you should not execute the message, and you should also note this in your datastore.
5. Check for History of Failures
At times we may not know why a message fails, but it can happen. If you have attempted to execute this message in the past and it failed, you should note that in your datastore so that your executor isn't continually attempting to execute a message with a history of failures.
6. Check for Profit
Finally the most difficult evaluation and where you can get the most creative is when you are checking the profitability of a signed message. This is where you can gain the biggest competitive edge against other executors in the network. We can't give you an exact formula for calculating profit, but here are some guidelines:
Check for the highest swap value using on chain data or an API. You will also need to create an adapter contract to interact with the chosen protocol. We provide our own Uniswap V3 adapter for public use, but we encourage you to build your own adapters and utilize AMMs other than Uniswap V3 to achieve the highest profit and best competitive edge.
Encode the function call to your adapter. You can use Brink Utils to help here.
Calculate the cost of gas to execute this transaction and subtract it from
excessEth
. You can use our SDK'sestimateGas
feature to help estimate the cost of the transaction.
7. Execute the Transaction!
Once you have calculated the profit, you can execute the signed message and reap the rewards!
Last updated