Skip to content

Commit

Permalink
Remove btoa (#192)
Browse files Browse the repository at this point in the history
The `btoa` function must now be passed in as a middleware option. This
lets us remove an additional dependency, and makes this package less
dependent upon Node.js or browser specific APIs.
  • Loading branch information
Gudahtt authored Feb 10, 2023
1 parent 51edeb7 commit ce20d95
Show file tree
Hide file tree
Showing 4 changed files with 36 additions and 16 deletions.
1 change: 0 additions & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,6 @@
"@metamask/eth-sig-util": "^5.0.0",
"@metamask/safe-event-emitter": "^2.0.0",
"@metamask/utils": "^3.0.3",
"btoa": "^1.2.1",
"clone": "^2.1.1",
"eth-block-tracker": "^6.1.0",
"eth-rpc-errors": "^4.0.3",
Expand Down
19 changes: 18 additions & 1 deletion src/fetch.test.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,17 @@
import { createFetchConfigFromReq } from '.';

/**
* Generate a base64-encoded string from a binary string. This should be equivalent to
* `window.btoa`.
*
* @param stringToEncode - The string to encode.
* @returns The base64-encoded string.
*/
// eslint-disable-next-line @typescript-eslint/no-shadow
function btoa(stringToEncode: string) {
return Buffer.from(stringToEncode).toString('base64');
}

describe('fetch', () => {
it('should create a fetch config from a request', async () => {
const req = {
Expand All @@ -9,7 +21,11 @@ describe('fetch', () => {
params: ['0x482103', true],
};
const rpcUrl = 'http://www.xyz.io/rabbit:3456?id=100';
const { fetchUrl, fetchParams } = createFetchConfigFromReq({ req, rpcUrl });
const { fetchUrl, fetchParams } = createFetchConfigFromReq({
btoa,
req,
rpcUrl,
});
expect(fetchUrl).toStrictEqual(rpcUrl);
expect(fetchParams).toStrictEqual({
method: 'POST',
Expand All @@ -32,6 +48,7 @@ describe('fetch', () => {
const rpcUrl = 'http://www.xyz.io/rabbit:3456?id=100';
const originHttpHeaderKey = 'x-dapp-origin';
const { fetchUrl, fetchParams } = createFetchConfigFromReq({
btoa,
req: requestWithOrigin,
rpcUrl,
originHttpHeaderKey,
Expand Down
22 changes: 18 additions & 4 deletions src/fetch.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,10 +6,6 @@ import {
import { EthereumRpcError, ethErrors } from 'eth-rpc-errors';
import type { Block } from './types';

/* eslint-disable @typescript-eslint/no-require-imports,@typescript-eslint/no-shadow */
const btoa = global.btoa || require('btoa');
/* eslint-enable @typescript-eslint/no-require-imports,@typescript-eslint/no-shadow */

const RETRIABLE_ERRORS: string[] = [
// ignore server overload errors
'Gateway timeout',
Expand Down Expand Up @@ -38,24 +34,29 @@ interface FetchConfig {
* Create middleware for sending a JSON-RPC request to the given RPC URL.
*
* @param options - Options
* @param options.btoa - Generates a base64-encoded string from a binary string.
* @param options.fetch - The `fetch` function; expected to be equivalent to `window.fetch`.
* @param options.rpcUrl - The URL to send the request to.
* @param options.originHttpHeaderKey - If provider, the origin field for each JSON-RPC request
* will be attached to each outgoing fetch request under this header.
* @returns The fetch middleware.
*/
export function createFetchMiddleware({
// eslint-disable-next-line @typescript-eslint/no-shadow
btoa,
// eslint-disable-next-line @typescript-eslint/no-shadow
fetch,
rpcUrl,
originHttpHeaderKey,
}: {
btoa: (stringToEncode: string) => string;
fetch: typeof global.fetch;
rpcUrl: string;
originHttpHeaderKey?: string;
}): JsonRpcMiddleware<unknown, unknown> {
return createAsyncMiddleware(async (req, res, _next) => {
const { fetchUrl, fetchParams } = createFetchConfigFromReq({
btoa,
req,
rpcUrl,
originHttpHeaderKey,
Expand Down Expand Up @@ -136,11 +137,24 @@ function parseResponse(fetchRes: Response, body: Record<string, Block>): Block {
return body.result;
}

/**
* Generate `fetch` configuration for sending the given request to an RPC API.
*
* @param options - Options
* @param options.btoa - Generates a base64-encoded string from a binary string.
* @param options.rpcUrl - The URL to send the request to.
* @param options.originHttpHeaderKey - If provider, the origin field for each JSON-RPC request
* will be attached to each outgoing fetch request under this header.
* @returns The fetch middleware.
*/
export function createFetchConfigFromReq({
// eslint-disable-next-line @typescript-eslint/no-shadow
btoa,
req,
rpcUrl,
originHttpHeaderKey,
}: {
btoa: (stringToEncode: string) => string;
rpcUrl: string;
originHttpHeaderKey?: string;
req: PayloadWithOrigin;
Expand Down
10 changes: 0 additions & 10 deletions yarn.lock
Original file line number Diff line number Diff line change
Expand Up @@ -867,7 +867,6 @@ __metadata:
"@types/pify": ^3.0.2
"@typescript-eslint/eslint-plugin": ^4.21.0
"@typescript-eslint/parser": ^4.21.0
btoa: ^1.2.1
clone: ^2.1.1
eslint: ^7.14.0
eslint-config-prettier: ^8.1.0
Expand Down Expand Up @@ -1883,15 +1882,6 @@ __metadata:
languageName: node
linkType: hard

"btoa@npm:^1.2.1":
version: 1.2.1
resolution: "btoa@npm:1.2.1"
bin:
btoa: bin/btoa.js
checksum: afbf004fb1b1d530e053ffa66ef5bd3878b101c59d808ac947fcff96810b4452abba2b54be687adadea2ba9efc7af48b04228742789bf824ef93f103767e690c
languageName: node
linkType: hard

"buffer-from@npm:^1.0.0":
version: 1.1.2
resolution: "buffer-from@npm:1.1.2"
Expand Down

0 comments on commit ce20d95

Please sign in to comment.