> ## Documentation Index
> Fetch the complete documentation index at: https://build.flashnet.xyz/llms.txt
> Use this file to discover all available pages before exploring further.

# Reading Locks

> Query active lock state

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

## List locks for a pool

```typescript theme={null}
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

```typescript theme={null}
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:

| Field                | Description                                            |
| -------------------- | ------------------------------------------------------ |
| `poolId`             | Pool identifier (LP identity public key)               |
| `ownerPublicKey`     | Owner of the locked position                           |
| `lockUntilTimestamp` | Unix-seconds string. `"0"` when the lock is indefinite |
| `isIndefinite`       | `true` when the lock has no expiry                     |
| `tickLower`          | Lower tick bound (V3 only; absent for V2)              |
| `tickUpper`          | Upper 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

```typescript theme={null}
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.

```typescript theme={null}
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 Flashnet alongside the rest of the pool state.

## Next steps

* [Position locks overview](/products/flashnet-amm/lock-overview)
* [Create a lock](/products/flashnet-amm/lock-create)
