Claim all parked UI on LimitOrderMyPlacementsPanel (batch claim #246 follow-up) #253
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#253
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?
Summary
Add a Claim all parked control to
LimitOrderMyPlacementsPanelso makers with multiplelifecycle_status: parked_expiredrows can recover escrow in one on-chain transaction viaClaimExpiredLimitOrders, mirroring the Cancel all mine batch UX shipped in GitLab #246.Current codebase
frontend-dapp/src/components/trade/LimitOrderMyPlacementsPanel.tsx— used on/limitsand/trade(compact variant). Partitions indexer rows viapartitionLimitPlacementsByLifecycleintoactivevsparkedExpired.useMutation→claimExpiredLimitOrder→ pairExecuteMsg::ClaimExpiredLimitOrder { order_id }. N parked rows ⇒ N wallet prompts / N txs at ~450k gas each.ClaimExpiredLimitOrders { order_ids }insmartcontracts/contracts/pair/src/limit_batch_withdraw.rsand frontend serviceclaimExpiredLimitOrders. Gas model reusesgasLimitForLimitOrderCancelBatch(n)interraGas.ts(400k + 80k×N). Indexer parses columnar batch claim attrs inindexer/src/indexer/parser.rs.OrderBookPanelCancel all mine uses shareduseLimitOrderCancelMutation(number | number[]) → batch whenorderIds.length > 1.limitClaimUserMessage.tsmapsNoExpiredLimitClaimfor single claims viahumanizeTerraTxError.skills/AGENTS_FRONTEND_LIMIT_PARKED_EXPIRED.md· product invariants indocs/limit-orders.md§ parked-expired recovery · contract L11 indocs/contracts-security-audit.md.Why this is needed
Ladder traders and market makers can accumulate many parked-expired rows after expiry parks during taker walks. Today they must click Claim refund per row — poor UX, high cumulative gas (~4.5M for 10 claims vs ~1.2M batch), and unnecessary wallet friction. On-chain + indexer support exists from #246; only the placements panel UI + shared mutation hook are missing.
Constraints / guardrails
claimExpiredLimitOrders, do not add new contract messages.max_batch_rungs/MAX_LIMIT_BATCH_RUNGS_HARD_CAP). If indexed parked count exceeds cap, UI must chunk (multiple batch txs) or disable Claim all with clear copy — document chosen behavior in PR.parkedExpiredrows for the connected wallet on this pair.isPairPaused(same as per-row claim).parked_expiredin UI but alreadyrefundedon-chain — optional preflight via stale-row filter or rely on revert + humanized error (extendlimitClaimUserMessage.tsfor batch failures if needed).claimExpiredLimitOrderfor gas parity with cancel-all pattern).limitPlacements, book previews,tokenBalance.Relevant files
frontend-dapp/src/components/trade/LimitOrderMyPlacementsPanel.tsxfrontend-dapp/src/hooks/useLimitExpiredClaimMutation.ts(mirroruseLimitOrderCancelMutation)frontend-dapp/src/services/terraclassic/pair.ts(claimExpiredLimitOrder,claimExpiredLimitOrders)frontend-dapp/src/services/terraclassic/terraGas.ts(gasLimitForLimitOrderCancelBatch,getGasLimitForTx)frontend-dapp/src/utils/limitPlacementLifecycle.ts,frontend-dapp/src/utils/limitClaimUserMessage.tsfrontend-dapp/src/pages/LimitOrdersPage.tsx,frontend-dapp/src/components/trade/TradeOrderTicket.tsx(mount panel only)docs/limit-orders.md,docs/frontend.md,skills/AGENTS_FRONTEND_LIMIT_PARKED_EXPIRED.mdfrontend-dapp/e2e/limit-orders-tx.spec.tsRecommended solution direction
useLimitExpiredClaimMutation(pairAddr, walletAddress)acceptingnumber | number[]: length 1 →claimExpiredLimitOrder; length > 1 →claimExpiredLimitOrders. Same invalidation + sounds as today's inline mutation.parkedExpired.length > 1:parkedExpired.length > 30, either batch in chunks of 30 with sequential txs (confirm once per chunk) or show inline notice + cap button at 30 — prefer chunked batch with progress copy over silent omission.gasLimitForLimitOrderCancelBatch(N)+estimateFeeUlunaAmountForGasLimitin confirm dialog (nice-to-have, not blocking).docs/limit-orders.mdparked-expired bullet +skills/AGENTS_FRONTEND_LIMIT_PARKED_EXPIRED.mdwith Claim all behavior and crosslink #246 / this issue.Acceptance criteria
parkedExpiredrows for connected wallet on current pair (both/limitsand/tradecompact panel).Test plan — functional paths
parkedExpired.length >= 2; disabled when paused / disconnected.refundedlifecycle.Test plan — attack / abuse vectors
parkedExpiredids for connected wallet — cannot inject foreign ids via devtools without revert (on-chain owner check).Paused.Verification criteria
npm test/ Vitest for new hook + panel tests pass.npm run build(frontend) clean.claim_expired_limit_orderlifecycle updates from one batch tx (existing parser)./tradeand/limitswith wallet connected.Related
mentioned in commit
b5d3664f45Implementation complete (merged to
main@b5d3664)Added Claim all parked (N) to
LimitOrderMyPlacementsPanelon/limitsand/trade(compact), mirroring the Cancel all mine batch UX from #246.What changed
useLimitExpiredClaimMutation— shared hook: 1 id →claimExpiredLimitOrder; 2+ ids →claimExpiredLimitOrders(same invalidation + sounds as per-row claim).limitExpiredClaimBatch— dedupe/sort ids, chunk at 30 (MAX_LIMIT_BATCH_RUNGS_HARD_CAP), confirm copy per chunk.parked_expiredrows; hidden for single row; disabled when wallet disconnected or pair paused (L6).docs/limit-orders.mdinvariants (#253),docs/frontend.mdgas table,skills/AGENTS_FRONTEND_LIMIT_PARKED_EXPIRED.mdQA checklist.Verification checklist (QA agent team — please sign off)
/limits+/tradecompact: Claim all parked (N) visible when N ≥ 2 parked rows for connected wallet; absent when N = 1.Unavailable (pair paused)).limitClaimUserMessagepath.useLimitExpiredClaimMutation.test.tsx,limitExpiredClaimBatch.test.ts,LimitOrderMyPlacementsPanel.test.tsx— all pass locally.Automated tests run
npm test -- --runon the three Vitest files above — 12/12 passed.Follow-ups (optional)
Requesting verification from @qa agent team on LocalTerra with 3+ parked-expired ladder rows (gas compare: 1 batch vs N single claims).
Issue left open pending QA sign-off.
mentioned in issue #259
marked as related to #259
Heads up on #253 — the Claim-all panel test is red on main.
LimitOrderMyPlacementsPanel.test.tsx asserts the exact Claim-all confirm string, but #259 (
2e6f2cf) added the gas-estimate suffix to that copy ("... Est. ~X LUNC gas (saves ~Y LUNC vs N separate claims).") and didn't update this panel test, so it has failed since that merge:expected '...in one transaction?'
received '...in one transaction? Est. ~15.86 LUNC gas (saves ~9.63 LUNC vs 2 separate claims).'
Feature's fine — just a stale assertion. Fix: match the stable prefix via stringContaining; the exact gas copy is already covered by regex in limitExpiredClaimBatch.test.ts, so no coverage loss. The three #253 vitest files go 13/13 with that. MR incoming.
Still to come: browser Claim-all sign-off with a few seeded parked-expired rows (one batch tx vs N single claims).
mentioned in merge request !736
Live Claim-all sign-off on LocalTerra (dev wallet, /limits) — the batch path works end to end.
Setup: 2 parked-expired bids for the maker (order 128 @ 2, 129 @ 1.99; ExpiredLimitRefund remaining 9996 each after the 4 bps maker fee).
Walkthrough:
On-chain after:
Acceptance criteria:
Unit: the three #253 vitest files pass 13/13 after the stale-assertion fix in LimitOrderMyPlacementsPanel.test.tsx (MR !736 — the test had gone red on main when #259 added the gas-estimate suffix to the confirm copy).
Good to close from my side once !736 lands. @PlasticDigits
mentioned in issue #246
mentioned in commit
487f46569amentioned in issue #419