Add a Cash out action to a live position row: quote, show, confirm, execute, with the full status machine and error handling.
Cash-out is a two-step flow on a live position row: fetch a quoter-signed buy-back price, show it to the user, then execute it on-chain from the taker’s wallet. useCashOut owns the state machine; you render it.
The signed quote expires 120 seconds after issuance (quote.deadline, unix seconds). Disable the confirm button when Date.now() / 1000 > Number(quote.deadline) and offer a re-quote instead; the contract rejects expired signatures anyway, this just saves the user a failed transaction.
Two distinct failure surfaces, both landing in status === "error" with a message in error:
Quote errors (relayer): "not your parlay" (403), "already settled" (409), "unknown parlay" (404), "could not fetch HL prices" (502). These need a slip-level message, not a retry loop.
Execution errors (wallet or chain): user rejection, an expired deadline, or a revert. The hook truncates the reason to the first line, 140 chars, so it is safe to render directly.
After any error, reset() returns to idle (it also clears quote and error).
execute calls ParlayEscrow.cashOut(parlayId, cashValue, quoterNonce, deadline, sig) from the user’s wallet (this transaction is the taker’s, not the relayer’s, so the user pays gas here) and waits for the receipt. The escrow pays cashValue to the taker, marks the parlay settled, and releases the remaining escrowed funds to the vault. Details in Cash-out concepts.