Skip to content

Commit ce8eead

Browse files
authoredNov 27, 2023
feat(rpc): make fetch customizable (#574)
1 parent 68e4f5b commit ce8eead

File tree

7 files changed

+87
-23
lines changed

7 files changed

+87
-23
lines changed
 

‎.changeset/new-foxes-heal.md

+5
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
---
2+
"@ckb-lumos/rpc": minor
3+
---
4+
5+
make `fetch` customizable
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,25 @@
1+
const { RPC } = require("..");
2+
3+
describe("custom fetch", () => {
4+
test("should work", async () => {
5+
const customizedFetch = jest.fn((_, { body }) =>
6+
Promise.resolve({
7+
json: () =>
8+
Promise.resolve({
9+
jsonrpc: "2.0",
10+
result: "0x8dd",
11+
id: JSON.parse(body).id,
12+
}),
13+
})
14+
);
15+
16+
const rpc = new RPC("", { fetch: customizedFetch });
17+
await rpc.getTipBlockNumber();
18+
19+
expect(customizedFetch).toBeCalled();
20+
expect(JSON.parse(customizedFetch.mock.calls[0][1].body)).toHaveProperty(
21+
"method",
22+
"get_tip_block_number"
23+
);
24+
});
25+
});

‎packages/rpc/src/index.ts

+13-10
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,7 @@ import {
99
PayloadInBatchException,
1010
} from "./exceptions";
1111
import { RPCConfig } from "./types/common";
12-
import fetch from "cross-fetch";
12+
import fetch_ from "cross-fetch";
1313
import { AbortController as CrossAbortController } from "abort-controller";
1414

1515
export const ParamsFormatter = paramsFormatter;
@@ -37,10 +37,11 @@ export class CKBRPC extends Base {
3737
return this.#resultFormatter;
3838
}
3939

40-
constructor(url: string, config: RPCConfig = { timeout: 30000 }) {
40+
constructor(url: string, config: Partial<RPCConfig> = {}) {
4141
super();
4242
this.setNode({ url });
43-
this.#config = config;
43+
const { timeout = 30000, fetch = fetch_ } = config;
44+
this.#config = { timeout, fetch };
4445

4546
Object.defineProperties(this, {
4647
addMethod: {
@@ -59,7 +60,7 @@ export class CKBRPC extends Base {
5960
});
6061

6162
Object.keys(this.rpcProperties).forEach((name) => {
62-
this.addMethod({ name, ...this.rpcProperties[name] }, config);
63+
this.addMethod({ name, ...this.rpcProperties[name] }, this.#config);
6364
});
6465
}
6566

@@ -141,12 +142,14 @@ export class CKBRPC extends Base {
141142
ctx.#config.timeout
142143
);
143144

144-
const batchRes = await fetch(ctx.#node.url, {
145-
method: "POST",
146-
headers: { "content-type": "application/json" },
147-
body: JSON.stringify(payload),
148-
signal: signal,
149-
}).then((res) => res.json());
145+
const batchRes = await ctx.#config
146+
.fetch(ctx.#node.url, {
147+
method: "POST",
148+
headers: { "content-type": "application/json" },
149+
body: JSON.stringify(payload),
150+
signal: signal,
151+
})
152+
.then((res) => res.json());
150153

151154
clearTimeout(timeout);
152155

‎packages/rpc/src/method.ts

+13-11
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,8 @@
11
import { IdNotMatchException, ResponseException } from "./exceptions";
22
import { CKBComponents } from "./types/api";
33
import { RPCConfig } from "./types/common";
4-
import fetch from "cross-fetch";
54
import { AbortController as CrossAbortController } from "abort-controller";
5+
import fetch_ from "cross-fetch";
66

77
export class Method {
88
#name: string;
@@ -24,12 +24,13 @@ export class Method {
2424
constructor(
2525
node: CKBComponents.Node,
2626
options: CKBComponents.Method,
27-
config: RPCConfig = { timeout: 30000 }
27+
config: Partial<RPCConfig> = {}
2828
) {
2929
this.#node = node;
3030
this.#options = options;
3131
this.#name = options.name;
32-
this.#config = config;
32+
const { timeout = 30000, fetch = fetch_ } = config;
33+
this.#config = { timeout, fetch };
3334

3435
Object.defineProperty(this.call, "name", {
3536
value: options.name,
@@ -46,14 +47,15 @@ export class Method {
4647

4748
const timeout = setTimeout(() => controller.abort(), this.#config.timeout);
4849

49-
const res = await fetch(this.#node.url, {
50-
method: "POST",
51-
headers: {
52-
"content-type": "application/json",
53-
},
54-
body: JSON.stringify(payload),
55-
signal,
56-
})
50+
const res = await this.#config
51+
.fetch(this.#node.url, {
52+
method: "POST",
53+
headers: {
54+
"content-type": "application/json",
55+
},
56+
body: JSON.stringify(payload),
57+
signal,
58+
})
5759
.then((res) => res.json())
5860
.then((res) => {
5961
if (res.id !== payload.id) {

‎packages/rpc/src/types/api.ts

-2
Original file line numberDiff line numberDiff line change
@@ -50,8 +50,6 @@ export namespace CKBComponents {
5050
export type Since = string;
5151
export interface Node {
5252
url: string;
53-
httpAgent?: any;
54-
httpsAgent?: any;
5553
}
5654
export interface Method {
5755
name: string;

‎packages/rpc/src/types/common.ts

+3
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,6 @@
1+
/// <reference lib="dom" />
2+
13
export type RPCConfig = {
24
timeout: number;
5+
fetch: typeof fetch;
36
};
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,28 @@
1+
# Migrate to Lumos v0.21
2+
3+
### Deprecated the `httpAgent` and `httpsAgent` in `RPC.setNode`
4+
5+
Please use the `fetch` option in `RPC` constructor instead.
6+
7+
```diff
8+
-const rpc = new RPC(url)
9+
+const rpc = new RPC(
10+
+ url,
11+
+ { fetch: (request, init) => originalFetch(request, { ...init, keepalive: true }) },
12+
+)
13+
-rpc.setNode({ url, httpAgent, httpsAgent })
14+
+rpc.setNode({ url })
15+
```
16+
17+
If you are still in working with Node.js(or Electron) runtime, you can migrate to `node-fetch` to continue using the customized agent
18+
19+
```ts
20+
import fetch from "node-fetch"
21+
import { Agent } from "http"
22+
23+
const rpc = new RPC(url, {
24+
fetch: (request, init) => {
25+
return fetch(request, { ...init, httpAgent: new Agent({ keepAlive: true }) })
26+
},
27+
})
28+
```

2 commit comments

Comments
 (2)

github-actions[bot] commented on Nov 27, 2023

@github-actions[bot]
Contributor

🚀 New canary release: 0.0.0-canary-ce8eead-20231127085615

npm install @ckb-lumos/lumos@0.0.0-canary-ce8eead-20231127085615

vercel[bot] commented on Nov 27, 2023

@vercel[bot]
Please sign in to comment.