Skip to content

Commit

Permalink
New Flashbots Protect button (#506)
Browse files Browse the repository at this point in the history
* replace flashbots button

* remopve sandbox RL

* remove unused components

* center button, make longer for arrow EL

* replace preview with correct url

---------

Co-authored-by: Daniel Sukoneck <[email protected]>
  • Loading branch information
72L and sukoneck authored Jan 9, 2024
1 parent 320bb3c commit 6736419
Show file tree
Hide file tree
Showing 10 changed files with 66 additions and 415 deletions.
6 changes: 3 additions & 3 deletions .vscode/settings.json
Original file line number Diff line number Diff line change
@@ -1,13 +1,13 @@
{
"editor.codeActionsOnSave": {
"source.fixAll.eslint": true,
"source.fixAll.stylelint": true
"source.fixAll.eslint": "explicit",
"source.fixAll.stylelint": "explicit"
},
"editor.defaultFormatter": "esbenp.prettier-vscode",
"css.validate": false,
"scss.validate": false,
"javascript.validate.enable": false,
"typescript.validate.enable": true,
"javascript.suggest.paths": false,
"typescript.suggest.paths": false,
"typescript.suggest.paths": false
}
54 changes: 27 additions & 27 deletions docs/flashbots-mev-share/searchers/getting-started.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -2,8 +2,8 @@
title: Getting Started
---

import Tabs from '@theme/Tabs'
import TabItem from '@theme/TabItem'
import Tabs from '@theme/Tabs';
import TabItem from '@theme/TabItem';

To start searching on MEV-Share, you will first need to connect to a MEV-Share Node. As a reminder, the MEV-Share Node is responsible for receiving transactions and bundles from users, and selectively sharing information ("hints") about them with searchers. When a searcher wants to include a transaction in their bundle, they use that transaction's hash. The MEV-Share Node replaces it with the original transaction before sending the bundle to a block builder.

Expand All @@ -16,44 +16,44 @@ The simplest way to connect to the Flashbots MEV-Share Node is to use a [client
<Tabs>
<TabItem value="ts" label="mev-share-client-ts">

*Add library to your project:*
_Add library to your project:_

```bash
yarn add @flashbots/mev-share-client
```

*Use the following code to import the library* (Replace ALL_CAPS placeholders with your data):
_Use the following code to import the library_ (Replace ALL_CAPS placeholders with your data):

```typescript
import { Wallet, JsonRpcProvider } from "ethers"
import {Wallet, JsonRpcProvider} from 'ethers';
import MevShareClient, {
BundleParams,
HintPreferences,
IPendingBundle,
IPendingTransaction,
TransactionOptions
} from "@flashbots/mev-share-client"

const provider = new JsonRpcProvider(RPC_URL)
const authSigner = new Wallet(FB_REPUTATION_PRIVATE_KEY, provider)
const mevShareClient = MevShareClient.useEthereumMainnet(authSigner)
BundleParams,
IPendingBundle,
IPendingTransaction,
TransactionOptions,
} from '@flashbots/mev-share-client';

const provider = new JsonRpcProvider(RPC_URL);
const authSigner = new Wallet(FB_REPUTATION_PRIVATE_KEY, provider);
const mevShareClient = MevShareClient.useEthereumMainnet(authSigner);
```

_Connecting to Goerli:_

```typescript
const mevShareClient = MevShareClient.useEthereumGoerli(authSigner)
const mevShareClient = MevShareClient.useEthereumGoerli(authSigner);
```

*Advanced setup* (for developers):
_Advanced setup_ (for developers):

```typescript
// connect to MEV-Share on mainnet
const mevShareClient = new MevShareClient(authSigner, {
name: "mainnet",
chainId: 1,
streamUrl: "https://mev-share.flashbots.net",
apiUrl: "https://relay.flashbots.net",
})
name: 'mainnet',
chainId: 1,
streamUrl: 'https://mev-share.flashbots.net',
apiUrl: 'https://relay.flashbots.net',
});
```

Further documentation on the client library can be found in the [mev-share-client-ts](https://github.com/flashbots/mev-share-client-ts).
Expand All @@ -74,9 +74,9 @@ Now you should be connected to the Flashbots MEV-Share Node. Continue reading on
Searching on MEV-Share is different from searching on the mempool in that only certain parts of a transaction are shared with searchers. In the mempool, we can see all parts of a transaction, such as its calldata or who the transaction is from. But on MEV-Share, a transaction might only reveal its function selector, making a traditional arbitrage calculation infeasible.

There are three primary strategies for searching on MEV-Share:
* Probabilistically: send many bundles that probabilistically backrun MEV-Share orderflow.
* On-chain: perform more of your searching on-chain instead of off-chain.
* Existing: only search on transactions which share all the information you need.

To maximally leverage MEV-Share searchers will need to employ new strategies.
:::
- Probabilistically: send many bundles that probabilistically backrun MEV-Share orderflow.
- On-chain: perform more of your searching on-chain instead of off-chain.
- Existing: only search on transactions which share all the information you need.

To maximally leverage MEV-Share searchers will need to employ new strategies. :::
8 changes: 3 additions & 5 deletions docs/flashbots-protect/mev-share.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ title: MEV-Share

import HintsTable from '../specs/mev-share/HintsTable';
import Builders from '../specs/mev-share/_builders.mdx';
import ProtectButtonSelector from '@site/src/components/ProtectButtonSelector';
import ProtectButton from '@site/src/components/ProtectButton';

## Introduction

Expand All @@ -14,7 +14,7 @@ MEV-Share enables users to reclaim up to 90% of the MEV generated by their trans

Advanced users can exert more control over their transactions and preferences through the advanced panel or by manually configuring their Protect RPC request.

<ProtectButtonSelector />
<ProtectButton />

## Common configurations

Expand Down Expand Up @@ -116,6 +116,4 @@ All percentages in the refund parameters must total less than 100. The remaining

### Priority fee

When sending private transaction to rpc endpoint you should set priority fee (tips) to be strictly greater than zero.
Transactions with 0 priority fee will not be shared with block builders and included on chain, unless they are bundled
by a searcher via MEV-Share.
When sending private transaction to rpc endpoint you should set priority fee (tips) to be strictly greater than zero. Transactions with 0 priority fee will not be shared with block builders and included on chain, unless they are bundled by a searcher via MEV-Share.
9 changes: 6 additions & 3 deletions docs/flashbots-protect/overview.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -4,10 +4,13 @@ title: MEV Protection Overview

<head>
<title>MEV Protection - Block MEV With Flashbots Protect RPC</title>
<meta name="description" content="Privacy notice: Flashbots MEV Protect RPC does not track any user information (i.e. IP, location, etc.). No user information is ever stored or even logged." />
<meta
name="description"
content="Privacy notice: Flashbots MEV Protect RPC does not track any user information (i.e. IP, location, etc.). No user information is ever stored or even logged."
/>
</head>

import ProtectButtonSelector from "@site/src/components/ProtectButtonSelector";
import ProtectButton from '@site/src/components/ProtectButton';

> **Privacy notice: Flashbots Protect RPC does not track** any kind of user information (i.e. IP, location, etc.). No user information is ever stored or even logged.
Expand All @@ -22,7 +25,7 @@ It has the following key benefits:

You can use Flashbots Protect by clicking the button below, or by sending transactions using `eth_sendRawTransaction` to `rpc.flashbots.net` or the custom URL based on your advanced configuration below.

<ProtectButtonSelector />
<ProtectButton />

<br />
<br />
Expand Down
6 changes: 4 additions & 2 deletions docs/flashbots-protect/quick-start.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -2,11 +2,12 @@
title: Quick start
---

import ProtectButtonSelector from "@site/src/components/ProtectButtonSelector";
import ProtectButton from '@site/src/components/ProtectButton';

## Key Considerations

Flashbots Protect has the following key benefits:

- **Configurable:** you can choose which builders to send to and your mev-share settings.
- **Frontrunning protection:** your transaction will not be seen by hungry sandwich bots in the public mempool.
- **Get MEV back**: if your transaction creates MEV, you get up to 90% of it back through [MEV-Share](/flashbots-mev-share/introduction).
Expand All @@ -17,6 +18,7 @@ Flashbots Protect has the following key benefits:
You can speed up your transaction's inclusion by using Protect in fast mode. Click the "fast" option when [configuring your Protect RPC](/flashbots-protect/quick-start#using-flashbots-protect) or manually set your RPC to `rpc.flashbots.net/fast`.

Fast mode has 2 key differences from the default Protect experience:

1. **Shared with all builders:** By default, Protect transactions are only shared with the Flashbots Builder, which builds only a subset of all Ethereum blocks. In fast mode, transactions are shared with all [registered builders](https://github.com/flashbots/dowg/blob/main/builder-registrations.json) to increase the number of blocks the user's transaction can be included in.
2. **Larger refund paid to validator:** By default, only 10% of MEV-Share refunds are paid to validators. In fast mode, validators receive 50% of refunds which makes it more likely that the user’s transactions will be chosen in a given block.

Expand All @@ -38,7 +40,7 @@ There are three ways to use Flashbots Protect:

Which way you integrate is up to you and your preferences. The most simple way to use Flashbots Protect is to add the Flashbots Protect RPC to your wallet. You can do so using the below button or by following the manual instructions below. **Note that you can configure the builders you send to and your MEV-Share hints as well**.

<ProtectButtonSelector />
<ProtectButton />

## Adding Flashbots Protect RPC Manually

Expand Down
150 changes: 23 additions & 127 deletions src/components/ProtectButton/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -4,137 +4,33 @@
* This source code is licensed under the MIT license found in the
* LICENSE file in the root directory of this source tree.
*/
import {PropsWithChildren} from 'react';
import {snakeCase} from 'change-case';

const RPC_FLASHBOTS_NET = 'https://rpc.flashbots.net';
const ETH_CHAIN_ID = '0x1';
const ETH_CHAIN_NAME = 'Ethereum Mainnet';
import { useEffect, useState } from 'react';

interface HintPreferences {
calldata: boolean;
contractAddress: boolean;
functionSelector: boolean;
logs: boolean;
defaultLogs: boolean;
hash: boolean;
}

export interface ProtectButtonOptions extends PropsWithChildren {
/** Specify data to share; if undefined, uses default
* [Stable config](https://docs.flashbots.net/flashbots-protect/rpc/mev-share#stable-configuration) */
hints: HintPreferences;
/** Selected builders that are permitted to build blocks using the client's
* transactions. */
builders: Array<string>;
/** `fast` mode enables all supported builders implicitly. Setting `fast`
* will override `builders`. */
fast: boolean;
}
export default function ProtectButton() {

export const generateRpcUrl = ({
options: {hints, builders, fast},
}: {
options: ProtectButtonOptions;
}) => {
const rpcUrl = new URL(RPC_FLASHBOTS_NET);

if (hints) {
Object.entries(hints).forEach(([hintName, hintEnabled]) => {
if (hintEnabled) {
rpcUrl.searchParams.append('hint', snakeCase(hintName));
}
});
}

if (fast) {
rpcUrl.pathname += 'fast';
} else if (builders) {
builders.forEach((builder) => {
rpcUrl.searchParams.append('builder', builder.toLowerCase());
});
}
return rpcUrl;
};

/**
* Button that connects Metamask to Flashbots Protect when it's clicked.
*/
function FlashbotsProtectButton(options: ProtectButtonOptions) {
const {children} = options;
const rpcUrl = generateRpcUrl({
options,
});

const provider = window.ethereum;

const connectToProtect = async () => {
if (provider) {
const addChainParams = {
chainId: ETH_CHAIN_ID,
chainName: `Flashbots Protect (${ETH_CHAIN_NAME})`,
iconUrls: ['https://docs.flashbots.net/img/logo.png'],
nativeCurrency: {
name: 'Ethereum',
symbol: 'ETH',
decimals: 18,
},
rpcUrls: [rpcUrl.toString()],
};
// do it manually with window.ethereum
try {
await provider.request({
method: 'wallet_addEthereumChain',
params: [addChainParams],
});
} catch (err) {
// handle "add" error
console.error('addChain failed');
}
} else {
console.error('ethereum provider not found');
}
};
// listen for light/dark theme changes
const [theme, setTheme] = useState('light')
useEffect(() => {
const htmlElement = document.documentElement;
const handleThemeChange = () => {
const currentTheme = htmlElement.getAttribute('data-theme');
setTheme(currentTheme || 'light');
};
handleThemeChange();
const observer = new MutationObserver(handleThemeChange);
observer.observe(htmlElement, { attributes: true, attributeFilter: ['data-theme'] });
}, [])

return (
<div className="flex flex-col items-center gap-2">
<div
role="button"
tabIndex={0}
onClick={() => navigator.clipboard.writeText(rpcUrl.toString())}
onKeyDown={(event) => {
if (event.key === 'Enter') {
navigator.clipboard.writeText(rpcUrl.toString());
}
}}
className="group relative flex min-w-full max-w-full items-start gap-2 rounded-md border-solid border-slate-200 p-3 transition-colors duration-200 hover:bg-gray-100">
<svg
xmlns="http://www.w3.org/2000/svg"
viewBox="0 0 24 24"
fill="currentColor"
className="mt-0.5 w-4 min-w-[16px]">
<path
fillRule="evenodd"
d="M19.902 4.098a3.75 3.75 0 00-5.304 0l-4.5 4.5a3.75 3.75 0 001.035 6.037.75.75 0 01-.646 1.353 5.25 5.25 0 01-1.449-8.45l4.5-4.5a5.25 5.25 0 117.424 7.424l-1.757 1.757a.75.75 0 11-1.06-1.06l1.757-1.757a3.75 3.75 0 000-5.304zm-7.389 4.267a.75.75 0 011-.353 5.25 5.25 0 011.449 8.45l-4.5 4.5a5.25 5.25 0 11-7.424-7.424l1.757-1.757a.75.75 0 111.06 1.06l-1.757 1.757a3.75 3.75 0 105.304 5.304l4.5-4.5a3.75 3.75 0 00-1.035-6.037.75.75 0 01-.354-1z"
clipRule="evenodd"
/>
</svg>
<div>
<p className="m-0 text-sm font-bold">RPC URL</p>
<p className="m-0 break-all text-sm text-gray-700">
{rpcUrl.toString()}
</p>
</div>
</div>
<button
type="button"
className="ring-offset-background focus-visible:ring-ring inline-flex h-10 min-w-full cursor-pointer items-center justify-center whitespace-nowrap rounded-md border-none bg-gray-950 px-4 py-2 text-base font-bold text-white transition-colors hover:bg-gray-700 focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-offset-2"
onClick={() => connectToProtect()}>
{children}
</button>
<div className='w-full flex flex-row justify-center'>
<iframe
title='Protect Button'
id="protect-button"
src={`https://protect.flashbots.net/button?theme=${theme}`}
height="88" width="348"
className="flex dark:dark border-none rounded-lg hover:outline"
/>
</div>
);
)
}

export default FlashbotsProtectButton;
export type {HintPreferences};
34 changes: 0 additions & 34 deletions src/components/ProtectButtonSelector/BuilderOptions.tsx

This file was deleted.

Loading

1 comment on commit 6736419

@vercel
Copy link

@vercel vercel bot commented on 6736419 Jan 9, 2024

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Please sign in to comment.