Skip to content

Commit eb72279

Browse files
committed
[DDW-1203] Define a proxy for currency conversions
1 parent 139ac3c commit eb72279

File tree

3 files changed

+148
-1
lines changed

3 files changed

+148
-1
lines changed

flake.nix

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,7 @@
2727
default = package.mainnet;
2828
makeSignedInstaller = __mapAttrs (_: a: a.makeSignedInstaller) internal;
2929
buildkitePipeline = import ./nix/buildkite-pipeline.nix { inherit inputs targetSystem; };
30+
ociImages = import ./nix/oci-images.nix { inherit inputs targetSystem; };
3031
}) {
3132
x86_64-linux = ./nix/x86_64-linux.nix;
3233
x86_64-windows = ./nix/x86_64-windows.nix;

nix/oci-images.nix

Lines changed: 140 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,140 @@
1+
{ inputs, targetSystem }:
2+
3+
let pkgs = inputs.nixpkgs.legacyPackages.${targetSystem}; in
4+
5+
if targetSystem == "x86_64-linux" then {
6+
7+
coinGeckoProxy = let
8+
nginx = pkgs.nginxMainline;
9+
nginxCmd = { listenPort }: [ "${nginx}/bin/nginx" "-c" (nginxConf { inherit listenPort; }) ];
10+
nginxConf = { listenPort }: let
11+
cacheZone = "one";
12+
nginxConf = ''
13+
daemon off;
14+
user root root;
15+
error_log stderr notice;
16+
events {
17+
worker_connections 1024;
18+
}
19+
http {
20+
access_log /dev/stdout;
21+
include ${nginx}/conf/mime.types;
22+
default_type application/octet-stream;
23+
sendfile on;
24+
keepalive_timeout 65;
25+
proxy_cache_path /var/cache/nginx/${cacheZone} keys_zone=${cacheZone}:16m inactive=10m max_size=256m;
26+
resolver 8.8.8.8 8.8.4.4;
27+
server {
28+
listen ${toString listenPort};
29+
server_name localhost;
30+
location / {
31+
return 404;
32+
}
33+
error_page 500 502 503 504 /50x.html;
34+
location = /50x.html {
35+
root ${nginx}/html;
36+
}
37+
location = /api/v3/coins/list {
38+
${proxyConf}
39+
proxy_cache_valid 200 10m;
40+
proxy_cache_valid any 1m;
41+
set $coingecko https://api.coingecko.com;
42+
proxy_pass $coingecko;
43+
}
44+
location = /api/v3/simple/supported_vs_currencies {
45+
${proxyConf}
46+
proxy_cache_valid 200 10m;
47+
proxy_cache_valid any 1m;
48+
set $coingecko https://api.coingecko.com;
49+
proxy_pass $coingecko;
50+
}
51+
location = /api/v3/coins/markets {
52+
if ( $args !~ ^ids=cardano&vs_currency=[a-z0-9]+$ ) { return 400; }
53+
${proxyConf}
54+
proxy_cache_valid 200 400 10m;
55+
proxy_cache_valid any 1m;
56+
set $coingecko https://api.coingecko.com;
57+
proxy_pass $coingecko;
58+
}
59+
}
60+
}
61+
'';
62+
proxyConf = ''
63+
proxy_cache ${cacheZone};
64+
proxy_cache_lock on;
65+
proxy_cache_lock_age 10s;
66+
proxy_cache_lock_timeout 10s;
67+
proxy_connect_timeout 60s;
68+
# Don’t let our clients control caching behavior:
69+
proxy_cache_revalidate off;
70+
proxy_cache_use_stale error timeout invalid_header updating
71+
http_500 http_502 http_503 http_504
72+
http_403 http_404 http_429;
73+
proxy_cache_background_update on;
74+
# Hide some original headers:
75+
proxy_hide_header x-request-id;
76+
proxy_hide_header x-runtime;
77+
proxy_hide_header cf-ray;
78+
proxy_hide_header set-cookie;
79+
proxy_hide_header age;
80+
proxy_hide_header expires;
81+
proxy_hide_header etag;
82+
proxy_hide_header alternate-protocol;
83+
proxy_hide_header cf-cache-status;
84+
# Don’t close upstream connections if our client closes before getting a response:
85+
proxy_ignore_client_abort on;
86+
# Ignore all upstream fields that could interfere with our caching policies:
87+
proxy_ignore_headers X-Accel-Redirect X-Accel-Expires X-Accel-Limit-Rate
88+
X-Accel-Buffering X-Accel-Charset
89+
Expires Cache-Control Set-Cookie Vary;
90+
# Hide errors ≥300:
91+
proxy_intercept_errors on;
92+
proxy_pass_request_body off;
93+
proxy_set_header Content-Length "";
94+
proxy_pass_request_headers off;
95+
proxy_ssl_verify on;
96+
proxy_ssl_trusted_certificate /etc/ssl/certs/ca-bundle.crt;
97+
proxy_ssl_server_name on;
98+
add_header X-Cache-Status $upstream_cache_status;
99+
proxy_set_header User-Agent "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/112.0.0.0 Safari/537.36";
100+
'';
101+
in pkgs.writeText "nginx-${toString listenPort}.conf" nginxConf;
102+
entrypoint = pkgs.writeShellScript "entrypoint" ''
103+
set -euo pipefail
104+
export PATH="${with pkgs; lib.makeBinPath [ coreutils ]}:$PATH"
105+
106+
# Let’s pre-populate the cache with the most popular requests:
107+
108+
${pkgs.lib.escapeShellArgs (nginxCmd { listenPort = 81; })} &
109+
initial_pid=$!
110+
111+
for endpoint in \
112+
'/api/v3/coins/list' \
113+
'/api/v3/simple/supported_vs_currencies' \
114+
'/api/v3/coins/markets?ids=cardano&vs_currency=usd' \
115+
'/api/v3/coins/markets?ids=cardano&vs_currency=jpy' \
116+
; do
117+
sleep 2
118+
echo "Will pre-populate cache with: ‘$endpoint’…"
119+
sleep 3
120+
${pkgs.curl}/bin/curl >/dev/null -sS "http://127.0.0.1:81$endpoint" && echo ' ok' || echo ' failed'
121+
done
122+
123+
kill -s TERM $initial_pid
124+
exec ${pkgs.lib.escapeShellArgs (nginxCmd { listenPort = 80; })}
125+
'';
126+
in pkgs.dockerTools.buildImage rec {
127+
name = "daedalus-coingecko-proxy";
128+
tag = inputs.self.rev or "dirty";
129+
copyToRoot = with pkgs.dockerTools; [ caCertificates fakeNss ]; # XXX: needed for nginx
130+
runAsRoot = ''
131+
#!/bin/sh
132+
set -euo pipefail
133+
mkdir -p /var/log/nginx /var/cache/nginx
134+
exec ${pkgs.lib.escapeShellArgs (nginxCmd { listenPort = 80; })} -t
135+
'';
136+
config.Expose = "80/tcp";
137+
config.Entrypoint = [entrypoint];
138+
};
139+
140+
} else {}

source/renderer/app/config/currencyConfig.coingecko.ts

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -26,24 +26,30 @@ type CurrencyRateGeckoResponse = Array<{
2626
const id = 'coingecko';
2727
const name = 'CoinGecko';
2828
const website = 'https://www.coingecko.com/en/api';
29-
const hostname = 'api.coingecko.com';
29+
const hostname = '127.0.0.1';
3030
const version = 'v3';
3131
const pathBase = `api/${version}`;
3232
const requests = {
3333
list: [
3434
{
3535
hostname,
36+
port: 8095,
37+
protocol: 'http',
3638
method: 'GET',
3739
path: `/${pathBase}/coins/list`,
3840
},
3941
{
4042
hostname,
43+
port: 8095,
44+
protocol: 'http',
4145
method: 'GET',
4246
path: `/${pathBase}/simple/supported_vs_currencies`,
4347
},
4448
],
4549
rate: ({ code }: LocalizedCurrency) => ({
4650
hostname,
51+
port: 8095,
52+
protocol: 'http',
4753
method: 'GET',
4854
path: `/${pathBase}/coins/markets?ids=cardano&vs_currency=${code}`,
4955
}),

0 commit comments

Comments
 (0)