Imagine you own a small currency exchange booth. You put Bitcoin on one side of the counter and your Rune on the other. Travelers stop by and trade one for the other, and every trade pays you a small fee.
Now imagine that booth lives inside your own house, the cash never leaves your hands, and kray.space is just the street sign pointing travelers to your door. That is a User Pool. Nobody — not even Kray Space — can touch your money. You can close the booth any time by turning it off.
A User Pool is a Bitcoin/Runes liquidity pool where you hold the private keys, on your own computer, in your own wallet. Kray Space lists your pool on the swap page so anyone can trade with it — but Kray Space never sees, holds, or touches your keys. The liquidity is real coins sitting at a real Bitcoin address that only you control — verifiable on-chain by anyone.
The bridge between your wallet and the public swap UI is a small open-source program called
kray-pool-agent (the “Daemon Soberano”). It runs on your laptop or server and
signs swap transactions only when they obey strict rules.
mempool.space and ordinals.com. It then checks the PSBT against AMM math, fee caps, sighash flags, Runestone integrity, and ~20 other rules.
| Known Attack | Defense |
|---|---|
Kray 2b0ea40c (SIGHASH_SINGLE|ANYONECANPAY) | Rejected |
| Atomicals “0-yuan” (zero-value drain) | Rejected |
| Cenotaph rune burn (out-of-range pointer/edict) | Rejected |
| Inflated-reserve spoof (server lies about pool balance) | Rejected |
| Phantom signatures (r=0 / s=0) | Rejected |
| OP_RETURN burn drain (value > 0) | Rejected |
| Mempool griefing (far-future locktime) | Rejected |
25/25 attack vectors verified by the simulation suite at scripts/simulate-user-pool-attacks.js.
macOS / Linux / Windows (via WSL). Takes about 5 minutes total.
Open your terminal (macOS: press ⌘ + Space, type “Terminal”) and paste:
The installer checks that Node.js 20+ is present (offers to install it if not),
downloads the open-source agent from GitHub, and sets up the
kray-pool-agent command. It never asks for keys or funds —
you can read the script before running it.
During setup the agent creates a brand-new wallet that exists only
for your pool. You never deposit into your personal wallet, and you never put
personal funds into the pool wallet. Each one has exactly one job:
The 12 words the setup shows you are full ownership of the pool funds. Write them on paper, keep them offline, never photograph or paste them anywhere. The password only unlocks the encrypted file on your machine — the 12 words recover everything even if the machine burns down.
After setup prints your pool address (bc1p…), send it two things
from any wallet you like: some BTC and some of your Rune. Wait for 1
confirmation. That's the whole deposit — those coins sitting at that address
are the pool. Anyone can verify them on-chain.
The ratio you deposit sets the starting price. Example: deposit
0.01 BTC (丰 1,000,000 sats) + 100,000 RUNE → the pool opens at
丰 10 sats per RUNE. From there the AMM curve moves the price with every swap,
and each swap pays your fee straight into the pool — your liquidity grows on-chain.
Tip: send the Rune in a single clean UTXO (the /tools page has Split/Transfer helpers if you need to organize UTXOs first).
The pool address is a standard Taproot address (BIP86, derivation
m/86'/0'/0'/0/0 — the first address of any modern wallet). To close shop:
Ctrl+C) — pool goes offline, no more swaps.No permission needed, no lock-ups, no withdrawal function that can be frozen. Kray Space cannot stop you from leaving — it never had your keys.
Your pool is online while the daemon is running. Close the laptop, pool goes offline (safely — funds never move) and disappears from /swap until you start it again. Three common setups:
Once kray-pool-agent start is running, your pool appears on the public
/swap page with an online dot. Anyone can swap against it.
Every swap is logged in this dashboard — including any rejected ones (so you'll see
attacks if they happen, with the rule that blocked them).
To pause the pool, just kill the daemon (Ctrl+C) — Kray Space marks it offline
within 30 seconds and stops routing swaps to you. Restart to resume.
Both halves of the system are open-source and minimal:
kray-pool-agent/src/core/verifier.js — the immutable rules the daemon enforceskray-space/src/defi/poolAgentVerifier.js — the same rules re-applied by the serverkray-space/scripts/simulate-user-pool-attacks.js — runnable attack suite (25 cases)