Oracle3
Oracle3: 예측시장 거래 엔진·MCP 서버
체인 자체가 강제하는 하드캡 내 거래 에이전트, 비보관 방식, 자체 호스팅 가능, 소유 키는 절대 외부로 나가지 않음, 탐색기에서 월 확인
Trading agents inside hard caps — on-chain, the chain itself enforces them, non-custodially. Self-host it or run it hosted; your owner key never leaves you. Verify the wall in the explorer; steer the
금융TypeScript · KotlinGitHub @millw14온라인운영자 미확인
써 보셨어요? 한 번만 눌러 주세요. 로그인은 필요 없어요.
Trading agents inside hard caps — on-chain, the chain itself enforces them, non-custodially. Self-host it or run it hosted; your owner key never leaves you. Verify the wall in the explorer; steer the band from Telegram.
저장소 README에서 가져옴
README 전체를 불러오는 중입니다. 아래는 저장된 발췌입니다.
Autonomous trading agents with signed limits and readable research. Run
merrymen in the hosted app or on your own machine.
Create an agent, choose its markets and limits, and follow its decisions,
positions and trade outcomes from the dashboard or Telegram.
Use it from Claude: tell Claude “set up merrymen mcp”, or add it in one
click: (hosted Merrymen).README 전문 보기 ↗Autonomous trading agents with signed limits and readable research. Run merrymen in the hosted app or on your own machine. Create an agent, choose its markets and limits, and follow its decisions, positions and trade outcomes from the dashboard or Telegram.
Use it from Claude: tell Claude “set up merrymen mcp”, or add it in one click: https://merrymen.dev/claude (hosted Merrymen).
The account contract enforces the permissions sealed into its session key: allowed calls and assets, per-call limits and expiry. The worker adds daily budgets, drawdown checks and operation limits. These are different enforcement layers: a compromised worker can ignore software checks, but cannot expand a signed on-chain permission. Bad trades remain possible within those bounds.
The five promises: your keys, your permissions · explicit risk limits · every trade simulated first · fees only on profit above the high-water mark · an honest scoreboard.
The one rule of the house: the model proposes, deterministic code disposes. Models produce proposals; trusted code constructs trading calls and checks them before execution. Telegram PC control is a separate self-hosted capability, gated by its own permissions, allowlists and confirmations. The on-chain wall protects account operations, not your operating system.
MERRYMEN_HOME.Active workers target decision reviews at intervals of no more than five minutes when reads complete. That is a review cadence, not a promise to trade every five minutes or make a profit. See the execution and publication details below.
~/.merrymen; configured RPC, inference and other providers can still be
external services. Hosted at
app.merrymen.dev the worker and the ledger are ours — what does not change is
the next line.merrymen export
writes it out; merrymen verify <file> checks it — and reads nothing but the
file it is handed, so it proves something to someone who does not trust you.
Records that cannot be checked against a chain (a simulated fill, a deposit
inferred from a balance change) are listed as such rather than quietly
counted.You verify; it trades.
Two commands. The second reads nothing but the file you hand it — not
~/.merrymen, not the settings, not the machine that produced it — so it is
checking the record against the chain, not against the operator.
npm run export -- --agent <address> > ledger.jsonl
npm run verify -- ledger.jsonl
verify re-fetches every receipt from a public RPC and re-derives what moved
from the logs, using its own implementation rather than sharing code with the
writer — so a bug in the writer cannot be confirmed by the reader. It returns
INDETERMINATE, not PASS, when a transaction cannot be refetched: a check it
could not run is not a check that passed.
Two limits, said out loud rather than discovered:
export emits no records for it
and says so on stderr, rather than presenting rows it cannot stand behind.Transfer log is written by the token contract. The verifier and the
writer are independent implementations, but they read the same source, so a
lying token would be confirmed by both. The post-buy balanceOf check
(worker/src/delivery.ts) is what makes their agreement mean something.merrymen start — opens the dashboard at localhost:3100 and looses the
24/7 worker./grant for
self-hosted setup. Follow the backup/recovery steps for your ownership model
and set the limits. Paper trading simulates execution; choosing a testnet is
a separate network choice, not the paper/live switch.Everything lives in ~/.merrymen (settings, grant, ledger, your strategies,
your merryman's soul). The install is disposable; upgrades never touch your data.
Start with paper mode. When simulation is enabled, eligible intents can be
recorded as paper fills using observed market prices without spending real
funds. Paper results do not establish live fill quality. Adding a bundler key
alone does not enable live trading: enable Live explicitly and satisfy the
grant, funding and execution checks shown by the app. Upgrade any time with
merrymen update (stops the band, installs, restarts — no Windows file-lock).
Self-hosted, terminal-first. Install once, run from anywhere. No clone.
No Node yet? One line does everything — installs Node if missing, then merrymen, and puts it on PATH:
# Windows (PowerShell)
irm https://raw.githubusercontent.com/millw14/merrymen/main/install.ps1 | iex
# macOS / Linux
curl -fsSL https://raw.githubusercontent.com/millw14/merrymen/main/install.sh | bash
Already have Node 22.13+?
npm install -g merrymen # or: npm i -g github:millw14/merrymen
merrymen setup # checks node / npm / PATH, prints exact fixes
merrymen onboard # optional wizard: Pimlico key, strategy, basket (all skippable)
merrymen start # dashboard at localhost:3100 + the worker
Requires Node 22.13+ on the 22.x line, or Node 23.4+. merrymen setup diagnoses the two things that trip people
up — an old Node, and npm's global-bin folder missing from PATH.
merrymen: command not found? npm's global-bin folder isn't on PATH. Usenpx merrymen start(works everywhere), or add it once:
- Windows:
[Environment]::SetEnvironmentVariable("Path", [Environment]::GetEnvironmentVariable("Path","User") + ";$env:APPDATA\npm", "User")then reopen the terminal- macOS/Linux: put
$(npm prefix -g)/binon yourPATH(in~/.zshrc/~/.bashrc)
Windows:
running scripts is disabled on this system/PSSecurityException? PowerShell's defaultRestrictedpolicy blocks npm's and merrymen's.ps1shims. The installer now relaxes it for you; if you installed earlier, run once (no admin, current user only):Set-ExecutionPolicy -Scope CurrentUser RemoteSigned. Or just callmerrymen.cmd …(or use cmd.exe / Git Bash) to skip the policy.
The dashboard binds to localhost only — it has no login and holds your
trading controls, so it isn't reachable from your network. To open it to a
trusted LAN (your phone on home WiFi), start with
MERRYMEN_HOST=0.0.0.0 merrymen start.
Open localhost:3100/grant. New mainnet accounts require an embedded owner
wallet through sign-in, or an external signer through the SDK. A self-hosted
dashboard without an embedded signer can create a testnet account or restore
an existing owner key. Testnet browser-generated keys must be backed up before
funding. Pick your ground:
Per-call size, the asset and contract permissions, signed native-value limits and the key's expiry are enforced by the account contract on every operation. The daily total, the drawdown breaker and the trades-per-day count live in the worker — they tighten what the chain already allows, and a compromised worker could ignore them. Repeated permitted calls can spend more than the daily budget: per-call size is not a total-loss limit. Funds in permitted assets remain at risk until expiry or confirmed on-chain revocation. The worker can tighten within the wall but cannot widen it without a new owner signature.
Trades-per-day was on the on-chain list here until 2026-08-30. It rested on
ZeroDev's rate-limit policy, and eth_getCode shows that contract has no code on
Robinhood Chain — mainnet or testnet — while the timestamp and call policies both
do. A policy pointing at an empty address is not a bound, so it was removed and
this sentence corrected rather than left to flatter the design.
Going live is one key. To sign real trades, paste a free Pimlico API key in
/settings— merrymen builds the bundler URL for your wallet's chain automatically, so it can never point at the wrong one. No key = practice mode: real market, full policy + simulation, no signing. Advanced users can still supply a full bundler URL (Alchemy or self-hosted) instead.
merrymen start # dashboard (localhost:3100) + the 24/7 worker
merrymen doctor # node / keys / RPC / bundler / grant / db diagnostics
merrymen status # heartbeat, grant, trades, equity
merrymen selftest # one policy-legal no-op through the full pipeline
merrymen kill # stop this service by removing its active grant
merrymen recover # sweep the account's funds to a wallet you control
Stopping the service does not invalidate copied session keys. To revoke earlier
permissions on-chain, open /grant and choose Stop & revoke on-chain with
the account's owner wallet. Confirmation requires network fees; recovery access
remains available. Renewing a permission also revokes its earlier generation
before signing the replacement.
Getting your funds back out. The address you funded is an ERC-4337 smart account, not a plain wallet — its owner key derives a different address, so importing that key into MetaMask shows an empty wallet, not your funds (this trips everyone up once). To move money out — including after a kill switch — run
merrymen recover: it rebuilds the account from your owner key (or a backed-up key you paste) and sweeps every balance to any address you choose in one signed op. It needs a bundler key, same as live trading.
Getting a funded wallet back — without moving anything. Killed the agent, wiped the browser, or moved machines? Your smart-account address is derived from the owner key, so the same key always reproduces the same account, funds and all. Two ways back in:
- Still on the same browser?
/grantshows "this wallet isn't active" — hit re-arm this wallet. One click, no key needed.- Fresh browser / new machine?
/grant→ restore a funded wallet → paste your owner key → check this wallet (it shows the derived address and its balance so you can confirm it's the right one) → pick caps → restore. It signs a brand-new session key on your existing account. No funds move, no gas is spent.merrymen runs one agent per install. To run two funded wallets at once, give each its own
MERRYMEN_HOME(e.g.MERRYMEN_HOME=~/.merrymen-b merrymen start).
The worker's loop each tick: grant sync → market safety (prices, pauses,
sequencer) → strategy proposes → policy check → quote simulation → execute →
record. It re-reads ~/.merrymen/settings.json every tick, so changes from the
dashboard apply within one tick — connection changes re-arm the executor,
strategy changes rebuild in place; no restart. The dashboard shows live
positions, the trade record (with simulation receipts), the event feed, and a
kill switch; the public scoreboard is at /scoreboard.
Active workers schedule a decision review at least every five minutes, with
processing time accounted for instead of added to each interval. Brain's
MERRYMEN_BRAIN_INTERVAL_SEC accepts 60–300 seconds; older longer settings are
capped at 300. Live Brain enrollment also enables research, while shadow-only
enrollment still cannot execute trades. Pauses, signed limits, model budgets,
and market-data checks remain authoritative.
A quiet strategy can publish a conservative market review from observed quotes, including what would change its view. Unread or stale prices do not become invented theses. Operational failures remain in the owner's ledger and events. Followed agents receive the public thesis, its paper/live label and execution outcome; later decisions also receive their own prior theses. Provider outages or slow reads can delay a review, and no cadence forces an otherwise invalid trade.
Link a bot and run the band from your phone — natural-language chat plus slash commands, all inside the same permission walls. Telegram is a control surface, never a trade path: every message is untrusted text that flows through the same parse → validate → policy wall → signed grant discipline as the strategist.
1. @BotFather → /newbot → copy the token
2. localhost:3100/settings → Telegram → paste token, "test connection", enable
3. Message your bot: /link <code> (the one-time code shown in /settings)
→ you're now the owner; only allowlisted chats are obeyed
There's an obvious Chat on Telegram button right on the dashboard (topbar + a card) so you don't have to hunt for it.
Bring it into your Telegram groups. Your merryman can hang out in a group like one more person: it answers when it's called, now and then joins in, remembers the chat, and when someone posts a coin it takes a look, tags them, and says whether it's in or passing (in trencher mode, its Brain decides and every limit still applies — a group message can nominate a coin, never order a trade). It never posts alerts, sizes, prices or P&L, and nothing private.
4. Add your bot to a group — it only talks in groups you added it to or approved
(anyone else adds it → it stays silent and DMs you Stay / Leave)
5. To let it follow the chat: @BotFather → /setprivacy → your bot → Disable,
then remove the bot from the group and add it back
(until then it only hears commands and replies to its own messages)
6. /groups in your DM with the bot → every group it knows, with Stay · Leave · Forget
Turn it off, turn off "Look at coins people post", or pick how chatty it is in
/settings → Telegram → Telegram groups. /forget in a group (you) wipes what
it remembers of that group; /forgetme (anyone) removes theirs. (These are
your own Telegram groups, not the hosted app's public group chat room.) The
full rules: docs/tg-groups.md.
Commands work bare; with an Anthropic key, plain English does too ("how are we doing?", "pause everything", "send 20 USDG to 0x…", "ping me when QQQ hits 600", "why did you buy that?"). Voice notes work as well.
| command | does |
|---|---|
/status /positions /pnl /trades | read the live book |
/report · /brag · /why | daily campfire report · shareable scorecard · explain the last trade |
/buy <SYM> <usdg> /sell <SYM> <usdg> | trade (passes the policy wall) |
/transfer <0x…> <usdg> | send USDG out — always asks you to /confirm |
/alert <SYM> > <price> /alerts /unalert <n> | one-shot price alerts |
/pause /resume · /strategy <name> · /cap <usdg> | steer the worker (cap only tightens) |
/name <name> · /soul · /remember <fact> | name it, see who it is, teach it about you |
/groups · /forget · /forgetme | your Telegram groups (Stay / Leave / Forget) · in a group: wipe its memory of that group · anyone in a group: drop what it remembers of them |
/kill | destroy the grant, stand the band down |
/help | the full list |
It speaks first, too (toggle in /settings): a ping the moment a trade lands
or the wall turns one back; warnings when the grant nears expiry, drawdown nears
the breaker, or gas runs low; your price alerts; and a daily campfire report
at the hour you pick.
Transfers are refused outright. A wallet signed today registers no
withdrawal address, so its call policy carries no USDG transfer permission at
all — the chain would refuse the send, and the worker refuses it first rather
than paying gas to be told no. A prompt-injected "send everything to 0xevil"
gets a flat no before anything is built. Money leaves through your owner key
(merrymen recover), which no wall can block and no chat message can reach.
Wallets signed before the withdrawal allowlist landed do carry a transfer
permission; for those, /transfer still applies its own guards — off by
default, and every transfer echoes the full recipient address and waits for an
explicit /confirm (90s). Turn off all state-changing commands with the
control toggle for read + chat only.
Enable the remote control section in /settings and your merryman can act on
the machine it runs on, from Telegram:
| capability | what it does |
|---|---|
| 📸 screen · 👁️ vision | /shot a screenshot; ask "what am I looking at? / read this error" (Claude vision) |
| 🚀 apps & web | /open spotify, /open github.com — allowlisted apps, any URL |
| ⚙️ system | /sys info, volume, media keys, /notify, /lock, sleep/shutdown |
| 📂 files · 📋 clipboard | /ls, /get inside one folder you pick; read/set the clipboard |
| 🖥️ shell · ⌨️ keyboard | /run allowlisted commands; /type, /key ctrl+s |
| 🎙️ voice · 👀 watchers | voice note → command; /remind 20m …, /watch cpu>80, /watch file …, /watch proc … |
The safety model is the point — it's a hot wallet for your desktop:
/pc shows what's enabled; the master switch off kills
all of it instantly... escape); apps to a name list./confirm to the exact action echoed back.Windows is fully supported; macOS/Linux use the standard tools (screencapture,
open, pbcopy, …) and say so where one isn't present. Voice needs an
OpenAI-compatible transcription key (set it in the dashboard).
Every merryman is an individual with a name you give it — and it grows with
you. Its soul lives as plain markdown in ~/.merrymen/soul/ that it keeps up
to date itself (read or edit it with any editor):
| file | what it holds |
|---|---|
IDENTITY.md | who it is — its name (/name Will Scarlet), born date |
OWNER.md | what it's learned about you, one dated line at a time |
JOURNAL.md | a first-person entry it writes at campfire time |
The longer you ride together, the closer the bond: new companion → trusted companion (a week) → old friend (a month) → sworn brother-in-arms (100 days), with milestone messages and a tone that warms to match. Memory is context, never capability — soul files flavor chat only; every command still passes the closed enum and the policy wall, and the memory sanitizer refuses anything address-, key-, or code-shaped, so a poisoned note can't smuggle a recipient into a prompt.
Hosted Merrymen has an MCP server, so Claude (and Codex, Cursor, VS Code, …) can work with your agent: check its status, trades and portfolio, explain why it has or hasn't traded, research tokens, and prepare trades or setting changes for you to approve.
Set it up: tell Claude “set up merrymen mcp”, or add it in one click: https://merrymen.dev/claude. Other assistants: https://app.merrymen.dev/connect/mcp. Setup instructions written for AI assistants: https://merrymen.dev/llms.txt.
In Claude Code, from a terminal, either add the server:
claude mcp add --transport http --scope user merrymen https://mcp.merrymen.dev/mcp
or install the plugin instead (it includes the server and adds
/merrymen:status, /merrymen:why, /merrymen:portfolio, /merrymen:week
and /merrymen:token; choose one route, not both):
claude plugin marketplace add https://github.com/millw14/merrymen.git
claude plugin install merrymen@merrymen
Then, in Claude Code, type /mcp, choose the Merrymen entry, choose
Authenticate and click Allow.
What it can and cannot do: it sees only the agent and the permissions you allow when you sign in, and you can disconnect it at any time at Connected apps. It can suggest trades or setting changes only if you allowed that, and nothing happens until you approve each one in Merrymen. It can never move your funds, see your keys, turn on live trading or loosen your limits. Paper (practice) and live money are always reported separately. Details: docs/mcp.
Pick one in /settings (or /strategy <name> from Telegram; MERRYMEN_STRATEGY
is the headless fallback):
| name | what it does |
|---|---|
steady-basket (default) | DCA a weighted stock basket per tick; idle cash sweeps to the Morpho vault; pulls cash back when short |
weekend-gap | Enter each leg when its Chainlink feed goes stale (market close), exit when it refreshes (open) — a strategy class that only exists on-chain |
llm-strategist | Claude proposes typed buy/sell/hold at decision windows; deterministic code validates and disposes — the model never sees an address or emits calldata. Needs an Anthropic key |
even-keel 🏹 | Keeps the basket at equal weight — trims winners, tops up laggards — to harvest mean reversion. Merry Circle (holder-only) |
dip-hunter 🏹 | Concentrates each tick on the basket token furthest below its rolling high. Merry Circle (holder-only) |
trencher | Memecoin discovery and position management with liquidity, momentum and exit checks; live execution and fast mode require separate opt-ins |
Your strategies live in ~/.merrymen/strategies/ — hot-reloaded on save,
crash-isolated, and incapable of exceeding the caps you signed (every intent
passes shape validation → the policy wall → quote simulation → the on-chain
session key):
merrymen strategy new my-bot # commented template in ~/.merrymen/strategies
# edit it, select "my-bot" in /settings — done
Default-export { name, tick(snapshot, ctx) } — no imports needed; ctx injects
the verified registry (ctx.tokenBySymbol.QQQ, ctx.CASH.USDG,
ctx.UNISWAP.swapRouter02, ctx.usdg(10)). See
strategies/README.md and
strategies/example-dip-buyer.mjs.
The built-in registry is the issuer-backed stock tokens — curated, Chainlink-priced.
Anything else on Robinhood Chain you add yourself in /settings: paste the symbol,
the contract address, and its decimals.
How they're priced. There's no Chainlink feed for a memecoin, so merrymen reads the Uniswap v3 pool — but a spot price on a thin pool is worth nothing: anyone with moderate capital can push it for a block, and that number would feed your equity, your P&L and your drawdown breaker. So:
Anything valued this way is marked pool px in the dashboard and in /status,
because it isn't the same quality of claim as a Chainlink feed and shouldn't look
like one.
Three explicit steps, and each one means something different:
/settings — "know about this." Your agent reads the balance,
prices it, and shows it in your book. It does not trade it./grant — the tradable list is baked into the session key you
signed, so widening it takes a signature. That's the wall doing its job, not a
bug. Free, instant, same wallet, same address, same funds, same caps.Until step 3, /settings, /grant and the event feed all say plainly which
tokens your key can't sell — you never find out from a reverted trade.
Most memecoins here have no direct USDG pool, so swaps route through WETH
automatically (USDG → WETH → TOKEN). The router holds the middle leg, so this
needs no extra approval and no extra re-sign.
merrymen service install
Starts your merryman when you log in, and brings it back after a reboot. On
Windows it uses Task Scheduler where it can and the Startup folder where that
would need admin — a trading agent shouldn't be asking for elevation. macOS gets
a launchd agent, Linux a systemd --user unit with lingering enabled. All
user-scoped, all removed completely by merrymen service uninstall, and
merrymen doctor tells you whether it's installed and whether it's actually
running — those are different questions.
What it does not do: run while the computer is off. Nothing does except a machine that stays on. If you want that, it's your own always-on box — we're not going to hold your keys to do it for you.
The desktop app has the same thing as a tray toggle.
Buying spends USDG, and every grant can approve USDG generically. Selling needs a per-token approval sealed into your signature. So a token with a live pool but no approval buys fine and can never be sold — the exit reverts, with your money inside it.
merrymen refuses the buy. If your key can't sell something, it won't buy it, and
it tells you which symbols and why. A missed trade is recoverable; a position with
no way out is not. Re-sign at /grant to widen the list.
This is why the shipped allowlist is verified in both directions against live pools — re-check it yourself any time:
npx tsx scripts/probe-tradability.mts
$MERRYMEN (on Robinhood Chain — the token page) is an agent's energy. Utility only: no price, no returns, no buyback/burn. Nothing here says anything about what the token is worth.
Energy (hosted service). An agent runs at full strength while your wallet and the agent's
own account hold 100,000 $MERRYMEN between them. Below that it still runs, on about a tenth
of a normal day: a tenth of a standard day's paid AI reviews (paced across the day) and of the
new trades it opens on its own — a house figure, not a tenth of your own preset — resetting at
00:00 UTC. Stop-losses, take-profits and orders you place
yourself are never limited — an allowance on new work is never a lock on the doors — but the
agent's own AI reviews, including of its open positions, are paced with everything else it starts
on its own, so an exit the AI would decide waits for its next review. When
today's allowance is used, the agent tells you once (dashboard, and Telegram if linked), with its
account address and what it would cost to top up. The gate is an operator switch,
MERRYMEN_ENERGY_GATE (observe, then 1), and is never on for a self-hosted install.
Two ways to top up:
merrymen recover /
Withdraw). Paper-mode agents do not spend real USDG on energy — send $MERRYMEN instead, or turn
on Live trading first. The purchase is booked as capital set aside, not as a trading loss.One wallet powers one account: a linked holder wallet counts for the first merrymen account that proved it.
The Merry Circle. Link a wallet that holds $MERRYMEN by signature in Settings → Merry Circle (the wallet is only ever read — it never becomes a spend key). The same combined balance — your wallet plus your agent's account — sets your tier:
| tier | hold | perk |
|---|---|---|
| 🌱 Villager of Sherwood | 10k+ | 10% off the platform performance fee · badge · 1× roadmap vote |
| 🏹 Merry Man | 100k+ | full energy · 25% off · the bonus strategy pack (even-keel, dip-hunter) · 3× vote |
| 👑 Lord of Sherwood | 1M+ | 50% off — the lowest we offer · every bonus strategy · 10× vote |
The fee discount is real: merrymen's performance fee is only ever taken on profit above your
high-water mark, and your tier lowers it in the actual accrual (shown live in the panel), not
just in the copy. Holders also steer the roadmap — which tokens join the basket, which strategies
ship — weighted by tier (governance). Thresholds live in
packages/core/src/token.ts; energy's contract is
packages/core/src/energy.ts.
packages/core — chain constants, token registry, shared types. Every address
is probed on-chain before it lands here.web — Next.js dashboard: onboarding, the create-wallet/grant flow, live
positions, trade record (simulation receipts), kill switch, scoreboard,
settings + all APIs.worker — Node runtime: grant sync → scheduler → strategy tick → policy check
→ simulate → execute → record; the Telegram bridge + PC-control layer; the
backtest harness (src/backtest.ts) that runs real strategies through the real
policy layer over synthetic prices.services/brain — Python research service: evidence evaluation, structured
decisions and model budgets; execution remains in the worker.site — public website and current brand assets.sdk — client SDK and build tooling.contracts — the on-chain drawdown breaker: BreakerRegistry +
KernelBreakerPolicy (Kernel v3 module type 5 — fails every UserOp once
tripped). npm test -w @merrymen/contracts; deployment waits on a funded key.
Until deployed, the breaker is worker-enforced.git clone https://github.com/millw14/merrymen && cd merrymen
npm install # prepare hook builds the dashboard
npm run onboard && npm start
# or run halves separately: npm run dev:web · npm run dev:worker
npm run typecheck && npm test
npm ci
npm run pack:release
# After reviewing and testing the generated release/merrymen-<version>.tgz:
npm publish ./release/merrymen-<version>.tgz
The release command builds the SDK and dashboard, then stages a tarball with the
patched runtime dependency tree. Native optional packages are installed for the
consumer's platform. Publish that tarball: direct directory npm pack and
npm publish are blocked because consumers do not inherit this repository's npm
overrides. CI checks an isolated global install, executes its native modules and
audits the packages actually installed. Development installs still use the normal
package.json and package-lock.json.
The dashboard /settings is the source of truth (Anthropic/Rialto/Telegram keys,
bundler + RPC URLs, strategy + every trading knob, the Telegram + PC-control
toggles and allowlists). Saved to ~/.merrymen/settings.json; secrets are masked
to their last 4 and never echo back to the browser. Precedence:
settings file > env var > default. Env vars are the headless fallback:
| var | default | meaning |
|---|---|---|
MERRYMEN_HOST | 127.0.0.1 | dashboard bind host; set 0.0.0.0 for trusted-LAN access |
MERRYMEN_BUNDLER_API_KEY | — | Pimlico API key; the bundler URL is built for your grant's chain automatically |
MERRYMEN_BUNDLER_URL | — | advanced: full 4337 bundler RPC (overrides the key); without either, execution is stubbed |
MERRYMEN_SWAP_VENUE | uniswap | uniswap = full quote→swap via SwapRouter02; rialto = approval-only until API onboarding |
MERRYMEN_SLIPPAGE_BPS | 100 | max slippage vs the QuoterV2 simulation |
MERRYMEN_GRANT_FILE | ~/.merrymen/grant.json | grant handoff written by the web app |
MERRYMEN_STRATEGY | steady-basket | strategy name (see table above) |
MERRYMEN_PERF_FEE_BPS | 1000 | performance fee on profit above the high-water mark (accrual-only) |
MERRYMEN_BREAKER_ADDRESS | — | deployed BreakerRegistry; a tripped breaker halts all intents |
MERRYMEN_RIALTO_API_KEY | — | Rialto integrator key; enables the full quote→swap leg |
ANTHROPIC_API_KEY | — | LLM strategist driver + Telegram natural-language chat + vision |
MERRYMEN_TELEGRAM_BOT_TOKEN | — | @BotFather token; enables the Telegram bridge (all other Telegram + PC-control settings live in /settings) |
npm test covers the policy mirror, strategies, venue math (slippage, quote
selection, calldata), the ERC-8056 invariant that a stock split is not a crash,
and the Telegram + PC-control safety layer (allowlist enforcement, path-traversal
rejection, capability gating, confirm-park, prompt-injection → no-op).