Skip to content
This repository has been archived by the owner on Jan 22, 2025. It is now read-only.

Commit

Permalink
refactor(experimental): Use the native fetch built into Node 18+ (#…
Browse files Browse the repository at this point in the history
…1802)

# Summary

OK, so here's what I'm thinking.

`node-fetch` is in this weird state where:

- they refuse to build CommonJS bundles for the 3.x line
- the 2.x line supports `HttpAgent`
  - note that browsers will never support `HttpAgent`
- the 2.x line does not support HTTP/2

This means that we're taking on a huge dependency and exposing its config through web3.js, but will never end up in the ideal state (HTTP/2 support everywhere).

In this PR, we throw in the towel and make the _default_ transport that ships with web3.js API compatible with the `fetch` in both Node and browsers.

From that point:

- We could write our own HTTP/2 transport that's API compatible with `fetch()` and ship that
- Someone _else_ could write an all-singing, all-dancing transport _specifically_ for Node and open source it

Addresses #1680.
  • Loading branch information
steveluscher authored Oct 29, 2023
1 parent 762ff13 commit d32897d
Show file tree
Hide file tree
Showing 6 changed files with 3 additions and 102 deletions.
4 changes: 0 additions & 4 deletions packages/fetch-impl/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -45,7 +45,6 @@
"@solana/eslint-config-solana": "^1.0.2",
"@swc/jest": "^0.2.29",
"@types/jest": "^29.5.6",
"@types/node-fetch": "^2.6.4",
"@typescript-eslint/eslint-plugin": "^6.7.0",
"@typescript-eslint/parser": "^6.3.0",
"agadoo": "^3.0.0",
Expand All @@ -61,8 +60,5 @@
"tsconfig": "workspace:*",
"tsup": "7.2.0",
"typescript": "^5.1.6"
},
"peerDependencies": {
"node-fetch": "^2.6.7"
}
}
10 changes: 2 additions & 8 deletions packages/fetch-impl/src/index.node.ts
Original file line number Diff line number Diff line change
@@ -1,8 +1,2 @@
// When building the browser bundle, this import gets replaced by `globalThis.fetch`.
import fetchImpl from 'node-fetch';

export default typeof globalThis.fetch === 'function'
? // The Fetch API is supported experimentally in Node 17.5+ and natively in Node 18+.
globalThis.fetch
: // Otherwise use the polyfill.
fetchImpl;
// TODO(https://github.com/solana-labs/solana-web3.js/issues/1787) Write HTTP/2 implementation.
export default globalThis.fetch; // The Fetch API is supported natively in Node 18+.
1 change: 0 additions & 1 deletion packages/rpc-transport/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -90,7 +90,6 @@
"ws-impl": "workspace:*"
},
"peerDependencies": {
"node-fetch": "^2.6.7",
"ws": "^8.14.0"
},
"bundlewatch": {
Expand Down

This file was deleted.

14 changes: 1 addition & 13 deletions packages/rpc-transport/src/transports/http/http-transport.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,3 @@
import type { Agent as NodeHttpAgent } from 'node:http';
import type { Agent as NodeHttpsAgent } from 'node:https';

import fetchImpl from 'fetch-impl';

import { IRpcTransport } from '../transport-types';
Expand All @@ -13,29 +10,20 @@ import {

type Config = Readonly<{
headers?: AllowedHttpRequestHeaders;
httpAgentNodeOnly?: NodeHttpAgent | NodeHttpsAgent | ((parsedUrl: URL) => NodeHttpAgent | NodeHttpsAgent);
url: string;
}>;

export function createHttpTransport({ httpAgentNodeOnly, headers, url }: Config): IRpcTransport {
export function createHttpTransport({ headers, url }: Config): IRpcTransport {
if (__DEV__ && headers) {
assertIsAllowedHttpRequestHeaders(headers);
}
const agent = __NODEJS__ ? httpAgentNodeOnly : undefined;
if (__DEV__ && httpAgentNodeOnly != null) {
console.warn(
'createHttpTransport(): The `httpAgentNodeOnly` config you supplied has been ' +
'ignored; HTTP agents are only usable in Node environments.'
);
}
const customHeaders = headers && normalizeHeaders(headers);
return async function makeHttpRequest<TResponse>({
payload,
signal,
}: Parameters<IRpcTransport>[0]): Promise<TResponse> {
const body = JSON.stringify(payload);
const requestInfo = {
agent,
body,
headers: {
...customHeaders,
Expand Down
38 changes: 0 additions & 38 deletions pnpm-lock.yaml

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

0 comments on commit d32897d

Please sign in to comment.