Skip to main content
Call transferPosition on the FlashnetClient with a pool ID, the recipient’s public key, and shape-specific options. The sender must already hold an active lock on the position.

Signature

Pick one shape per call. Supplying both V2 (lpTokensToTransfer) and V3 (tickLower/tickUpper) options together is rejected before the message is signed.

Transfer a V2 position

lpTokensToTransfer is a decimal string of atomic LP units. The validator rejects:
  • Non-digit characters (no sign, no decimal point, no scientific notation, no whitespace).
  • Leading zeros ("01", "007").
  • Zero or negative values.
The sender’s residual after the call is lp_shares[sender] - lpTokensToTransfer. If the residual is zero, the server deletes the sender’s lock row in the same transaction. Otherwise the sender’s lock stays at its original expiry.

Transfer a V3 position

Both tickLower and tickUpper are required. The pair must match an existing position the caller owns. The transfer moves the whole (pool_id, sender, tickLower, tickUpper) row to the recipient and rewrites the matching lp_locks row.

Locking the recipient on V2

A V2 transfer carries the sender’s lock to the recipient only when the recipient has no prior lp_shares in the pool. To deliver locked shares to a recipient who already holds an unlocked position, the recipient must lock first:
After the transfer, the recipient’s combined balance (existing + transferred) sits under the recipient’s existing lock terms. The sender’s lock metadata is not propagated.

Verify the result

The transfer commits two pieces of state. Read both to confirm:
For a V3 transfer, query getLpPosition with the recipient’s key and the original tick range; the row should now exist under the recipient. The sender’s row at the same range no longer exists.

Error handling

Common rejection paths:
  • No active lock. The sender holds no lp_locks row for the source position, or the lock has expired. Set or extend a lock first.
  • Insufficient lp_shares (V2). The requested amount is greater than lp_shares[sender]. Read the sender’s balance and adjust.
  • Position not found (V3). The (tickLower, tickUpper) pair does not match a position the sender owns.
  • Self-transfer. newOwnerPublicKey equals the caller’s key. Rejected client-side before signing.
  • Mixed shape. Both lpTokensToTransfer and a tick pair were supplied. Pick one.

Concurrency

Two parallel transfers from the same sender on the same pool serialize through the per-pool batch executor. The first commit wins; the second sees the new state and is rejected with insufficient lp_shares (V2) or position does not exist (V3). No race lets the sender double-spend the same balance.

Limitations

  • V3 transfer moves the entire position at one tick range. Partial V3 transfer requires decreaseLiquidity followed by an off-chain delivery.
  • The intent is signed once and cannot be revoked. A typo in newOwnerPublicKey is recoverable only if the recipient cooperates.
  • There is no on-chain record of a transfer. State lives in Flashnet alongside the rest of the pool state.

Next steps