Skip to content
This repository was archived by the owner on Feb 26, 2024. It is now read-only.

Commit 8801d55

Browse files
committed
add option to change the rpc endpoint to support filecoin
1 parent bb2a96b commit 8801d55

File tree

6 files changed

+110
-65
lines changed

6 files changed

+110
-65
lines changed

src/packages/cli/src/args.ts

Lines changed: 75 additions & 59 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@ import {
66
FilecoinFlavorName
77
} from "@ganache/flavors";
88
import { Definitions } from "@ganache/options";
9+
import { serverDefaults } from "@ganache/core";
910

1011
const COLORS = {
1112
Bold: "\x1b[1m",
@@ -14,6 +15,65 @@ const COLORS = {
1415
FgYellow: "\x1b[33m"
1516
};
1617

18+
function processOption(
19+
category: string,
20+
option: string,
21+
optionObj: Definitions<any>[string | number],
22+
argv: yargs.Argv
23+
) {
24+
if (optionObj.disableInCLI !== true) {
25+
const group = `${category.charAt(0).toUpperCase()}${category.substr(1)}:`;
26+
27+
const useAliases = typeof optionObj.cliAliases !== "undefined";
28+
const alias = useAliases
29+
? optionObj.cliAliases
30+
: (optionObj as any).legacyName;
31+
32+
let description = optionObj.shortDescription;
33+
if (
34+
alias &&
35+
(!Array.isArray(alias) || alias.filter(a => a.length > 1).length > 0)
36+
) {
37+
description = `${description}\n${COLORS.Bold}${
38+
COLORS.FgYellow
39+
}Deprecated aliases: ${
40+
Array.isArray(alias)
41+
? alias.filter(a => a.length > 1).join(", ")
42+
: alias
43+
}${COLORS.Reset}\n`;
44+
}
45+
46+
let defaultValue;
47+
try {
48+
const defaultGetter = (optionObj as any).default;
49+
if (defaultGetter && defaultGetter.length > 0) {
50+
defaultValue = defaultGetter();
51+
}
52+
} catch (e) {}
53+
if (optionObj.cliType === "array" && !Array.isArray(defaultValue)) {
54+
// if we pass `default: undefined`, yargs will return `[ undefined ]`
55+
// this just explicitly fixes array types
56+
57+
if (typeof defaultValue === "undefined") {
58+
defaultValue = [];
59+
} else {
60+
defaultValue = [defaultValue];
61+
}
62+
}
63+
64+
argv = argv.option(`${category}.${option}`, {
65+
group,
66+
description,
67+
alias,
68+
default: defaultValue,
69+
defaultDescription: (optionObj as any).defaultDescription,
70+
type: optionObj.cliChoices ? undefined : optionObj.cliType,
71+
choices: optionObj.cliChoices,
72+
coerce: optionObj.normalize
73+
});
74+
}
75+
}
76+
1777
export default function (version: string, isDocker: boolean) {
1878
let args = yargs.strict();
1979

@@ -43,73 +103,29 @@ export default function (version: string, isDocker: boolean) {
43103
hidden: true
44104
});
45105

46-
const group = `${category.charAt(0).toUpperCase()}${category.substr(
47-
1
48-
)}:`;
49106
const categoryObj = flavorDefaults[category] as Definitions<any>;
50107
const options = Object.keys(categoryObj);
51108
for (const option of options) {
52109
const optionObj = categoryObj[option];
53-
if (optionObj.disableInCLI !== true) {
54-
const useAliases = typeof optionObj.cliAliases !== "undefined";
55-
const alias = useAliases
56-
? optionObj.cliAliases
57-
: (optionObj as any).legacyName;
58-
59-
let description = optionObj.shortDescription;
60-
if (
61-
alias &&
62-
(!Array.isArray(alias) ||
63-
alias.filter(a => a.length > 1).length > 0)
64-
) {
65-
description = `${description}\n${COLORS.Bold}${
66-
COLORS.FgYellow
67-
}Deprecated aliases: ${
68-
Array.isArray(alias)
69-
? alias.filter(a => a.length > 1).join(", ")
70-
: alias
71-
}${COLORS.Reset}\n`;
72-
}
73-
74-
let defaultValue;
75-
try {
76-
const defaultGetter = (optionObj as any).default;
77-
if (defaultGetter && defaultGetter.length > 0) {
78-
defaultValue = defaultGetter();
79-
}
80-
} catch (e) {}
81-
if (
82-
optionObj.cliType === "array" &&
83-
!Array.isArray(defaultValue)
84-
) {
85-
// if we pass `default: undefined`, yargs will return `[ undefined ]`
86-
// this just explicitly fixes array types
87-
88-
if (typeof defaultValue === "undefined") {
89-
defaultValue = [];
90-
} else {
91-
defaultValue = [defaultValue];
92-
}
93-
}
94-
95-
flavorArgs = flavorArgs.option(`${category}.${option}`, {
96-
group,
97-
description,
98-
alias,
99-
default: defaultValue,
100-
defaultDescription: (optionObj as any).defaultDescription,
101-
type: optionObj.cliChoices ? undefined : optionObj.cliType,
102-
choices: optionObj.cliChoices,
103-
coerce: optionObj.normalize
104-
});
105-
}
110+
processOption(category, option, optionObj, flavorArgs);
111+
}
112+
}
113+
114+
flavorArgs = flavorArgs.option("server", { hidden: true });
115+
116+
const categoryObj = serverDefaults.server;
117+
const options = Object.keys(categoryObj);
118+
for (const option of options) {
119+
const optionObj = categoryObj[option];
120+
121+
if (option === "rpcEndpoint" && flavor === FilecoinFlavorName) {
122+
optionObj.default = () => "/rpc/v0";
106123
}
124+
125+
processOption("server", option, optionObj, flavorArgs);
107126
}
108127

109128
flavorArgs = flavorArgs
110-
.option("server", {
111-
hidden: true
112-
})
113129
.option("server.host", {
114130
group: "Server:",
115131
description: `Hostname to listen on.\n${COLORS.Bold}${COLORS.FgYellow}Deprecated aliases: host, hostname${COLORS.Reset}\n`,

src/packages/core/index.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@ import ConnectorLoader from "./src/connector-loader";
22
import { ProviderOptions, ServerOptions } from "./src/options";
33
import Server from "./src/server";
44

5-
export { ProviderOptions, ServerOptions } from "./src/options";
5+
export { ProviderOptions, ServerOptions, serverDefaults } from "./src/options";
66

77
export default {
88
server: (options?: ServerOptions) => new Server(options),

src/packages/core/src/options/server-options.ts

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -32,6 +32,16 @@ export type ServerConfig = {
3232
hasDefault: true;
3333
};
3434

35+
/**
36+
* Defines the endpoint route the HTTP and WebSocket servers will listen on.
37+
*
38+
* @default "/"
39+
*/
40+
readonly rpcEndpoint: {
41+
type: string;
42+
hasDefault: true;
43+
};
44+
3545
/**
3646
* @obsolete Option removed in v3
3747
*/
@@ -61,6 +71,13 @@ export const ServerOptions: Definitions<ServerConfig> = {
6171
"Whether or not websockets should response with binary data (ArrayBuffers) or strings.",
6272
default: () => "auto"
6373
},
74+
rpcEndpoint: {
75+
normalize,
76+
shortDescription:
77+
"Defines the endpoint route the HTTP and WebSocket servers will listen on.",
78+
default: () => "/",
79+
defaultDescription: "'/rpc/v0' for Filecoin, '/' otherwise"
80+
},
6481
keepAliveTimeout: {
6582
normalize: () => {
6683
throw new Error("`keepAliveTimeout` was removed in v3");

src/packages/core/src/server.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -74,7 +74,7 @@ export default class Server {
7474
opts.server
7575
);
7676
}
77-
this.#httpServer = new HttpServer(_app, connector);
77+
this.#httpServer = new HttpServer(_app, connector, opts.server);
7878
}
7979

8080
listen(port: number): Promise<void>;

src/packages/core/src/servers/http-server.ts

Lines changed: 11 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@ import {
77
import ContentTypes from "./utils/content-types";
88
import HttpResponseCodes from "./utils/http-response-codes";
99
import { Connector } from "@ganache/flavors";
10+
import { ServerOptions } from "../options";
1011

1112
type HttpMethods = "GET" | "OPTIONS" | "POST";
1213

@@ -84,13 +85,21 @@ function sendResponse(
8485
});
8586
}
8687

88+
export type HttpServerOptions = Pick<ServerOptions["server"], "rpcEndpoint">;
89+
8790
export default class HttpServer {
8891
#connector: Connector;
89-
constructor(app: TemplatedApp, connector: Connector) {
92+
constructor(
93+
app: TemplatedApp,
94+
connector: Connector,
95+
options: HttpServerOptions
96+
) {
9097
this.#connector = connector;
9198

9299
// JSON-RPC routes...
93-
app.post("/", this.#handlePost).options("/", this.#handleOptions);
100+
app
101+
.post(options.rpcEndpoint || "/", this.#handlePost)
102+
.options(options.rpcEndpoint || "/", this.#handleOptions);
94103

95104
// because Easter Eggs are fun...
96105
app.get("/418", response => {

src/packages/core/src/servers/ws-server.ts

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -20,7 +20,10 @@ export type WebSocketCapableFlavor = {
2020

2121
export type GanacheWebSocket = WebSocket & { closed?: boolean };
2222

23-
export type WebsocketServerOptions = Pick<ServerOptions["server"], "wsBinary">;
23+
export type WebsocketServerOptions = Pick<
24+
ServerOptions["server"],
25+
"wsBinary" | "rpcEndpoint"
26+
>;
2427

2528
export default class WebsocketServer {
2629
#connections = new Map<WebSocket, Set<() => void>>();
@@ -32,7 +35,7 @@ export default class WebsocketServer {
3235
const connections = this.#connections;
3336
const wsBinary = options.wsBinary;
3437
const autoBinary = wsBinary === "auto";
35-
app.ws("/", {
38+
app.ws(options.rpcEndpoint || "/", {
3639
/* WS Options */
3740
compression: uWS.SHARED_COMPRESSOR, // Zero memory overhead compression
3841
maxPayloadLength: 16 * 1024, // 128 Kibibits

0 commit comments

Comments
 (0)