Liquidity that knows when to fall.
HANAMI is a Solana program that implements a single opinionated primitive: time-bounded constant-product liquidity positions that auto-settle at a known slot. Impermanent loss is bounded by design because every position carries its own horizon.
Why time-bounded
A standard constant-product LP has unbounded impermanent loss. As price drifts, the position quietly bleeds value with no horizon at which it stops. HANAMI inverts the default: every position declares its own end_slot at deposit, and at that slot anyone can permissionlessly settle it. The IL distribution is finite because the timeline is finite.
pub fn create_bloom(
ctx: Context<CreateBloom>,
nonce: u64,
amount_a: u64,
amount_b: u64,
duration_slots: u64,
) -> Result<()> {
require!(
duration_slots >= MIN_BLOOM_SLOTS && duration_slots <= MAX_BLOOM_SLOTS,
HanamiError::InvalidDuration
);
// ...
}What ships in this repo
- On-chain program: Anchor 0.31, five instructions (
initialize_pool,create_bloom,swap,settle_bloom,chirigiwa) and two account types. - TypeScript SDK: typed client, PDA helpers, error mirror, math utilities.
- Rust CLI: subcommands for every entrypoint.
- Examples: runnable scripts for the full lifecycle.
- Integration suite: 14 tests on a real validator.
Quick orientation
Account layout
How pools, vaults and bloom positions are derived and stored on-chain.
命令 · instructionsInstruction reference
Every entrypoint, its accounts, args and the errors it can return.
経済 · economicsEconomics & IL math
Why bounded timelines bound IL, and how chirigiwa redistributes the penalty.
sdkTypeScript SDK
Open a bloom in five lines of code.