Quick Start
This quickstart guide contains all the information necessary to get up and running as a searcher on Eden.
How does Eden work for searchers?
Eden connects searchers directly to block builders and allows them to avoid the public tx pool. Searchers with transactions they would like to send block builders first craft what we call "bundles" and send these to the Eden Bundles RPC. Eden Bundles RPC is a gateway that Eden runs today which simulates searchers' bundles, and if there are no errors then forwards them on to block builders. Block builders then receive bundles and include them in blocks if it is profitable for them to do so.
Getting onboarded to Eden is easy for searchers; you simply need to update how you send transactions.
How to send your first Eden bundle
To access Eden Network you will need three things:
- A private key that you use to sign your bundles
- A way to interact with Eden
- A "bundle" for your transactions
When you send bundles to Eden you will sign them with a private key so that we can establish identity for searchers and establish reputation for them over time. This private key does not store funds and is not the primary private key you use for executing transactions. Again, it is only used for identity, and it can be any private key.
Second, you'll need a way to interact with Eden. Eden runs a relay you will send bundles to at https://api.edennetwork.io/v1/bundle
. You can choose to send bundles directly to this endpoint or use SDKs for popular libraries like Ethers.js or web3.py to make interacting with Eden Bundles RPC as easy as possible. Here are a few examples of how to set up an Eden provider:
- ethers.js
- web3.py
- go
const ethers = require("ethers.js");
const {
FlashbotsBundleProvider,
} = require("@flashbots/ethers-provider-bundle");
const provider = new ethers.providers.JsonRpcProvider({
url: ETHEREUM_RPC_URL,
});
// Standard json rpc provider directly from ethers.js. For example you can use Infura, Alchemy, or your own node.
const authSigner = new ethers.Wallet(
"0x0000000000000000000000000000000000000000000000000000000000000000"
);
// `authSigner` is an Ethereum private key that does NOT store funds and is NOT your bot's primary key.
// This is an identifying key for signing payloads to establish reputation and whitelisting
const flashbotsProvider = await FlashbotsBundleProvider.create(
provider,
authSigner
);
// Flashbots provider requires passing in a standard provider and an auth signer
import os
from eth_account.account import Account
from eth_account.signers.local import LocalAccount
from flashbots import flashbot
from web3 import Web3, HTTPProvider
# Create a web3 object with a standard json rpc provider, such as Infura, Alchemy, or your own node.
w3 = Web3(HTTPProvider("http://localhost:8545"))
# ETH_ACCOUNT_SIGNATURE is an Ethereum private key that does NOT store funds and is NOT your bot's primary key.
# This is an identifying key for signing payloads to establish reputation and whitelisting
ETH_ACCOUNT_SIGNATURE: LocalAccount = Account.from_key(os.environ.get("ETH_SIGNATURE_KEY"))
# Flashbots providers require both a standard provider and ETH_ACCOUNT_SIGNATURE (to establish reputation)
flashbot(w3, ETH_ACCOUNT_SIGNATURE)
package main
import (
"bytes"
"crypto/ecdsa"
"encoding/json"
"fmt"
"io/ioutil"
"math/big"
"net/http"
"time"
"github.com/ethereum/go-ethereum/accounts"
"github.com/ethereum/go-ethereum/common/hexutil"
"github.com/ethereum/go-ethereum/crypto"
)
const (
j = "application/json"
edenURL = "https://api.edennetwork.io/v1/bundle"
stats = "eden_getUserStats"
header = "X-Flashbots-Signature"
p = "POST"
)
var (
privateKey, _ = crypto.HexToECDSA(
"2e19800fcbbf0abb7cf6d72ee7171f08943bc8e5c3568d1d7420e52136898154",
)
)
func createHeader(signature []byte, privateKey *ecdsa.PrivateKey) string {
return crypto.PubkeyToAddress(privateKey.PublicKey).Hex() +
":" + hexutil.Encode(signature)
}
func main() {
mevHTTPClient := &http.Client{
Timeout: time.Second * 3,
}
currentBlock := big.NewInt(12_900_000)
params := map[string]interface{}{
"jsonrpc": "2.0",
"id": 1,
"method": stats,
"params": []interface{}{
fmt.Sprintf("0x%x", currentBlock.Uint64()),
},
}
payload, _ := json.Marshal(params)
req, _ := http.NewRequest(p, edenURL, bytes.NewBuffer(payload))
signature, _ := crypto.Sign(
accounts.TextHash([]byte(hexutil.Encode(crypto.Keccak256(payload)))),
privateKey,
)
req.Header.Add("content-type", j)
req.Header.Add("Accept", j)
req.Header.Add(header, createHeader(signature, privateKey))
resp, _ := mevHTTPClient.Do(req)
res, _ := ioutil.ReadAll(resp.Body)
fmt.Println(string(res))
}
Now that we have a private key to identify ourselves with and a bundle provider we can create and send a bundle. Here's an example in node.js
const ethers = require("ethers.js");
const {
FlashbotsBundleProvider,
} = require("@flashbots/ethers-provider-bundle");
const provider = new ethers.providers.JsonRpcProvider({
url: ETHEREUM_RPC_URL,
});
const authSigner = new ethers.Wallet(
"0x2000000000000000000000000000000000000000000000000000000000000000"
);
const flashbotsProvider = await FlashbotsBundleProvider.create(
provider,
authSigner
);
const signedBundle = await flashbotsProvider.signBundle([
{
signer: SOME_SIGNER_TO_SEND_FROM,
transaction: SOME_TRANSACTION_TO_SEND,
},
]);
const bundleReceipt = await flashbotsProvider.sendRawBundle(
signedBundle,
TARGET_BLOCK_NUMBER
);
That's it!
What's Next
Congrats! You should now have everything you need to start sending transactions to the Eden Network.
Keep reading about: