From 51999df5e0beed6c53053c28f286f37dc915d40f Mon Sep 17 00:00:00 2001 From: Emre Akinci Date: Thu, 14 Apr 2022 19:31:08 +0300 Subject: [PATCH 1/3] Add middleware support --- src/index.ts | 9 ++++++++- src/types.ts | 6 ++++++ src/web3-adapter/sendJsonRpcPayload.ts | 18 ++++++++++++++---- 3 files changed, 28 insertions(+), 5 deletions(-) diff --git a/src/index.ts b/src/index.ts index dbbde58..0f875bd 100644 --- a/src/index.ts +++ b/src/index.ts @@ -243,11 +243,18 @@ export function createAlchemyWeb3( function fillInConfigDefaults({ writeProvider = getWindowProvider(), + jsonRpcSenderMiddlewares = [], maxRetries = DEFAULT_MAX_RETRIES, retryInterval = DEFAULT_RETRY_INTERVAL, retryJitter = DEFAULT_RETRY_JITTER, }: AlchemyWeb3Config = {}): FullConfig { - return { writeProvider, maxRetries, retryInterval, retryJitter }; + return { + writeProvider, + jsonRpcSenderMiddlewares, + maxRetries, + retryInterval, + retryJitter, + }; } function getWindowProvider(): Provider | null { diff --git a/src/types.ts b/src/types.ts index 87cf888..a577912 100644 --- a/src/types.ts +++ b/src/types.ts @@ -53,6 +53,7 @@ export function isSubscriptionEvent( export interface AlchemyWeb3Config { writeProvider?: Provider | null; + jsonRpcSenderMiddlewares?: JsonRpcSenderMiddleware[]; maxRetries?: number; retryInterval?: number; retryJitter?: number; @@ -86,3 +87,8 @@ export type SendJsonRpcFunction = ( export interface TransactionsOptions { address?: string; } + +export type JsonRpcSenderMiddleware = ( + req: SingleOrBatchRequest, + next: () => Promise, +) => Promise; diff --git a/src/web3-adapter/sendJsonRpcPayload.ts b/src/web3-adapter/sendJsonRpcPayload.ts index ae2cb7e..48f70e7 100644 --- a/src/web3-adapter/sendJsonRpcPayload.ts +++ b/src/web3-adapter/sendJsonRpcPayload.ts @@ -3,6 +3,7 @@ import { FullConfig, JsonRpcRequest, JsonRpcResponse, + JsonRpcSenderMiddleware, Provider, SingleOrBatchRequest, SingleOrBatchResponse, @@ -34,11 +35,12 @@ export function makeJsonRpcPayloadSender( alchemySendJsonRpc: AlchemySendJsonRpcFunction, config: FullConfig, ): JsonRpcPayloadSender { - let currentWriteProvider = config.writeProvider; + // Copy middlewares from config. + const middlewares: JsonRpcSenderMiddleware[] = []; + config.jsonRpcSenderMiddlewares.forEach((m) => middlewares.push(m)); - const sendJsonRpcPayload = ( - payload: SingleOrBatchRequest, - ): Promise => { + let currentWriteProvider = config.writeProvider; + middlewares.push((payload) => { const disallowedMethod = getDisallowedMethod(payload); if (!disallowedMethod) { try { @@ -63,6 +65,14 @@ export function makeJsonRpcPayloadSender( } return sendJsonRpcWithProvider(currentWriteProvider, payload); } + }); + + const sendJsonRpcPayload = ( + payload: SingleOrBatchRequest, + ): Promise => { + let i = 0; + const next = () => middlewares[i++](payload, next); + return next(); }; function setWriteProvider(writeProvider: Provider | null | undefined) { From 0ba21e32bc13f4afa164d770ab0c090d1c4e02ed Mon Sep 17 00:00:00 2001 From: Emre Akinci Date: Fri, 15 Apr 2022 22:26:51 +0300 Subject: [PATCH 2/3] Handle calling a middleware twice --- src/web3-adapter/sendJsonRpcPayload.ts | 14 ++++++++++++-- 1 file changed, 12 insertions(+), 2 deletions(-) diff --git a/src/web3-adapter/sendJsonRpcPayload.ts b/src/web3-adapter/sendJsonRpcPayload.ts index 48f70e7..3e781b0 100644 --- a/src/web3-adapter/sendJsonRpcPayload.ts +++ b/src/web3-adapter/sendJsonRpcPayload.ts @@ -71,8 +71,18 @@ export function makeJsonRpcPayloadSender( payload: SingleOrBatchRequest, ): Promise => { let i = 0; - const next = () => middlewares[i++](payload, next); - return next(); + const getNext = () => { + let called = false; + const middleware = middlewares[i++]; + return () => { + if (called) { + throw new Error(`Cannot call "next" in a middleware twice`); + } + called = true; + return middleware(payload, getNext()); + }; + }; + return getNext()(); }; function setWriteProvider(writeProvider: Provider | null | undefined) { From 3ee0298ccefe4e3b543e6f5132d132c936358ac9 Mon Sep 17 00:00:00 2001 From: Emre Akinci Date: Mon, 18 Apr 2022 01:00:03 +0300 Subject: [PATCH 3/3] Allow calling `next` multiple times in middleware --- src/web3-adapter/sendJsonRpcPayload.ts | 16 ++++------------ 1 file changed, 4 insertions(+), 12 deletions(-) diff --git a/src/web3-adapter/sendJsonRpcPayload.ts b/src/web3-adapter/sendJsonRpcPayload.ts index 3e781b0..9adc526 100644 --- a/src/web3-adapter/sendJsonRpcPayload.ts +++ b/src/web3-adapter/sendJsonRpcPayload.ts @@ -70,19 +70,11 @@ export function makeJsonRpcPayloadSender( const sendJsonRpcPayload = ( payload: SingleOrBatchRequest, ): Promise => { - let i = 0; - const getNext = () => { - let called = false; - const middleware = middlewares[i++]; - return () => { - if (called) { - throw new Error(`Cannot call "next" in a middleware twice`); - } - called = true; - return middleware(payload, getNext()); - }; + const getNext = (i: number) => { + const middleware = middlewares[i]; + return () => middleware(payload, getNext(i + 1)); }; - return getNext()(); + return getNext(0)(); }; function setWriteProvider(writeProvider: Provider | null | undefined) {