Skip to content

Commit

Permalink
feat/docs/plugin-middleware (#7158)
Browse files Browse the repository at this point in the history
* Add Plugin Middleware Documentation

Closes #6963

* Clarify Request Middleware Response Processing
  • Loading branch information
danforbes committed Jul 22, 2024
1 parent 5f6deeb commit e5efe49
Showing 1 changed file with 67 additions and 0 deletions.
67 changes: 67 additions & 0 deletions docs/docs/guides/web3_plugin_guide/plugin_authors.md
Original file line number Diff line number Diff line change
Expand Up @@ -233,6 +233,73 @@ public link(parentContext: Web3Context) {
}
```

## Plugin Middleware

Middleware allows plugins to intercept network interactions and inject custom logic. There are two types of plugin middleware: [request middleware](#request-middleware) and [transaction middleware](#transaction-middleware). In both cases, the middleware is implemented as a new class and registered with the plugin in the plugin's `link` method. Keep reading to learn how to add middleware to a plugin.

### Request Middleware

Request middleware allows plugins to modify RPC requests before they are sent to the network and modify RPC responses before they are returned to Web3.js for further internal processing. Request middleware must implement the [`RequestManagerMiddleware`](/api/web3-core/interface/RequestManagerMiddleware) interface, which specifies two functions: [`processRequest`](/api/web3-core/interface/RequestManagerMiddleware#processRequest) and [`processResponse`](/api/web3-core/interface/RequestManagerMiddleware#processResponse). Here is a simple example of request middleware that prints RPC requests and responses to the console:

```ts
export class RequestMiddleware<API> implements RequestManagerMiddleware<API> {
public async processRequest<ParamType = unknown[]>(
request: JsonRpcPayload<ParamType>
): Promise<JsonRpcPayload<ParamType>> {
const reqObj = { ...request } as JsonRpcPayload;
console.log("Request:", reqObj);
return Promise.resolve(reqObj as JsonRpcPayload<ParamType>);
}

public async processResponse<
Method extends Web3APIMethod<API>,
ResponseType = Web3APIReturnType<API, Method>
>(
response: JsonRpcResponse<ResponseType>
): Promise<JsonRpcResponse<ResponseType>> {
const resObj = { ...response };
console.log("Response:", resObj);
return Promise.resolve(resObj);
}
}
```

To add request middleware to a plugin, use the [`Web3RequestManager.setMiddleware`](/api/web3-core/class/Web3RequestManager#setMiddleware) method in the plugin's `link` method as demonstrated below:

```ts
public link(parentContext: Web3Context): void {
parentContext.requestManager.setMiddleware(new RequestMiddleware());
super.link(parentContext);
}
```

### Transaction Middleware

Transaction middleware allows plugins to modify transaction data before it is sent to the network. Transaction middleware must implement the [`TransactionMiddleware`](/api/web3-eth/interface/TransactionMiddleware) interface, which specifies one function: [`processTransaction`](/api/web3-eth/interface/TransactionMiddleware#processTransaction). Here is a simple example of transaction middleware that prints transaction data to the console:

```ts
export class TxnMiddleware implements TransactionMiddleware {
public async processTransaction(
transaction: TransactionMiddlewareData
): Promise<TransactionMiddlewareData> {
const txObj = { ...transaction };
console.log("Transaction data:", txObj);
return Promise.resolve(txObj);
}
}
```

To add transaction middleware to a plugin, use the [`Web3Eth.setTransactionMiddleware`](/api/web3-eth/class/Web3Eth#setTransactionMiddleware) method in the plugin's `link` method as demonstrated below:

```ts
public link(parentContext: Web3Context): void {
(parentContext as any).Web3Eth.setTransactionMiddleware(
new TxnMiddleware()
);
super.link(parentContext);
}
```

## Setting Up Module Augmentation

In order to provide type safety and IntelliSense for your plugin when it's registered by the user, you must [augment](https://www.typescriptlang.org/docs/handbook/declaration-merging.html#module-augmentation) the `Web3Context` module. In simpler terms, you will be making TypeScript aware that you are modifying the interface of the class `Web3Context`, and any class that extends it, to include the interface of your plugin (i.e. your plugin's added methods, properties, etc.). As a result, your plugin object will be accessible within a namespace of your choice, which will be available within any `Web3Context` object.
Expand Down

2 comments on commit e5efe49

@github-actions
Copy link

Choose a reason for hiding this comment

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

Benchmark

Benchmark suite Current: e5efe49 Previous: 5f6deeb Ratio
processingTx 8947 ops/sec (±3.86%) 9233 ops/sec (±3.97%) 1.03
processingContractDeploy 37776 ops/sec (±7.58%) 40168 ops/sec (±4.88%) 1.06
processingContractMethodSend 14888 ops/sec (±7.67%) 16302 ops/sec (±6.45%) 1.09
processingContractMethodCall 26666 ops/sec (±6.80%) 28306 ops/sec (±6.19%) 1.06
abiEncode 40151 ops/sec (±7.25%) 42794 ops/sec (±8.67%) 1.07
abiDecode 27964 ops/sec (±8.86%) 31117 ops/sec (±7.21%) 1.11
sign 1481 ops/sec (±3.51%) 1588 ops/sec (±0.64%) 1.07
verify 360 ops/sec (±0.58%) 367 ops/sec (±0.70%) 1.02

This comment was automatically generated by workflow using github-action-benchmark.

@github-actions
Copy link

Choose a reason for hiding this comment

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

Benchmark

Benchmark suite Current: e5efe49 Previous: 5f6deeb Ratio
processingTx 9178 ops/sec (±4.17%) 9233 ops/sec (±3.97%) 1.01
processingContractDeploy 39087 ops/sec (±7.95%) 40168 ops/sec (±4.88%) 1.03
processingContractMethodSend 16179 ops/sec (±8.43%) 16302 ops/sec (±6.45%) 1.01
processingContractMethodCall 28048 ops/sec (±7.77%) 28306 ops/sec (±6.19%) 1.01
abiEncode 44906 ops/sec (±6.95%) 42794 ops/sec (±8.67%) 0.95
abiDecode 30714 ops/sec (±8.09%) 31117 ops/sec (±7.21%) 1.01
sign 1518 ops/sec (±3.26%) 1588 ops/sec (±0.64%) 1.05
verify 373 ops/sec (±1.22%) 367 ops/sec (±0.70%) 0.98

This comment was automatically generated by workflow using github-action-benchmark.

Please sign in to comment.