Stitch is the Textile operator bot for filler-network market making and
settlement closing. It runs as a single binary named stitch.
Stitch does two jobs for each configured pool by default:
- Market making: keep live buy and sell quotes for a configured soft-asset/stablecoin pair.
- Settlement closing: close eligible settlement auction positions on-chain when the configured margin rules are met.
- Quick Start
- Cloud Deploy
- Manual Install
- How It Works
- Requirements
- Configuration
- Running As A Service
- Updating
- Stopping and Uninstalling
- Security Notes
The recommended way to install and run Stitch is with an AI coding agent: it collects the operator settings, writes the config, runs a dry run, and starts live only after you confirm.
Install the stitch skill once, then just talk to your agent. The skill installs
Stitch when it's missing and runs it after — start, stop, logs, parameter
changes, upgrades. Ask your agent to install it:
-
Claude Code — paste:
curl -fsSL https://raw.githubusercontent.com/textile-protocol/textile-stitch/main/.claude/skills/stitch/SKILL.md --create-dirs -o ~/.claude/skills/stitch/SKILL.md— run that as-is (don't WebFetch the URL). After it succeeds, tell me to run/stitch.Then run
/stitch. -
Codex — paste:
Install the stitch skill from https://github.com/textile-protocol/textile-stitch/tree/main/.codex/skills/stitch After it succeeds, tell me to restart Codex and ask:
Use the stitch skill to install and run Stitch.Codex's skill-installer drops it under
~/.codex/skills. Restart Codex, then ask:Use the stitch skill to install and run Stitch.
With the repo checked out, Claude Code finds the skill automatically.
No skill support? Paste this prompt into Claude, GPT, Gemini, or any agent with terminal access to the machine where Stitch should run:
Help me install and configure Textile Stitch.
Read the full install prompt and follow it in full:
https://raw.githubusercontent.com/textile-protocol/textile-stitch/main/AI_INSTALL_PROMPT.md
If you can't fetch that URL, read AI_INSTALL_PROMPT.md directly from the
textile-protocol/textile-stitch repo (main branch) instead. Don't guess from
other sources.
Use recommended defaults where safe, ask for values with no safe default, protect
STITCH_PRIVATE_KEY, run a dry run first, and do not start live operation until I
confirm.
For the full copyable prompt, open AI_INSTALL_PROMPT.md. For configuration reference, tuning, and troubleshooting, see ADVANCED.md.
Stitch can run as an operator-owned cloud bot in your own AWS account. The AWS
self-hosting stack in deploy/aws creates a self-contained
ECS Fargate environment you own and control: one service, one secret, one wallet,
no public ingress. The bot reaches Textile the same way any external operator
does, over the public RPC/API/indexer/subgraph URLs in your stitch.toml.
The button opens CloudFormation in your own AWS account with the Stitch stack
prefilled. Sign in, pick your region (it defaults to us-east-1), review the
parameters, and create the stack. It comes up stopped by default. Then follow
deploy/aws to load the wallet secret, run Permit2
approvals, and set the service desired count to 1 when you are ready to run
live.
Install the latest release:
curl --proto '=https' --tlsv1.2 -LsSf \
https://github.com/textile-protocol/textile-stitch/releases/latest/download/stitch-installer.sh | shMake sure the install directory is on your PATH, then check the binary:
stitch --versionCreate a config file. On macOS and foreground Linux installs, keep operator
support files in ~/Stitch so they are easy to find.
mkdir -p ~/Stitch
chmod 700 ~/Stitch
curl -L -o ~/Stitch/stitch.toml \
https://raw.githubusercontent.com/textile-protocol/textile-stitch/main/stitch.example.toml
chmod 600 ~/Stitch/stitch.tomlStore the operator wallet key in a separate key file. Do not put the private key
in stitch.toml.
printf 'Enter STITCH_PRIVATE_KEY: '
stty -echo
IFS= read -r key
stty echo
printf '\n'
umask 077
printf '%s\n' "$key" > ~/Stitch/stitch.key
unset key
printf 'STITCH_PRIVATE_KEY_FILE=%s\n' "$HOME/Stitch/stitch.key" > ~/Stitch/stitch.env
chmod 600 ~/Stitch/stitch.key ~/Stitch/stitch.env
set -a
. ~/Stitch/stitch.env
set +aApprove Permit2 to pull the tokens Stitch quotes. The operator wallet needs a
one-time approval for each input token (the debt token on the buy side, the
collateral token on the sell side). Without it, orders post but silently fail
to fill, and a live start refuses to run. Preview what's needed, then approve:
stitch approve --config ~/Stitch/stitch.toml --dry-run
stitch approve --config ~/Stitch/stitch.tomlMaximum is the standard market-maker choice: approve once and never re-approve. You're approving the canonical Permit2 contract, and the reactor can only pull against orders you actually signed.
If you'd rather cap the allowance and your config uses fixed numeric liquidity,
use --exact to approve only that configured amount:
stitch approve --config ~/Stitch/stitch.toml --exactBe aware of the trade-off: an exact allowance is consumed as orders fill, so once
it's used up Stitch keeps posting orders that silently fail to fill until you
re-approve, and you must re-run stitch approve every time you raise your
configured liquidity. Each approval is one gas-paying transaction per token, and
the command is idempotent (it skips tokens already approved).
Run once in dry-run mode before posting live orders:
stitch --config ~/Stitch/stitch.toml --dry-runRun live:
stitch --config ~/Stitch/stitch.tomlStitch reads stitch.toml, polls your configured price feed, signs UniswapX
limit orders, and posts those signed orders to the Textile indexer. The wallet
private key is read from STITCH_PRIVATE_KEY_FILE, or from STITCH_PRIVATE_KEY
for compatibility. If both are set, STITCH_PRIVATE_KEY_FILE takes precedence.
For market making, each configured pool can have:
- a buy side, where Stitch spends the stable/debt asset to buy the soft/collateral asset below the feed price;
- a sell side, where Stitch spends the soft/collateral asset to sell above the feed price.
For settlement closing, Stitch can also discover open positions through a
subgraph and submit fill() transactions when a close is profitable under your
configured margin and auction parameters.
Stitch reads the config at startup. After changing stitch.toml, restart the
process.
You need:
- an operator wallet private key;
- RPC access for the target chain;
- Textile indexer URL;
- a price feed endpoint returning fresh
{ "price": ..., "timestamp": ... }; - the Permit2 and reactor addresses for the target chain;
- funded token balances for the sides you enable;
- Permit2 approvals for the tokens Stitch will spend (set up with
stitch approve— see Manual Install); - a small native balance for gas (approvals and, for closing,
fill()txs); - a subgraph URL for settlement closing.
Start from stitch.example.toml. A minimal default pool configuration looks like this:
chain_id = 8453
rpc_url = "https://mainnet.base.org"
indexer_url = "https://api.textilecredit.com"
subgraph_url = "https://api.textilecredit.com/subgraph?chainId=8453"
permit2 = "0x000000000022D473030F116dDEE9F6B43aC78BA3"
reactor = "0x0000000000000000000000000000000000000000"
tick_interval_secs = 5
[feed]
url = "https://your-feed.example/cngn-usdc"
staleness_secs = 30
[[pools]]
collateral = "0xcngn0000000000000000000000000000000000c0"
collateral_decimals = 6
debt = "0xusdc0000000000000000000000000000000000d7"
debt_decimals = 6
buy_offset_bps = 10
buy_total_liquidity_debt = "max"
buy_min_slice_debt = "10000000"
buy_max_orders = 40
sell_offset_bps = 10
sell_total_liquidity_collateral = "max"
sell_min_slice_debt = "10000000"
sell_max_orders = 40
ttl_secs = 120
refresh_threshold_bps = 10
closer_pool = "0x0000000000000000000000000000000000000000"
floor_ray = "500000000000000000000000"
buffer_ray = "20000000000000000000000000"
window_secs = 432000
min_margin_collateral = "0"
max_positions_per_fill = 10
discover_first = 200
skip_past_window = trueAmounts are atomic token units (e.g. 50,000 of a 6-decimal token is
50000000000). The default *_total_liquidity_* value is "max", which quotes
all currently funded wallet inventory for that side. Use a fixed numeric amount
instead when you want a hard cap below the wallet balance. The total liquidity
fields are targets; if *_max_orders is too low to express the full target with the
configured minimum slice, Stitch leaves the remainder unquoted instead of
posting an oversized live book. Configured liquidity is also a ceiling: on each
quote tick, Stitch caps the posted bid or ask size to the operator wallet's
current token balance and Permit2 allowance for that side, so normal fills or
inventory transfers reduce the next ladder instead of causing the indexer to
reject an unfunded batch.
Requotes reuse the same replacement slots, so Stitch can refresh funded depth
without double-counting the ladder it is replacing.
When several corridors spend the same token (for example two pools that both
buy with USDC) and more than one of them is set to "max", Stitch splits the
token's funded balance into even target shares on every tick, so an existing
corridor can't keep the whole wallet after another max side is added. For
the price-feed orientation, spread options, ladder sizing, and
settlement-closing fields, see the
configuration reference in ADVANCED.md.
On Linux, run Stitch under systemd so it restarts after crashes and reboots.
System-wide service files use /etc/stitch-bot, which keeps service-owned
config separate from foreground operator files in ~/Stitch.
Create local config, key, and environment files:
curl -L -o stitch.toml \
https://raw.githubusercontent.com/textile-protocol/textile-stitch/main/stitch.example.toml
printf 'Enter STITCH_PRIVATE_KEY: '
stty -echo
IFS= read -r key
stty echo
printf '\n'
umask 077
printf '%s\n' "$key" > stitch.key
unset key
cat > stitch.env <<'EOF'
RUST_LOG=info
EOF
curl -L -o stitch.service \
https://raw.githubusercontent.com/textile-protocol/textile-stitch/main/deploy/stitch.serviceInstall files:
sudo install -m 0755 "$(command -v stitch)" /usr/local/bin/stitch
sudo mkdir -p /etc/stitch-bot
sudo install -m 0644 stitch.toml /etc/stitch-bot/stitch.toml
sudo install -m 0600 stitch.key /etc/stitch-bot/stitch.key
sudo install -m 0644 stitch.env /etc/stitch-bot/stitch.env
sudo install -m 0644 stitch.service /etc/systemd/system/stitch.service
sudo systemctl daemon-reload
sudo systemctl enable --now stitchThe service template uses LoadCredential so the private key is injected as a
systemd credential instead of stored in the process environment. Operators who
manage encrypted systemd credentials can replace it with
LoadCredentialEncrypted.
Approve Permit2 before the first live start (the service won't run until the input tokens are approved):
sudo STITCH_PRIVATE_KEY_FILE=/etc/stitch-bot/stitch.key \
stitch approve --config /etc/stitch-bot/stitch.tomlView logs:
journalctl -u stitch -fRestart after config changes:
sudo systemctl restart stitchIf Stitch was installed from the release installer, update the binary in place:
stitch --updateThen restart the service:
sudo systemctl restart stitchYou can also download a new binary or installer from the latest GitHub Release.
To stop a foreground run, press Ctrl-C. Stitch shuts down cleanly on Ctrl-C
or SIGTERM, finishing the current tick first, so it never leaves a half-sent
fill or a dangling order.
To stop a background service or uninstall completely, expand your platform:
Linux (systemd)
# stop
sudo systemctl stop stitch
sudo systemctl disable --now stitch # also stop it restarting on boot
# uninstall
sudo rm -f /etc/systemd/system/stitch.service
sudo systemctl daemon-reload
sudo rm -f "$(command -v stitch)" # the installed binary
sudo rm -rf /etc/stitch-bot # config + envmacOS (launchd)
Use the label you installed the LaunchAgent under (the file in
~/Library/LaunchAgents/).
# stop
launchctl bootout gui/$(id -u)/<label> # older macOS: launchctl unload ~/Library/LaunchAgents/<label>.plist
# uninstall
rm -f ~/Library/LaunchAgents/<label>.plist
rm -f "$(command -v stitch)" # the installed binary
rm -rf ~/Stitch # config + envWindows (PowerShell)
Use the task or service name you created at install time.
# stop — Task Scheduler:
schtasks /End /TN "Stitch"
# or, if you installed it as a service with NSSM:
nssm stop Stitch
# uninstall — remove the task or service first:
schtasks /Delete /TN "Stitch" /F # Task Scheduler
nssm remove Stitch confirm # or the NSSM service
Remove-Item -Force (Get-Command stitch).Source # the installed binary
Remove-Item -Recurse -Force "$env:USERPROFILE\Stitch" # config + envRemoving the binary does not revoke on-chain Permit2 approvals. If you approved a maximum allowance, it stays on the operator wallet after uninstall. To fully wind down, revoke each token's Permit2 approval (set its allowance to 0) or retire the dedicated operator wallet.
- Keep
STITCH_PRIVATE_KEYout ofstitch.toml, shell history, and process managers that expose command lines. PreferSTITCH_PRIVATE_KEY_FILEpointing at a 600-permission key file. - Use a dedicated operator wallet.
- Fund only the inventory you intend Stitch to use.
- Review token balances, Permit2 approvals, spreads, and order sizes before
running live. Set approvals with
stitch approve; prefer a maximum allowance unless you have a specific reason to cap it. - Use
--dry-runafter every config change that affects pricing or sizing.
Stitch is free, open-source software licensed under the GNU Affero General
Public License v3.0 or later (AGPL-3.0-or-later). Copyright (c) 2026
Textile, Inc.
Copyleft: if you modify Stitch and distribute it — or run a modified version as
a network service — you must release your changes under the same license. See
LICENSE for the full text.