Skip to main content
Read active locks with getPositionLocks. The endpoint is unauthenticated; no signature is required to query.

List locks for a pool

const locks = await client.getPositionLocks(poolId);

for (const lock of locks) {
  console.log("Owner:", lock.ownerPublicKey);
  console.log("Indefinite:", lock.isIndefinite);
  console.log("Expires at:", lock.lockUntilTimestamp);
  if (lock.tickLower !== undefined) {
    console.log("Range:", lock.tickLower, "to", lock.tickUpper);
  }
}
The response lists every active lock in the pool. Expired bounded locks are excluded; the server removes them lazily on the next read.

Filter by owner

const ownerPublicKey = await client.wallet.getIdentityPublicKey();

const myLocks = await client.getPositionLocks(poolId, ownerPublicKey);
Passing an owner public key scopes the response to that owner’s positions.

Lock data

Each LpLockInfo contains:
FieldDescription
poolIdPool identifier (LP identity public key)
ownerPublicKeyOwner of the locked position
lockUntilTimestampUnix-seconds string. "0" when the lock is indefinite
isIndefinitetrue when the lock has no expiry
tickLowerLower tick bound (V3 only; absent for V2)
tickUpperUpper tick bound (V3 only; absent for V2)
For a V2 lock, tickLower and tickUpper are absent. For V3, both are present.

Checking a specific position

async function isLocked(
  poolId: string,
  ownerPublicKey: string,
  tickLower?: number,
  tickUpper?: number
): Promise<boolean> {
  const locks = await client.getPositionLocks(poolId, ownerPublicKey);

  return locks.some(
    (l) => l.tickLower === tickLower && l.tickUpper === tickUpper
  );
}

Interaction with other operations

A removeLiquidity, decreaseLiquidity, or rebalancePosition call on a locked position is rejected before any Spark transfer is made. No funds move. Callers can retry the operation after the lock expires. Read the duration before retrying. A bounded lock exposes its expiry as a Unix timestamp; an indefinite lock (isIndefinite === true) does not expose a release time.
const [lock] = await client.getPositionLocks(poolId, ownerPublicKey);

if (lock && !lock.isIndefinite) {
  const remaining = Number(lock.lockUntilTimestamp) - Math.floor(Date.now() / 1000);
  console.log(`Retry in ${remaining} seconds`);
}

Limitations

  • Locks are per-position, not per-pool. Locking one owner’s position does not affect another owner’s position in the same pool.
  • V3 locks match an exact (tickLower, tickUpper) pair. A position at a neighboring tick range is not covered.
  • There is no on-chain record of a lock. State lives in the Flashnet settlement database alongside the rest of the pool state.

Next steps