Pure package detail
rbac
gno.land/p/gnoswap/rbac
Indexed deployment identity with independently loaded latest RPC source. Functions and Render are realm-only RPC capabilities.
Indexed deployment
Identity
- Package path
- gno.land/p/gnoswap/rbac
- Block
- 192932
- Deployed (UTC)
- Transaction
- Kxi9IZS3xadFO22yoS7SW9zVA4NfcEDRh/eNtfJV2gw=
Latest RPC state
Source
package rbac
import (
"chain"
"errors"
)
const (
OwnershipTransferEvent = "OwnershipTransfer"
OwnershipTransferStartedEvent = "OwnershipTransferStarted"
)
// Ownable2Step implements a two-step ownership transfer mechanism.
// It requires the new owner to explicitly accept ownership before the transfer is completed,
// preventing accidental transfers to incorrect addresses.
//
// Note: This package does not verify callers. Consuming realms must extract the actual
// caller from the live realm context and pass it to these methods.
type Ownable2Step struct {
owner address
pendingOwner address
}
// newOwnable2StepWithAddress creates a new Ownable2Step instance with addr as owner.
func newOwnable2StepWithAddress(addr address) *Ownable2Step {
return &Ownable2Step{
owner: addr,
pendingOwner: "",
}
}
// TransferOwnershipBy initiates ownership transfer by setting newOwner as pending owner.
// The newOwner must call AcceptOwnershipBy to complete the transfer.
//
// Errors:
// - ErrUnauthorized: caller is not the current owner
// - ErrInvalidAddress: newOwner is empty or has an invalid format
func (o *Ownable2Step) TransferOwnershipBy(newOwner, caller address) error {
if !o.IsOwner(caller) {
return errors.New(ErrUnauthorized)
}
if newOwner == zeroAddress || !newOwner.IsValid() {
return errors.New(ErrInvalidAddress)
}
o.pendingOwner = newOwner
chain.Emit(
OwnershipTransferStartedEvent,
"from", o.owner.String(),
"to", newOwner.String(),
)
return nil
}
// AcceptOwnershipBy completes the ownership transfer.
// Must be called by the pending owner.
//
// Errors:
// - ErrNoPendingOwner: no ownership transfer is pending
// - ErrPendingUnauthorized: caller is not the pending owner
func (o *Ownable2Step) AcceptOwnershipBy(caller address) error {
if o.pendingOwner == zeroAddress {
return errors.New(ErrNoPendingOwner)
}
if !o.IsPendingOwner(caller) {
return errors.New(ErrPendingUnauthorized)
}
prevOwner := o.owner
o.owner = o.pendingOwner
o.pendingOwner = ""
chain.Emit(
OwnershipTransferEvent,
"from", prevOwner.String(),
"to", o.owner.String(),
)
return nil
}
// DropOwnershipBy removes the owner, disabling all owner-only actions.
// This is irreversible - when ownership is dropped, no future owner-only operations can be performed.
//
// Errors:
// - ErrUnauthorized: caller is not the current owner
func (o *Ownable2Step) DropOwnershipBy(caller address) error {
if !o.IsOwner(caller) {
return errors.New(ErrUnauthorized)
}
prevOwner := o.owner
o.owner = ""
o.pendingOwner = ""
chain.Emit(
OwnershipTransferEvent,
"from", prevOwner.String(),
"to", "",
)
return nil
}
// Owner returns the current owner address. Returns empty address if ownership has been dropped.
func (o *Ownable2Step) Owner() address {
return o.owner
}
// PendingOwner returns the pending owner address during ownership transfer. Returns empty address if no transfer is pending.
func (o *Ownable2Step) PendingOwner() address {
return o.pendingOwner
}
// IsOwner returns true if the origin caller is the current owner.
func (o *Ownable2Step) IsOwner(caller address) bool {
return o.owner == caller
}
// IsPendingOwner returns true if the origin caller is the pending owner.
func (o *Ownable2Step) IsPendingOwner(caller address) bool {
return o.pendingOwner == caller
}
The verified vm/qfuncs operation accepts realm paths only.
Pure packages expose source files but do not have Realm Render.