Skip to main content
A Hinkal private swap whose payout fails is not refunded on its own. The funds wait at Hinkal, on the chain the swap started from: in a temporary wallet when the bridge failed, or in Hinkal’s pool when the payout never ran. This endpoint gets them back. Only the wallet that paid for the swap can sign the recovery, and the funds only ever go back to that wallet, never to an address from the request. Use it when /status reports the swap failed with venueStatus ending (needs recovery), or when its deposit has confirmed but /status still answers pending 25 minutes after the order was placed (a payout that never ran). RAVN can recover a swap while it holds its record, 7 days after the order was placed.
A recovery is public. It is an ordinary on-chain payment back to the paying wallet, which can link that wallet to the one it was paying: the link the private swap was hiding. Tell your user before they sign.

Request

string
required
The statusRef of the Hinkal swap’s TRANSACTION from /execute (Hinkal’s order id). Alone, it always answers sign step 1, the same answer for any order id, so it tells no one but the payer anything about the swap.
string
After a sign answer: its authorization (hk_ and 32 hex characters), with the paying wallet’s signature over its sign. After done: its authorization alone, with no signature, to look for more.
string
With a sign answer’s authorization: the paying wallet’s signature over its sign, 0x hex. Never with the authorization from done.
No API key required (see Authentication): up to 30 calls an hour per IP, or 300 per key.

The flow

1

Ask with the statusRef alone

{ statusRef } answers sign step 1: a personal_sign message that opens a read-only Hinkal session for the paying wallet. Check it as on /execute: exactly Authorize Hinkal session, Session ID: …, Public Key: …, and never one that adds This signature can also be used to submit transactions.
2

Prove the wallet paid

{ statusRef, authorization, signature } with that signature. Hinkal opens the session only for the swap’s paying wallet, so a signature from any other wallet is refused (400). It answers sign step 2, a recovery to sign with eth_signTypedData_v4, or nothing.
3

Sign the recovery

Check the typed data before your user signs it: domain { name: "Hinkal Enclave", chainId } on the swap’s source chain, primaryType RecoverStuckBridgeBalance or WithdrawStuckUtxos, message.chainId equal to the domain’s, one tokenAddress, and recipient the paying wallet. Send { statusRef, authorization, signature } again: the funds are sent, and the answer is done with what was recovered.
4

Look again

A swap can leave more than one token behind. Send { statusRef, authorization } with the authorization from done and no signature: it looks again under the wallet already proven, with no new session, and answers step 2 again or nothing. Repeat until nothing.
Each authorization is single-use, tied to this statusRef, and lasts 10 minutes (a sign answer’s expiresAt). Sign and call again before then.

Response

string
sign: a step to sign (step 1, the session, with sign.message; step 2, a recovery, with sign.typedData). done: a recovery was sent. nothing: nothing to recover.
object[]
With done: chainId, tokenAddress and amount (in the token’s smallest unit) of what was recovered, before Hinkal’s recovery fee, which it deducts: the wallet receives slightly less.
nothing means nothing is stuck: the payout is still on its way, it was delivered, it was already recovered, or RAVN holds no such swap (its record lasts 7 days). A bridge refund shows at Hinkal about 3 minutes after the payout fails, so a call made sooner can answer nothing: try again a few minutes later. A deposit whose payout never ran is offered once the order has failed, or 25 minutes after it was placed with no payout scheduled, never while a payout may still spend it.

Errors

With the SDK

@ravnexchange/sdk 0.4.1 or later runs the whole flow, checking each step before your user signs it:
In Python, ravnexchange 0.1.7 or later does the same with recover_stuck_funds(client, status_ref, user_address, sign_message, sign_typed_data).