Oracle3
Oracle3: 예측시장 거래 엔진·MCP 서버
tula는 실제 노출과 최초 위험을 알려주는 비보관·읽기 전용 터미널 도구
A terminal tool that answers what no single venue can: what is my real exposure, and what breaks first? Non-custodial, and read-only for the moment — placing trades will come later.
금융TypeScript · ShellGitHub @hsnice16온라인운영자 미확인
써 보셨어요? 한 번만 눌러 주세요. 로그인은 필요 없어요.
Your true exposure, what breaks first, and more, across every venue at once.
저장소 README에서 가져옴
README 전체를 불러오는 중입니다. 아래는 저장된 발췌입니다.
Your true exposure, what breaks first, and more, across every venue at once.
Non-custodial, and read-only for the moment — placing trades will come later;
moving funds will not.
The name is taken from Sanskrit: tula, the balance. The scale that weighs one
side against the other, and the same object Latin calls Libra.
Crypto and fiat: Hyperliquid, Aave, Kraken, Binance and Coinbase sit beside Stripe, because
a business's settled balance is part of the same picture as its positions.README 전문 보기 ↗Your true exposure, what breaks first, and more, across every venue at once.
Non-custodial, and read-only for the moment — placing trades will come later; moving funds will not.
The name is taken from Sanskrit: tula, the balance. The scale that weighs one side against the other, and the same object Latin calls Libra.
Crypto and fiat: Hyperliquid, Aave, Kraken, Binance and Coinbase sit beside Stripe, because a business's settled balance is part of the same picture as its positions.
To check one position without installing anything, use the Hyperliquid liquidation price calculator, the Hyperliquid funding rate calculator or the Aave health factor calculator.
You are long ETH spot on Kraken, short ETH perp on Hyperliquid, and holding ETH as Aave collateral against USDC debt.
What is your actual ETH exposure? What breaks first if ETH drops 20%?
Kraken cannot tell you — it sees Kraken. Hyperliquid sees Hyperliquid. Aave sees a health factor and nothing either side of it. Portfolio trackers show balances, which is not the same as risk. And no venue will ever build this, because aggregating a user's positions across competitors is against its interest.
That gap is the product. Every venue weighs only what it holds. Nothing weighs both sides of a position that spans them.
| What it is | What it does not do | |
|---|---|---|
| Kraken CLI, Binance Agent OS, OKX Agent Trade Kit | Exchange-native agent CLIs, free and well built | Each knows one venue. None will ever manage your Aave health factor |
| DeBank, Zerion, Zapper | On-chain portfolio views | Balances, not risk. No CEX side, no liquidation math, no scenarios |
| Bitsgap, goodcryptoX | No-code bots across CEXs and perp DEXs | Template bots in a web GUI; no unified risk, no lending |
| TradingAgents, AI Hedge Fund | LLM reasoning over markets | Signals and analysis, not your positions |
| Bloomberg ASKB | Conversational AI in the Terminal | Not for crypto, not for you |
What we do differently: one canonical position model spanning CEX spot, perp DEX margin and lending collateral, so a single asset held three ways nets to one number with one liquidation answer. Nobody spans those three domains, and the incumbents are structurally unable to.
tula is non-custodial, and read-only for the moment — placing trades will come
later. No code path can move funds off a venue, and none places an order today;
scripts/guard.sh fails the build if one appears, and scripts/guard-test.sh
proves that check still catches one.
~/.config/tula/credentials.json,
mode 600, plain JSON, refused if it is a link or if anything else can write to
its directory. A key kept beside the ciphertext would protect nothing and a
passphrase would break the unattended commands, so the choice is stated rather
than dressed up.scripts/guard.sh in CI, not by convention.Network egress is the venues you connect, the price source you chose, a public node on each chain read — Ethereum, Arbitrum One, Base, Polygon, Optimism, Avalanche, Gnosis, Scroll and Linea — and a token list for the on-chain venues, GitHub each time the interactive shell opens to see whether there is a newer release — and, only when you ask a question in plain English, Anthropic, which receives the computed figures and never a credential. Drive tula with commands and it never talks to a model at all. SECURITY.md lists each one and what it sees.
TULA_REQUIRE_ATTESTATION=1 makes the unproven case a refusal. There is no
signing key for this project to lose.Report a vulnerability: SECURITY.md. The canonical page to check before trusting a binary is the security model.
curl --proto '=https' --tlsv1.2 -LsSf https://usetu.la/install.sh | sh
brew install hsnice16/tap/tula # or: npm install -g @hsnice16/tula
macOS 13 or later and Linux, on 64-bit Intel and ARM. Alpine and other musl systems are not supported, and there is no native Windows build — install inside WSL. The installer always checks the download against its published checksum, and checks the sigstore-backed attestation proving this repository's release workflow built it wherever the GitHub CLI can — saying so either way. Check one by hand:
gh attestation verify tula-v0.4.2-darwin-arm64.tar.gz --repo hsnice16/tula \
--signer-workflow hsnice16/tula/.github/workflows/release.yml \
--source-ref refs/tags/v0.4.2 --deny-self-hosted-runners
Pin a version with TULA_VERSION, require provenance with
TULA_REQUIRE_ATTESTATION=1. Versions install side by side under
~/.tula/versions behind a symlink, so going back to one is a link flip.
Wallet, Hyperliquid and Aave read from a public address, so you can point tula at any address — yours or a public one — and see live positions without handing it a single credential:
tula # / -> wallet -> connect -> paste any 0x address
On first run it offers to set up plain-English questions, and takes "no" for an
answer — every command works without a model. Type / for the command menu.
Building from source: CONTRIBUTING.md.
Point it at a public address first — Wallet, Hyperliquid and Aave need no credential, so you can see the whole cross-venue path work before deciding whether to trust it with a key. When you do connect an exchange, make the key query-only; tula verifies that against the venue and refuses anything that can withdraw.
Two things worth knowing before you report anything: never paste an API key into an issue, and tula's output is a picture of your net worth — replace the numbers or describe the shape. The issue templates say the same at the point you need it. "I would not use this because…" is the most useful thing you can send.
| Venue | Reads | Needs |
|---|---|---|
| Wallet (Ethereum, Arbitrum One, Base, Polygon, Optimism, Avalanche, Gnosis, Scroll and Linea) | native and ERC-20 balances off a token list, per chain | one or more public addresses |
| Hyperliquid | every account mode — standard, unified and portfolio margin — with balances as the venue states them; perps on the first-party dex and every builder-deployed dex, with the liquidation price or the account ratio the venue liquidates on; portfolio-margin borrowing; what each balance is held against; staked HYPE, vault equity and sub-accounts | one or more public addresses |
| Aave v3 (Ethereum, Arbitrum One, Base, Polygon, Optimism, Avalanche, Gnosis, Scroll and Linea) | collateral, debt, health factor, per asset, across twelve markets | one or more public addresses |
| Kraken | spot, staked and held balances in every wallet, and open margin positions with the loan behind each | one or more query-only API keys |
| Binance | spot balances with free and locked stated apart, and cross and isolated margin with the liquidation price each carries | one or more read-only API keys |
| Coinbase Advanced | every account the key can list, free and held stated apart, and Coinbase International perpetual positions with liquidation price and leverage | one or more CDP API keys (view-only) |
| Stripe | five of the six balance buckets /v1/balance carries, per currency — instant_available is a slice of available and would state the same money twice | one or more restricted (rk_) keys |
| Net exposure, scenarios, liquidation distance | working |
| More than one account per venue — a hot wallet and a cold one, two exchange keys | working; every figure counts all of them, each row carries the account it came from, and INCOMPLETE names the account that failed rather than only the venue |
| One position in full, at any venue — entry and mark, PnL and ROE, funding, margin, what liquidates it, what it backs | working; /position <asset>, or ↓ on an empty line to pick one. Each venue fills what it states, and a figure it does not state says so rather than reading zero. Figures are as of the last read — live updating is planned |
| How much of a holding you can move, and what is holding the rest | working; FREE, UNAVAILABLE and REASON columns where something is held, and an em dash where the venue reports too little to prove it |
| What tula never asked for | working; /venues names every area a connector declares it does not read, with what each may hide, and every one of them is scheduled work in ROADMAP.md |
| Interactive shell — slash commands and arguments that complete, suggestions from your history and the conversation that Tab takes, ctrl+s to search them, ctrl+r through saved history, Readline keys, questions over several lines (ctrl+j, or shift+Enter where the terminal sends it), opt-in vim editing, ctrl+o for long output, ? for every key, type and queue the next line while one runs with Esc to stop a question, plain English | working; both command lists take the mouse as well as the keyboard |
| Prices — CoinGecko, CoinPaprika, CoinMarketCap, CryptoCompare | working; one active at a time, /<source> use switches |
Staying current — the shell checks each time it opens and says so in a line; /update checks there and then | working; nothing is installed until you type /update install |
| Kraken's account margin level | planned — Kraken liquidates on an account-wide level and no position carries that figure, so those rows rank unknown until it is read |
| Binance futures |
| Keys | Does |
|---|---|
? | Show or hide these keys, on an empty line |
/ | Open the command menu |
ctrl+s | Search all commands; while searching history, go to a newer match |
ctrl+o | Show all of a long output, or shorten it again |
ctrl+l | Clear the screen |
ctrl+c | Clear the line; on an empty line, leave tula |
ctrl+d | Delete the character under the cursor; on an empty line, leave tula |
Esc | Close a list, the command search, a position or these keys; cancel removing a venue |
Enter | While something is running, save what you typed to run next |
Esc, ctrl+c | Stop an answer while it is being written; ctrl+c clears what you typed first |
↑ | On an empty line, bring back the last line waiting to run, to edit it |
↓ | Past the newest line you sent, on an empty line: pick a position to open in full — Enter opens it, Esc steps back |
| Keys | Does |
|---|---|
ctrl+a, Home | Go to the start of the line |
ctrl+e, End | Go to the end of the line |
ctrl+b, ← | Move back one character |
ctrl+f, → | Move forward one character |
alt+b, ctrl+←, alt+← | Move back one word — alt needs Option as Meta on macOS |
alt+f, ctrl+→, alt+→ | Move forward one word — alt needs Option as Meta on macOS |
ctrl+w | Delete back to the previous space |
alt+backspace | Delete the word before the cursor — alt needs Option as Meta on macOS |
alt+d | Delete the word after the cursor — alt needs Option as Meta on macOS |
ctrl+u | Delete to the start of the line |
ctrl+k | Delete to the end of the line; at its end, join the next line |
ctrl+y | Put back what was last deleted |
Delete | Delete the character under the cursor |
ctrl+t | Swap the two characters around the cursor |
ctrl+_ | Undo the last edit |
| Keys | Does |
|---|---|
↑, ctrl+p | Move up a line; on the top line, show the line you sent before |
↓, ctrl+n | Move down a line; on the bottom line, show the next line you sent |
ctrl+r | Search what you sent before — ctrl+r for older, Enter to run, Esc to edit, ctrl+g to cancel |
| Keys | Does |
|---|---|
↑ ↓, ctrl+p ctrl+n | Move through an open list |
Enter | Run the highlighted command; in a list of choices for a command, put the choice on the line |
Tab | Accept the suggestion shown after the cursor; otherwise put the highlighted command on the line |
→, ctrl+f, ctrl+e | At the end of the line, accept the suggestion shown after the cursor |
alt+f | Accept one word of the suggestion — alt needs Option as Meta on macOS |
| Keys | Does |
|---|---|
Enter | Send what you typed |
ctrl+j | Start a new line — works in every terminal |
shift+Enter | Start a new line — needs a terminal that sends it — one with the kitty keyboard protocol, or tmux with extended-keys |
alt+Enter, ctrl+Enter | Start a new line — alt needs Option as Meta on macOS; ctrl+Enter needs a terminal that sends it |
\ then Enter | Start a new line; the backslash is removed |
| Keys | Does |
|---|---|
Esc | Switch to NORMAL mode; if a list is open, the first Esc closes it |
i a, I A, o O | Switch to INSERT mode: before or after the cursor, at the start or end of the line, or on a new line below or above |
h l, j k | Left and right; up and down a line, and to earlier or later lines you sent from the top or bottom line |
w e b, W E B | Move by word; the capitals count everything between spaces as one word |
0 ^ $, gg G | Go to the start, the first character or the end of the line; to the first or last line |
f F t T, ; , | Jump to a character on the line; repeat the jump, or repeat it backwards |
d c y, dd cc yy, D C | Delete, change or copy as far as the next move goes; the whole line; to the end of the line |
x r ~ J, p P | Delete a character, replace it, switch its case, join lines; paste after or before |
iw aw, i" a", i( a(, i[ a[, i{ a{ | After d, c or y: inside or around a word, quotes or brackets |
3dw, ., u | Repeat a command a number of times; repeat the last change; undo |
/, ? | Open the command menu; show these keys |
bun build --compile.
One artifact, no runtime to install, and the same binary ships through every
channel.number for money — a float rounding error in
a liquidation distance is a wrong answer that looks right.0.x while the read-only risk view is finding its shape. 1.0 when it is
complete and trustworthy without an agent — if it is not useful alone, an agent
on top will not save it.
Milestones and the order they are in, in ROADMAP.md; the task
breakdown behind each in tasks/; shipped work in
CHANGELOG.md.
Read CONTRIBUTING.md. Agents: AGENTS.md.
New venue connectors are the most useful contribution, and the one thing that directly attacks the integration treadmill.
MIT — see LICENSE.
ALTERED| not while tula is read-only — Binance's futures permission grants trading, and a key holding it is refused |
| Solana | planned — a different RPC and account model, so a connector of its own rather than a registry entry (breadth/12) |
| Hyperliquid's own EVM chain (HyperEVM) | planned — both legs or neither. A balance there is a HyperCore spot balance and an EVM ERC-20 scaled against each other, so one leg alone is a number that is not the holding (breadth/12) |
| Aave V4 | planned — v4 is Hubs and Spokes rather than Pools, so no call the connector makes reaches it (breadth/08) |
| Execution | later — see ROADMAP.md |