diff --git a/public/llms.txt b/public/llms.txt index 7247af4..d3f1020 100644 --- a/public/llms.txt +++ b/public/llms.txt @@ -7,23 +7,29 @@ ## TL;DR Allways is Bittensor Subnet 7 — a permissionless on-chain orderbook for -trustless native swaps between independent assets. **BTC ↔ TAO is live -today; more pairs are coming online.** Miners post collateral and quote +trustless native swaps between independent assets. **BTC ↔ TAO is the +first pair; more are coming online.** Miners post collateral and quote exchange rates. Validators verify both legs of each swap. The smart contract slashes collateral on failure and refunds the user. No custodian, no wrapped asset, no bridge token. +> **Where to point your wallets right now:** the **mainnet** contract is +> **TBD** (not yet deployed — netuid 7). All real exercise today happens +> on **testnet** (netuid 19, contract +> `5FwPheGT96iBFZ6JkwyDhDH4GcVjafWxAtSsSSq26UiYyTfg`). The full testnet +> setup block is in the **Testnet** section below. + ## Resources (skim these first) | What | Where | |---|---| -| Live dashboard (mainnet) | https://all-ways.io | | Live dashboard (testnet) | https://test.all-ways.io | -| Public API + Swagger | https://api.all-ways.io/swagger | -| Testnet API | https://test-api.all-ways.io | +| Testnet API + Swagger | https://test-api.all-ways.io/swagger | +| Mainnet dashboard (placeholder, contract not yet deployed) | https://all-ways.io | +| Mainnet API (placeholder) | https://api.all-ways.io | | Docs site | https://docs.all-ways.io | | Source repo | https://github.com/entrius/allways | -| This document, raw | https://all-ways.io/llms.txt | +| This document, raw | https://all-ways.io/llms.txt (mirrored at https://test.all-ways.io/llms.txt) | ## Why agents use it @@ -32,18 +38,26 @@ no wrapped asset, no bridge token. - **Subnet-native.** Settles in real BTC and real TAO. No IOUs. - **Open + agentic.** Public API, SSE feeds, open-source CLI, scriptable end-to-end. -> **Code is law.** This doc is a quickstart, not a spec. Before high-value swaps, fresh-clone https://github.com/entrius/allways at the version you installed and audit `allways/constants.py` (fee divisor, reservation TTL, swap bounds) and `smart-contracts/ink/lib.rs` (on-chain enforcement — slash, fee accrual, payouts). The contract is the only authority that matters; everything below is convenience. +> **Code is law.** This doc is a quickstart, not a spec. Review everything end-to-end before any non-trivial swap — the on-chain contract (`smart-contracts/ink/lib.rs`), the validator and miner code, the CLI, and the constants under `allways/constants.py`. The contract is the only authority that matters; everything below is convenience and may lag the source. Source of truth: https://github.com/entrius/allways at the version you installed. ## Concepts you actually need -- **Actors.** User picks a miner. Miner posts collateral + rate, fulfills. Validators verify both legs and vote. Contract enforces slash / timeout / payout. -- **Statuses.** `ACTIVE → FULFILLED → COMPLETED` (happy) or `ACTIVE → TIMED_OUT` (slash to user). +- **Actors.** Miners post collateral and quote live rates per pair on-chain — they're active and quoting *before any swap exists*. Users pick a pair and an acceptable rate; that selection resolves on the backend to a specific miner who's offering it. Validators verify both legs of the swap and vote. Contract enforces slash / timeout / payout. +- **Reservation lifecycle.** Before a swap reaches `ACTIVE`, you go through `reserve → confirm → initiate`. A successful reserve locks a miner to you for the reservation TTL. Once you broadcast your source tx and validators verify it (on the source chain, correct sender, correct amount), the reservation graduates to an on-chain `ACTIVE` swap. If you don't confirm in time, the reservation expires, the miner unlocks, and nothing is lost — start over. View pre-initiate state via `alw view reservation` (yours) or `GET /reservations/by-source/{address}` (any). +- **Statuses (on-chain swap, post-initiate).** `ACTIVE → FULFILLED → COMPLETED` (happy) or `ACTIVE → TIMED_OUT` (slash to user). - **Fee — 1%, paid via the rate.** The fee is *implicit in the price you accept*. If a miner quotes `1 BTC = 300 TAO` and you send 1 BTC, you receive **297 TAO** — the 3-TAO fee is the protocol's cut. The fee never leaves your wallet as a separate charge; it's harvested from the miner's collateral on settlement. Always preview with `alw swap quote` (or the rate display in `alw swap now`) — the post-fee receive amount is shown. -- **Block time.** ~12s on Bittensor; 30 blocks ≈ 6 min. -- **Reservation TTL.** Once a miner is reserved, you have ~6 min (30 blocks, `RESERVATION_TTL_BLOCKS`) to broadcast your source tx. Miss the window and the reservation expires, the miner unlocks, and nothing is lost — just start over. -- **BTC fees gate the whole flow — underprice them and you lose your send.** For BTC-source swaps, validators only extend your reservation once the source tx has ≥1 confirmation (tier-1 extension is gated on `confirmations >= 1`). Set the fee too low and the tx sits in mempool: no confirmation → no extension → the reservation eventually times out *while your BTC is still in flight*. When it finally mines, it lands in the miner's address with no on-chain swap to credit it against, and the funds are gone. The CLI's auto-estimated rate is the safe default — only override `--btc-fee-rate` if you've checked current mempool conditions (e.g. https://mempool.space), and never set it below a next-block tier. Same rule if you broadcast from your own wallet: validators cannot wait all day for a confirmation, so frugal fees = lost send. +- **Block time.** ~12s on Bittensor. +- **Live contract parameters — read before assuming.** All time-bounded values (reservation TTL, fulfillment timeout, extension caps, challenge window) and economic bounds (fee, min/max swap, min/max collateral) are on-chain and readable via `alw view contract` or `GET /protocol/constants`. Don't hardcode — values can change. The fields you'll see and what they mean: + - `Reservation TTL` — how long a reserve holds a miner for you before it expires. Broadcast your source tx and confirm inside this window. + - `Fulfillment Timeout` — once `ACTIVE`, how long the miner has to deliver before validators can vote `TIMED_OUT`. + - `Fee` — protocol cut, currently 1%, paid implicitly via the rate. + - `Min/Max Swap Amount` — bounds on the TAO-equivalent swap size. Out-of-range reservations get rejected at the contract. + - `Min/Max Collateral` — what miners must lock; affects who can fulfill. + - `Extension Challenge Window` / `Max Extension Length` / `Max Extensions per Reservation|Swap` — control how long swap deadlines can be auto-extended while you're awaiting confirmations. + - `Consensus` — validator quorum required to advance a swap. +- **BTC fees gate the whole flow — underprice them and you lose your send.** For BTC-source swaps, validators only extend your reservation once the source tx has ≥1 confirmation (tier-1 extension is gated on `confirmations >= 1`). Set the fee too low and the tx sits in mempool: no confirmation → no extension → the reservation eventually times out *while your BTC is still in flight*. When it finally mines, it lands in the miner's address with no on-chain swap to credit it against, and the funds are gone. The CLI's auto-estimated `--btc-fee-rate` is intended to be a safe default — only override it if you've checked current mempool conditions (e.g. https://mempool.space), and never set it below a next-block tier. Same rule if you broadcast from your own wallet: validators cannot wait all day for a confirmation, so frugal fees = lost send. - **Slash payouts are always TAO.** Even on BTC-side swaps you need a Bittensor wallet — that's where any timeout refund lands. -- **Sender verification.** Validators reject any source tx whose on-chain sender does not match the address you proved at reserve time. Don't try to send from a different wallet than the one you registered. +- **Sender verification.** Validators reject any source tx whose on-chain sender does not match the address you proved at reserve time. Don't broadcast from any wallet other than the one tied to your reservation. > **Bittensor primer.** Allways runs on Bittensor (an L1 subnet network). You don't need to learn it — the CLI handles all chain interaction. Background reading only: https://docs.bittensor.com. @@ -52,8 +66,8 @@ no wrapped asset, no bridge token. This is what actually happens between "I want to swap" and "funds in my wallet": 1. **Quote.** You call `alw swap quote` (or read `GET /miners`). Miners advertise live rates on-chain via subnet commitments — no off-chain orderbook. -2. **Reserve.** You sign a proof of ownership of your source address and broadcast a `SwapReserveSynapse` to validators. Quorum of validators vote on-chain to lock the chosen miner to you for ~6 min. `alw swap now` does this for you. -3. **Send source funds.** You broadcast a tx on the source chain (TAO via your hotkey, BTC via WIF or your own wallet) sending the agreed amount **from the address you proved at reserve time** to the miner's address. Must happen inside the reservation window. +2. **Reserve.** You sign a proof of ownership of your source address and broadcast a `SwapReserveSynapse` to validators. Quorum of validators vote on-chain to lock the chosen miner to you for the **reservation TTL** (live value via `alw view contract`). `alw swap now` does this for you. +3. **Send source funds.** You broadcast a tx on the source chain — for TAO source, your **coldkey** signs and sends the transfer (your hotkey is *not* involved); for BTC source, the CLI signs with the WIF in `.env` or you broadcast from your own wallet. Either way, the source must be **the address you proved at reserve time** going to the miner's address, and it must happen inside the reservation TTL. As an Allways user (not a miner) you don't actually need a hotkey at all — bittensor wallets bundle one by convention but no swap step uses it on the user side. 4. **Confirm.** You sign a proof binding your source tx to the reservation and broadcast a `SwapConfirmSynapse` to validators. They: - Verify the source tx exists on the source chain, has enough confirmations, came from your reserved address, and matches the agreed amount. - Vote on-chain to **initiate** the swap. The contract creates an `ACTIVE` swap and locks miner collateral. Status: `ACTIVE`. @@ -61,7 +75,7 @@ This is what actually happens between "I want to swap" and "funds in my wallet": 6. **Validators confirm fulfillment.** Validators verify the destination tx (on-chain, correct amount, correct recipient, enough confirmations) and vote to complete. Contract releases miner collateral, books the 1% fee. Status: `FULFILLED → COMPLETED`. Done. 7. **Timeout / refund.** If the miner doesn't fulfill within the swap timeout, validators vote `TIMED_OUT`. The contract slashes the miner's collateral and pays you out in TAO directly. If that on-chain transfer fails, the slash is held pending — `alw claim ` claims it. -Throughout, you can poll `GET /swaps/{id}` or watch `alw view swap --watch` for the live timeline. +Throughout, you can poll the live state — pre-initiate via `alw view reservation` or `GET /reservations/by-source/{address}` (look up by your source address), and post-initiate via `alw view swap --watch` or `GET /swaps/{id}`. Reservations carry their own request hash, so once you have one you can also fetch `GET /reservations/{requestHash}` directly. ## Setup (shell-first) @@ -93,7 +107,26 @@ Standard Bittensor wallet conventions. Create one if you don't have one: btcli wallet new_coldkey --wallet.name btcli wallet new_hotkey --wallet.name --wallet.hotkey -Wallets land in `~/.bittensor/wallets/`. **Fund the hotkey with TAO** — it signs swap and collateral calls and pays extrinsic fees. Keep a small buffer (~0.02 TAO is enough — the in-code constant is `MIN_BALANCE_FOR_TX_RAO = 20_000_000`) above your intended swap amount. +Wallets land in `~/.bittensor/wallets/`. The hotkey is a Bittensor convention; as a swap user (not a miner) you don't actively use it on the happy path — see "Wallet roles & funding" below. + +#### Wallet roles & funding (read this before funding anything) + +The bittensor wallet bundles a coldkey and a hotkey. They do *different* things, and the doc has historically buried this — surface it now: + +| Operation | Who signs / where funds come from | +|---|---| +| **TAO source transfer** (TAO → BTC swap, your sending leg) | **Coldkey** signs and the TAO debits from coldkey balance. | +| **BTC source transfer** (BTC → TAO swap, your sending leg) | Your BTC WIF (`BTC_PRIVATE_KEY`) or your own BTC wallet — no Bittensor key involved. | +| **Reserve / confirm proofs** (off-chain message signing) | **Coldkey** for TAO source addresses. No on-chain fee; no balance needed. | +| **Receiving destination asset** | The address you pass via `--receive-address` — TAO ss58 for `--to tao`, BTC `bc1q…` for `--to btc`. | +| **Auto-paid timeout refund** (slash) | Lands in `swap.user` (your registered source ss58 / coldkey for TAO source). Hotkey not involved. | +| **`alw claim `** (manual claim if auto-payout failed) | **Hotkey** signs the on-chain extrinsic; the funds still go to `swap.user` (coldkey). Hotkey only needs the ~0.02 TAO extrinsic-fee buffer (`MIN_BALANCE_FOR_TX_RAO = 20_000_000` rao). | +| **Miner ops** (collateral, activate, mark-fulfilled) | Hotkey signs and pays from hotkey balance — ignore unless you're running a miner. | + +**Pre-flight funding checklist (per-direction, swap-only):** + +- **TAO → BTC.** Top up the **coldkey** with at least `amount + 0.02 TAO` (swap amount + extrinsic fee buffer). Hotkey can be empty. `--receive-address` is your **BTC** address. +- **BTC → TAO.** Top up the BTC wallet whose WIF / address you'll broadcast from with at least `amount + estimated BTC fee`. Coldkey and hotkey can both be empty *for the swap itself* — though if you ever expect to need `alw claim`, fund the hotkey with ~0.02 TAO. `--receive-address` is your **TAO** ss58. ### 2b. (BTC-side only) Bitcoin wallet via Electrum @@ -119,56 +152,82 @@ The WIF (without `p2wpkh:`) is what you put in `BTC_PRIVATE_KEY`; the `bc1q…`/ ### 3. Configure the CLI +**Mainnet (TBD — not yet deployed):** the mainnet contract has not landed yet. Until it does, default to **testnet** for any real exercise of the system. The mainnet config shape will be: + alw config set wallet alw config set hotkey alw config set network finney alw config set netuid 7 + # contract-address: TBD — bundled in code on release -The mainnet contract address is **bundled in code** (`5FTkUEhRmLPsALn4b7bJpVFhDQqohGbc6khnmA2aiYFLMZYP`) — you do not need to set `contract-address` for production. Only override for testnet (see the Testnet section). +**Testnet (live today):** see the Testnet section below for the full block including the testnet contract address and BTC env. For now most agents should target testnet. Config persists at `~/.allways/config.json`. ### 4. (BTC-side only) BTC sending -For BTC→TAO swaps, the CLI can broadcast BTC for you if you put a WIF private key in a `.env` next to where you invoke `alw`: +For BTC→TAO swaps, the CLI can broadcast BTC for you if you put a WIF private key in a `.env` file in your **current working directory** when you run `alw` (the CLI loads `.env` from CWD, not `~/.allways/` and not the install path): BTC_MODE=lightweight BTC_NETWORK=mainnet BTC_PRIVATE_KEY= -`lightweight` mode talks to the Blockstream API — no Bitcoin node required. +`lightweight` mode talks to public Esplora-compatible APIs (Blockstream as primary, with a Mempool.space fallback if Blockstream is unreachable) — no Bitcoin node required. -If `BTC_PRIVATE_KEY` is unset, BTC→TAO falls back to a manual flow: the CLI prints the miner's address + exact amount, you broadcast from your own wallet, **then run `alw swap post-tx ` *within the ~6 min reservation window***. Miss the window and the reservation expires before you can confirm. +If `BTC_PRIVATE_KEY` is unset, BTC→TAO falls back to a manual flow: the CLI prints the miner's address + exact amount, you broadcast from your own wallet, **then run `alw swap post-tx ` *within the reservation TTL window* (run `alw view contract` for the current value)**. Miss the window and the reservation expires before you can confirm. -TAO→BTC swaps need no `.env` — TAO is signed by your hotkey. +TAO→BTC swaps need no `.env` — your **coldkey** signs and sends the source TAO transfer directly. -## Verify the install (read-only, no funds spent) +## Verify the install + scope the system (read-only, no funds spent) -Run in order. Each step confirms the previous one. +Run in order. Each step confirms the previous one. Steps 7–8 are the most important *before* attempting a swap — they tell you the live bounds and who's online. alw --help # 1. Binary works; disclaimer prints. - alw config # 2. Saved config is correct. + alw config # 2. Saved config is correct (network, netuid, contract). alw status # 3. Connects to chain; balances appear. - alw view miners # 4. Rows of miner UIDs + rates. - alw view rates --pair btc-tao # 5. Live orderbook for BTC↔TAO. - alw swap quote --from btc --to tao --amount 0.001 # 6. Preview a quote (no commitment). + alw view miners # 4. Rows of miner UIDs + rates. Empty list = miners offline / wrong contract address. + alw view validators # 5. Whitelisted validator allowlist — confirms you're talking to a live validator set. + alw view rates --pair btc-tao # 6. Live orderbook (only swappable miners). + alw view contract # 7. **Read this.** Live values for reservation TTL, fulfillment timeout, fee, min/max swap, extension caps. Use these instead of any number quoted in this doc. + alw swap quote --from btc --to tao --amount 0.001 # 8. Preview a quote (no commitment). See output shape below. + +`alw swap quote` example output (fields you'll parse): + + Pair: BTC → TAO + Source amount: 0.00100000 BTC + Best rate: 1 BTC = 300.123456 TAO (miner UID 12, hotkey 5Hax…) + You receive: 0.297122 TAO # ← post-fee receive amount + Protocol fee: 1% (implicit in rate) + +The "You receive" line is the post-fee amount that will actually land in your destination address — the 1% fee is implicit in the rate, not a separate charge. Always treat this number, not the headline rate, as the bottom-line outcome. -If any step fails, jump to **Known issues** below. +If any step fails, jump to **Known issues** below. In particular, an empty `alw view miners` while the dashboard shows active miners almost always means `contract-address` in your config doesn't match the live deployment — re-check it against the values in this doc. ## Run a swap ### Non-interactive (recommended for agents) -Drive the entire flow with flags — no prompts. `--auto` picks the best-rate eligible miner; `--yes` skips every confirmation. +Drive the entire flow with flags — no prompts. `--auto` picks the best-rate eligible miner; `--yes` skips every confirmation. Read the flag table below before copying — every flag is meaningful and several have no safe default. + +**BTC → TAO** (you send BTC; receive TAO): + + alw swap now \ + --from btc --to tao \ # direction + --amount 0.001 \ # source amount, in BTC + --receive-address 5C... \ # destination — your TAO ss58 (where miner sends to) + --from-address bc1q... \ # source — your BTC address (must match the wallet that broadcasts) + --auto --yes + +**TAO → BTC** (you send TAO; receive BTC). `--receive-address` here is a **BTC address**, not a TAO address — that's the destination chain: alw swap now \ - --from btc --to tao \ - --amount 0.001 \ - --receive-address 5C... \ # your TAO (dest) address - --from-address bc1q... \ # your BTC (source) address — must match the wallet that broadcasts + --from tao --to btc \ # direction + --amount 1.0 \ # source amount, in TAO + --receive-address bc1q... \ # destination — your BTC address (where miner sends to) + --from-address 5C... \ # source — your TAO coldkey ss58 (the coldkey signs the source transfer) --auto --yes -If you've already broadcast the source tx yourself (e.g. you skipped `BTC_PRIVATE_KEY`), pass `--from-tx-hash` so the CLI doesn't try to send for you: +If you've already broadcast the source tx yourself (e.g. you skipped `BTC_PRIVATE_KEY` for BTC source), pass `--from-tx-hash` so the CLI doesn't try to send for you: alw swap now --from btc --to tao --amount 0.001 \ --receive-address 5C... --from-address bc1q... \ @@ -178,15 +237,15 @@ Available flags on `alw swap now`: | Flag | Purpose | |---|---| -| `--from ` | Source chain (`btc`, `tao`) | -| `--to ` | Destination chain | -| `--amount ` | Source amount in chain units (e.g. 0.001 BTC) | -| `--receive-address ` | Destination address — where the miner sends to you | -| `--from-address ` | Source address — where you send from (must match the wallet you'll broadcast with) | -| `--from-tx-hash ` | Reuse an existing source tx (skip the send step) | -| `--auto` | Auto-pick the best-rate eligible miner — no menu | -| `--yes` | Skip every confirmation prompt | -| `--btc-fee-rate ` | Override BTC fee rate (default: auto-estimated) | +| `--from ` | Source chain (`btc`, `tao`) — the chain you spend from | +| `--to ` | Destination chain — the chain you receive on | +| `--amount ` | **Source amount**, expressed in source-chain units. e.g. `--from btc --amount 0.001` = 0.001 BTC; `--from tao --amount 1.0` = 1 TAO. The matching help text in `alw swap now --help` calls this "Source amount". | +| `--receive-address ` | Destination address — where the miner sends the destination asset to **you**. Must be on the `--to` chain (BTC `bc1q…` if `--to btc`; TAO ss58 if `--to tao`). | +| `--from-address ` | Source address — where **you** broadcast the source tx from. Must be on the `--from` chain and match the wallet that signs (BTC `bc1q…` for `--from btc`; TAO **coldkey** ss58 for `--from tao`). Validators reject any source tx whose sender doesn't match this. | +| `--from-tx-hash ` | Reuse an existing source tx — skip the CLI's send step (use when you broadcast manually). | +| `--auto` | Auto-pick the best-rate eligible miner — no menu. | +| `--yes` | Skip every confirmation prompt. | +| `--btc-fee-rate ` | Override BTC fee rate (default: auto-estimated to a next-block tier — see the BTC fee warning above). | After it returns a swap ID: @@ -290,28 +349,38 @@ live state instead of polling, and don't hammer it. - **Empty `SWAP_ID` from `alw swap now`** — almost always a missing `BTC_PRIVATE_KEY` or unreachable BTC RPC. Check `~/.allways/logs/`; re-run with `--verbose` for full output. - **`Wallet not found`** — `wallet` / `hotkey` in `alw config` don't match anything in `~/.bittensor/wallets/`. Verify with `btcli wallet list`. - **`InsufficientBalance` on a swap** — whichever key signs the failing extrinsic needs ≥ 0.02 TAO of headroom (`MIN_BALANCE_FOR_TX_RAO`). For TAO→BTC, the **coldkey** signs the source TAO transfer — top up the coldkey above the swap amount. For `alw claim` and miner collateral ops, the **hotkey** signs — top up the hotkey. -- **Reservation expired before send** — miner is auto-unlocked. Start a new swap; nothing is lost. Reservation TTL is ~6 min (30 blocks). +- **Reservation expired before send** — miner is auto-unlocked. Start a new swap; nothing is lost. Live reservation TTL is read via `alw view contract`. - **BTC tx stuck unconfirmed → reservation timed out → BTC sent but no swap** — you broadcast with too low a fee rate for current mempool conditions, the source tx never reached 1 confirmation, validators stopped extending, and the reservation expired. When the tx eventually mines, the BTC lands in the miner's wallet with no on-chain swap to credit it against — the funds are unrecoverable. Prevention: omit `--btc-fee-rate` (let the CLI auto-estimate), or check next-block tiers on https://mempool.space before overriding. If you're already stuck pre-confirmation, RBF (replace-by-fee) up to a next-block rate immediately — recovery is only possible while the tx is still in mempool. -- **Miner timed out — where's my refund?** — slashed collateral is paid in TAO to your hotkey automatically. If that fails, run `alw claim `. +- **Miner timed out — where's my refund?** — slashed collateral is paid in TAO to your registered swap user (coldkey for TAO source) automatically. If the on-chain transfer fails, the slash goes to a pending-claims map — run `alw claim ` (signed by your hotkey) to release it. Funds always end up at your registered user address regardless of who signs the claim. -## Testnet (dry-run only) +## Testnet (the default, until mainnet ships) -> **Default to mainnet.** Users who ask for "a swap" want a real one — testnet settles in fake assets and is for verifying setup, not delivering value. Only target testnet when the user has *explicitly* asked you to dry-run, smoke-test the system, or work without real funds at risk. +> Mainnet is **not yet live** — until it is, all real exercise of Allways happens on testnet. Use real-fund tone (proper sender verification, fee estimation, etc.) so the muscle memory transfers, but the assets themselves are test-TAO and test-BTC. -When you do need testnet, override config and point any BTC env vars at testnet too: +Configure the CLI for testnet: + alw config set wallet + alw config set hotkey alw config set network test alw config set netuid 19 - alw config set contract-address 5HTL2snUCca5tjhp6vxNHuo8FZyCSE3wnmyQTNFEKSo6h6kA + alw config set contract-address 5FwPheGT96iBFZ6JkwyDhDH4GcVjafWxAtSsSSq26UiYyTfg + +For BTC-side testnet swaps, use a testnet `.env` (CWD when invoking `alw`): -For BTC, set `BTC_NETWORK=testnet` (lightweight uses Blockstream's testnet endpoint automatically) and use a testnet WIF. Inspect state with the testnet API at `https://test-api.all-ways.io` and the dashboard at `https://test.all-ways.io`. + BTC_MODE=lightweight + BTC_NETWORK=testnet + BTC_PRIVATE_KEY= + +Lightweight mode auto-selects Blockstream's testnet endpoint when `BTC_NETWORK=testnet`. Source addresses are `tb1q…` (testnet SegWit). Inspect state via the testnet API at `https://test-api.all-ways.io` and the dashboard at `https://test.all-ways.io`. Faucets: -- Test-TAO: see https://docs.bittensor.com — request via the test subtensor; the path varies by `btcli` version, so prefer the docs over a hard-coded command. +- Test-TAO: try the community faucet at `https://taoswap.org/testnet-faucet`. Bittensor's docs (https://docs.bittensor.com) cover the in-CLI path, but the official `btcli` faucet is intermittently disabled on testnet, so a web faucet or a peer transfer is often the only path. - Test-BTC: any public testnet3 faucet works (e.g. `https://coinfaucet.eu/en/btc-testnet/`, `https://bitcoinfaucet.uo1.net/`). Send to the `tb1q…` address from your testnet Electrum wallet. -Testnet parameters drift — always check `alw view contract` for current bounds before assuming. +If you can't get either faucet working, ask the operator to seed your wallets — that's normal on testnet. + +Testnet parameters drift — always check `alw view contract` for current bounds before assuming, and run `alw view miners` / `alw view validators` to confirm the system is actually live before trying to swap. ## Disclaimer @@ -324,6 +393,5 @@ your own risk. No warranty. Not financial advice. - Repo: https://github.com/entrius/allways - Docs: https://docs.all-ways.io -- API + Swagger: https://api.all-ways.io/swagger -- Mainnet UI: https://all-ways.io -- Testnet UI: https://test.all-ways.io +- Testnet UI + API: https://test.all-ways.io · https://test-api.all-ways.io/swagger +- Mainnet UI + API (placeholder until contract deploys): https://all-ways.io · https://api.all-ways.io/swagger diff --git a/src/components/agents/AgentMarkdown.ts b/src/components/agents/AgentMarkdown.ts index e692957..e404c5f 100644 --- a/src/components/agents/AgentMarkdown.ts +++ b/src/components/agents/AgentMarkdown.ts @@ -10,23 +10,29 @@ export const AGENT_MARKDOWN = `# Allways — Agent Quickstart ## TL;DR Allways is Bittensor Subnet 7 — a permissionless on-chain orderbook for -trustless native swaps between independent assets. **BTC ↔ TAO is live -today; more pairs are coming online.** Miners post collateral and quote +trustless native swaps between independent assets. **BTC ↔ TAO is the +first pair; more are coming online.** Miners post collateral and quote exchange rates. Validators verify both legs of each swap. The smart contract slashes collateral on failure and refunds the user. No custodian, no wrapped asset, no bridge token. +> **Where to point your wallets right now:** the **mainnet** contract is +> **TBD** (not yet deployed — netuid 7). All real exercise today happens +> on **testnet** (netuid 19, contract +> \`5FwPheGT96iBFZ6JkwyDhDH4GcVjafWxAtSsSSq26UiYyTfg\`). The full testnet +> setup block is in the **Testnet** section below. + ## Resources (skim these first) | What | Where | |---|---| -| Live dashboard (mainnet) | https://all-ways.io | | Live dashboard (testnet) | https://test.all-ways.io | -| Public API + Swagger | https://api.all-ways.io/swagger | -| Testnet API | https://test-api.all-ways.io | +| Testnet API + Swagger | https://test-api.all-ways.io/swagger | +| Mainnet dashboard (placeholder, contract not yet deployed) | https://all-ways.io | +| Mainnet API (placeholder) | https://api.all-ways.io | | Docs site | https://docs.all-ways.io | | Source repo | https://github.com/entrius/allways | -| This document, raw | https://all-ways.io/llms.txt | +| This document, raw | https://all-ways.io/llms.txt (mirrored at https://test.all-ways.io/llms.txt) | ## Why agents use it @@ -35,18 +41,26 @@ no wrapped asset, no bridge token. - **Subnet-native.** Settles in real BTC and real TAO. No IOUs. - **Open + agentic.** Public API, SSE feeds, open-source CLI, scriptable end-to-end. -> **Code is law.** This doc is a quickstart, not a spec. Before high-value swaps, fresh-clone https://github.com/entrius/allways at the version you installed and audit \`allways/constants.py\` (fee divisor, reservation TTL, swap bounds) and \`smart-contracts/ink/lib.rs\` (on-chain enforcement — slash, fee accrual, payouts). The contract is the only authority that matters; everything below is convenience. +> **Code is law.** This doc is a quickstart, not a spec. Review everything end-to-end before any non-trivial swap — the on-chain contract (\`smart-contracts/ink/lib.rs\`), the validator and miner code, the CLI, and the constants under \`allways/constants.py\`. The contract is the only authority that matters; everything below is convenience and may lag the source. Source of truth: https://github.com/entrius/allways at the version you installed. ## Concepts you actually need -- **Actors.** User picks a miner. Miner posts collateral + rate, fulfills. Validators verify both legs and vote. Contract enforces slash / timeout / payout. -- **Statuses.** \`ACTIVE → FULFILLED → COMPLETED\` (happy) or \`ACTIVE → TIMED_OUT\` (slash to user). +- **Actors.** Miners post collateral and quote live rates per pair on-chain — they're active and quoting *before any swap exists*. Users pick a pair and an acceptable rate; that selection resolves on the backend to a specific miner who's offering it. Validators verify both legs of the swap and vote. Contract enforces slash / timeout / payout. +- **Reservation lifecycle.** Before a swap reaches \`ACTIVE\`, you go through \`reserve → confirm → initiate\`. A successful reserve locks a miner to you for the reservation TTL. Once you broadcast your source tx and validators verify it (on the source chain, correct sender, correct amount), the reservation graduates to an on-chain \`ACTIVE\` swap. If you don't confirm in time, the reservation expires, the miner unlocks, and nothing is lost — start over. View pre-initiate state via \`alw view reservation\` (yours) or \`GET /reservations/by-source/{address}\` (any). +- **Statuses (on-chain swap, post-initiate).** \`ACTIVE → FULFILLED → COMPLETED\` (happy) or \`ACTIVE → TIMED_OUT\` (slash to user). - **Fee — 1%, paid via the rate.** The fee is *implicit in the price you accept*. If a miner quotes \`1 BTC = 300 TAO\` and you send 1 BTC, you receive **297 TAO** — the 3-TAO fee is the protocol's cut. The fee never leaves your wallet as a separate charge; it's harvested from the miner's collateral on settlement. Always preview with \`alw swap quote\` (or the rate display in \`alw swap now\`) — the post-fee receive amount is shown. -- **Block time.** ~12s on Bittensor; 30 blocks ≈ 6 min. -- **Reservation TTL.** Once a miner is reserved, you have ~6 min (30 blocks, \`RESERVATION_TTL_BLOCKS\`) to broadcast your source tx. Miss the window and the reservation expires, the miner unlocks, and nothing is lost — just start over. -- **BTC fees gate the whole flow — underprice them and you lose your send.** For BTC-source swaps, validators only extend your reservation once the source tx has ≥1 confirmation (tier-1 extension is gated on \`confirmations >= 1\`). Set the fee too low and the tx sits in mempool: no confirmation → no extension → the reservation eventually times out *while your BTC is still in flight*. When it finally mines, it lands in the miner's address with no on-chain swap to credit it against, and the funds are gone. The CLI's auto-estimated rate is the safe default — only override \`--btc-fee-rate\` if you've checked current mempool conditions (e.g. https://mempool.space), and never set it below a next-block tier. Same rule if you broadcast from your own wallet: validators cannot wait all day for a confirmation, so frugal fees = lost send. +- **Block time.** ~12s on Bittensor. +- **Live contract parameters — read before assuming.** All time-bounded values (reservation TTL, fulfillment timeout, extension caps, challenge window) and economic bounds (fee, min/max swap, min/max collateral) are on-chain and readable via \`alw view contract\` or \`GET /protocol/constants\`. Don't hardcode — values can change. The fields you'll see and what they mean: + - \`Reservation TTL\` — how long a reserve holds a miner for you before it expires. Broadcast your source tx and confirm inside this window. + - \`Fulfillment Timeout\` — once \`ACTIVE\`, how long the miner has to deliver before validators can vote \`TIMED_OUT\`. + - \`Fee\` — protocol cut, currently 1%, paid implicitly via the rate. + - \`Min/Max Swap Amount\` — bounds on the TAO-equivalent swap size. Out-of-range reservations get rejected at the contract. + - \`Min/Max Collateral\` — what miners must lock; affects who can fulfill. + - \`Extension Challenge Window\` / \`Max Extension Length\` / \`Max Extensions per Reservation|Swap\` — control how long swap deadlines can be auto-extended while you're awaiting confirmations. + - \`Consensus\` — validator quorum required to advance a swap. +- **BTC fees gate the whole flow — underprice them and you lose your send.** For BTC-source swaps, validators only extend your reservation once the source tx has ≥1 confirmation (tier-1 extension is gated on \`confirmations >= 1\`). Set the fee too low and the tx sits in mempool: no confirmation → no extension → the reservation eventually times out *while your BTC is still in flight*. When it finally mines, it lands in the miner's address with no on-chain swap to credit it against, and the funds are gone. The CLI's auto-estimated \`--btc-fee-rate\` is intended to be a safe default — only override it if you've checked current mempool conditions (e.g. https://mempool.space), and never set it below a next-block tier. Same rule if you broadcast from your own wallet: validators cannot wait all day for a confirmation, so frugal fees = lost send. - **Slash payouts are always TAO.** Even on BTC-side swaps you need a Bittensor wallet — that's where any timeout refund lands. -- **Sender verification.** Validators reject any source tx whose on-chain sender does not match the address you proved at reserve time. Don't try to send from a different wallet than the one you registered. +- **Sender verification.** Validators reject any source tx whose on-chain sender does not match the address you proved at reserve time. Don't broadcast from any wallet other than the one tied to your reservation. > **Bittensor primer.** Allways runs on Bittensor (an L1 subnet network). You don't need to learn it — the CLI handles all chain interaction. Background reading only: https://docs.bittensor.com. @@ -55,8 +69,8 @@ no wrapped asset, no bridge token. This is what actually happens between "I want to swap" and "funds in my wallet": 1. **Quote.** You call \`alw swap quote\` (or read \`GET /miners\`). Miners advertise live rates on-chain via subnet commitments — no off-chain orderbook. -2. **Reserve.** You sign a proof of ownership of your source address and broadcast a \`SwapReserveSynapse\` to validators. Quorum of validators vote on-chain to lock the chosen miner to you for ~6 min. \`alw swap now\` does this for you. -3. **Send source funds.** You broadcast a tx on the source chain (TAO via your hotkey, BTC via WIF or your own wallet) sending the agreed amount **from the address you proved at reserve time** to the miner's address. Must happen inside the reservation window. +2. **Reserve.** You sign a proof of ownership of your source address and broadcast a \`SwapReserveSynapse\` to validators. Quorum of validators vote on-chain to lock the chosen miner to you for the **reservation TTL** (live value via \`alw view contract\`). \`alw swap now\` does this for you. +3. **Send source funds.** You broadcast a tx on the source chain — for TAO source, your **coldkey** signs and sends the transfer (your hotkey is *not* involved); for BTC source, the CLI signs with the WIF in \`.env\` or you broadcast from your own wallet. Either way, the source must be **the address you proved at reserve time** going to the miner's address, and it must happen inside the reservation TTL. As an Allways user (not a miner) you don't actually need a hotkey at all — bittensor wallets bundle one by convention but no swap step uses it on the user side. 4. **Confirm.** You sign a proof binding your source tx to the reservation and broadcast a \`SwapConfirmSynapse\` to validators. They: - Verify the source tx exists on the source chain, has enough confirmations, came from your reserved address, and matches the agreed amount. - Vote on-chain to **initiate** the swap. The contract creates an \`ACTIVE\` swap and locks miner collateral. Status: \`ACTIVE\`. @@ -64,7 +78,7 @@ This is what actually happens between "I want to swap" and "funds in my wallet": 6. **Validators confirm fulfillment.** Validators verify the destination tx (on-chain, correct amount, correct recipient, enough confirmations) and vote to complete. Contract releases miner collateral, books the 1% fee. Status: \`FULFILLED → COMPLETED\`. Done. 7. **Timeout / refund.** If the miner doesn't fulfill within the swap timeout, validators vote \`TIMED_OUT\`. The contract slashes the miner's collateral and pays you out in TAO directly. If that on-chain transfer fails, the slash is held pending — \`alw claim \` claims it. -Throughout, you can poll \`GET /swaps/{id}\` or watch \`alw view swap --watch\` for the live timeline. +Throughout, you can poll the live state — pre-initiate via \`alw view reservation\` or \`GET /reservations/by-source/{address}\` (look up by your source address), and post-initiate via \`alw view swap --watch\` or \`GET /swaps/{id}\`. Reservations carry their own request hash, so once you have one you can also fetch \`GET /reservations/{requestHash}\` directly. ## Setup (shell-first) @@ -96,7 +110,26 @@ Standard Bittensor wallet conventions. Create one if you don't have one: btcli wallet new_coldkey --wallet.name btcli wallet new_hotkey --wallet.name --wallet.hotkey -Wallets land in \`~/.bittensor/wallets/\`. **Fund the hotkey with TAO** — it signs swap and collateral calls and pays extrinsic fees. Keep a small buffer (~0.02 TAO is enough — the in-code constant is \`MIN_BALANCE_FOR_TX_RAO = 20_000_000\`) above your intended swap amount. +Wallets land in \`~/.bittensor/wallets/\`. The hotkey is a Bittensor convention; as a swap user (not a miner) you don't actively use it on the happy path — see "Wallet roles & funding" below. + +#### Wallet roles & funding (read this before funding anything) + +The bittensor wallet bundles a coldkey and a hotkey. They do *different* things, and the doc has historically buried this — surface it now: + +| Operation | Who signs / where funds come from | +|---|---| +| **TAO source transfer** (TAO → BTC swap, your sending leg) | **Coldkey** signs and the TAO debits from coldkey balance. | +| **BTC source transfer** (BTC → TAO swap, your sending leg) | Your BTC WIF (\`BTC_PRIVATE_KEY\`) or your own BTC wallet — no Bittensor key involved. | +| **Reserve / confirm proofs** (off-chain message signing) | **Coldkey** for TAO source addresses. No on-chain fee; no balance needed. | +| **Receiving destination asset** | The address you pass via \`--receive-address\` — TAO ss58 for \`--to tao\`, BTC \`bc1q…\` for \`--to btc\`. | +| **Auto-paid timeout refund** (slash) | Lands in \`swap.user\` (your registered source ss58 / coldkey for TAO source). Hotkey not involved. | +| **\`alw claim \`** (manual claim if auto-payout failed) | **Hotkey** signs the on-chain extrinsic; the funds still go to \`swap.user\` (coldkey). Hotkey only needs the ~0.02 TAO extrinsic-fee buffer (\`MIN_BALANCE_FOR_TX_RAO = 20_000_000\` rao). | +| **Miner ops** (collateral, activate, mark-fulfilled) | Hotkey signs and pays from hotkey balance — ignore unless you're running a miner. | + +**Pre-flight funding checklist (per-direction, swap-only):** + +- **TAO → BTC.** Top up the **coldkey** with at least \`amount + 0.02 TAO\` (swap amount + extrinsic fee buffer). Hotkey can be empty. \`--receive-address\` is your **BTC** address. +- **BTC → TAO.** Top up the BTC wallet whose WIF / address you'll broadcast from with at least \`amount + estimated BTC fee\`. Coldkey and hotkey can both be empty *for the swap itself* — though if you ever expect to need \`alw claim\`, fund the hotkey with ~0.02 TAO. \`--receive-address\` is your **TAO** ss58. ### 2b. (BTC-side only) Bitcoin wallet via Electrum @@ -122,56 +155,82 @@ The WIF (without \`p2wpkh:\`) is what you put in \`BTC_PRIVATE_KEY\`; the \`bc1q ### 3. Configure the CLI +**Mainnet (TBD — not yet deployed):** the mainnet contract has not landed yet. Until it does, default to **testnet** for any real exercise of the system. The mainnet config shape will be: + alw config set wallet alw config set hotkey alw config set network finney alw config set netuid 7 + # contract-address: TBD — bundled in code on release -The mainnet contract address is **bundled in code** (\`5FTkUEhRmLPsALn4b7bJpVFhDQqohGbc6khnmA2aiYFLMZYP\`) — you do not need to set \`contract-address\` for production. Only override for testnet (see the Testnet section). +**Testnet (live today):** see the Testnet section below for the full block including the testnet contract address and BTC env. For now most agents should target testnet. Config persists at \`~/.allways/config.json\`. ### 4. (BTC-side only) BTC sending -For BTC→TAO swaps, the CLI can broadcast BTC for you if you put a WIF private key in a \`.env\` next to where you invoke \`alw\`: +For BTC→TAO swaps, the CLI can broadcast BTC for you if you put a WIF private key in a \`.env\` file in your **current working directory** when you run \`alw\` (the CLI loads \`.env\` from CWD, not \`~/.allways/\` and not the install path): BTC_MODE=lightweight BTC_NETWORK=mainnet BTC_PRIVATE_KEY= -\`lightweight\` mode talks to the Blockstream API — no Bitcoin node required. +\`lightweight\` mode talks to public Esplora-compatible APIs (Blockstream as primary, with a Mempool.space fallback if Blockstream is unreachable) — no Bitcoin node required. -If \`BTC_PRIVATE_KEY\` is unset, BTC→TAO falls back to a manual flow: the CLI prints the miner's address + exact amount, you broadcast from your own wallet, **then run \`alw swap post-tx \` *within the ~6 min reservation window***. Miss the window and the reservation expires before you can confirm. +If \`BTC_PRIVATE_KEY\` is unset, BTC→TAO falls back to a manual flow: the CLI prints the miner's address + exact amount, you broadcast from your own wallet, **then run \`alw swap post-tx \` *within the reservation TTL window* (run \`alw view contract\` for the current value)**. Miss the window and the reservation expires before you can confirm. -TAO→BTC swaps need no \`.env\` — TAO is signed by your hotkey. +TAO→BTC swaps need no \`.env\` — your **coldkey** signs and sends the source TAO transfer directly. -## Verify the install (read-only, no funds spent) +## Verify the install + scope the system (read-only, no funds spent) -Run in order. Each step confirms the previous one. +Run in order. Each step confirms the previous one. Steps 7–8 are the most important *before* attempting a swap — they tell you the live bounds and who's online. alw --help # 1. Binary works; disclaimer prints. - alw config # 2. Saved config is correct. + alw config # 2. Saved config is correct (network, netuid, contract). alw status # 3. Connects to chain; balances appear. - alw view miners # 4. Rows of miner UIDs + rates. - alw view rates --pair btc-tao # 5. Live orderbook for BTC↔TAO. - alw swap quote --from btc --to tao --amount 0.001 # 6. Preview a quote (no commitment). + alw view miners # 4. Rows of miner UIDs + rates. Empty list = miners offline / wrong contract address. + alw view validators # 5. Whitelisted validator allowlist — confirms you're talking to a live validator set. + alw view rates --pair btc-tao # 6. Live orderbook (only swappable miners). + alw view contract # 7. **Read this.** Live values for reservation TTL, fulfillment timeout, fee, min/max swap, extension caps. Use these instead of any number quoted in this doc. + alw swap quote --from btc --to tao --amount 0.001 # 8. Preview a quote (no commitment). See output shape below. + +\`alw swap quote\` example output (fields you'll parse): + + Pair: BTC → TAO + Source amount: 0.00100000 BTC + Best rate: 1 BTC = 300.123456 TAO (miner UID 12, hotkey 5Hax…) + You receive: 0.297122 TAO # ← post-fee receive amount + Protocol fee: 1% (implicit in rate) + +The "You receive" line is the post-fee amount that will actually land in your destination address — the 1% fee is implicit in the rate, not a separate charge. Always treat this number, not the headline rate, as the bottom-line outcome. -If any step fails, jump to **Known issues** below. +If any step fails, jump to **Known issues** below. In particular, an empty \`alw view miners\` while the dashboard shows active miners almost always means \`contract-address\` in your config doesn't match the live deployment — re-check it against the values in this doc. ## Run a swap ### Non-interactive (recommended for agents) -Drive the entire flow with flags — no prompts. \`--auto\` picks the best-rate eligible miner; \`--yes\` skips every confirmation. +Drive the entire flow with flags — no prompts. \`--auto\` picks the best-rate eligible miner; \`--yes\` skips every confirmation. Read the flag table below before copying — every flag is meaningful and several have no safe default. + +**BTC → TAO** (you send BTC; receive TAO): + + alw swap now \\ + --from btc --to tao \\ # direction + --amount 0.001 \\ # source amount, in BTC + --receive-address 5C... \\ # destination — your TAO ss58 (where miner sends to) + --from-address bc1q... \\ # source — your BTC address (must match the wallet that broadcasts) + --auto --yes + +**TAO → BTC** (you send TAO; receive BTC). \`--receive-address\` here is a **BTC address**, not a TAO address — that's the destination chain: alw swap now \\ - --from btc --to tao \\ - --amount 0.001 \\ - --receive-address 5C... \\ # your TAO (dest) address - --from-address bc1q... \\ # your BTC (source) address — must match the wallet that broadcasts + --from tao --to btc \\ # direction + --amount 1.0 \\ # source amount, in TAO + --receive-address bc1q... \\ # destination — your BTC address (where miner sends to) + --from-address 5C... \\ # source — your TAO coldkey ss58 (the coldkey signs the source transfer) --auto --yes -If you've already broadcast the source tx yourself (e.g. you skipped \`BTC_PRIVATE_KEY\`), pass \`--from-tx-hash\` so the CLI doesn't try to send for you: +If you've already broadcast the source tx yourself (e.g. you skipped \`BTC_PRIVATE_KEY\` for BTC source), pass \`--from-tx-hash\` so the CLI doesn't try to send for you: alw swap now --from btc --to tao --amount 0.001 \\ --receive-address 5C... --from-address bc1q... \\ @@ -181,15 +240,15 @@ Available flags on \`alw swap now\`: | Flag | Purpose | |---|---| -| \`--from \` | Source chain (\`btc\`, \`tao\`) | -| \`--to \` | Destination chain | -| \`--amount \` | Source amount in chain units (e.g. 0.001 BTC) | -| \`--receive-address \` | Destination address — where the miner sends to you | -| \`--from-address \` | Source address — where you send from (must match the wallet you'll broadcast with) | -| \`--from-tx-hash \` | Reuse an existing source tx (skip the send step) | -| \`--auto\` | Auto-pick the best-rate eligible miner — no menu | -| \`--yes\` | Skip every confirmation prompt | -| \`--btc-fee-rate \` | Override BTC fee rate (default: auto-estimated) | +| \`--from \` | Source chain (\`btc\`, \`tao\`) — the chain you spend from | +| \`--to \` | Destination chain — the chain you receive on | +| \`--amount \` | **Source amount**, expressed in source-chain units. e.g. \`--from btc --amount 0.001\` = 0.001 BTC; \`--from tao --amount 1.0\` = 1 TAO. The matching help text in \`alw swap now --help\` calls this "Source amount". | +| \`--receive-address \` | Destination address — where the miner sends the destination asset to **you**. Must be on the \`--to\` chain (BTC \`bc1q…\` if \`--to btc\`; TAO ss58 if \`--to tao\`). | +| \`--from-address \` | Source address — where **you** broadcast the source tx from. Must be on the \`--from\` chain and match the wallet that signs (BTC \`bc1q…\` for \`--from btc\`; TAO **coldkey** ss58 for \`--from tao\`). Validators reject any source tx whose sender doesn't match this. | +| \`--from-tx-hash \` | Reuse an existing source tx — skip the CLI's send step (use when you broadcast manually). | +| \`--auto\` | Auto-pick the best-rate eligible miner — no menu. | +| \`--yes\` | Skip every confirmation prompt. | +| \`--btc-fee-rate \` | Override BTC fee rate (default: auto-estimated to a next-block tier — see the BTC fee warning above). | After it returns a swap ID: @@ -293,28 +352,38 @@ live state instead of polling, and don't hammer it. - **Empty \`SWAP_ID\` from \`alw swap now\`** — almost always a missing \`BTC_PRIVATE_KEY\` or unreachable BTC RPC. Check \`~/.allways/logs/\`; re-run with \`--verbose\` for full output. - **\`Wallet not found\`** — \`wallet\` / \`hotkey\` in \`alw config\` don't match anything in \`~/.bittensor/wallets/\`. Verify with \`btcli wallet list\`. - **\`InsufficientBalance\` on a swap** — whichever key signs the failing extrinsic needs ≥ 0.02 TAO of headroom (\`MIN_BALANCE_FOR_TX_RAO\`). For TAO→BTC, the **coldkey** signs the source TAO transfer — top up the coldkey above the swap amount. For \`alw claim\` and miner collateral ops, the **hotkey** signs — top up the hotkey. -- **Reservation expired before send** — miner is auto-unlocked. Start a new swap; nothing is lost. Reservation TTL is ~6 min (30 blocks). +- **Reservation expired before send** — miner is auto-unlocked. Start a new swap; nothing is lost. Live reservation TTL is read via \`alw view contract\`. - **BTC tx stuck unconfirmed → reservation timed out → BTC sent but no swap** — you broadcast with too low a fee rate for current mempool conditions, the source tx never reached 1 confirmation, validators stopped extending, and the reservation expired. When the tx eventually mines, the BTC lands in the miner's wallet with no on-chain swap to credit it against — the funds are unrecoverable. Prevention: omit \`--btc-fee-rate\` (let the CLI auto-estimate), or check next-block tiers on https://mempool.space before overriding. If you're already stuck pre-confirmation, RBF (replace-by-fee) up to a next-block rate immediately — recovery is only possible while the tx is still in mempool. -- **Miner timed out — where's my refund?** — slashed collateral is paid in TAO to your hotkey automatically. If that fails, run \`alw claim \`. +- **Miner timed out — where's my refund?** — slashed collateral is paid in TAO to your registered swap user (coldkey for TAO source) automatically. If the on-chain transfer fails, the slash goes to a pending-claims map — run \`alw claim \` (signed by your hotkey) to release it. Funds always end up at your registered user address regardless of who signs the claim. -## Testnet (dry-run only) +## Testnet (the default, until mainnet ships) -> **Default to mainnet.** Users who ask for "a swap" want a real one — testnet settles in fake assets and is for verifying setup, not delivering value. Only target testnet when the user has *explicitly* asked you to dry-run, smoke-test the system, or work without real funds at risk. +> Mainnet is **not yet live** — until it is, all real exercise of Allways happens on testnet. Use real-fund tone (proper sender verification, fee estimation, etc.) so the muscle memory transfers, but the assets themselves are test-TAO and test-BTC. -When you do need testnet, override config and point any BTC env vars at testnet too: +Configure the CLI for testnet: + alw config set wallet + alw config set hotkey alw config set network test alw config set netuid 19 - alw config set contract-address 5HTL2snUCca5tjhp6vxNHuo8FZyCSE3wnmyQTNFEKSo6h6kA + alw config set contract-address 5FwPheGT96iBFZ6JkwyDhDH4GcVjafWxAtSsSSq26UiYyTfg + +For BTC-side testnet swaps, use a testnet \`.env\` (CWD when invoking \`alw\`): -For BTC, set \`BTC_NETWORK=testnet\` (lightweight uses Blockstream's testnet endpoint automatically) and use a testnet WIF. Inspect state with the testnet API at \`https://test-api.all-ways.io\` and the dashboard at \`https://test.all-ways.io\`. + BTC_MODE=lightweight + BTC_NETWORK=testnet + BTC_PRIVATE_KEY= + +Lightweight mode auto-selects Blockstream's testnet endpoint when \`BTC_NETWORK=testnet\`. Source addresses are \`tb1q…\` (testnet SegWit). Inspect state via the testnet API at \`https://test-api.all-ways.io\` and the dashboard at \`https://test.all-ways.io\`. Faucets: -- Test-TAO: see https://docs.bittensor.com — request via the test subtensor; the path varies by \`btcli\` version, so prefer the docs over a hard-coded command. +- Test-TAO: try the community faucet at \`https://taoswap.org/testnet-faucet\`. Bittensor's docs (https://docs.bittensor.com) cover the in-CLI path, but the official \`btcli\` faucet is intermittently disabled on testnet, so a web faucet or a peer transfer is often the only path. - Test-BTC: any public testnet3 faucet works (e.g. \`https://coinfaucet.eu/en/btc-testnet/\`, \`https://bitcoinfaucet.uo1.net/\`). Send to the \`tb1q…\` address from your testnet Electrum wallet. -Testnet parameters drift — always check \`alw view contract\` for current bounds before assuming. +If you can't get either faucet working, ask the operator to seed your wallets — that's normal on testnet. + +Testnet parameters drift — always check \`alw view contract\` for current bounds before assuming, and run \`alw view miners\` / \`alw view validators\` to confirm the system is actually live before trying to swap. ## Disclaimer @@ -327,7 +396,6 @@ your own risk. No warranty. Not financial advice. - Repo: https://github.com/entrius/allways - Docs: https://docs.all-ways.io -- API + Swagger: https://api.all-ways.io/swagger -- Mainnet UI: https://all-ways.io -- Testnet UI: https://test.all-ways.io +- Testnet UI + API: https://test.all-ways.io · https://test-api.all-ways.io/swagger +- Mainnet UI + API (placeholder until contract deploys): https://all-ways.io · https://api.all-ways.io/swagger `; diff --git a/src/components/landing/AgentTeaser.tsx b/src/components/landing/AgentTeaser.tsx index c5154c3..ca755e6 100644 --- a/src/components/landing/AgentTeaser.tsx +++ b/src/components/landing/AgentTeaser.tsx @@ -73,7 +73,8 @@ const AgentTeaser: React.FC = () => { }} > Copy a single markdown bundle of context, CLI, and API. Paste it - into any LLM and it can quote, exchange, and watch live state. + into any agent harness and it can quote, exchange, and watch + live state. diff --git a/src/components/landing/HowItWorks.tsx b/src/components/landing/HowItWorks.tsx index 8a78e18..07f2bf0 100644 --- a/src/components/landing/HowItWorks.tsx +++ b/src/components/landing/HowItWorks.tsx @@ -14,12 +14,12 @@ const STEPS: Step[] = [ { num: '01', title: 'Quote', - body: 'Allways publishes live BTC↔TAO rates backed by on-chain collateral. The orderbook is fully on-chain.', + body: 'Allways miners publish live BTC↔TAO rates backed by on-chain collateral. The orderbook is fully on-chain.', }, { num: '02', title: 'Initiate', - body: 'User commits a transaction on-chain. Allways collateral locks. No custodian, no wrapped asset.', + body: 'User commits a transaction on-chain. Supporting miner has collateral locked. No custodian, no wrapped asset.', }, { num: '03', diff --git a/src/components/landing/MetricsStrip.tsx b/src/components/landing/MetricsStrip.tsx index be9581d..6314bcf 100644 --- a/src/components/landing/MetricsStrip.tsx +++ b/src/components/landing/MetricsStrip.tsx @@ -8,9 +8,10 @@ interface MetricProps { label: string; value: string; loading?: boolean; + unit?: string; } -const Metric: React.FC = ({ label, value, loading }) => ( +const Metric: React.FC = ({ label, value, loading, unit }) => ( = ({ label, value, loading }) => ( lineHeight: 1, color: 'text.primary', minHeight: '1em', + display: 'flex', + alignItems: 'baseline', + gap: 0.5, }} > {loading ? ( @@ -49,7 +53,21 @@ const Metric: React.FC = ({ label, value, loading }) => ( sx={{ bgcolor: 'action.hover' }} /> ) : ( - + <> + + {unit && ( + + {unit} + + )} + )} @@ -78,7 +96,12 @@ const MetricsStrip: React.FC = () => { /> - + { > Discord - - Status - diff --git a/src/components/nav/links.ts b/src/components/nav/links.ts index 6991c79..227d887 100644 --- a/src/components/nav/links.ts +++ b/src/components/nav/links.ts @@ -9,7 +9,6 @@ export const LINKS = { github: 'https://github.com/entrius/allways', twitter: 'https://x.com/allways_io', discord: 'https://discord.gg/Q99Z2UQt9J', - status: 'https://status.all-ways.io', } as const; export const docsUrl = (): string => diff --git a/src/pages/AgentsPage.tsx b/src/pages/AgentsPage.tsx index 0df31eb..6ad2145 100644 --- a/src/pages/AgentsPage.tsx +++ b/src/pages/AgentsPage.tsx @@ -63,6 +63,19 @@ const AgentsPage: React.FC = () => { Everything an LLM needs to quote rates, swap, and watch live state on Bittensor SN7. Copy. Paste. Ship. + + Hand it to your agent so it can swap natively between digital assets + on its own — no human in the loop, no custodian in the middle. + diff --git a/src/pages/SwapPage.tsx b/src/pages/SwapPage.tsx index 6276238..64f8f35 100644 --- a/src/pages/SwapPage.tsx +++ b/src/pages/SwapPage.tsx @@ -4,170 +4,190 @@ import { Link as RouterLink } from 'react-router-dom'; import ArrowDownwardIcon from '@mui/icons-material/ArrowDownward'; import { FONTS } from '../theme'; import { Page, SEO, TokenInput } from '../components'; +import { docsUrl } from '../components/nav/links'; -const SwapPage: React.FC = () => ( - - - - - {/* Card (greyed + blurred, non-interactive) */} - - { + const swapGuideUrl = `${docsUrl()}swap-guide`; + return ( + + + + + {/* Card (greyed + blurred, non-interactive) */} + - Exchange - - - - - - - - - - - - Rate + Exchange - + + + + + + + + + + Rate + + + — TAO / BTC + + + + - - - - {/* Coming Soon overlay */} - - - Coming Soon - - - In-browser exchanges land soon. Today, exchange with the CLI or - bring an agent —{' '} - - get the agent bundle → - - - - - - -); + Coming Soon + + + In-browser exchanges land soon. Today, exchange with the{' '} + + CLI + {' '} + or bring an agent —{' '} + + get the agent bundle → + + + + + + + ); +}; export default SwapPage;