From an X mention to a trade
Prove your account, grant a spending limit, then inspect the receipt.
Trade from X connects a supported mention to a bounded instruction for your Trading Balance. Signing into X identifies you. A separate wallet grant authorizes spending. You need both.
Explore each part and its connections. Expand to use more of your screen.
Follow an arrow to explore a connected part.
OAuth 1.0a consent
What this part does
The server exchanges a temporary request token after the same-browser callback and learns the signed-in account id and handle. User access tokens are not kept for posting.
Outgoing connections
- From Sign in with Xsign linkAction or record
The server exchanges a temporary request token after the same-browser callback and learns the signed-in account id and handle. User access tokens are not kept for posting.
Read the map as text
- Sign in with X Link your wallet: sign link.
- A supported mention Mention transport: new mention.
- Mention transport Link + grammar + grant: parse request.
- Link your wallet Link + grammar + grant: bound author.
- Authorize the X executor Link + grammar + grant: live grant.
- Link + grammar + grant Executor signs: accepted call.
- Executor signs Real market position: bounded trade.
- Real market position Inspect your receipt: store result.
The two permissions
Link your account. The site signs you in through X's OAuth 1.0a flow. It retains your account id and handle in a signed session, then asks your wallet to sign the link. Your X sign-in alone cannot connect someone else's wallet.
Authorize the executor. Your wallet grants the configured X executor a budget, expiry and caps in EventVault. That executor can act only within the contract permission. Payouts stay with your wallet's vault account.
The login flow does not retain your X access token to post as you. Public relay replies use the operator account's separately configured session.
One supported instruction
@handle btc up 5 15mReplace @handle with the account shown in the app. The parser expects one asset, one side, one positive stake and one Window length.
| Field | Accepted primary values |
|---|---|
| Asset | btc, eth |
| Side | up, down |
| Stake | A positive amount, such as 5 or $10 |
| Window | 1m, 5m, 15m, 1h, 4h |
Common word aliases exist, but duplicate or conflicting fields are refused. Numeric extras such as 3x do not create leverage. The executor chooses the soonest still-enterable Window matching the requested asset and length.
How the relay handles it
The current relay reads mentions through rettiwt-api, using the operator account's session. It checks the linked author, parses the instruction, reads the current grant, gets a fresh quote and uses the shared vault transaction lane.
Each new mention id is claimed once in Postgres before execution. When posting is enabled, the future reply is queued in the same database transaction. An already-claimed mention is not executed again. The first-ever poll establishes a starting cursor and leaves older posts alone.
Later polls drain the mention pages after that cursor, remove duplicate ids and process them oldest first. A later-page failure or repeated page cursor keeps the saved cursor unchanged. Each processed mention's receipt is stored before the polling cursor moves past it.
The transport first resolves the authenticated account's stable id and checks its handle against configuration. The relay excludes that account's own replies and any saved delivery reply id before claiming a command. Other users' reply commands remain eligible; an authorized top-level command from the bot account remains eligible too. This prevents a receipt mentioning its sender from becoming another instruction.
A reply describes the receipt
Execution and reply delivery run in separate loops. The reply loop reads completed receipts; it has no signer or trade submitter. It formats validated receipt facts into short text and, when enabled, a branded image. If image preparation or upload fails, it can send the same facts as text.
Requested stake and actual booked cost are different fields. Order filled describes a booked position, not a winning market result. Status needs checking preserves uncertainty, including a failure to read or store the result after a transaction was sent. The reply links to the transaction when a valid hash is available, or to the app otherwise.
The image is rendered separately for each receipt. It uses the sender handle saved when the mention was claimed, falling back to its saved numeric X account id. A later handle change does not relabel the old receipt. Status, side, Window, requested amount, measured spend and full validated transaction hash come from that receipt. The text keeps a full clickable explorer URL; the printed hash in a picture is not a substitute for that link.
Before making the X post, delivery saves the exact text and optional media id. An acknowledged reply id marks delivery as sent. A timeout or a failure to save that acknowledgement leaves delivery uncertain; it does not trigger an automatic repost or a second trade. Operators must inspect the original mention before considering a manual recovery.
Startup also suppresses pending or uncertain recursive reply deliveries. Database acquisition and the final pre-post check exclude known receipt ids again. Existing sent acknowledgements remain available for audit. Deployment and live checks remain distinct from source review. The release rehearsal on 7 September verified suppression before posting resumed, then observed one intentional refusal with no transaction or recursive reply. That dated test does not replace the current service checks.
X_POSTING_ENABLED controls replies independently of trade execution. X_REPLY_IMAGES_ENABLED controls the optional image. Existing historical receipts are not backfilled into the reply queue, and enabling replies does not replay instructions processed while posting was off. A missing reply does not establish that no trade happened; check the receipt page.
Recovery after an interrupted execution
Before submitting an order, the relay persists the linked wallet, market, side, grant, executor, token decimals, chain block and expected executor nonce. Its transaction journal stores the intent before broadcast and the hash as soon as broadcast returns. A failed durable checkpoint stops submission.
Recovery reads chain evidence without signing or replaying the instruction. A known hash must match the executor, EventVault and exact execution event. If the hash was lost during broadcast, recovery searches bounded block pages and checks the recorded nonce and execution facts. Missing or conflicting evidence keeps the receipt uncertain. A submitted or uncertain broadcast with no hash holds later submissions by that X executor so another order cannot reuse its reserved nonce.
Older receipts without enough recovery context still need inspection. A bounded scan that finds nothing is not proof that no transaction happened. Recovery can establish an execution result independently of X reply delivery; it never automatically repeats an ambiguous public post.
Read the separate service checks
The page reports Mentions, Orders and Replies separately. A successful mention poll does not prove an order filled or an image reached X. Old checks become Status out of date, and missing checks remain Not verified. The image acknowledgement time is shown only after X returned a reply id for a post containing media.
Known bot receipt replies stay in the audit store but are excluded from wallet instruction lists. Intentionally suppressed recursive deliveries do not count as actionable delivery failures; unrelated failed or uncertain deliveries still require inspection.
Current operational limits
Mention catch-up is bounded to 50 pages of 20 per poll. A backlog exceeding that bound leaves the cursor unchanged and needs operator attention. Recovery scans are also bounded; unresolved evidence stays visible rather than being treated as a failed trade.
The current transport is still rettiwt-api 7.1.3 with the operator account session; this update does not migrate it to the official X API. Its media interface has no alt-text parameter, so all essential receipt facts stay in the adjacent reply text. These implementation limits are separate from the account link and wallet grant.
Unlinking removes the account route. Revoking the Executor grant is the on-chain way to stop its spending authority. Neither action withdraws your funds automatically.
Follow Trade from X for the screen-by-screen setup.
Source notes
This guide follows the application code reviewed on 2026-09-07. Links point to that reviewed commit and require repository access. GitHub may show 404 if you are signed out or do not have access.
- web/src/features/x/oauth.server.ts
- web/src/features/x/session.server.ts
- web/src/features/x/gate.server.ts
- web/src/app/api/x/bind/route.ts
- services/ops/src/actors/x-relay/index.ts
- services/ops/src/actors/x-relay/execute.ts
- services/ops/src/actors/x-relay/rettiwt.ts
- services/ops/src/actors/x-relay/reply-format.ts
- services/ops/src/actors/x-relay/reply-delivery.ts
- services/ops/src/actors/x-relay/reply-card.ts
- packages/db/src/x-reply-delivery.ts
- packages/core/src/x/parse.ts
- services/ops/src/actors/x-relay/poll-cycle.ts
- services/ops/src/actors/x-relay/transport.ts
- services/ops/src/actors/x-relay/execution-journal.ts
- services/ops/src/actors/x-relay/execution-recovery.ts
- packages/markets/src/vault/recovery.ts
- packages/db/src/x.ts
- packages/db/src/x-health.ts
- web/src/features/x/XRelayStatus.tsx