Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
34 changes: 33 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -86,9 +86,41 @@ percolator-nft (this program)
is exposed. Gated by program-upgrade governance.
- **no-entrypoint Feature**: Program entrypoint is gated behind a `no-entrypoint` cargo
feature for library-style composition (e.g. embedding in test harnesses).
- **GetPositionValue is fail-CLOSED**: stale/slot-reuse/no-active-leg conditions return
- **GetPositionValue is fail-CLOSED**: every non-transferable condition returns
errors, not `Ok(())`. Clients using `simulateTransaction` must check the error.

### GetPositionValue log contract

The instruction returns nothing via CPI, so its logs are its API. Every response
emits `POSITION_VALUE_V16:portfolio=`, `POSITION_VALUE_V16:asset_index=` and
exactly one `POSITION_VALUE_V16:status=`:

| `status=` | Meaning | Error |
|---|---|---|
| `ok` | Healthy bound leg; the economic fields follow under `POSITION_VALUE_V16:`. | — |
| `no_active_leg` | The position is closed or never existed; route to `EmergencyBurn`. | `LegNotActive` (22) |
| `leg_stale` | The bound leg owes chunked settlement. Transient — a crank clears it. | `TransferBlocked` (24) |
| `portfolio_locked_or_stale` | Portfolio-level liquidation lock or stale state. | `TransferBlocked` (24) |
| `resolved` | Terminal resolved-payout receipt present; claim rather than price it. | `TransferBlocked` (24) |
| `close_in_progress` | A close is mid-flight for this asset. Transient. | `TransferBlocked` (24) |
| `slot_reuse_detected` | The slot was reused by a different position instance; this NFT is dead. Accompanied by `market_id_at_mint=` and `current_market_id=`. | `MarketIdMismatch` (25) |

Notes for integrators:

- `simulateTransaction` returns `logs` alongside `err`, so the status line is
readable on a failed instruction. (`logs` is `null` only when simulation fails
*before* execution — bad blockhash, unloadable account, signature verification.)
- On a blocked status the economic fields are emitted under the separate
**`POSITION_BLOCKED_V16:`** prefix, not `POSITION_VALUE_V16:`. A parser
scanning for the latter therefore fails closed by construction; opt into
distressed pricing deliberately by reading the former. `slot_reuse_detected`
emits no economics at all — they would describe a different position.
- **Batching caveat:** a failing instruction aborts the whole transaction, so
packing many `GetPositionValue` calls into one simulation means a single
blocked position suppresses every instruction after it. Batch defensively, or
price positions individually.
- Logs are capped at 10,000 bytes per transaction and truncate silently.

## v17 Layout Support

The NFT program mirrors the converged v17 portfolio layout (`PortfolioAccountV16Account`,
Expand Down
7 changes: 6 additions & 1 deletion src/instruction.rs
Original file line number Diff line number Diff line change
Expand Up @@ -73,7 +73,12 @@ pub const TAG_SETTLE_FUNDING: u8 = 2;
/// Read-only valuation diagnostics for marketplaces and lending protocols.
/// Emits raw leg/valuation fields via transaction logs; does NOT return a
/// value via CPI (no set_return_data). Clients use `simulateTransaction`.
/// Fail-CLOSED: stale/slot-reuse/no-active-leg conditions return an error.
/// Fail-CLOSED: every condition that makes the bound leg non-transferable
/// returns an error. `POSITION_VALUE_V16:status=` carries the reason, one of:
/// `ok`, `no_active_leg`, `leg_stale`, `portfolio_locked_or_stale`, `resolved`,
/// `close_in_progress`, `slot_reuse_detected`. Blocked positions still report
/// their economics under the separate `POSITION_BLOCKED_V16:` prefix (except
/// slot-reuse, whose fields would describe a different position instance).
///
/// Accounts:
/// 0. `[]` PositionNft PDA
Expand Down
Loading
Loading