Nymi — my auto-updater, my checker, and a 3-year-old mascot walk into a Telegram bot

Well then. Today an update magically landed in my head that I honestly don’t know where to file - because it quietly merged three (!) of my creations into one.

It started as a simple question: what’s the next step for my auto-updater / (forum link)? It already keeps nym-node current on its own, but it does its work silently - and “silent automation running on my node” makes people (understandably) nervous. So the obvious answer was a Telegram bot: tell the operator when a release is out, and whether their node actually took it.

Simple enough. But the moment I started building it, I realized I was sitting on a goldmine of data I’d already collected for my main passion - node checker / (forum link) - version, stake, saturation, stress, rewards, health, for every node on the network. Why stop at “a release is out” when I could also tell you your mixnode just lost 40% of its stress score, or that a delegator walked off with 5k NYM, or that your gateway went dark?

So the bot grew. And then I hit the question every side project hits: what makes this different from any other notifier?

…and I remembered.

Three years ago, for one of Nym’s contests, I designed this little creature - a mysterious cryptographic guardian, half animal, half machine. It got a few upvotes, even a prize and then sat in a folder for three years. Not anymore. She (or He? who knows) 's the face and the voice of the bot. Meet Nymi@nyminodebot. (Fair warning: they have a personality.)

What Nymi watches for you

Add a node and Nymi keeps an eye on it, pinging you only when something actually matters - transitions, not noise:

  • New releases - the moment a new nym-node (or a prerelease) drops.
  • Your node updated - when your specific node moves to a new version. No more “wait, did it update?”
  • Stake moves - a meaningful delegation in or out, with the amount, the new saturation, and your delegator count.
  • Stress drop (mixnodes) - this one matters: a mixnode quietly failing its stress test bleeds rewards and is easy to miss. Nymi catches the drop, and tells you when it recovers.
  • Offline / not routing - your node stopped doing its job; you find out immediately, and again when it’s back.

Because Nymi has a bit of a mouth, the alerts don’t read like a cron job. A stress warning looks like:

:warning: your-mixnode stress 0.96 → 0.38 - it’s flunking the stress test, rewards on the line. go poke it.

The narration here is me; the sass is theirs.

On demand: /status

/status is the checker distilled to exactly what you care about, one block per node, so you can eyeball your whole fleet in a single message. For each node you get:

  • a :green_circle:/:yellow_circle:/:red_circle: health dot and the node’s name;
  • role (exit-gateway / entry-gateway / mixnode);
  • version - with an “↑ 1.38.0 out” nudge if it’s fallen behind;
  • performance (routing quality) for gateways, or the stress test score for mixnodes - the numbers that actually decide your rewards;
  • saturation - how full your stake is (over 100% is wasted stake, under means room to grow);
  • stake and delegators - total NYM on the node and how many people back it;
  • claimable - rewards sitting there waiting for you to collect.

It looks like this:

:green_circle: NYMLEM STOCKHOLM GATEWAY exit-gateway
version 1.37.0
performance 97%
saturation 76%
stake 195,261 NYM
delegators 8
claimable 110.9 NYM

No graphs, no fluff - just the vitals you’d otherwise go dig out of a dashboard.

On demand: /update - the impatient button

The updater already checks for a new release every hour. But sometimes you don’t want to wait - a release just dropped and you want your node on it now. That’s what /update is for.

Here’s the catch that makes it interesting: the bot cannot reach into your node. Your node sits behind its own firewall; nothing on the internet - my hub included - can open a connection to it and order it around. That’s a feature, not a bug; it’s exactly the property you want. So how does a button in Telegram make your node act?

The node checks in. The updater on your node quietly asks the hub, every ~45 seconds, “did my operator ask me to update?” - a tiny authenticated request. Almost always the answer is “no” and it goes back to sleep. But when you press /update, the hub flags a request for that node, and on its next check-in the node picks it up, runs the exact same update it would run on its hourly timer, and reports the result back. Nothing is ever pushed to your node; your node stays in control the whole time.

From your side it looks like this:

  1. You send /update and pick which node.
  2. Nymi asks you to confirm (so you can’t fat-finger it).
  3. Nymi runs over - and because there’s a real few-second wait while the node checks in and updates, fills it with a live animation: the message edits itself through “on my way… almost there… checking the release feed… updating…”, typing indicator and all.
  4. When the node reports back, it resolves to the outcome - either it updated, or it grumbles that there was nothing to do:

update_success

update_noupdate

Every one of those steps is authenticated with a per-node secret (below), so only your node can pick up your request and report your result. Nobody can trigger or fake an update on a node they don’t own.

How the whole thing fits together

Three layers, each doing what it’s good at:

  • The checker already tracks every node’s version, stake, stress and health from public data. That’s where most alerts come from - which means Nymi works even if you never install my updater. You’d just miss the alerts only visible from inside the box (a rollback, a crash), and you couldn’t use /update.
  • The auto-updater on your node is Nymi’s eyes on the machine: it keeps nym-node current (checksum-verified, health-gated, automatic rollback if a release doesn’t come up healthy), confirms real updates, and makes /update possible.
  • A small hub stitches it together and is the only thing that ever talks to Telegram.

Security - it runs on your node, so you should ask

I’d want to know exactly this before running someone’s script as root, so:

  • Your node never holds the bot token. It authenticates to the hub with a secret it generates itself (stored 0600, root-only). Only your node can drive your node’s /update or report its results - a stranger who knows your node’s public IP cannot.
  • The updater does not eval anything it fetches from the network. An earlier feature that ran commands from the operator changelog was removed outright; the only automated firewall/tunnel work goes through a separate, snapshot-protected path that rolls back on failure.
  • Binaries are sha256-verified against the release’s published hashes before anything is swapped, with health-gated auto-rollback - if the node doesn’t come back healthy, it reverts to the previous binary immediately.
  • The hub is sandboxed (dropped Linux capabilities, read-only filesystem, memory/task caps) and its endpoints are size-capped and rate-limited.
  • All of it went through an adversarial security review before this post, and the findings were fixed.

How to get it - three doors, pick yours

1. You already run my auto-updater. One line pulls the latest script and links your node; then open the bot and press Start:

curl -fsSL https://raw.githubusercontent.com/vvmmaann/nym-node-autoupdate/main/nym-node-autoupdate.sh -o /usr/local/sbin/nym-node-autoupdate.sh && chmod +x /usr/local/sbin/nym-node-autoupdate.sh && /usr/local/sbin/nym-node-autoupdate.sh link @yourtelegram

2. You don’t have the updater yet. Install it - it detects your setup, sets up the hourly auto-update, and asks for your Telegram @nick at the end to link the node for you:

curl -fsSL https://raw.githubusercontent.com/vvmmaann/nym-node-autoupdate/main/nym-node-autoupdate.sh -o /usr/local/sbin/nym-node-autoupdate.sh && chmod +x /usr/local/sbin/nym-node-autoupdate.sh && sudo /usr/local/sbin/nym-node-autoupdate.sh install

3. You just want the bot, no updater. Perfectly fine - message @nyminodebot, /addnode <your node ip>, and you get stress / stake / offline alerts and full /status. You’ll only miss the update/crash alerts and /update, which need the agent on the box.

Feedback, bug reports and feature requests very welcome - this is v1 and I’ll keep polishing. Nymi, for their part, would like it noted that there are many of you and only one of them.

4 Likes

Nice job, excellent bot :+1:

1 Like

Nymi update — what’s shipped since launch

A handful of things landed since the first post, most of them straight from operator feedback:

One-tap add from the checker. Every node card on the Nym node checker now has a Watch with Nymi button. Tap it and the node is on your watch-list — no copy-pasting IPs into the bot.

Force-update the whole fleet at once. /update used to be one node at a time. Now, if you run the auto-updater on more than one node, there’s an All N at once button: Nymi fans out to every box in parallel and reports back when they’ve all landed. Yes, it casts shadow clones.

:high_voltage::high_voltage::high_voltage: KAGE BUNSHIN NO JUTSU! :high_voltage::high_voltage::high_voltage:

update_all

Buttons instead of slash-commands. There’s a persistent button menu now — My nodes, Status, Update, Add node, About, Help — so nothing has to be memorised. The typed commands still work for anyone who prefers them.

Fewer false alarms. The offline detector now requires both the performance and the routing score to drop before it flags a node. A one-hour blip in the upstream validator annotation no longer fires a false “went offline” alert while the node has been routing fine the whole time.

/about now says what Nymi is, and carries a NymVPN perk: buy any plan through the link and your first month is free.

Running the auto-updater? Link a node with nym-node-autoupdate link @you and Nymi picks up updates, rollbacks and crashes too. Bug reports and requests welcome.

1 Like

Are you into ninjitsu? This looks amazing. @unclelem has been delivering consistently over years and his knowledge of Nym network - both technical and social - shows in the tools he has been building.

I would like to encourage everyone who is using Telegram bots and runs a nym node to double check the code (can be a free LLM audit) and then test it and provide feedback.

2 Likes

Ha - guilty. Lifelong Naruto fan, so when /update had to hit a few nodes at once, there was only ever one jutsu for the job. Kage Bunshin or nothing. :paw_prints:

Thank you, Serinko - genuinely, that means a lot coming from you.

And I want to amplify your ask: please audit and test before trusting it. That’s exactly the right reflex for anything that touches a node. It’s easy to check here - the code that actually runs on your box is the open-source auto-updater, and the bot never holds a token on your node or pushes anything to it: your node authenticates with its own per-node secret and pulls work itself, so the trust surface is small and readable. A free LLM audit plus a run on a spare node is exactly how I’d kick the tyres too - and I do want the feedback, “this felt off” very much included.

1 Like

good to see nymi back!! :cat:

2 Likes

Update #2

The next step for Nymi is as hyped as it is obvious: the ambitious goal of making her something more, and giving her a character. So here’s what I did.

She used to just reply from keyword-matched canned lines - a typical FAQ bot. Now she’s got a real brain under the hood. She understands the question by meaning, digs into the Nym docs, finds the right spot, and answers in her own words - but strictly from the facts. All on my own hardware and free: not a single paid API, nothing leaves the box.

Technically it’s honest RAG (retrieval-augmented generation - instead of answering from memory, the model first pulls the relevant passages and answers only from those), built entirely from free pieces. The knowledge base is 538 fragments of the official Nym docs, split by section, plus a glossary I wrote by hand where the operator docs go quiet or get confused (node hardware vs validator hardware, saturation, ARM, and so on).

Search runs down two roads at once, because one always misses somewhere. The first is semantic: the question and every document go through the bge-small embedder, then cosine similarity - it finds by meaning even when the words differ. The second is plain lexical BM25, which catches exact terms and port numbers where semantics drift. I fuse the two with RRF (reciprocal rank fusion) - it doesn’t need the two scales reconciled, it just adds by rank. On top I put a cross-encoder reranker (ms-marco MiniLM): it takes the top candidates and re-scores each as a real question-document pair, which is more accurate than plain vector closeness. And here’s the key honesty bit: if the best chunk doesn’t clear the reranker threshold, she doesn’t reach for an answer - she says “not in the docs.” Better an honest “I don’t know” than confident nonsense from a half-relevant paragraph.

Then the retrieved chunks go into a local Qwen3-1.7B (quantized, via llama.cpp) with a tightly constrained prompt: answer only from these excerpts, don’t invent commands, numbers or versions, don’t confirm anything the text doesn’t say. The model is small, so all the anti-hallucination protection sits in the retrieval and the prompt, not in “trust the model.”

But the interesting part started when I took her beyond the docs, to live data. Now she answers not just “what’s a gateway,” but real operator questions about your nodes and the network, pulling everything straight from the checker:

  • how much is staked on my Stockholm node
  • which of my nodes has the highest APR
  • how much do I have staked in total
  • how are my nodes doing (a summary across the whole fleet)
  • what’s NYM trading at right now
  • how many nodes does operator X have, give me the links

And these aren’t answers hardwired to specific phrasings - it’s not “I bolted on a couple more ifs.” When the question is about nodes or an operator, I don’t search for an answer, I assemble a snapshot. I pull everything needed from the checker (per-node economics: stake, saturation, pledge, reward per epoch, claimable; the NYM price; versions), compute the derived stuff and aggregates myself (APR as the annualized reward over stake, fleet totals), and lay it out in a compact labeled block, one line per node, numbers already crunched.

Then the same model, except instead of doc excerpts I feed it that snapshot: answer from this live data, the numbers are ready, don’t recompute or invent anything. So the model here doesn’t do arithmetic (I won’t trust a 1.7B with that) - it selects and phrases. “Which has the highest APR” - it runs down the lines and names it. “How are they doing” - it gives a summary. Any phrasing lands on the same snapshot, so a new question needs no new code.

The division of labor is honest: the code computes the exact numbers and aggregates, the model does the phrasing and the reasoning, and the exact strings where the model can’t be let loose (node links, so it doesn’t mangle a URL) I hand back deterministically, no LLM at all. Plus the small stuff under the hood: the snapshot is cached so I don’t hammer the checker on every question; for other operators I take a light listing without the heavy economics; version and price questions skip the model and go straight to the live source.

I also taught her our own tools - the checker and the auto-updater are part of her knowledge now. Ask “how do I install the updater” and she hands you the commands. Everything around the node is her turf.

And the character. She remembers who she’s talking to and which nodes are yours. She calls your nodes yours, not hers. In short, not a sterile reference desk but a creature with her own voice, one that doesn’t confuse “I don’t know” with “let me make something up.”

Now about the hardware. She lives on something pretty modest for now: 8 cores, no GPU, the model squeezed down to 1.7B. It’s a bit cramped in there at the moment, but we’re managing so far. Retrieval and data-gathering it handles easily; the numbers I precompute for her myself, and she presents them cleanly - on a small model that’s the safer way.

Where I want to go next is for her to not just present the figures but reason over them. “Break down what’s off with my nodes.” “Compare two nodes and explain the difference.” That already calls for a bigger brain, something in the 7B-14B class. And it’s exactly the live data that makes such an upgrade worth the most.

We can move her up any time - the only wall is compute we don’t have. A GPU isn’t even required: a bigger model runs fine on CPU if there’s plenty of RAM. Slower per token, but for a chat bot that’s fine, and a box like that is many times cheaper than a GPU one.

So I’m open to advice on building this out sensibly. And if anyone can help with a server (RAM matters more than a GPU here), I’d be hugely grateful. Nymi will put that hardware to work.

@serinko @sudonym @salazar

qa_apr
qa_bitcoin
qa_howare
qa_howareyou
qa_mixnode
qa_weather
image-1786976410677

If someone wants to join to the test chat and help - welcome

Nymi security update

Last post was all about the brain. This one is the security side, since the bot can force-update nodes you run and it answers inside your chats. Both of those had to be locked down before this goes anywhere near a wider audience.

Force-update authorization. Nymi can force-update a node from Telegram, so the real question is who’s allowed to press that button, and every part of that path is now authenticated:

  • The node proves itself to the hub with a per-node secret, generated on the box (0600), sent in an Authorization header and checked constant-time, on both the “was I asked to update?” poll and the result report. So nobody can suppress your updates or spoof an outcome.
  • Ownership is proven on the node itself: you run nym-node-autoupdate pair @yourhandle on the box, and the pairing request has to arrive from that node’s own IP. That is the proof it’s yours, because a stranger who only knows the public IP is on a different machine and can’t send from it. Each node has exactly one authoritative owner, and only that owner can trigger an update. Anyone else just gets told it isn’t their node.
  • Watching and owning are cleanly split: /addnode <ip> is watch-only (alerts, zero ability to touch the node), pairing is ownership (force-update). You can keep an eye on other people’s nodes without any power over them.

The hub is locked down. It’s a shared bot, so the token lives on a hub, not on nodes. That token sits only in a root-only env file, never in the repo, script or logs. The service runs sandboxed (strict filesystem, no Linux capabilities, private tmp, memory and task caps), the database is 0600, and the Q&A engine and the checker are bound to localhost, not exposed. Requests are size-capped and rate-limited, so the bot can’t be used to hammer the box it shares.

Bot safety in chats. Nymi answers only from the docs or from live data, cites the source, and abstains instead of bluffing. Its factual answers no longer take in your chat history, which removes a channel for planting “ignore your rules” style instructions; in testing it held up against direct injection attempts and leading questions. Retrieved text is treated as untrusted, and source links are escaped.

It can’t starve anything. The model shares hardware, so it’s capped: one question at a time with a small queue, hard request-size limits, and CPU headroom reserved outside the model so it can never crowd out a node.

On process. This went through several adversarial security reviews: a multi-agent audit at launch, an external review, and a fresh pre-deploy review of the pairing rework specifically, which caught a couple of real bugs (including an unsafe ownership migration) that were fixed before anything shipped. A few further items, like explicit remember/forget for the memory and moving the hub and checker off root, are deliberately held back for the wider community rollout.


Nymi update

  • Fixed two cases where it gave confident wrong answers: asked for your nodes’ IPs it said nodes have “no public IP”; asked for the $NYM BSC contract it said the address “isn’t publicly known.” Both wrong. It now answers these from data or says it doesn’t know — no guessing.
  • Node IPs and $NYM token contracts (ERC-20, BEP-20, native, IBC) are answered deterministically from the checker/verified sources, not the model. Contract replies flag that BSC has copycat NYM tokens. IP answers are owner-only.
  • Re-scraped the entire blog (511 posts). The old scrape had missed ~two dozen posts and dropped facts that lived inside links (the BSC address was one of them). Links are now kept, stale posts refreshed. Embeddings rebuilt without loading the nodes it runs on.
  • “Latest update” now reads the live announcements feed instead of an old blog post. “How many mixnodes/gateways” comes from the live network.
  • Stopped re-announcing an update it had just run for you.
  • djibouti readiness: status view shows each of your nodes’ Cosmos-account funding (owner-only), alerts you if one drops under 1 NYM, reads the real on-chain balance (not the lagging network flag), and a one-time heads-up went out to all operators.
  • Operator-reported fixes: stale node name now refreshes, alert when a node silently stops accepting the T&C, and identity-key node tracking.
1 Like

Nymi update

  • Reads screenshots now. Send it a NymVPN screenshot — a connection error, say — and it reads the text off the image, works out what’s on screen, and replies in its own words: a real fix if the docs have one, otherwise it points you to Nym support. It won’t invent a fix, and won’t just parrot the error back at you. The reading happens on the bot’s own box, not a third-party service.
  • Minor: fixed a duplicate source link in the “couldn’t confirm that” replies (it was listing the same doc twice).