Search Apps Documentation Source Content File Folder Download Copy Actions Download State String Boolean Number Struct Map Slice Pointer Function Closure Reference Nil Package Type Interface Unknown

users state

Back to all declarations

initControllerPath

untyped string

Value

"gno.land/r/sys/users/init"

controllers

addrset.Set

// caller whitelist

Open
OID
0ed754…0a6a:4
controllers details

Inspect ref

AddControllerAtGenesis

func(addr .uverse.address)

AddControllerAtGenesis allows adding a controller during chain genesis (height 0). This is mostly useful for testing.

Open
OID
0ed754…0a6a:8
AddControllerAtGenesis details

Inspect func

ProposeNewController

func(addr .uverse.address) dao.ProposalRequest

ProposeNewController allows GovDAO to add a whitelisted caller

Open
OID
0ed754…0a6a:9
ProposeNewController details

Inspect func

ProposeControllerRemoval

func(addr .uverse.address) dao.ProposalRequest

ProposeControllerRemoval allows GovDAO to add a whitelisted caller

Open
OID
0ed754…0a6a:10
ProposeControllerRemoval details

Inspect func

ProposeControllerAdditionAndRemoval

func(toAdd .uverse.address, toRemove .uverse.address) dao.ProposalRequest

ProposeControllerAdditionAndRemoval allows GovDAO to add a new caller and remove an old caller in the same proposal.

Open
OID
0ed754…0a6a:11
ProposeControllerAdditionAndRemoval details

Inspect func

applyControllerSwap

func(toAdd .uverse.address, toRemove .uverse.address) .uverse.error

applyControllerSwap is the callback body of ProposeControllerAdditionAndRemoval, extracted so it can be unit-tested without driving the full GovDAO flow. The desired end state is "toAdd is in the whitelist AND toRemove is out". Both operations are made idempotent so the swap doesn't silently no-op when the chain state has drifted between proposal creation and execution: - If toAdd is already whitelisted, treat addToWhitelist's ErrAlreadyWhitelisted as benign and continue to the remove step. - If toRemove is already absent, treat deleteFromWhitelist's ErrNotWhitelisted as benign and return success. Without this idempotency, the original code returned early on an "already whitelisted" toAdd and skipped the remove entirely — a swap proposal could pass governance and silently leave the old controller active. (audit finding #6)

Open
OID
0ed754…0a6a:12
applyControllerSwap details

Inspect func

ProposeRegisterUser

func(name string, addr .uverse.address) dao.ProposalRequest

ProposeRegisterUser allows GovDAO to register a name without checking controllers. The executor closure runs with ignoreCanonical=true (decision #3): DAO grants always bypass canonical-collision detection. Voters see any collision in the proposal description and can vote NO if unintended.

Open
OID
0ed754…0a6a:13
ProposeRegisterUser details

Inspect func

ProposeUpdateName

func(addr .uverse.address, newName string) dao.ProposalRequest

ProposeUpdateName allows GovDAO to update a name with an alias without checking controllers. Like ProposeRegisterUser, the executor runs with ignoreCanonical=true (decision #3).

Open
OID
0ed754…0a6a:14
ProposeUpdateName details

Inspect func

ProposeDeleteUser

func(addr .uverse.address) dao.ProposalRequest

ProposeDeleteUser allows GovDAO to delete a user without checking controllers

Open
OID
0ed754…0a6a:15
ProposeDeleteUser details

Inspect func

IsController

func(addr .uverse.address) bool

IsController reports whether the given address is currently in the controller whitelist. Returns the same boolean that gating checks (RegisterUser, UpdateName, Delete) use internally — useful for off-chain monitoring and for governance proposals to inspect state before voting.

Open
OID
0ed754…0a6a:16
IsController details

Inspect func

Controllers

func() [].uverse.address
Open
OID
0ed754…0a6a:17
Controllers details

Inspect func

deleteFromWhitelist

func(addr .uverse.address) .uverse.error
Open
OID
0ed754…0a6a:18
deleteFromWhitelist details

Inspect func

addToWhitelist

func(newCaller .uverse.address) .uverse.error
Open
OID
0ed754…0a6a:19
addToWhitelist details

Inspect func

IsNameTaken

func(name string) bool

IsNameTaken reports whether the exact-string name exists in nameStore. Returns true for any name ever registered, including: - active registrations - tombstoned (deleted) users' names — Delete() sets \`deleted=true\` but does not remove the nameStore entry (anti-revival policy) - old aliases from renames — UpdateName inserts the new name alongside the old; the old key stays (anti-rename-squat policy) In short: IsNameTaken(name) answers "would RegisterUser(name, \_) fail with ErrNameTaken?" — same answer for active, deleted, or aliased-away names. Pairs with IsCanonicalTaken (canonical-match) and ResolveName (active-current-user lookup with full UserData). No canonicalization is applied. For controllers that want exact- match uniqueness without pulling in canonical-collision logic.

Open
OID
0ed754…0a6a:20
IsNameTaken details

Inspect func

IsCanonicalTaken

func(name string) (existing string, taken bool)

IsCanonicalTaken reports whether the given name's canonical form is already registered. Pass the raw name; canonicalization is applied internally. The first return is the original (non-canonical) name that owns the canonical key, for UX in collision messages. When a bypass write (RegisterUserIgnoreCanonical or the bypass path through ProposeRegisterUser/ProposeUpdateName) overwrites a prior canonical entry, this returns the most-recently-written original.

Open
OID
0ed754…0a6a:22
IsCanonicalTaken details

Inspect func

canonicalStore

*v0.BPTree

canonicalStore maps canonicalized full names to the original name that was registered. Keyed by the result of Canonicalize. Multiple controllers (namereg/v1, future registries, governance, genesis bootstrapping) all share this single store via RegisterUser and the bypass variant RegisterUserIgnoreCanonical. Cross-controller canonical-collision detection is uniform and atomic with the nameStore write.

Open
OID
0ed754…0a6a:24
canonicalStore details

Inspect pointer

Canonicalize

func(name string) string

Canonicalize returns the canonical form of a name. The substitutions collapse single-character visual confusables that arise across the allowed \[a-z0-9] character set, and strip the three separators that can sneak between identical alphanumeric runs. - {l, i, 1} → i - {0, o} → o - {-, ., \_} → stripped - all other characters unchanged CONTRACT: stable. Future controllers that want to share this canonical namespace MUST use this exact function — do not roll your own. Adding new substitutions later is a breaking change because it would silently re-key existing entries in canonicalStore. Input contract: ASCII-only. r/sys/users.validateName already rejects non-ASCII at the registration boundary, so by the time a name reaches Canonicalize through the standard write path it is guaranteed to be ASCII. Direct callers from other realms must honor this contract; non-ASCII bytes are passed through as-is and will produce undefined collision behavior. Multi-char confusables (m↔rn, nn↔m, cl↔d) are NOT canonicalized. They require fixed-point substring substitution rounds, which is out of scope for the unified store. Pure: no state access. Safe to call from anywhere.

Open
OID
0ed754…0a6a:26
Canonicalize details

Inspect func

prefix

untyped string

Value

"r/sys/users: "

ErrAlreadyWhitelisted

*errors.errorString
Open
OID
0ed754…0a6a:29
ErrAlreadyWhitelisted details

Inspect pointer

ErrWhitelistRemoveFailed

*errors.errorString
Open
OID
0ed754…0a6a:32
ErrWhitelistRemoveFailed details

Inspect pointer

ErrCanonicalCollision

*errors.errorString
Open
OID
0ed754…0a6a:38
ErrCanonicalCollision details

Inspect pointer

ErrInvalidAddress

*errors.errorString
Open
OID
0ed754…0a6a:41
ErrInvalidAddress details

Inspect pointer

ErrEmptyUsername

*errors.errorString
Open
OID
0ed754…0a6a:44
ErrEmptyUsername details

Inspect pointer

ErrNameLikeAddress

*errors.errorString
Open
OID
0ed754…0a6a:47
ErrNameLikeAddress details

Inspect pointer

ErrInvalidUsername

*errors.errorString
Open
OID
0ed754…0a6a:50
ErrInvalidUsername details

Inspect pointer

ErrAlreadyHasName

*errors.errorString
Open
OID
0ed754…0a6a:53
ErrAlreadyHasName details

Inspect pointer

ErrUserNotExistOrDeleted

*errors.errorString
Open
OID
0ed754…0a6a:59
ErrUserNotExistOrDeleted details

Inspect pointer

ErrNotWhitelisted

type

ErrNotWhitelisted stores the failing caller's realm identity as a plain string so the error is a pure data record (no live realm values in its fields).

Value

users.ErrNotWhitelisted

NewErrNotWhitelisted

func(int, caller .uverse.realm) users.ErrNotWhitelisted

NewErrNotWhitelisted constructs the error with the caller's realm identity captured as a string at construction time. The \_ int discriminator keeps this non-crossing (a non-crossing function can't take a \`realm\`-named-\`cur\` first param, so we use the standard \_ int, rlm realm shape).

Open
OID
0ed754…0a6a:64
NewErrNotWhitelisted details

Inspect func

nameStore

*v0.BPTree

// name/aliases > \*UserData

Open
OID
0ed754…0a6a:69
nameStore details

Inspect pointer

addressStore

*v0.BPTree

// address > \*UserData

Open
OID
0ed754…0a6a:72
addressStore details

Inspect pointer

maxNameLen

untyped bigint

Value

(64 <untyped> bigint)

RegisterUserEvent

untyped string

Value

"Registered"

UpdateNameEvent

untyped string

Value

"Updated"

DeleteUserEvent

untyped string

Value

"Deleted"

UserData

type

Value

users.UserData

registerUser

func(name string, address_XXX .uverse.address, ignoreCanonical bool) .uverse.error

registerUser adds a new user to the system without checking controllers. The ignoreCanonical flag suppresses ErrCanonicalCollision; the canonical store is written either way (decision #14: later-wins on bypass).

Open
OID
0ed754…0a6a:458
registerUser details

Inspect func

RegisterUser

func(name string, address_XXX .uverse.address) .uverse.error

RegisterUser adds a new user to the system. Enforces canonical- collision detection: a name whose Canonicalize-form matches a prior registration returns ErrCanonicalCollision.

Open
OID
0ed754…0a6a:460
RegisterUser details

Inspect func

RegisterUserIgnoreCanonical

func(name string, address_XXX .uverse.address) .uverse.error

RegisterUserIgnoreCanonical is the bypass path: same controller- whitelist gate, but ErrCanonicalCollision is suppressed. The canonical store is still written; a prior entry with the same canonical key is silently overwritten (decision #14, later-wins). Use sparingly — names registered here can canonical-collide with existing ones, weakening confusable protection for everyone.

Open
OID
0ed754…0a6a:461
RegisterUserIgnoreCanonical details

Inspect func

validateName

func(username string) .uverse.error

Validate validates username and address passed in Most of the validation is done in the controllers This provides more flexibility down the line

Open
OID
0ed754…0a6a:462
validateName details

Inspect func

ResolveName

func(name string) (data *users.UserData, isCurrent bool)

ResolveName returns the latest UserData of a specific user by name or alias

Open
OID
0ed754…0a6a:463
ResolveName details

Inspect func

ResolveAddress

func(addr .uverse.address) *users.UserData

ResolveAddress returns the latest UserData of a specific user by address

Open
OID
0ed754…0a6a:465
ResolveAddress details

Inspect func

ResolveAny

func(input string) (*users.UserData, bool)

ResolveAny tries to resolve any given string to \*UserData If the input is not found in the registry in any form, nil is returned

Open
OID
0ed754…0a6a:466
ResolveAny details

Inspect func

GetReadonlyAddrStore

func() *rotree.ReadOnlyTree

GetReadonlyAddrStore exposes the address store in readonly mode

Open
OID
0ed754…0a6a:467
GetReadonlyAddrStore details

Inspect func

GetReadOnlyNameStore

func() *rotree.ReadOnlyTree

GetReadOnlyNameStore exposes the name store in readonly mode

Open
OID
0ed754…0a6a:468
GetReadOnlyNameStore details

Inspect func

makeUserDataSafe

func(data interface{...}) interface{...}
Open
OID
0ed754…0a6a:469
makeUserDataSafe details

Inspect func
initControllerPath : untyped string ="gno.land/r/sys/users/init"
controllers : addrset.Set Inspect
init.2 : func() Inspect
AddControllerAtGenesis : func(addr .uverse.address) Inspect
ProposeNewController : func(addr .uverse.address) dao.ProposalRequest Inspect
ProposeControllerRemoval : func(addr .uverse.address) dao.ProposalRequest Inspect
ProposeControllerAdditionAndRemoval : func(toAdd .uverse.address, toRemove .uverse.address) dao.ProposalRequest Inspect
applyControllerSwap : func(toAdd .uverse.address, toRemove .uverse.address) .uverse.error Inspect
ProposeRegisterUser : func(name string, addr .uverse.address) dao.ProposalRequest Inspect
ProposeUpdateName : func(addr .uverse.address, newName string) dao.ProposalRequest Inspect
ProposeDeleteUser : func(addr .uverse.address) dao.ProposalRequest Inspect
IsController : func(addr .uverse.address) bool Inspect
Controllers : func() [].uverse.address Inspect
deleteFromWhitelist : func(addr .uverse.address) .uverse.error Inspect
addToWhitelist : func(newCaller .uverse.address) .uverse.error Inspect
IsNameTaken : func(name string) bool Inspect
IsCanonicalTaken : func(name string) (existing string, taken bool) Inspect
canonicalStore : *v0.BPTree Inspect
Canonicalize : func(name string) string Inspect
prefix : untyped string ="r/sys/users: "
ErrAlreadyWhitelisted : *errors.errorString Inspect
ErrWhitelistRemoveFailed : *errors.errorString Inspect
ErrNameTaken : *errors.errorString Inspect
ErrCanonicalCollision : *errors.errorString Inspect
ErrInvalidAddress : *errors.errorString Inspect
ErrEmptyUsername : *errors.errorString Inspect
ErrNameLikeAddress : *errors.errorString Inspect
ErrInvalidUsername : *errors.errorString Inspect
ErrAlreadyHasName : *errors.errorString Inspect
ErrDeletedUser : *errors.errorString Inspect
ErrUserNotExistOrDeleted : *errors.errorString Inspect
ErrInvalidRealm : *errors.errorString Inspect
ErrNotWhitelisted : type =users.ErrNotWhitelisted
NewErrNotWhitelisted : func(int, caller .uverse.realm) users.ErrNotWhitelisted Inspect
Render : func(string) string Inspect
nameStore : *v0.BPTree Inspect
addressStore : *v0.BPTree Inspect
reAddressLookalike : *regexp.Regexp Inspect
reName : *regexp.Regexp Inspect
maxNameLen : untyped bigint =(64 <untyped> bigint)
RegisterUserEvent : untyped string ="Registered"
UpdateNameEvent : untyped string ="Updated"
DeleteUserEvent : untyped string ="Deleted"
UserData : type =users.UserData
registerUser : func(name string, address_XXX .uverse.address, ignoreCanonical bool) .uverse.error Inspect
RegisterUser : func(name string, address_XXX .uverse.address) .uverse.error Inspect
RegisterUserIgnoreCanonical : func(name string, address_XXX .uverse.address) .uverse.error Inspect
validateName : func(username string) .uverse.error Inspect
ResolveName : func(name string) (data *users.UserData, isCurrent bool) Inspect
ResolveAddress : func(addr .uverse.address) *users.UserData Inspect
ResolveAny : func(input string) (*users.UserData, bool) Inspect
GetReadonlyAddrStore : func() *rotree.ReadOnlyTree Inspect
GetReadOnlyNameStore : func() *rotree.ReadOnlyTree Inspect
makeUserDataSafe : func(data interface{...}) interface{...} Inspect