package nslogic import ( "strconv" "gno.land/r/nym-mnsrehearsal001/nsdata/v2" ) // GENERATED BY tools/gen-reserved.py FROM collections/reserved-labels.json. // Do not edit by hand: the site reads the same source, and a change made // in one place only is a label the site offers and the chain refuses. // // STRUCTURAL RULES ONLY. The wordlists live off chain, in that JSON, // because storage is 100 ugnot per byte and a ten-thousand-word // dictionary is about 57 GNOT paid forever to encode a marketing // decision that will change. This is the backstop against a bug in the // issuer, not the place the policy lives. // // THE NUMBERS ARE SETTABLE, the shape is not. A minimum length is a // promotion knob and belongs in the panel — redeploying this realm to // change a 5 to a 4 costs about 22 GNOT. So the lengths read from the // vault's globals and fall back to the values generated here; the // pattern rules are structural facts about what a handle looks like and // stay in code. const ( defaultFreeMinLength = 5 defaultFreeMaxLength = 63 keyFreeMin = "freemin" keyFreeMax = "freemax" ) // FreeMinLength is the shortest label the free tier will issue. Settable // from the panel, because which lengths are worth money is a commercial // judgement that moves. func FreeMinLength() int { if v := nsdata.GetGlobal(keyFreeMin); v != "" { if n, err := strconv.Atoi(v); err == nil && n > 0 && n <= 63 { return n } } return defaultFreeMinLength } func FreeMaxLength() int { if v := nsdata.GetGlobal(keyFreeMax); v != "" { if n, err := strconv.Atoi(v); err == nil && n > 0 && n <= 63 { return n } } return defaultFreeMaxLength } /* FreeLabelAllowed reports whether a label may be ISSUED on the free tier. ISSUED, and never renewed. This is called by GrantFreeName and by nothing else, deliberately: if the minimum length rises from three to five, somebody who already holds a three-character free name keeps it and keeps renewing it free. Tightening a rule must not reach backwards and take away what was already given — that is the single fastest way to make a giveaway cost more trust than it ever bought. A name that LAPSES and is registered again is a new issuance, and gets whatever the rules say that day. That is not retroactive; it is a different name event. */ func FreeLabelAllowed(label string) bool { n := len(label) if n < FreeMinLength() || n > FreeMaxLength() { return false } // Pure digits: 1337, 420, years. Collectible, and no handle is one. digits := true for i := 0; i < n; i++ { if label[i] < '0' || label[i] > '9' { digits = false break } } if digits { return false } // aaaa — every character the same. same := true for i := 1; i < n; i++ { if label[i] != label[0] { same = false break } } if same { return false } // abab — a two-character cycle. Also collectible, also not a handle. if n >= 4 { cycle := true for i := 2; i < n; i++ { if label[i] != label[i-2] { cycle = false break } } if cycle { return false } } return true }