Socket
Socket
Sign inDemoInstall

@flashbots/matchmaker-ts

Package Overview
Dependencies
22
Maintainers
3
Versions
17
Alerts
File Explorer

Advanced tools

Install Socket

Detect and block malicious and high-risk dependencies

Install

Comparing version 0.7.5 to 0.7.6

build/api/index.d.ts

6

build/api/events.d.ts
import { LogParams } from 'ethers';
import { IMatchmakerEvent, IPendingBundle, IPendingTransaction } from './interfaces';
import { IMevShareEvent, IPendingBundle, IPendingTransaction } from './interfaces';
export declare class PendingTransaction implements IPendingTransaction {

@@ -11,3 +11,3 @@ hash: string;

gasUsed?: bigint;
constructor(event: IMatchmakerEvent);
constructor(event: IMevShareEvent);
}

@@ -24,4 +24,4 @@ export declare class PendingBundle implements IPendingBundle {

gasUsed?: bigint;
constructor(event: IMatchmakerEvent);
constructor(event: IMevShareEvent);
}
//# sourceMappingURL=events.d.ts.map

@@ -5,7 +5,7 @@ import { LogParams } from 'ethers';

*/
export declare enum StreamEvent {
export declare enum StreamEventType {
Bundle = "bundle",
Transaction = "transaction"
}
export type StreamEventName = `${StreamEvent}`;
export type StreamEventName = `${StreamEventType}`;
/** Data about the event history endpoint. */

@@ -46,14 +46,10 @@ export type EventHistoryInfo = {

/**
* Configuration used to connect to the Matchmaker.
* Configuration used to connect to the MEV-Share node.
*
* Use [supportedNetworks](./networks.ts) for presets.
*/
export type MatchmakerNetwork = {
/** Chain ID of the network. e.g. `1` */
chainId: number;
/** Lowercase name of network. e.g. "mainnet" */
name: string;
export type MevShareNetwork = {
/** Matchmaker event stream URL. */
streamUrl: string;
/** Matchmaker bundle & transaction API URL. */
/** MEV-Share bundle & transaction API URL. */
apiUrl: string;

@@ -99,3 +95,3 @@ };

};
/** Transactions that make up the bundle. `hash` refers to a transaction hash from the Matchmaker event stream. */
/** Transactions that make up the bundle. `hash` refers to a transaction hash from the MEV-Share event stream. */
body: Array<{

@@ -137,3 +133,3 @@ hash: string;

}
/** Response received from matchmaker API */
/** Response received from MEV-Share API */
interface ISendBundleResponse {

@@ -178,3 +174,3 @@ /** Bundle hash. */

}
/** Response received from matchmaker api. */
/** Response received from MEV-Share api. */
interface ISimBundleResponse {

@@ -204,5 +200,5 @@ success: boolean;

/**
* General API wrapper for events received by the SSE stream (via `matchmaker.on(...)`).
* General API wrapper for events received by the SSE stream (via `mevshare.on(...)`).
*/
export interface IMatchmakerEvent {
export interface IMevShareEvent {
/** Transaction or Bundle hash. */

@@ -221,17 +217,21 @@ hash: string;

/**
* Change in coinbase value after inserting tx/bundle, divided by gas used.
* Hex string; change in coinbase value after inserting tx/bundle, divided by gas used.
*
* Can be used to determine the minimum payment to the builder to make your backrun look more profitable to builders.
*
* _Note: this only applies to builders like Flashbots who order bundles by MEV gas price._
*
* _Note: EXPERIMENTAL; only implemented on Goerli._
*/
mevGasPrice?: string;
/** Gas used by the tx/bundle, rounded up to 2 most significant digits.
/** Hex string; gas used by the tx/bundle, rounded up to 2 most significant digits.
*
* _Note: EXPERIMENTAL; only implemented on Goerli_ */
* _Note: EXPERIMENTAL; only implemented on Goerli._
*/
gasUsed?: string;
}
/**
* Pending transaction from the matchmaker stream.
* Pending transaction from the MEV-Share event stream.
*/
export interface IPendingTransaction extends Omit<Omit<Omit<IMatchmakerEvent, 'txs'>, 'mevGasPrice'>, 'gasUsed'> {
export interface IPendingTransaction extends Omit<Omit<Omit<IMevShareEvent, 'txs'>, 'mevGasPrice'>, 'gasUsed'> {
to?: string;

@@ -241,22 +241,39 @@ functionSelector?: string;

/**
* {@link IMatchmakerEvent.mevGasPrice}
* {@link IMevShareEvent.mevGasPrice}
*/
mevGasPrice?: bigint;
/**
* {@link IMatchmakerEvent.gasUsed}
* {@link IMevShareEvent.gasUsed}
*/
gasUsed?: bigint;
}
/** Pending bundle from the matchmaker stream. */
export interface IPendingBundle extends Omit<Omit<IMatchmakerEvent, 'mevGasPrice'>, 'gasUsed'> {
/** Pending bundle from the MEV-Share event stream. */
export interface IPendingBundle extends Omit<Omit<IMevShareEvent, 'mevGasPrice'>, 'gasUsed'> {
/**
* {@link IMatchmakerEvent.mevGasPrice}
* {@link IMevShareEvent.mevGasPrice}
*/
mevGasPrice?: bigint;
/**
* {@link IMatchmakerEvent.gasUsed}
* {@link IMevShareEvent.gasUsed}
*/
gasUsed?: bigint;
}
/** A past event from the MEV-Share event stream. */
export declare class EventHistoryEntry {
block: number;
timestamp: number;
hint: {
txs?: Array<{
to: string;
callData: string;
functionSelector: string;
}>;
hash: string;
logs?: Array<LogParams>;
gasUsed: bigint;
mevGasPrice: bigint;
};
constructor(entry: IEventHistoryEntry);
}
export {};
//# sourceMappingURL=interfaces.d.ts.map
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.SimBundleResult = exports.SendBundleResult = exports.StreamEvent = void 0;
exports.EventHistoryEntry = exports.SimBundleResult = exports.SendBundleResult = exports.StreamEventType = void 0;
/**
* Used to specify which type of event to listen for.
*/
var StreamEvent;
(function (StreamEvent) {
StreamEvent["Bundle"] = "bundle";
StreamEvent["Transaction"] = "transaction";
})(StreamEvent = exports.StreamEvent || (exports.StreamEvent = {}));
var StreamEventType;
(function (StreamEventType) {
StreamEventType["Bundle"] = "bundle";
StreamEventType["Transaction"] = "transaction";
})(StreamEventType = exports.StreamEventType || (exports.StreamEventType = {}));
/** Decodes a raw sendBundle response. */

@@ -29,2 +29,11 @@ const SendBundleResult = (response) => ({

exports.SimBundleResult = SimBundleResult;
/** A past event from the MEV-Share event stream. */
class EventHistoryEntry {
constructor(entry) {
this.block = entry.block;
this.timestamp = entry.timestamp;
this.hint = Object.assign(Object.assign({}, entry.hint), { gasUsed: entry.hint.gasUsed ? BigInt(entry.hint.gasUsed) : BigInt(0), mevGasPrice: entry.hint.mevGasPrice ? BigInt(entry.hint.mevGasPrice) : BigInt(0) });
}
}
exports.EventHistoryEntry = EventHistoryEntry;
//# sourceMappingURL=interfaces.js.map

@@ -1,5 +0,4 @@

import { LogParams } from 'ethers';
import { BundleParams, IEventHistoryEntry, SimBundleOptions, TransactionOptions } from './interfaces';
import { BundleParams, SimBundleOptions, TransactionOptions } from './interfaces';
/**
* Converts user-specified parameters into parameters for a sendPrivateTransaction call to the Matchmaker API.
* Converts user-specified parameters into parameters for a sendPrivateTransaction call to the MEV-Share API.
* @param signedTx - Signed transaction to send.

@@ -21,3 +20,3 @@ * @param options - Privacy/execution settings for the transaction.

/**
* Converts user-specified parameters into parameters for a mev_sendBundle call to the Matchmaker API.
* Converts user-specified parameters into parameters for a mev_sendBundle call to the MEV-Share API.
* @param params - Privacy/execution parameters for the bundle

@@ -61,18 +60,2 @@ * @returns Single-element array containing params object for sendPrivateTransaction call.

};
export declare class EventHistoryEntry {
block: number;
timestamp: number;
hint: {
txs?: Array<{
to: string;
callData: string;
functionSelector: string;
}>;
hash: string;
logs?: Array<LogParams>;
gasUsed: bigint;
mevGasPrice: bigint;
};
constructor(entry: IEventHistoryEntry);
}
//# sourceMappingURL=mungers.d.ts.map
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.EventHistoryEntry = exports.mungeSimBundleOptions = exports.mungeBundleParams = exports.mungePrivateTxParams = void 0;
exports.mungeSimBundleOptions = exports.mungeBundleParams = exports.mungePrivateTxParams = void 0;
/**
* Convert name format of user-specified hints for Matchmaker API requests.
* Convert name format of user-specified hints for MEV-Share API requests.
* @param hints - Hints specified by the user.

@@ -15,3 +15,3 @@ */

tx_hash: hints.txHash,
hash: true, // tx hash is always shared on Flashbots Matchmaker; abstract away from user
hash: true, // tx hash is always shared on Flashbots MEV-Share; abstract away from user
// setting all hints except hash to false will enable full privacy

@@ -30,3 +30,3 @@ };

/**
* Converts user-specified parameters into parameters for a sendPrivateTransaction call to the Matchmaker API.
* Converts user-specified parameters into parameters for a sendPrivateTransaction call to the MEV-Share API.
* @param signedTx - Signed transaction to send.

@@ -52,3 +52,3 @@ * @param options - Privacy/execution settings for the transaction.

/**
* Converts user-specified parameters into parameters for a mev_sendBundle call to the Matchmaker API.
* Converts user-specified parameters into parameters for a mev_sendBundle call to the MEV-Share API.
* @param params - Privacy/execution parameters for the bundle

@@ -73,10 +73,2 @@ * @returns Single-element array containing params object for sendPrivateTransaction call.

exports.mungeSimBundleOptions = mungeSimBundleOptions;
class EventHistoryEntry {
constructor(entry) {
this.block = entry.block;
this.timestamp = entry.timestamp;
this.hint = Object.assign(Object.assign({}, entry.hint), { gasUsed: BigInt(entry.hint.gasUsed), mevGasPrice: BigInt(entry.hint.mevGasPrice) });
}
}
exports.EventHistoryEntry = EventHistoryEntry;
//# sourceMappingURL=mungers.js.map
/**
* Network connection presets supported by the Flashbots Matchmaker.
* Network connection presets supported by Flashbots.
*/

@@ -22,2 +22,3 @@ export declare class SupportedNetworks {

static supportsChainId(chainId: number): boolean;
/** Gets the network preset matching the provided chainId, throws an error if not found. */
static getNetwork(chainId: number): {

@@ -24,0 +25,0 @@ name: string;

@@ -7,3 +7,3 @@ "use strict";

/**
* Network connection presets supported by the Flashbots Matchmaker.
* Network connection presets supported by Flashbots.
*/

@@ -17,2 +17,3 @@ class SupportedNetworks {

}
/** Gets the network preset matching the provided chainId, throws an error if not found. */
static getNetwork(chainId) {

@@ -19,0 +20,0 @@ if (this.supportsChainId(chainId)) {

import { AxiosError } from 'axios';
import { StreamEvent } from './api/interfaces';
declare class MatchmakerError extends Error {
import { StreamEventType } from './api/interfaces';
declare class MevShareError extends Error {
constructor(message: string);
}
export declare class JsonRpcError extends MatchmakerError {
export declare class JsonRpcError extends MevShareError {
constructor(error: {

@@ -12,6 +12,6 @@ code: number;

}
export declare class NetworkFailure extends MatchmakerError {
export declare class NetworkFailure extends MevShareError {
constructor(e: AxiosError);
}
export declare class UnimplementedNetwork extends MatchmakerError {
export declare class UnimplementedNetwork extends MevShareError {
constructor({ chainId }: {

@@ -21,6 +21,6 @@ chainId: number;

}
export declare class UnimplementedStreamEvent extends MatchmakerError {
constructor(eventType: StreamEvent);
export declare class UnimplementedStreamEvent extends MevShareError {
constructor(eventType: StreamEventType);
}
export default MatchmakerError;
export default MevShareError;
//# sourceMappingURL=error.d.ts.map
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.UnimplementedStreamEvent = exports.UnimplementedNetwork = exports.NetworkFailure = exports.JsonRpcError = void 0;
class MatchmakerError extends Error {
class MevShareError extends Error {
constructor(message) {
super(message);
this.name = "MatchmakerError";
this.name = "MevShareError";
}
}
class JsonRpcError extends MatchmakerError {
class JsonRpcError extends MevShareError {
constructor(error) {

@@ -18,3 +18,3 @@ super(`${error.code}: ${error.message}`);

exports.JsonRpcError = JsonRpcError;
class NetworkFailure extends MatchmakerError {
class NetworkFailure extends MevShareError {
constructor(e) {

@@ -28,3 +28,3 @@ var _a, _b;

exports.NetworkFailure = NetworkFailure;
class UnimplementedNetwork extends MatchmakerError {
class UnimplementedNetwork extends MevShareError {
constructor({ chainId }) {

@@ -36,3 +36,3 @@ super(`Cannot infer network params from chainId: ${chainId}`);

exports.UnimplementedNetwork = UnimplementedNetwork;
class UnimplementedStreamEvent extends MatchmakerError {
class UnimplementedStreamEvent extends MevShareError {
constructor(eventType) {

@@ -44,3 +44,3 @@ super(`Unimplemented stream event type: ${eventType.toString()}`);

exports.UnimplementedStreamEvent = UnimplementedStreamEvent;
exports.default = MatchmakerError;
exports.default = MevShareError;
//# sourceMappingURL=error.js.map

@@ -15,11 +15,9 @@ "use strict";

const provider = (0, helpers_1.getProvider)();
const { matchmaker } = yield (0, helpers_1.initExample)(provider);
const info = yield matchmaker.getEventHistoryInfo();
const { mevshare } = yield (0, helpers_1.initExample)(provider);
const info = yield mevshare.getEventHistoryInfo();
console.log(info);
info.minBlock;
info.count;
let i = 0;
let done = false;
while (!done) {
const resHistory = yield matchmaker.getEventHistory({
const resHistory = yield mevshare.getEventHistory({
limit: info.maxLimit,

@@ -26,0 +24,0 @@ offset: i * info.maxLimit,

import { JsonRpcProvider, Wallet } from 'ethers';
import Matchmaker from '../..';
import MevShareClient from '../..';
export declare function getProvider(): JsonRpcProvider;

@@ -8,5 +8,5 @@ export declare function initExample(provider: JsonRpcProvider): Promise<{

authSigner: Wallet;
matchmaker: Matchmaker;
mevshare: MevShareClient;
feeData: import("ethers").FeeData;
}>;
//# sourceMappingURL=helpers.d.ts.map

@@ -30,3 +30,3 @@ "use strict";

authSigner,
matchmaker: __1.default.useEthereumGoerli(authSigner),
mevshare: __1.default.useEthereumGoerli(authSigner),
feeData: yield provider.getFeeData(),

@@ -33,0 +33,0 @@ };

@@ -6,3 +6,3 @@ import { JsonRpcProvider, TransactionRequest } from 'ethers';

provider: JsonRpcProvider;
matchmaker: import("../..").default;
mevshare: import("../..").default;
tx: TransactionRequest;

@@ -9,0 +9,0 @@ signedTx: string;

@@ -16,3 +16,3 @@ "use strict";

const setupTxExample = (provider, tip, flair) => __awaiter(void 0, void 0, void 0, function* () {
const { wallet, feeData, matchmaker } = yield (0, helpers_1.initExample)(provider);
const { wallet, feeData, mevshare } = yield (0, helpers_1.initExample)(provider);
const tipActual = tip ? tip.valueOf() : BigInt(0);

@@ -33,3 +33,3 @@ const tx = {

provider,
matchmaker,
mevshare,
tx,

@@ -41,6 +41,6 @@ signedTx: yield wallet.signTransaction(tx),

const sendTx = (provider, hints, maxBlockNumber, tip) => __awaiter(void 0, void 0, void 0, function* () {
const { matchmaker, signedTx } = yield (0, exports.setupTxExample)(provider, tip);
return yield matchmaker.sendTransaction(signedTx, { hints, maxBlockNumber });
const { mevshare, signedTx } = yield (0, exports.setupTxExample)(provider, tip);
return yield mevshare.sendTransaction(signedTx, { hints, maxBlockNumber });
});
exports.sendTx = sendTx;
//# sourceMappingURL=sendTx.js.map

@@ -21,3 +21,3 @@ "use strict";

*/
const sendTestBackrunBundle = (provider, pendingTx, matchmaker, targetBlock) => __awaiter(void 0, void 0, void 0, function* () {
const sendTestBackrunBundle = (provider, pendingTx, mevshare, targetBlock) => __awaiter(void 0, void 0, void 0, function* () {
// send bundle w/ (basefee + 100)gwei gas fee

@@ -38,3 +38,3 @@ const { tx, wallet } = yield (0, sendTx_1.setupTxExample)(provider, BigInt(1e9) * BigInt(1e3), "im backrunniiiiing");

};
const backrunResult = yield matchmaker.sendBundle(bundleParams);
const backrunResult = yield mevshare.sendBundle(bundleParams);
return {

@@ -46,3 +46,3 @@ bundleParams,

/** Async handler which backruns an mev-share tx with another basic example tx. */
const handleBackrun = (pendingTx, provider, matchmaker, pendingMutex, pendingTxHashes) => __awaiter(void 0, void 0, void 0, function* () {
const handleBackrun = (pendingTx, provider, mevshare, pendingMutex, pendingTxHashes) => __awaiter(void 0, void 0, void 0, function* () {
console.log("pendingTxHashes", yield pendingTxHashes.get());

@@ -57,3 +57,3 @@ if (!(yield pendingTxHashes.includes(pendingTx.hash))) {

const targetBlock = (yield provider.getBlockNumber()) + 1;
const { bundleParams, backrunResult, } = yield sendTestBackrunBundle(provider, pendingTx, matchmaker, targetBlock);
const { bundleParams, backrunResult, } = yield sendTestBackrunBundle(provider, pendingTx, mevshare, targetBlock);
console.log("backrun result", backrunResult);

@@ -83,3 +83,3 @@ // watch future blocks for backrun tx inclusion

};
const simResult = yield matchmaker.simulateBundle(bundleParams, simOptions);
const simResult = yield mevshare.simulateBundle(bundleParams, simOptions);
console.log(`simResult (simOptions=${JSON.stringify(simOptions, null, 2)})`, simResult);

@@ -106,3 +106,3 @@ console.log(`profit: ${(0, ethers_1.formatEther)(simResult.profit)} ETH`);

const provider = (0, helpers_1.getProvider)();
const { matchmaker } = yield (0, helpers_1.initExample)(provider);
const { mevshare } = yield (0, helpers_1.initExample)(provider);
// used for tracking txs we sent. we only want to backrun txs we sent,

@@ -114,4 +114,4 @@ // since we're using one account and incrementing the nonce of the bundle's 2nd tx

// listen for txs
const txHandler = matchmaker.on("transaction", (pendingTx) => __awaiter(void 0, void 0, void 0, function* () {
yield handleBackrun(pendingTx, provider, matchmaker, pendingMutex, pendingTxHashes);
const txHandler = mevshare.on("transaction", (pendingTx) => __awaiter(void 0, void 0, void 0, function* () {
yield handleBackrun(pendingTx, provider, mevshare, pendingMutex, pendingTxHashes);
}));

@@ -118,0 +118,0 @@ console.log("listening for transactions...");

@@ -20,3 +20,3 @@ "use strict";

/** Send a bundle that shares as much data as possible by setting the `privacy` param. */
const sendTestBundle = (provider, matchmaker, wallet, targetBlock) => __awaiter(void 0, void 0, void 0, function* () {
const sendTestBundle = (provider, mevshare, wallet, targetBlock) => __awaiter(void 0, void 0, void 0, function* () {
const feeData = yield provider.getFeeData();

@@ -60,3 +60,3 @@ const tip = BigInt(1e9) * BigInt(2e7); // 0.02 eth

};
const backrunResult = yield matchmaker.sendBundle(bundleParams);
const backrunResult = yield mevshare.sendBundle(bundleParams);
return {

@@ -69,6 +69,6 @@ bundleParams,

const provider = (0, helpers_1.getProvider)();
const { matchmaker } = yield (0, helpers_1.initExample)(provider);
const { mevshare } = yield (0, helpers_1.initExample)(provider);
const targetBlock = (yield provider.getBlockNumber()) + 1;
const wallet = new ethers_1.Wallet(env_1.default.senderKey, provider);
const { bundleParams, backrunResult } = yield sendTestBundle(provider, matchmaker, wallet, targetBlock);
const { bundleParams, backrunResult } = yield sendTestBundle(provider, mevshare, wallet, targetBlock);
console.log("bundleParams", bundleParams);

@@ -75,0 +75,0 @@ console.log("backrunResult", backrunResult);

@@ -1,5 +0,5 @@

import Matchmaker from './matchmaker';
export { BundleParams, HintPreferences, IPendingBundle, IPendingTransaction, TransactionOptions, StreamEvent, } from "./api/interfaces";
import MevShareClient from './client';
export { BundleParams, HintPreferences, IPendingBundle, IPendingTransaction, TransactionOptions, EventHistoryInfo, EventHistoryParams, EventHistoryEntry, } from "./api/interfaces";
export { SupportedNetworks } from "./api/networks";
export default Matchmaker;
export default MevShareClient;
//# sourceMappingURL=index.d.ts.map

@@ -6,9 +6,9 @@ "use strict";

Object.defineProperty(exports, "__esModule", { value: true });
exports.SupportedNetworks = exports.StreamEvent = void 0;
const matchmaker_1 = __importDefault(require("./matchmaker"));
exports.SupportedNetworks = exports.EventHistoryEntry = void 0;
const client_1 = __importDefault(require("./client"));
var interfaces_1 = require("./api/interfaces");
Object.defineProperty(exports, "StreamEvent", { enumerable: true, get: function () { return interfaces_1.StreamEvent; } });
Object.defineProperty(exports, "EventHistoryEntry", { enumerable: true, get: function () { return interfaces_1.EventHistoryEntry; } });
var networks_1 = require("./api/networks");
Object.defineProperty(exports, "SupportedNetworks", { enumerable: true, get: function () { return networks_1.SupportedNetworks; } });
exports.default = matchmaker_1.default;
exports.default = client_1.default;
//# sourceMappingURL=index.js.map
import { Wallet } from 'ethers';
import EventSource from "eventsource";
import { BundleParams, MatchmakerNetwork, TransactionOptions, StreamEvent, IPendingTransaction, IPendingBundle, SimBundleOptions, ISimBundleResult, ISendBundleResult, StreamEventName, EventHistoryInfo, EventHistoryParams } from './api/interfaces';
import { BundleParams, MevShareNetwork, TransactionOptions, StreamEvent, IPendingTransaction, IPendingBundle, SimBundleOptions, ISimBundleResult, ISendBundleResult, StreamEventName, EventHistoryInfo, EventHistoryParams } from './api/interfaces';
import { EventHistoryEntry } from "./api/mungers";

@@ -8,3 +8,3 @@ export default class Matchmaker {

private network;
constructor(authSigner: Wallet, network: MatchmakerNetwork);
constructor(authSigner: Wallet, network: MevShareNetwork);
/** Connect to Flashbots Mainnet Matchmaker. */

@@ -20,3 +20,3 @@ static useEthereumMainnet(authSigner: Wallet): Matchmaker;

* @param url - URL to send the request to.
* @param params - body & headers.
* @param payload - body & headers.
* @returns Response data.

@@ -26,3 +26,3 @@ */

/** Make an HTTP GET request.
* @param url - URL to send the request to.
* @param urlSuffix - URL to send the request to.
*/

@@ -29,0 +29,0 @@ private streamGet;

@@ -72,3 +72,3 @@ "use strict";

* @param url - URL to send the request to.
* @param params - body & headers.
* @param payload - body & headers.
* @returns Response data.

@@ -89,3 +89,3 @@ */

/** Make an HTTP GET request.
* @param url - URL to send the request to.
* @param urlSuffix - URL to send the request to.
*/

@@ -92,0 +92,0 @@ streamGet(urlSuffix) {

{
"name": "@flashbots/matchmaker-ts",
"version": "0.7.5",
"version": "0.7.6",
"description": "Matchmaker client library for Flashbots mev-share.",

@@ -12,3 +12,2 @@ "main": "build/index.js",

"axios": "^1.3.4",
"ethers": "^6.5.1",
"eventsource": "^2.0.2"

@@ -24,2 +23,3 @@ },

"eslint-plugin-tsdoc": "^0.2.17",
"ethers": "^6.5.1",
"release-it": "^15.8.0",

@@ -29,2 +29,5 @@ "ts-node": "^10.9.1",

},
"peerDependencies": {
"ethers": "^6.5.1"
},
"scripts": {

@@ -31,0 +34,0 @@ "build": "tsc",

# Flashbots Matchmaker
Client library for Flashbots `MEV-share` Matchmaker.
> 🚧 NOTICE 🚧
>
> This library has been moved to [@flashbots/mev-share-client-ts](https://www.npmjs.com/package/@flashbots/mev-share-client).
Based on [prospective API docs](https://flashbots.notion.site/PUBLIC-Prospective-MEV-Share-API-docs-28610c583e5b485d92b62daf6e0cc874).
## quickstart

@@ -12,5 +12,5 @@

```sh
yarn add @flashbots/matchmaker-ts
yarn add @flashbots/mev-share-client
# or
npm i @flashbots/matchmaker-ts
npm i @flashbots/mev-share-client
```

@@ -21,4 +21,4 @@

```sh
git clone https://github.com/flashbots/matchmaker-ts
cd matchmaker-ts
git clone https://github.com/flashbots/mev-share-client-ts
cd mev-share-client-ts
yarn install && yarn build

@@ -29,286 +29,5 @@ ```

# in your project, assuming it has the same parent directory as matchmaker-ts
yarn add ../matchmaker-ts
yarn add ../mev-share-client-ts
```
### use matchmaker in your project
> :warning: Variables denoted in `ALL_CAPS` are placeholders; the code does not compile. [examples/](#examples) contains compilable demos.
In your project:
```typescript
import { Wallet, JsonRpcProvider } from "ethers"
import Matchmaker, {
BundleParams,
HintPreferences,
IPendingBundle,
IPendingTransaction,
TransactionOptions
} from "@flashbots/matchmaker-ts"
const provider = new JsonRpcProvider(RPC_URL)
const authSigner = new Wallet(FB_REPUTATION_PRIVATE_KEY, provider)
```
The `Matchmaker` class has built-in initializers for networks supported by Flashbots.
#### Connect to Ethereum Mainnet
```typescript
const matchmaker = Matchmaker.useEthereumMainnet(authSigner)
```
#### Connect to Ethereum Goerli
```typescript
const matchmaker = Matchmaker.useEthereumGoerli(authSigner)
```
#### Connect with an Ethers Provider or Chain ID
Networks supported by Flashbots have presets built-in. If it's more convenient, you can instantiate a Matchmaker using a `chainId` (or a ethers.js `Network` object, which has a `chainId` param).
```typescript
import { JsonRpcProvider, Wallet } from "ethers" // ethers v6
/** connects to Flashbots matchmaker on goerli */
const provider = new JsonRpcProvider("http://localhost:8545", {chainId: 5, name: "goerli"})
const authSigner = new Wallet("0xac0974bec39a17e36ba4a6b4d238ff944bacb478cbed5efcae784d7bf4f2ff80")
.connect(provider)
const matchmaker = Matchmaker.fromNetwork(authSigner, provider._network)
// manually with a chainId:
const matchmaker = Matchmaker.fromNetwork(authSigner, {chainId: 5})
```
#### Connect to a custom network
To use custom network parameters, you can instantiate a new Matchmaker directly. This example is what the client uses to connect to mainnet:
```typescript
const matchmaker = new Matchmaker(authSigner, {
name: "mainnet",
chainId: 1,
streamUrl: "https://mev-share.flashbots.net",
apiUrl: "https://relay.flashbots.net"
})
```
See [MatchmakerNetwork](/src/api/interfaces.ts#L15) for more details.
### examples
_[Source code](./src/examples/)_
> :information_source: Examples require a `.env` file (or that you populate your environment directly with the appropriate variables).
```sh
cd src/examples
cp .env.example .env
vim .env
```
#### send a tx with hints
This example sends a transaction to the Flashbots Goerli Matchmaker from the account specified by SENDER_PRIVATE_KEY with a hex-encoded string as calldata.
```sh
yarn example.tx
```
#### backrun a pending tx
This example watches the mev-share streaming endpoint for pending mev-share transactions and attempts to backrun them all. The example runs until a backrun has been included on-chain.
```sh
yarn example.backrun
```
## Usage
See [src/api/interfaces.ts](src/api/interfaces.ts) for interface definitions.
### `on`
Use `on` to start listening for events on mev-share. The function registers the provided callback to be called when a new event is detected.
```typescript
const handler = matchmaker.on("transaction", (tx: IPendingTransaction) => {
// handle pending tx
})
// ... before terminating program
handler.close()
```
### `sendTransaction`
Sends a private transaction to the Flashbots Matchmaker with specified hint parameters.
```typescript
const wallet = new Wallet(PRIVATE_KEY)
const tx = {
to: "0xfb000000387627910184cc42fc92995913806333",
value: BigInt(1e13 * 275), // price of a beer if ETH is $2000
data: "0x646f637320626179626565652121",
gasLimit: 42000,
maxFeePerGas: BigInt(1e9) * BigInt(42), // 42 gwei / gas
maxPriorityFeePerGas: BigInt(1e9) * BigInt(2), // 2 gwei / gas
chainId: 5,
type: 2,
}
// privacy & inclusion settings
const shareTxParams: TransactionOptions = {
hints: {
logs: true,
calldata: false,
functionSelector: true,
contractAddress: true,
},
maxBlockNumber: undefined,
builders: ["flashbots"]
}
const signedTx = await wallet.signTransaction(tx)
await matchmaker.sendTransaction(SIGNED_TX, shareTxParams)
```
### `sendBundle`
Sends a bundle; an array of transactions with parameters to specify conditions for inclusion and MEV kickbacks. Transactions are placed in the `body` parameter with wrappers to indicate whether they're a new signed transaction or a pending transaction from the event stream.
See [MEV-Share Docs](https://github.com/flashbots/mev-share/blob/main/src/mev_sendBundle.md) for detailed descriptions of these parameters.
```typescript
const targetBlock = 1 + await provider.getBlockNumber()
const bundleParams: BundleParams = {
inclusion: {
block: targetBlock,
},
body: [
{hash: TX_HASH_FROM_EVENT_STREAM},
{tx: SIGNED_TX, canRevert: false},
],
}
await matchmaker.sendBundle(bundleParams)
```
Bundles that _only_ contain signed transactions can share hints about the transactions in their bundle by setting the `privacy` parameter:
```typescript
const targetBlock = 1 + await provider.getBlockNumber()
const bundleParams: BundleParams = {
inclusion: {
block: targetBlock,
maxBlock: targetBlock + 5, // allow bundle to land in next 5 blocks
},
body: [
{tx: await wallet.signTransaction(TX1), canRevert: false},
{tx: await wallet.signTransaction(TX2), canRevert: false},
],
privacy: {
hints: {
txHash: true,
calldata: true,
logs: true,
functionSelector: true,
contractAddress: true,
},
}
}
const backrunResult = await matchmaker.sendBundle(bundleParams)
```
### `simulateBundle`
Simulates a bundle. Accepts options to modify block header for simulation.
```typescript
const bundle: BundleParams = {
inclusion: {
block: TARGET_BLOCK,
maxBlock: TARGET_BLOCK + 3,
},
body: [
{hash: "0xTARGET_TX_HASH"},
{tx: "0xSIGNED_BACKRUN_TX", canRevert: false}
],
// ...
}
// ...
// assume you sent the bundle and it didn't land, and you want to see if it would have landed in the previous block, but need the tx to think it's in the target block
const simBundleOptions: SimBundleOptions = {
parentBlock: TARGET_BLOCK - 1,
blockNumber: TARGET_BLOCK,
/*
Set any of these (block header) fields to override their respective values in the simulation context:
*/
// coinbase: string,
// timestamp: number,
// gasLimit: number,
// baseFee: bigint,
// timeout: number,
}
const simResult = await matchmaker.simulateBundle(bundle, simBundleOptions)
```
This example uses the state of `parentBlock`, but overrides the state's `blockNumber` value. Setting more fields in `SimBundleOptions` is useful when testing smart contracts which have specific criteria that must be met, like the block being a certain number, or a specific timestamp having passed.
### `getEventHistoryInfo`
Get information about the event history endpoint for use in [`getEventHistory`](#geteventhistory).
Example:
```typescript
const info = await matchmaker.getEventHistoryInfo()
console.log(info)
```
returns something like this:
```txt
{
count: 56934,
minBlock: 9091377,
maxBlock: 9190024,
minTimestamp: 1685452445,
maxTimestamp: 1686943324,
maxLimit: 500
}
```
### `getEventHistory`
Get historical event stream data.
Using the data from our [`getEventHistoryInfo`](#geteventhistoryinfo) call, we can read events starting from the beginning. The data is paginated, so to read all of it, you'll have to make multiple calls to iterate through the it.
```typescript
const info = await matchmaker.getEventHistoryInfo()
// read every event
for (let i = 0; i < Math.ceil(info.count / info.maxLimit); i++) {
const events = await matchmaker.getEventHistory({
limit: info.maxLimit,
offset: i * info.maxLimit,
blockStart: info.minBlock,
})
console.log(events)
}
```
You can also filter events by timestamp:
```typescript
const events = await matchmaker.getEventHistory({
limit: info.maxLimit,
offset: i * info.maxLimit,
timestampStart: 1686942023,
})
```
Please see the [new git repository](https://github.com/flashbots/mev-share-client-ts) or the [latest npm release](https://www.npmjs.com/package/@flashbots/mev-share-client) for more instructions.

@@ -6,3 +6,3 @@ import { LogParams } from 'ethers'

*/
export enum StreamEvent {
export enum StreamEventType {
Bundle = 'bundle',

@@ -12,3 +12,3 @@ Transaction = 'transaction',

export type StreamEventName = `${StreamEvent}`
export type StreamEventName = `${StreamEventType}`

@@ -58,6 +58,2 @@ /** Data about the event history endpoint. */

export type MatchmakerNetwork = {
/** Chain ID of the network. e.g. `1` */
chainId: number,
/** Lowercase name of network. e.g. "mainnet" */
name: string,
/** Matchmaker event stream URL. */

@@ -286,1 +282,26 @@ streamUrl: string,

}
export class EventHistoryEntry {
public block: number
public timestamp: number
public hint: {
txs?: Array<{
to: string,
callData: string,
functionSelector: string,
}>,
hash: string,
logs?: Array<LogParams>,
gasUsed: bigint,
mevGasPrice: bigint,
}
constructor(entry: IEventHistoryEntry) {
this.block = entry.block
this.timestamp = entry.timestamp
this.hint = {
...entry.hint,
gasUsed: entry.hint.gasUsed ? BigInt(entry.hint.gasUsed) : BigInt(0),
mevGasPrice: entry.hint.mevGasPrice ? BigInt(entry.hint.mevGasPrice) : BigInt(0),
}
}
}

@@ -1,3 +0,2 @@

import { LogParams } from 'ethers'
import { BundleParams, HintPreferences, IEventHistoryEntry, SimBundleOptions, TransactionOptions } from './interfaces'
import { BundleParams, HintPreferences, SimBundleOptions, TransactionOptions } from './interfaces'

@@ -92,26 +91,1 @@ /**

}
export class EventHistoryEntry {
public block: number
public timestamp: number
public hint: {
txs?: Array<{
to: string,
callData: string,
functionSelector: string,
}>,
hash: string,
logs?: Array<LogParams>,
gasUsed: bigint,
mevGasPrice: bigint,
}
constructor(entry: IEventHistoryEntry) {
this.block = entry.block
this.timestamp = entry.timestamp
this.hint = {
...entry.hint,
gasUsed: BigInt(entry.hint.gasUsed),
mevGasPrice: BigInt(entry.hint.mevGasPrice),
}
}
}
import { AxiosError } from 'axios'
import { StreamEvent } from './api/interfaces'
import { StreamEventType } from './api/interfaces'

@@ -35,3 +35,3 @@ class MatchmakerError extends Error {

export class UnimplementedStreamEvent extends MatchmakerError {
constructor(eventType: StreamEvent) {
constructor(eventType: StreamEventType) {
super(`Unimplemented stream event type: ${eventType.toString()}`)

@@ -38,0 +38,0 @@ this.name = "UnimplementedStreamEvent"

@@ -9,5 +9,2 @@ import { getProvider, initExample } from './lib/helpers'

info.minBlock
info.count
let i = 0

@@ -14,0 +11,0 @@ let done = false

@@ -9,3 +9,6 @@ import Matchmaker from './matchmaker'

TransactionOptions,
StreamEvent,
// StreamEventType,
EventHistoryInfo,
EventHistoryParams,
EventHistoryEntry,
} from "./api/interfaces"

@@ -12,0 +15,0 @@

@@ -11,3 +11,3 @@ import axios, { AxiosError } from "axios"

TransactionOptions,
StreamEvent,
StreamEventType,
IMatchmakerEvent,

@@ -24,5 +24,6 @@ IPendingTransaction,

EventHistoryParams,
IEventHistoryEntry
IEventHistoryEntry,
EventHistoryEntry
} from './api/interfaces'
import { EventHistoryEntry, mungeBundleParams, mungePrivateTxParams, mungeSimBundleOptions } from "./api/mungers"
import { mungeBundleParams, mungePrivateTxParams, mungeSimBundleOptions } from "./api/mungers"
import { SupportedNetworks } from './api/networks'

@@ -55,4 +56,5 @@ import { PendingBundle, PendingTransaction } from './api/events';

/** Connect to supported networks by specifying a network with a `chainId`. */
static fromNetwork(authSigner: Wallet, {chainId}: {chainId: number}): Matchmaker {
const network = SupportedNetworks.getNetwork(chainId)
static fromNetwork(authSigner: Wallet, {chainId}: {chainId: number | bigint}): Matchmaker {
const chainNum = typeof chainId == "bigint" ? Number(chainId) : chainId
const network = SupportedNetworks.getNetwork(chainNum)
return new Matchmaker(authSigner, network)

@@ -141,3 +143,3 @@ }

public on(
eventType: StreamEvent | StreamEventName,
eventType: StreamEventType | StreamEventName,
callback: (data: IPendingBundle | IPendingTransaction) => void

@@ -148,4 +150,4 @@ ): EventSource {

const eventHandler =
eventType === StreamEvent.Transaction ? this.onTransaction :
eventType === StreamEvent.Bundle ? this.onBundle :
eventType === StreamEventType.Transaction ? this.onTransaction :
eventType === StreamEventType.Bundle ? this.onBundle :
() => { throw new UnimplementedStreamEvent(eventType) }

@@ -152,0 +154,0 @@

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

SocketSocket SOC 2 Logo

Product

  • Package Alerts
  • Integrations
  • Docs
  • Pricing
  • FAQ
  • Roadmap

Stay in touch

Get open source security insights delivered straight into your inbox.


  • Terms
  • Privacy
  • Security

Made with ⚡️ by Socket Inc