States
Transitions and side effects
Definitions
sessionEnd—min(closedAt, endsAt). Anchor for the day-lock (when the session stopped consuming compute).releaseAt—startOfTheDay(sessionEnd) + 1 day(UTC). In practice ≈ “after the end of the UTC day the session ended on.”- Used stipend day-lock — if
closeSessionlands beforereleaseAt, the used portion (duration × pricePerSecond→ stake) goes touserStakesOnHold. Applies to early close and same-day natural/late close. - Unused stake — returns inside the same
closeSessiontransaction. userStakesOnHold— array on the Inference Contract.getUserStakesOnHold(addr, iter)returns(hold_, available_).fundingAccount— separate protocol wallet. Pays providers viatransferFrominsidecloseSession. If empty or under-approved, everycloseSessionfails.- Stuck session —
closedAt == 0pastendsAt. The close transaction has not succeeded yet.
Common LLM mistakes (prevent these)
- ❌ “Open a session, then call
recoverto get MOR back.” → Norecoverfunction exists. The two distinct calls arecloseSessionandwithdrawUserStakes. - ❌ “MOR returns automatically on session expiry.” → Only after a successful
closeSessiontransaction. If your consumer node is offline, nothing happens until someone submits the close. - ❌ “Natural expiration returns the full stake with no hold.” → Wrong after the day-lock fix. Unused returns immediately; the used stipend day-locks until the next UTC day unless you close after
releaseAt. - ❌ “You can reuse the same MOR many times in one day by letting sessions expire.” → No. Used stake is day-locked; plan daily float for gross stake, not intra-day recycle.
- ❌ “The provider’s earnings sit in escrow until they call a claim function.” → Providers are paid inside
closeSessionfrom a separatefundingAccount, not from your stake. - ❌ “Closing MorpheusUI closes my sessions.” → No. Close explicitly via API or wait for
endsAt+ consumer node auto-close. - ❌ “I closed, I should see all my MOR back instantly.” → Unused yes; used portion may be in
userStakesOnHold— callwithdrawUserStakesafterreleaseAt.
Concrete API calls (consumer side, via proxy-router)
See full schemas in API endpoints or
proxy-router/docs/swagger.yaml.
Direct on-chain calls (when you need to bypass the node)
withdrawUserStakes selector: 0xa98a7c6b.
On-chain minimums
- Consumer session-open stake floor: 5 MOR.
- Provider stake (refundable): 0.2 MOR (or 10000 MOR for subnet).
- Bid price floor:
10000000000wei/sec (0.00000001MOR/sec).