diff --git a/public/llms.txt b/public/llms.txt index 4cfe539..82efcf3 100644 --- a/public/llms.txt +++ b/public/llms.txt @@ -14,11 +14,11 @@ collateral and quote exchange rates. Validators verify both legs of each swap. The contract slashes collateral (in SOL) on failure and pays the taker. No custodian, no wrapped asset, no bridge token. -> **Where to point your wallets right now:** **testnet** (Bittensor netuid 19 + -> Solana devnet) is the live, usable environment — dry-run here. **Mainnet** -> (netuid 7) is in internal bring-up. Both use the same Solana program -> `6JVBEj5w27J2SVjERmv2c7wXgFee9nSSBKUJevHehyBD` — the program id is the same -> across clusters; only the network differs. Setup blocks for both are below. +> **Where to point your wallets:** **Mainnet** (Bittensor netuid 7 + Solana +> mainnet) is the live network — real SOL, BTC, and TAO. **Testnet** (netuid 19 + +> Solana devnet) mirrors it with free funds for dry-runs. Both use the same Solana +> program `6JVBEj5w27J2SVjERmv2c7wXgFee9nSSBKUJevHehyBD` — the program id is the +> same across clusters; only the network differs. Setup blocks for both are below. ## Resources (skim these first) @@ -70,7 +70,7 @@ custodian, no wrapped asset, no bridge token. 5. **Relay.** `alw swap post-tx ` immediately. Validators verify the deposit (sender, recipient, amount, freshness), submit the claim, and vote to initiate. Status: `PendingAttestation → Active`. 6. **Miner fulfils.** The miner sends 99% of the destination amount to your receive address and marks fulfilled. Status: `Active → Fulfilled`. 7. **Validators confirm.** Both legs verified → vote confirm. Contract skims the 1% fee from miner collateral. Status: `Fulfilled → Completed`. -8. **Timeout / refund.** If the miner doesn't deliver in time, validators vote `TimedOut`; the contract slashes 1.1× collateral to the taker in SOL. If the auto-payout fails, `alw claim ` releases it. +8. **Timeout / refund.** If the miner doesn't deliver in time, validators vote `TimedOut` and the contract pays 1.1× collateral to the taker's pinned SOL identity — **automatically, no action needed**. (A manual `alw claim` fallback for a failed auto-payout is coming to the CLI.) Throughout, poll live state — pre-send via `alw view reservation`, post-initiate via `alw view swap --watch` or the API. @@ -140,15 +140,15 @@ Optionally set a WIF via env (shell env, a project `.env` walked up from CWD, or ### 5. Configure the CLI -**Testnet (live — netuid 19):** +**Mainnet (live — netuid 7):** - alw config set env testnet # bittensor test + solana devnet + btc testnet4 + netuid 19 + alw config set env mainnet # bittensor finney + solana mainnet + btc mainnet + netuid 7 alw config set wallet alw config set hotkey -**Mainnet (in bring-up — netuid 7):** +**Testnet (free dry-runs — netuid 19):** - alw config set env mainnet # bittensor finney + solana mainnet + btc mainnet + netuid 7 + alw config set env testnet # bittensor test + solana devnet + btc testnet4 + netuid 19 `env` resolves the Bittensor network, Solana cluster, BTC network, and netuid together — no program id or RPC to copy (the program id is baked in, same across clusters). Config persists at `~/.allways/config.json`. @@ -179,10 +179,10 @@ The "You receive" line in a quote is the post-fee amount that lands in your dest --from btc --to sol \ --amount 0.001 \ --receive-address \ - --from-address tb1q... \ + --from-address bc1q... \ --yes -(`--from-address` is your source address on the source chain: a `tb1q…` on testnet4, `bc1q…` on mainnet.) +(`--from-address` is your source address on the source chain: a `bc1q…` on mainnet, `tb1q…` on testnet4.) **SOL → TAO** (send SOL, receive TAO). `--receive-address` here is a TAO ss58: @@ -208,12 +208,14 @@ In every case `alw swap now` only **reserves** — once it prints the miner's ad After it returns a swap key: alw view swap --watch # live timeline until Completed or TimedOut - alw claim # if TimedOut, claim the SOL slash -If interrupted before the send: +On `TimedOut`, the 1.1× SOL slash pays your pinned identity automatically — no action needed. + +If interrupted after the reserve but before the send, check for a still-live reservation and finish it: + + alw view reservation # still live? send the source funds to the miner, then alw swap post-tx - alw view reservation - alw swap resume-reservation [--from-tx-hash ] [--yes] +If the reservation has lapsed, just re-run `alw swap now` (you only forfeit the small reservation fee). ### Interactive @@ -235,8 +237,8 @@ If interrupted before the send: | `alw swap now [...flags]` | Run a swap | | `alw swap quote --from --to --amount ` | Preview rate + receive amount | | `alw swap post-tx ` | Relay your source tx to validators | -| `alw swap resume-reservation [...]` | Resume an interrupted flow | -| `alw claim [-y]` | Claim a SOL slash from a TimedOut swap | +| `alw swap resume-reservation [...]` | Resume an interrupted flow — *not yet wired in the CLI; re-run `alw swap now` instead* | +| `alw claim [-y]` | Claim a SOL slash — *not yet wired in the CLI; the TimedOut payout is automatic* | Miner-only commands (`alw miner …`, `alw collateral …`) and admin commands are documented at https://docs.all-ways.io/cli. @@ -270,11 +272,11 @@ Base URL: `https://api.all-ways.io` (testnet: `https://test-api.all-ways.io`). L - **`BTC_MODE=lightweight requires BTC_PRIVATE_KEY`** — set the WIF for auto-send, or accept the manual flow (`alw swap post-tx ` after sending). - **Reservation expired before send** — you only forfeit the small reservation fee. Start a new swap. Live TTL via `alw view config`. - **BTC tx stuck unconfirmed → reservation timed out → BTC sent but no swap** — fee too low; the tx never confirmed inside the extension budget. Prevention: let the CLI auto-estimate `--btc-fee-rate`, or check next-block tiers. If stuck pre-confirmation, RBF up immediately — recovery is only possible while the tx is in mempool. -- **Miner timed out — where's my refund?** — slashed collateral pays your pinned identity in SOL automatically; if the transfer fails, `alw claim ` releases it. +- **Miner timed out — where's my refund?** — the 1.1× slash pays your pinned SOL identity automatically; no action needed. (A manual `alw claim` fallback for the rare failed auto-payout is coming to the CLI.) ## Testnet -Testnet (Bittensor netuid 19 + Solana devnet) is the recommended place to dry-run. Configure: +Testnet (Bittensor netuid 19 + Solana devnet) mirrors mainnet with free funds — rehearse a flow here before spending real assets. Configure: alw config set env testnet alw config set wallet diff --git a/src/components/Ticker.tsx b/src/components/Ticker.tsx new file mode 100644 index 0000000..4cb5d01 --- /dev/null +++ b/src/components/Ticker.tsx @@ -0,0 +1,116 @@ +import React from 'react'; +import { Box, Stack, useMediaQuery } from '@mui/material'; + +// Rate-strip layout. Desktop (sm+) is the original wrapping row, untouched. +// Mobile (xs) becomes an auto-scrolling marquee — the four direction segments +// loop across one line so the strip never stacks into a tall column. Tap +// toggles pause so a moving rate can be read, and prefers-reduced-motion +// degrades to a static, hand-scrollable row (no animation at all). +// +// Shared by the dashboard (RatesTicker) and the miners page (StickyNetworkHeader) +// so the two strips scroll identically. + +const GAP = 2; // theme spacing between segments + +// Marquee speed. The duration is derived from the measured content width so both +// strips scroll at the same pixels/second — a fixed duration made the wider +// dashboard strip (it carries the EMA suffix) look faster than the narrower +// miners strip. ~22 px/s is a calm pace; MIN keeps very narrow content sane. +const PX_PER_SEC = 22; +const MIN_DURATION_SEC = 8; + +// One pass of the segments. Two identical copies sit in the animated track and +// the transform slides exactly one copy-width (-50%), so the loop is seamless +// regardless of how wide the content is. +const COPY_SX = { + display: 'inline-flex', + alignItems: 'center', + gap: GAP, + pr: GAP, + '& > *': { flexShrink: 0 }, +} as const; + +const Ticker: React.FC<{ children: React.ReactNode }> = ({ children }) => { + const items = React.Children.toArray(children); + const reduced = useMediaQuery('(prefers-reduced-motion: reduce)'); + const [paused, setPaused] = React.useState(false); + + // Measure one copy's width and set the duration to width / PX_PER_SEC, so the + // marquee holds a constant visual speed no matter how wide the segments are. + const copyRef = React.useRef(null); + const [durationSec, setDurationSec] = React.useState(20); + React.useEffect(() => { + if (reduced) return; + const el = copyRef.current; + if (!el) return; + const measure = () => { + const w = el.getBoundingClientRect().width; + if (w > 0) setDurationSec(Math.max(MIN_DURATION_SEC, w / PX_PER_SEC)); + }; + measure(); + const ro = new ResizeObserver(measure); + ro.observe(el); + return () => ro.disconnect(); + }, [reduced]); + + return ( + <> + {/* Desktop / tablet: the original wrapping row. */} + + {items} + + + {/* Mobile: marquee, or a static swipeable row when motion is reduced. */} + setPaused((p) => !p)} + sx={{ + display: { xs: 'block', sm: 'none' }, + width: '100%', + overflowX: reduced ? 'auto' : 'hidden', + WebkitOverflowScrolling: 'touch', + // Fade both edges so a clipped segment reads as "more to scroll", + // not cut off. Skipped in the static case (nothing is clipped mid-item). + maskImage: reduced + ? undefined + : 'linear-gradient(to right, transparent 0, #000 12px, #000 calc(100% - 12px), transparent 100%)', + }} + > + {reduced ? ( + {items} + ) : ( + + + {items} + + + {items} + + + )} + + + ); +}; + +export default Ticker; diff --git a/src/components/agents/AgentMarkdown.ts b/src/components/agents/AgentMarkdown.ts index 4287d4c..8489bbd 100644 --- a/src/components/agents/AgentMarkdown.ts +++ b/src/components/agents/AgentMarkdown.ts @@ -17,11 +17,11 @@ collateral and quote exchange rates. Validators verify both legs of each swap. The contract slashes collateral (in SOL) on failure and pays the taker. No custodian, no wrapped asset, no bridge token. -> **Where to point your wallets right now:** **testnet** (Bittensor netuid 19 + -> Solana devnet) is the live, usable environment — dry-run here. **Mainnet** -> (netuid 7) is in internal bring-up. Both use the same Solana program -> \`6JVBEj5w27J2SVjERmv2c7wXgFee9nSSBKUJevHehyBD\` — the program id is the same -> across clusters; only the network differs. Setup blocks for both are below. +> **Where to point your wallets:** **Mainnet** (Bittensor netuid 7 + Solana +> mainnet) is the live network — real SOL, BTC, and TAO. **Testnet** (netuid 19 + +> Solana devnet) mirrors it with free funds for dry-runs. Both use the same Solana +> program \`6JVBEj5w27J2SVjERmv2c7wXgFee9nSSBKUJevHehyBD\` — the program id is the +> same across clusters; only the network differs. Setup blocks for both are below. ## Resources (skim these first) @@ -73,7 +73,7 @@ custodian, no wrapped asset, no bridge token. 5. **Relay.** \`alw swap post-tx \` immediately. Validators verify the deposit (sender, recipient, amount, freshness), submit the claim, and vote to initiate. Status: \`PendingAttestation → Active\`. 6. **Miner fulfils.** The miner sends 99% of the destination amount to your receive address and marks fulfilled. Status: \`Active → Fulfilled\`. 7. **Validators confirm.** Both legs verified → vote confirm. Contract skims the 1% fee from miner collateral. Status: \`Fulfilled → Completed\`. -8. **Timeout / refund.** If the miner doesn't deliver in time, validators vote \`TimedOut\`; the contract slashes 1.1× collateral to the taker in SOL. If the auto-payout fails, \`alw claim \` releases it. +8. **Timeout / refund.** If the miner doesn't deliver in time, validators vote \`TimedOut\` and the contract pays 1.1× collateral to the taker's pinned SOL identity — **automatically, no action needed**. (A manual \`alw claim\` fallback for a failed auto-payout is coming to the CLI.) Throughout, poll live state — pre-send via \`alw view reservation\`, post-initiate via \`alw view swap --watch\` or the API. @@ -143,15 +143,15 @@ Optionally set a WIF via env (shell env, a project \`.env\` walked up from CWD, ### 5. Configure the CLI -**Testnet (live — netuid 19):** +**Mainnet (live — netuid 7):** - alw config set env testnet # bittensor test + solana devnet + btc testnet4 + netuid 19 + alw config set env mainnet # bittensor finney + solana mainnet + btc mainnet + netuid 7 alw config set wallet alw config set hotkey -**Mainnet (in bring-up — netuid 7):** +**Testnet (free dry-runs — netuid 19):** - alw config set env mainnet # bittensor finney + solana mainnet + btc mainnet + netuid 7 + alw config set env testnet # bittensor test + solana devnet + btc testnet4 + netuid 19 \`env\` resolves the Bittensor network, Solana cluster, BTC network, and netuid together — no program id or RPC to copy (the program id is baked in, same across clusters). Config persists at \`~/.allways/config.json\`. @@ -182,10 +182,10 @@ The "You receive" line in a quote is the post-fee amount that lands in your dest --from btc --to sol \\ --amount 0.001 \\ --receive-address \\ - --from-address tb1q... \\ + --from-address bc1q... \\ --yes -(\`--from-address\` is your source address on the source chain: a \`tb1q…\` on testnet4, \`bc1q…\` on mainnet.) +(\`--from-address\` is your source address on the source chain: a \`bc1q…\` on mainnet, \`tb1q…\` on testnet4.) **SOL → TAO** (send SOL, receive TAO). \`--receive-address\` here is a TAO ss58: @@ -211,12 +211,14 @@ In every case \`alw swap now\` only **reserves** — once it prints the miner's After it returns a swap key: alw view swap --watch # live timeline until Completed or TimedOut - alw claim # if TimedOut, claim the SOL slash -If interrupted before the send: +On \`TimedOut\`, the 1.1× SOL slash pays your pinned identity automatically — no action needed. + +If interrupted after the reserve but before the send, check for a still-live reservation and finish it: + + alw view reservation # still live? send the source funds to the miner, then alw swap post-tx - alw view reservation - alw swap resume-reservation [--from-tx-hash ] [--yes] +If the reservation has lapsed, just re-run \`alw swap now\` (you only forfeit the small reservation fee). ### Interactive @@ -238,8 +240,8 @@ If interrupted before the send: | \`alw swap now [...flags]\` | Run a swap | | \`alw swap quote --from --to --amount \` | Preview rate + receive amount | | \`alw swap post-tx \` | Relay your source tx to validators | -| \`alw swap resume-reservation [...]\` | Resume an interrupted flow | -| \`alw claim [-y]\` | Claim a SOL slash from a TimedOut swap | +| \`alw swap resume-reservation [...]\` | Resume an interrupted flow — *not yet wired in the CLI; re-run \`alw swap now\` instead* | +| \`alw claim [-y]\` | Claim a SOL slash — *not yet wired in the CLI; the TimedOut payout is automatic* | Miner-only commands (\`alw miner …\`, \`alw collateral …\`) and admin commands are documented at https://docs.all-ways.io/cli. @@ -273,11 +275,11 @@ Base URL: \`https://api.all-ways.io\` (testnet: \`https://test-api.all-ways.io\` - **\`BTC_MODE=lightweight requires BTC_PRIVATE_KEY\`** — set the WIF for auto-send, or accept the manual flow (\`alw swap post-tx \` after sending). - **Reservation expired before send** — you only forfeit the small reservation fee. Start a new swap. Live TTL via \`alw view config\`. - **BTC tx stuck unconfirmed → reservation timed out → BTC sent but no swap** — fee too low; the tx never confirmed inside the extension budget. Prevention: let the CLI auto-estimate \`--btc-fee-rate\`, or check next-block tiers. If stuck pre-confirmation, RBF up immediately — recovery is only possible while the tx is in mempool. -- **Miner timed out — where's my refund?** — slashed collateral pays your pinned identity in SOL automatically; if the transfer fails, \`alw claim \` releases it. +- **Miner timed out — where's my refund?** — the 1.1× slash pays your pinned SOL identity automatically; no action needed. (A manual \`alw claim\` fallback for the rare failed auto-payout is coming to the CLI.) ## Testnet -Testnet (Bittensor netuid 19 + Solana devnet) is the recommended place to dry-run. Configure: +Testnet (Bittensor netuid 19 + Solana devnet) mirrors mainnet with free funds — rehearse a flow here before spending real assets. Configure: alw config set env testnet alw config set wallet diff --git a/src/components/dashboard/RatesTicker.tsx b/src/components/dashboard/RatesTicker.tsx index 057efaa..fc529cc 100644 --- a/src/components/dashboard/RatesTicker.tsx +++ b/src/components/dashboard/RatesTicker.tsx @@ -4,6 +4,7 @@ import { useAllSwaps, useCurrentCrown } from '../../api'; import { ALL_DIRECTIONS } from '../../api/models/MinersDashboard'; import { FONTS } from '../../theme'; import { BlockIndicator } from '../index'; +import Ticker from '../Ticker'; import CrownDirectionSegment from '../miners/CrownDirectionSegment'; import { latestEmaRate } from './marketRate'; import { formatRate } from '../../utils/format'; @@ -38,12 +39,7 @@ const RatesTicker: React.FC = () => { }} > - + {DIRECTIONS.map((dir) => { const emaRate = latestEmaRate(swaps, dir); return ( @@ -98,7 +94,7 @@ const RatesTicker: React.FC = () => { ); })} - + ); }; diff --git a/src/components/miners/StickyNetworkHeader.tsx b/src/components/miners/StickyNetworkHeader.tsx index aaf24b1..289124a 100644 --- a/src/components/miners/StickyNetworkHeader.tsx +++ b/src/components/miners/StickyNetworkHeader.tsx @@ -1,9 +1,9 @@ import React from 'react'; import { Box, Stack, Typography } from '@mui/material'; -import { BlockIndicator } from '../index'; import { useCurrentCrown, useHaltState, useScoringState } from '../../api'; import { ALL_DIRECTIONS } from '../../api/models/MinersDashboard'; import CrownDirectionSegment from './CrownDirectionSegment'; +import Ticker from '../Ticker'; import { FONTS } from '../../theme'; // Live "time since the validator last flushed crown/rate data". The validator @@ -92,15 +92,15 @@ const StickyNetworkHeader: React.FC = () => { rowGap: { xs: 0.5, sm: 1 }, }} > - - - {segments} - + {segments} +