Localnet: trading bot swarm for frontend load testing #119
Labels
No labels
agent:fix_bugfix
agent:fix_conflicts
agent:fix_security
agent:gap_analysis
agent:implement
agent:implement
agent:implement
agent:open_issues
agent:ready
agent:research
agent:security_audit
agent:verify
architecture
backend
blocker:hybrid
blocker:launch
blocker:limit-orders
blocker:v2
block:log_only
block:security
bug
ci
contracts
correctness
deploy
dev
devops
docs
documentation
duplicate
e2e
enhancement
epic
feature
frontend
functional-completion
gas
good first issue
governance
help wanted
high-risk
hooks
hybrid
indexer
infra
infrastructure
integrators
invalid
launch-blocker
limit-orders
localnet
localterra
low priority
missing-implementation
needs-design
ops
performance
priority
high
priority
medium
product
qa
QA
question
ready
ready
research
scripts
security
security-hardening
smartcontracts
tech-debt
testing
ux
UX
v2
verification
wontfix
No milestone
No project
No assignees
1 participant
Notifications
Due date
No due date set.
Dependencies
No dependencies set.
Reference
code/cl8y-dex-terraclassic#119
Loading…
Add table
Add a link
Reference in a new issue
No description provided.
Delete branch "%!s()"
Deleting a branch is permanent. Although the deleted branch may continue to exist for a short time before it actually gets removed, it CANNOT be undone in most cases. Continue?
Motivation
Manual trading on LocalTerra is too slow and uniform to stress-test the dApp UI (swap, hybrid routes, limit orders, pool provide/withdraw, charts, indexer-backed lists, gas paths, and concurrent activity). A localnet-only scripted trading bot swarm should generate continuous, realistic on-chain activity so developers can run the frontend against a lively chain without hand-clicking every flow.
Scope
Requirements
Environment and safety
CHAIN_ID=localterra, correct LCD/RPC fromfrontend-dapp/.env.localor explicit env, localterra container healthy). No default wiring to public RPCs.TEST_MNEMONICdev wallet indocker/init-chain.sh(optional: derive bot keys from a local-only seed phrase env var for reproducibility).stopsubcommand),--dry-runor verbosity levels).Wallets and “profiles”
Timing model
Action types (must all appear across the swarm)
Across the swarm (not necessarily every profile on every tick), bots must execute on-chain flows that map to frontend features:
transactions.tstreat as hybrid), not only plain pool hops.execute_swap_operations(or equivalent) through the deployed router address from local env (VITE_ROUTER_ADDRESS), including multi-hop where sensible.provide_liquidityon selected pairs within factory/router graph.withdraw_liquidity/ burn LP on those pairs.Funding
uluna(LUNC) for fees,uusd(stand-in for USTC on LocalTerra genesis),scripts/deploy-dex-local.sh— align withVITE_CL8Y_TOKEN_ADDRESS,VITE_LUNC_C_TOKEN_ADDRESS,VITE_USTC_C_TOKEN_ADDRESS, and/or the Ember/Coral/… set as appropriate for realistic UI testing),terrad tx bank send/ mint ops.Document the funding mechanism (e.g.
terrad tx bank sendfrom genesistest1, CW20Mintfrom minter if available, or factory owner paths — mirror patterns fromscripts/e2e-provision-dev-wallet.shanddeploy-dex-local.sh).Acceptance criteria
deploy-dex-localproduces five funded bot addresses and begins broadcasting txs without manual per-wallet funding.--statsflag)..env.localcontracts, with actionable error messages.docs/local-development.md(or a shortscripts/READMEsection) lists: prerequisites, start/stop, env vars, and explicit warning that this is for local testing only.Code and files likely to be added or touched
scripts/localnet-trading-swarm.shand/orscripts/localnet-trading-swarm/(Node/TS or Python acceptable if team prefers — bash +terradin docker matches existingdeploy-dex-local.sh/e2e-provision-dev-wallet.sh).docker exec … terrad txpatterns fromscripts/deploy-dex-local.sh; optional small library for CW20 balance checks / mint (seescripts/e2e-provision-dev-wallet.shfactory enumeration).docs/local-development.mdordocs/testing.mdsubsection: “Trading swarm for UI load.”make swarm-localtarget that validates prerequisites then invokes the script.Contract message shapes should follow existing integration docs (
docs/contracts-terraclassic.md,docs/integrators.md) and the frontend services underfrontend-dapp/src/services/terraclassic/.Prerequisites and expected infra (before the script works)
make start/docker compose up -d localterraperdocs/local-development.mdanddocker-compose.yml.bash scripts/deploy-dex-local.sh(ormake deploy-local) sofrontend-dapp/.env.localcontainsVITE_FACTORY_ADDRESS,VITE_ROUTER_ADDRESS, token addresses, LCD/RPC, etc. The script should read from this file or documented env overrides (same pattern asscripts/e2e-provision-dev-wallet.sh).docs/qa-onboarding.md/scripts/qa/start-qa.shor manual indexer env; documentVITE_INDEXER_URLalignment.test1in the LocalTerra container (fromdocker/init-chain.sh) must remain funded to pay gas for provisioning txs that fund/mint for bots.Open questions (for implementer)
@terra-money/*or CosmJS) given maintenance cost.Related references in-repo
scripts/deploy-dex-local.sh— deploy, pair creation,.env.local/.env.development, LUNC_C / USTC_C addresses.scripts/e2e-provision-dev-wallet.sh— idempotent CW20 top-up pattern from factory pairs.docker/init-chain.sh—TEST_MNEMONIC, genesisuluna/uusdbalances.docs/local-development.md,docs/testing.md,frontend-dapp/e2e/README.md— local workflow expectations.assigned to @PlasticDigits
mentioned in commit
4f7749063cImplemented (merged to
main)@brouie please verify this fix when you have a moment (issue stays open).
Summary
packages/localnet-trading-swarm(@cl8y-dex/localnet-trading-swarm): fiveMnemonicWalletbots (indices 0–4), Poisson inter-arrival ~20s per bot, distinct profiles insrc/profiles.json.uluna/uusdbank sends fromtest1+ full factory CW20 enumeration (paginatedpairsquery) and idempotentMintper bot — same pattern asscripts/e2e-provision-dev-wallet.sh.execute_swap_operations(prefers 2+ hops), direct pair swap, hybrid pair swap,place_limit_order,provide_liquidity,withdraw_liquidity.src/liquidityGuards.tsdocumentsPAIR_MINIMUM_LIQUIDITY(1000) and conservative reserve / leg floors so defaultdeploy-dex-localpools stay tradeable../scripts/localnet-trading-swarm.shormake swarm-local; flags--dry-run,--stats.packages/localnet-trading-swarm/README.md,docs/local-development.md,docs/testing.md,skills/AGENTS_LOCALNET_TRADING_SWARM.md; CI joblocalnet-trading-swarmin.github/workflows/test.yml.Verification checklist
docker compose up -d localterraandbash scripts/deploy-dex-local.sh(writesfrontend-dapp/.env.local).cd packages/localnet-trading-swarm && npm ci && npm run test:run(Vitest, no chain)../scripts/localnet-trading-swarm.sh -- --dry-run— exits 0 only when LCD reportslocalterra, container running, requiredVITE_*set.--dry-run) several minutes — JSON logs should show all sixactionkinds across bots../scripts/localnet-trading-swarm.sh -- --stats, Ctrl+C —swarm_statsJSON: per-botmeanGapSecnear 20 with enough samples.VITE_TERRA_LCD_URLto a non-localterra LCD — expect immediate refusal with clear error.Commit:
4f77490onmain.QA run (infra + swarm) — 2026-04-27
What I ran
docker compose up -d(LocalTerra + Postgres).frontend-dapp/.env.localfrom a priordeploy-dex-localand factory smart-query works.cd packages/localnet-trading-swarm && npm ciSWARM_BOT_MNEMONIC="abandon … about" SWARM_FUNDING_TX_SLEEP_MS=1200 SWARM_MINT_SLEEP_MS=80 timeout 420 npm run start -- --stats(~7 min wall clock; SIGTERM at timeout).Outcome: good for local load-testing
main(1a862cc), genesistest1can fund all five bots: defaultuluna/uusdtop-ups were lowered to fit typical LocalTerra balances, andSWARM_FUNDING_TX_SLEEP_MS(default 2000 ms) pauses between eachterrad txfromtest1so account sequence does not race under--broadcast-mode sync.txHash):hybrid_swap,router_multihop,pair_swap,limit_order,add_liquidity— all present in JSON logs within the window. ~40 successful txs in the monitored period (greptxHashhex lines in local log).remove_liquidity: Often"note":"no_lp_balance"— expected until bots accumulate LP fromadd_liquidity; not a blocker for the swarm’s purpose.router_multihopfailures:Max spread assertion: actual spread (1) exceeds max allowed (0.5). Addressed onmainby settingmax_spread: "1"for router/pair/hybrid swap msgs inactions.ts(localnet-only load script).--statson SIGTERM): With only ~5–10 samples per bot in this short window, per-botmeanGapSecwas ~30–49s vs 20s target — variance is normal at lown; the design is still exponential with mean 20s (plus jitter). Longer runs should converge.Ops notes
test1(uluna/uusdinsufficient funds) — fixed via saner defaults + env docs.terrad tx bank send— fixed via inter-tx sleep for alltest1funding txs.Commits
1a862cc— funding defaults,SWARM_FUNDING_TX_SLEEP_MS,max_spread1 for swaps.@brouie — swarm verified end-to-end on live LocalTerra with deploy state; remaining noise is mostly LP-withdraw skips until LP builds up.
mentioned in issue #252
mentioned in issue #372
mentioned in merge request !886
mentioned in merge request !894
mentioned in issue #597
marked as related to #597
mentioned in issue #621
marked as related to #621