Documentation Index
Fetch the complete documentation index at: https://mintlify.com/tripolskypetr/wallet-manager/llms.txt
Use this file to discover all available pages before exploring further.
The Core Problem: Locked Funds on Binance Spot
On Binance spot, every resting order locks the quantity it requires:- A SELL order locks the base coin (e.g. SOL in SOLUSDT) equal to the sell quantity.
- A BUY order locks USDT equal to
quantity × price.
onOrder in the account balance — they are not available as free. If you attempt to sell a coin while a SELL or OCO order on that symbol is still live, one of two things happens:
- The request fails immediately with an insufficient balance error.
- Worse: it silently succeeds but only trades the unlocked remainder — leaving your TP/SL/stale entry orders holding the rest.
The
commitCancel function and the onOrderCloseCommit broker-adapter
example both follow the same safe three-step sequence to guarantee a clean
exit every time.The Correct Sequence
Cancel ALL open orders on the symbol
Fetch
openOrders(symbol) and cancel each one individually. Individual
cancel failures are tolerated — the sweep retries up to 10 rounds. This
handles race conditions where an order fills between the fetch and the
cancel.The loop exits as soon as one full sweep completes with no errors, or
after 10 rounds. If the last error is non-null after all rounds, it is
re-thrown so the caller (e.g. the broker adapter’s close hook) can retry
the entire close operation.Verify the order book is clean
Even after every cancel call succeeds, Binance may still briefly show the
orders as open while the cancellation propagates. A second polling loop
calls
openOrders(symbol) up to 10 times (with a 1-second delay
between each) and waits until length === 0.Only when the book is confirmed empty does execution proceed to the sell
step.Sell the free coin balance
With no resting orders, the full coin balance is
free. A limit SELL is
placed at price × 0.999 (slightly below market to fill faster). The
order is then polled every 10 seconds for up to 10 iterations (~100
seconds total). If it does not fill, the limit order is cancelled and the
remainder is market-sold — guaranteeing a complete cash exit.The Poll-with-Timeout-and-Market-Fallback Pattern
All three commit functions (commitBuy, commitSell, commitCancel) share
the same fill-polling pattern to ensure no order is ever left resting on
the book:
commit_cancel.function.ts:
How commitCancel Implements All Three Steps
COMMIT_CANCEL_FN in src/function/commit_cancel.function.ts is the
reference implementation. It encodes all three steps end-to-end:
Why commitBuy Returns 0 When Orders Exist
COMMIT_BUY_FN checks for open orders before placing a buy:
0 (instead of throwing) is a double-entry guard. If a
previous buy’s TP/SL OCO orders are still live, this call is a no-op.
The caller can treat a 0 return as “position already open, no action
taken” without needing exception-handling logic.
WalletPublicService.commitBuy does not pass the averagePrice from the
caller — it fetches it internally via fetchPrice. This ensures the limit
price is always based on the current market, not a stale value.The minQty Dust Guard
Before placing any sell, commitCancel computes the sell quantity net of
fees and the exchange’s minimum lot size:
minQty after subtracting
the maker commission, the function returns 0 immediately without placing
any order. This prevents rejected orders due to lot-size violations when only
a tiny residual (“dust”) amount remains after a partial fill or a previous
partial exit.