MustNew
MustNew is New but panics on error.
Command
gnokey query vm/qeval -remote "https://rpc.pearl.testnets.gno.land" -data "gno.land/p/g1ut6uspuh73e02yauxpmyt8g3wwddaq8utagvm3/duebook.MustNew(,,)"
Result
Package duebook is a pure scheduling primitive for realms that need to authorize an action now and perform it later. It is to *time* what feeledger is to *money*: it holds no coins, performs no effects, imports no chain APIs, and owns no package-level state. The importing realm owns a *Book, supplies the clock, and performs its own effects.
A realm does not ask duebook to execute anything — Gno has no autonomous execution, so "scheduled" always means "someone sends a transaction later". What a realm actually needs is for that later transaction to be authorized exactly once. Claim is that step:
1d, err := book.Claim(id, now)
2if err != nil {
3 panic(err) // not due, expired, cancelled, or already claimed
4}
5// ... the realm performs its own effect here, under its own authority
Claim checks due / not-expired / still-open and CONSUMES the deferral in the same call, before returning. The realm then acts. Replay is not guarded against, it is structurally impossible:
so at most one Claim per ID can ever succeed, across all transactions, forever. A second Claim of the same ID returns ErrNotFound whether the first one happened in this transaction or a year ago.
Because the realm performs the effect itself, no closure, callback, or capability ever crosses a realm boundary. duebook cannot be handed code to run, so it cannot be tricked into running the wrong code.
A deferral is open from Schedule until exactly one of Claim, Cancel, or Expire consumes it. There is no other transition and no way back.
1Schedule ──> open ──┬── Claim (now >= DueAt, before ExpiresAt)
2 ├── Cancel (owner only, any time while open)
3 └── Expire (anyone, once now >= ExpiresAt)
Claimability is the half-open interval [DueAt, ExpiresAt): due at DueAt, no longer claimable at ExpiresAt. A deferral scheduled with ttl == 0 never expires and has ExpiresAt == 0.
Consumed deferrals are removed, not archived — the ID counter, not a tombstone, is what prevents replay, so there is nothing to keep. Open deferrals are capped per Book at construction. Storage is therefore bounded by maxOpen regardless of how many deferrals have ever existed. Audit history belongs in the consuming realm's events.
All failures are returned as errors and leave the Book COMPLETELY UNCHANGED. Must* wrappers are the only functions here that panic.
The Book is address-agnostic: owners are non-empty strings. Realms normally use address.String().
MustNew is New but panics on error.
gnokey query vm/qeval -remote "https://rpc.pearl.testnets.gno.land" -data "gno.land/p/g1ut6uspuh73e02yauxpmyt8g3wwddaq8utagvm3/duebook.MustNew(,,)"
New returns an empty Book.
minDelay is the floor on how far ahead a deferral may be scheduled; 0 permits same-instant scheduling. maxDelay is the ceiling, and doubles as the overflow guard on now+delay. maxOpen caps simultaneously open deferrals and must be in [1, MaxOpenLimit].
Units are the caller's choice — block heights or seconds — but must be used consistently for the life of the Book.
gnokey query vm/qeval -remote "https://rpc.pearl.testnets.gno.land" -data "gno.land/p/g1ut6uspuh73e02yauxpmyt8g3wwddaq8utagvm3/duebook.New(,,)"