Skip to content

Commit 1e69763

Browse files
authored
DApps server (#9)
* DApps server * Update link to install script after repo rename
1 parent 4c3db98 commit 1e69763

File tree

5 files changed

+68
-19
lines changed

5 files changed

+68
-19
lines changed

README.md

+1-1
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,7 @@ Anyone with a computer and an internet connection can join the swarm. It’s fin
1818

1919
Open terminal and run the following command:
2020
```sh
21-
curl https://raw.githubusercontent.com/Synthetixio/snx-node/main/install-macos.sh | bash
21+
curl https://synthetixio.github.io/synthetix-node/install-macos.sh | bash
2222
```
2323

2424
### Manual Installation

assets/entitlements.mac.plist

+2
Original file line numberDiff line numberDiff line change
@@ -6,5 +6,7 @@
66
<true/>
77
<key>com.apple.security.cs.allow-jit</key>
88
<true/>
9+
<key>com.apple.security.network.server</key>
10+
<true/>
911
</dict>
1012
</plist>

src/main/dapps.ts

+3-3
Original file line numberDiff line numberDiff line change
@@ -64,7 +64,7 @@ export async function isPinned(qm: string): Promise<boolean> {
6464
}
6565
}
6666

67-
export async function getDappUrl(ens: string): Promise<string | undefined> {
67+
export async function getDappHost(ens: string): Promise<string | undefined> {
6868
try {
6969
const { codec, hash } = await resolveEns(ens);
7070
logger.log(ens, 'resolved', codec, hash);
@@ -87,8 +87,8 @@ export async function getDappUrl(ens: string): Promise<string | undefined> {
8787
await ipfs(`pin add --progress ${qm}`);
8888
}
8989
const bafy = await convertCid(qm);
90-
const url = `http://${bafy}.ipfs.localhost:8080`;
91-
logger.log(ens, 'local URL:', url);
90+
const url = `${bafy}.ipfs.localhost`;
91+
logger.log(ens, 'local IPFS host:', url);
9292
return url;
9393
} catch (e) {
9494
logger.error(e);

src/main/main.ts

+30-15
Original file line numberDiff line numberDiff line change
@@ -30,8 +30,10 @@ import {
3030
followerKill,
3131
followerPid,
3232
} from './follower';
33-
import { getDappUrl } from './dapps';
33+
import { getDappHost } from './dapps';
3434
import * as settings from './settings';
35+
import http from 'http';
36+
import { proxy } from './proxy';
3537

3638
logger.transports.file.level = 'info';
3739

@@ -53,6 +55,10 @@ const dapps: { [key: string]: string | undefined } = {
5355
'kwenta.eth': undefined,
5456
'staking.synthetix.eth': undefined,
5557
};
58+
const localDapps: { [key: string]: string | undefined } = {
59+
'kwenta.eth': 'kwenta',
60+
'staking.synthetix.eth': 'staking',
61+
};
5662

5763
if (process.env.NODE_ENV === 'production') {
5864
const sourceMapSupport = require('source-map-support');
@@ -204,15 +210,11 @@ function generateMenuItems() {
204210
separator: {
205211
type: 'separator',
206212
},
207-
dapps: Object.entries(dapps).map(([name, url]) => {
213+
dapps: Object.entries(localDapps).map(([name, shortcut]) => {
208214
return {
209-
enabled: Boolean(url),
215+
enabled: Boolean(dapps[name]),
210216
label: name,
211-
click: () => {
212-
if (url) {
213-
shell.openExternal(url);
214-
}
215-
},
217+
click: () => shell.openExternal(`http://${shortcut}.localhost:8888`),
216218
};
217219
}),
218220
quit: {
@@ -310,15 +312,12 @@ followerDaemon();
310312
const followerCheck = setInterval(followerDaemon, 10_000);
311313
app.on('will-quit', () => clearInterval(followerCheck));
312314

313-
ipcMain.handle('dapp', async (_event, ens: string) => {
314-
if (!(ens in dapps)) {
315-
dapps[ens] = undefined;
316-
}
317-
return dapps[ens];
318-
});
315+
ipcMain.handle('dapp', async (_event, ens: string) =>
316+
dapps[ens] ? `http://${localDapps[ens]}.localhost:8888` : null
317+
);
319318
async function updateAllDapps() {
320319
Object.keys(dapps).forEach((ens) =>
321-
getDappUrl(ens).then((url) => {
320+
getDappHost(ens).then((url) => {
322321
if (url) {
323322
dapps[ens] = url;
324323
updateContextMenu();
@@ -329,3 +328,19 @@ async function updateAllDapps() {
329328
const dappsUpdater = setInterval(updateAllDapps, 600_000); // 10 minutes
330329
app.on('will-quit', () => clearInterval(dappsUpdater));
331330
waitForIpfs().then(updateAllDapps).catch(logger.error);
331+
332+
http
333+
.createServer((req, res) => {
334+
const shortcut = `${req.headers.host}`.replace('.localhost:8888', '');
335+
const host = Object.keys(localDapps).find(
336+
(key) => localDapps[key] === shortcut
337+
);
338+
if (host && host in dapps && dapps[host]) {
339+
req.headers.host = dapps[host];
340+
proxy({ host: '127.0.0.1', port: 8080 }, req, res);
341+
return;
342+
}
343+
res.writeHead(404);
344+
res.end('Not found');
345+
})
346+
.listen(8888, '0.0.0.0');

src/main/proxy.ts

+32
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,32 @@
1+
import http, { IncomingMessage, ServerResponse } from 'http';
2+
import logger from 'electron-log';
3+
4+
export function proxy(
5+
upstream: {
6+
host: string;
7+
port: number;
8+
},
9+
req: IncomingMessage,
10+
res: ServerResponse
11+
) {
12+
const options = {
13+
hostname: upstream.host,
14+
port: upstream.port,
15+
path: req.url,
16+
method: req.method,
17+
headers: req.headers,
18+
};
19+
20+
const proxyReq = http.request(options, (proxyRes: IncomingMessage) => {
21+
res.writeHead(proxyRes.statusCode!, proxyRes.headers);
22+
proxyRes.pipe(res, { end: true });
23+
});
24+
25+
req.pipe(proxyReq, { end: true });
26+
27+
proxyReq.once('error', (err) => {
28+
logger.error(`Error in proxy request: ${err.message}`);
29+
res.writeHead(500, { 'Content-Type': 'text/plain' });
30+
res.end('Error occurred while processing the request.');
31+
});
32+
}

0 commit comments

Comments
 (0)