Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
9 changes: 4 additions & 5 deletions .env.example
Original file line number Diff line number Diff line change
Expand Up @@ -5,12 +5,11 @@
#
# These four are the Polymarket-traded names. Format:
# SYM:Name:coingecko-id[,SYM:Name:id…]
# Optional 4th field: Binance symbol if it is not SYM+USDT.
# A legacy fourth field is accepted and reduced to its base symbol.
#
# install.sh then asks for extra tickers to chart. It looks each one up on
# CoinGecko (id + name) and checks Binance for a USDT pair. No pair is fine:
# the server already serves those from CoinGecko. You can also add tokens later
# in ⚙ search.
# CoinGecko (id + name). Runtime prices and candles come from Kraken with
# Coinbase fallback. You can also add tokens later in ⚙ search.

POLYDISPLAY_ASSETS="BTC:Bitcoin:bitcoin,ETH:Ethereum:ethereum,SOL:Solana:solana,XRP:XRP:ripple"

Expand All @@ -23,5 +22,5 @@ POLYDISPLAY_ASSETS="BTC:Bitcoin:bitcoin,ETH:Ethereum:ethereum,SOL:Solana:solana,
# POLYDISPLAY_PIN=000000
# POLYDISPLAY_TOKEN_SECRET=

# Optional: free CoinGecko demo key for higher rate limits
# Optional: free CoinGecko demo key used only by asset search
# CG_DEMO_KEY=
16 changes: 9 additions & 7 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -11,13 +11,14 @@ a P/L card (the day's profit as polymarket.com reports it, over a 30-day
sparkline, with the 7d, 30d, and all-time figures), then the open positions
and recent activity. Right column is charts for a mix of trading and
monitoring assets. A Go process on the host serves the page and talks to Polymarket,
Binance, and CoinGecko. Browsers only talk to that process.
Kraken, and Coinbase. CoinGecko is used only for asset search. Browsers only talk
to that process.

```
┌────────────┐ http ┌─────────────────────────────┐ https
│ pad / │ ────────────► │ polydisplayd (Go) │ ──► Polymarket
│ browser │ /api/state │ polls + caches │ ──► Binance
│ │ ◄──────────── │ serves the page │ ──► CoinGecko
│ browser │ /api/state │ polls + caches │ ──► Kraken
│ │ ◄──────────── │ serves the page │ ──► Coinbase
└────────────┘ │ /api/config, /api/search │
└─────────────────────────────┘
```
Expand All @@ -36,8 +37,8 @@ Default listen port is 8080 (`POLYDISPLAY_PORT`). Dark/light follows the device.
Downloads Go if needed, asks for a Polymarket public address (`0x...`), writes
`config.json`, builds `polydisplayd`, and installs a login service: LaunchAgent
on macOS, systemd user unit on Linux. At the prompt you can add extra tickers;
those are looked up on CoinGecko. Binance is used at runtime when a USDT pair
exists, otherwise CoinGecko.
those are looked up on CoinGecko. Kraken supplies runtime prices and candles,
with Coinbase as the fallback.

```bash
POLYMARKET_WALLET=0x... POLYDISPLAY_EXTRA_ASSETS=FLR,HBAR ./install.sh
Expand Down Expand Up @@ -118,7 +119,7 @@ search, or run `./install.sh` again and add them at the prompt.

Port: `POLYDISPLAY_PORT` in `.env`, else `config.json` `port`, else 8080.
Wallet and candle range: ⚙ or `config.json`. Pad PIN: `POLYDISPLAY_PIN` in
`.env`. Optional `CG_DEMO_KEY` in `.env` for a higher CoinGecko rate limit.
`.env`. Optional `CG_DEMO_KEY` in `.env` applies only to asset search.

If ⚙ has saved a `coins` list into `config.json`, that list wins until you
delete the `coins` key. `config.json` and `.env` are gitignored.
Expand All @@ -128,7 +129,8 @@ Logs: `polydisplay.log` in the working directory. Rolled at local midnight to

## Data

Candles and prices: Binance when a USDT pair exists, otherwise CoinGecko.
Candles and prices: Kraken, with Coinbase fallback. Kraken ticker prices are
fetched in one request; OHLC requests are paced to its public API guidance.
Positions and activity: Polymarket data-api, polled every 30s. Account P/L:
Polymarket user-pnl-api, 720 hourly points over 30 days, polled every 2 min
and thinned to 120 points for the sparkline. Gamma market metadata supplies
Expand Down
2 changes: 1 addition & 1 deletion com.novatechflow.polydisplay.plist
Original file line number Diff line number Diff line change
Expand Up @@ -39,7 +39,7 @@
<string>/dev/null</string>
<key>EnvironmentVariables</key>
<dict>
<!-- optional: paste a free CoinGecko demo key for higher rate limits -->
<!-- optional: CoinGecko key used only by asset search -->
<key>CG_DEMO_KEY</key>
<string></string>
</dict>
Expand Down
6 changes: 3 additions & 3 deletions index.html
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@

polyDisplay - LAN web app: Polymarket positions + crypto watchlist.
The browser talks ONLY to the local Go server (/api/*): it aggregates
Polymarket + crypto (Binance-first, CoinGecko fallback) so the display
Polymarket + crypto (Kraken-first, Coinbase fallback) so the display
never hits an external API, rate limit, or geoblock.
-->
<style>
Expand Down Expand Up @@ -196,7 +196,7 @@ <h3>Settings</h3>
<button class="btn primary" id="saveBtn">Save &amp; reload</button>
</div>
<button class="btn" id="reloadBtn" style="width:100%;margin-top:10px">Reload app &middot; clear cache</button>
<div class="muted" style="margin-top:10px">Saved on the server (config.json). Data source: Binance &rarr; CoinGecko fallback.</div>
<div class="muted" style="margin-top:10px">Saved on the server (config.json). Data source: Kraken &rarr; Coinbase fallback.</div>
</div>
</div>

Expand Down Expand Up @@ -564,7 +564,7 @@ <h3>Unlock pad</h3>
if(!coins.length){ cl='<div class="empty">No assets. Tap &#9881; to add.</div>'; }
for(var k=0;k<coins.length;k++){
var c=coins[k];
var tag=c.source?('<span class="srctag">'+(c.source==="binance"?"Binance":"CoinGecko")+'</span>'):"";
var tag=c.source?('<span class="srctag">'+(c.source==="kraken"?"Kraken":"Coinbase")+'</span>'):"";
cl+='<div class="coin'+(c.active?' active':'')+'"><div class="top">'+
'<div><span class="sym">'+esc(c.sym)+'</span><span class="name">'+esc(c.name)+'</span></div>'+
'<div><span class="val">'+fmtUsd(c.price)+'</span>'+
Expand Down
30 changes: 7 additions & 23 deletions install.sh
Original file line number Diff line number Diff line change
Expand Up @@ -180,11 +180,11 @@ ensure_auth() {
echo "Clearing site data on the pad means typing the PIN again."
}

# CoinGecko search for id+name; Binance ticker tells us if SYM+USDT exists.
# Prints "SYM:Name:id<TAB>binance|coingecko" or exits non-zero.
# CoinGecko search supplies a stable id and display name. Runtime market data
# comes from Kraken with Coinbase fallback.
resolve_asset() {
py - "$1" <<'PY'
import json, sys, urllib.error, urllib.parse, urllib.request
import json, sys, urllib.parse, urllib.request

q = sys.argv[1].strip()
if not q:
Expand Down Expand Up @@ -217,30 +217,16 @@ name = pick.get("name") or sym
cid = pick.get("id") or ""
if not cid:
sys.exit(4)
src = "coingecko"
try:
urllib.request.urlopen(
urllib.request.Request(
"https://api.binance.com/api/v3/ticker/24hr?symbol=" + urllib.parse.quote(sym + "USDT"),
headers=ua,
),
timeout=10,
)
src = "binance"
except urllib.error.HTTPError:
pass
except Exception:
pass
print("%s:%s:%s\t%s" % (sym, name, cid, src))
print("%s:%s:%s" % (sym, name, cid))
PY
}

ask_assets() {
local extra raw spec src line
local extra raw spec line
extra="${POLYDISPLAY_EXTRA_ASSETS:-}"
if [ -z "$extra" ] && [ -t 0 ]; then
echo "Watchlist starts with BTC, ETH, SOL, XRP (Polymarket)."
echo "Extra names are looked up on CoinGecko; Binance is used when a USDT pair exists."
echo "Extra names are looked up on CoinGecko; charts use Kraken then Coinbase."
read -r -p "Additional assets to chart (tickers or names, comma-separated, empty to skip): " extra
fi
[ -n "$extra" ] || return 0
Expand All @@ -251,9 +237,7 @@ ask_assets() {
line="$(echo "$line" | sed 's/^[[:space:]]*//;s/[[:space:]]*$//')"
[ -n "$line" ] || continue
if spec="$(resolve_asset "$line")"; then
src="${spec##*$'\t'}"
spec="${spec%%$'\t'*}"
echo " $spec ($src)"
echo " $spec"
specs+=("$spec")
else
echo " skip $line (not found on CoinGecko)"
Expand Down
Loading