PathrockNetwork Gno Explorer
HomeBlocksTransactionsTokensRealmsPackagesValidatorsAnalytics

PathrockNetwork Gno Explorer — an independent explorer for Gno.land Mainnet (gnoland-1), operated by PathrockNetwork. Not an official Gno.land service.

gnowebarchive RPC

gno.land/r/gnoswap/gov/governance/v1

Realm
Open in gnoweb ↗

Overview

Kind
Realm (renderable)
Name
v1
Namespace
gnoswap / gov / governance
Files
23 (README)(gnomod.toml)
Exported functions
n/a — Gnoland RPC unavailable (functions): rpc abci_query: HTTP 500
Module
gno.land/r/gnoswap/gov/governance/v1
gno
0.9

Files (23)

  • README.mdmarkdown
  • gnomod.tomltoml
  • assert.gnogno
  • config.gnogno
  • consts.gnogno
  • doc.gnogno
  • errors.gnogno
  • getter_utils.gnogno
  • getter.gnogno
  • governance_execute.gnogno
  • governance_propose.gnogno
  • governance_vote.gnogno
  • init.gnogno
  • instance.gnogno
  • parameter_registry.gnogno
  • proposal_action_status.gnogno
  • proposal_data.gnogno
  • proposal_schedule_status.gnogno
  • proposal_status.gnogno
  • proposal_vote_status.gnogno
  • proposal.gnogno
  • render.gnogno
  • utils.gnogno
  • proposal_data.gnogno
    1package governance23import (4	"strings"56	"gno.land/p/gnoswap/utils/v1"7	ufmt "gno.land/p/nt/ufmt/v0"8

    Functions

    Gnoland RPC unavailable (functions): rpc abci_query: HTTP 500

    Signatures reconstructed verbatim from vm/qfuncs — interface params keep their inline definitions.

    Rendered

    RenderedRawgnoweb ↗

    Render unavailable

    rate limit exceeded — the render query is served by the Gnoland archive RPC.

    vm/qrender output, sanitized (docs/render-security.md) and displayed in an empty-sandbox iframe — scripts, forms and popups cannot run. Links stay inert in-preview; right-click to open.

    9 "gno.land/r/gnoswap/gov/governance"
    10)
    11
    12type ProposalMetadataResolver struct {
    13 *governance.ProposalMetadata
    14}
    15
    16// NewProposalMetadataResolver wraps proposal metadata for validation.
    17//
    18// Parameters:
    19// - metadata: proposal title and description to validate.
    20//
    21// Returns:
    22// - *ProposalMetadataResolver: resolver backed by metadata.
    23func NewProposalMetadataResolver(metadata *governance.ProposalMetadata) *ProposalMetadataResolver {
    24 return &ProposalMetadataResolver{
    25 ProposalMetadata: metadata,
    26 }
    27}
    28
    29// Validate performs comprehensive validation of the proposal metadata.
    30// Checks title and description length and content requirements.
    31//
    32// Returns:
    33// - error: validation error if metadata is invalid
    34func (r *ProposalMetadataResolver) Validate() error {
    35 // Validate title meets requirements
    36 if err := r.validateTitle(r.Title()); err != nil {
    37 return err
    38 }
    39
    40 // Validate description meets requirements
    41 if err := r.validateDescription(r.Description()); err != nil {
    42 return err
    43 }
    44
    45 return nil
    46}
    47
    48// validateTitle checks if the proposal title meets length and content requirements.
    49//
    50// Parameters:
    51// - title: title string to validate
    52//
    53// Returns:
    54// - error: validation error if title is invalid
    55func (r *ProposalMetadataResolver) validateTitle(title string) error {
    56 // Title cannot be empty
    57 if title == "" {
    58 return makeErrorWithDetails(errInvalidInput, "title is empty")
    59 }
    60
    61 // Title cannot exceed maximum length
    62 if len(title) > maxTitleLength {
    63 return makeErrorWithDetails(
    64 errInvalidInput,
    65 "title is too long, max length is 255 characters",
    66 )
    67 }
    68
    69 return nil
    70}
    71
    72// validateDescription checks if the proposal description meets length and content requirements.
    73//
    74// Parameters:
    75// - description: description string to validate
    76//
    77// Returns:
    78// - error: validation error if description is invalid
    79func (r *ProposalMetadataResolver) validateDescription(description string) error {
    80 // Description cannot be empty
    81 if description == "" {
    82 return makeErrorWithDetails(
    83 errInvalidInput,
    84 "description is empty",
    85 )
    86 }
    87
    88 // Description cannot exceed maximum length
    89 if len(description) > maxDescriptionLength {
    90 return makeErrorWithDetails(
    91 errInvalidInput,
    92 "description is too long, max length is 10,000 characters",
    93 )
    94 }
    95
    96 return nil
    97}
    98
    99// ProposalDataResolver handles business logic for proposal data.
    100type ProposalDataResolver struct {
    101 *governance.ProposalData
    102}
    103
    104// NewProposalDataResolver wraps proposal data for type-specific validation and
    105// execution-message parsing.
    106//
    107// Parameters:
    108// - proposalData: proposal data to resolve and validate.
    109//
    110// Returns:
    111// - *ProposalDataResolver: resolver backed by proposalData.
    112func NewProposalDataResolver(proposalData *governance.ProposalData) *ProposalDataResolver {
    113 return &ProposalDataResolver{
    114 ProposalData: proposalData,
    115 }
    116}
    117
    118// Validate performs type-specific validation of the proposal data.
    119// Different proposal types have different validation requirements.
    120//
    121// Returns:
    122// - error: validation error if data is invalid
    123func (r *ProposalDataResolver) Validate() error {
    124 switch r.ProposalType() {
    125 case governance.Text:
    126 return r.validateText()
    127 case governance.CommunityPoolSpend:
    128 return r.validateCommunityPoolSpend()
    129 case governance.ParameterChange:
    130 return r.validateParameterChange()
    131 }
    132 return nil
    133}
    134
    135// validateText validates text proposal data.
    136// Text proposals have no additional validation requirements.
    137//
    138// Returns:
    139// - error: always nil for text proposals
    140func (r *ProposalDataResolver) validateText() error {
    141 return nil
    142}
    143
    144// validateCommunityPoolSpend validates community pool spend proposal data.
    145// Checks recipient address, token path, and amount validity.
    146//
    147// Returns:
    148// - error: validation error if community pool spend data is invalid
    149func (r *ProposalDataResolver) validateCommunityPoolSpend() error {
    150 // Validate recipient address
    151 communityPoolSpend := r.ProposalData.CommunityPoolSpend()
    152 if communityPoolSpend == nil {
    153 return makeErrorWithDetails(
    154 errInvalidInput, "community pool spend info is missing")
    155 }
    156
    157 if !communityPoolSpend.To().IsValid() {
    158 return makeErrorWithDetails(
    159 errInvalidInput, "to is invalid address")
    160 }
    161
    162 // Validate amount is greater than 0
    163 if communityPoolSpend.Amount() <= 0 {
    164 return makeErrorWithDetails(
    165 errInvalidInput, "amount is not positive")
    166 }
    167
    168 return nil
    169}
    170
    171// validateParameterChange validates parameter change proposal data.
    172// Delegates to validateExecutions for full validation including count checks,
    173// message format, handler existence, and parameter type validation.
    174//
    175// Returns:
    176// - error: validation error if parameter change data is invalid
    177func (r *ProposalDataResolver) validateParameterChange() error {
    178 execution := r.Execution()
    179 if execution == nil {
    180 return makeErrorWithDetails(
    181 errInvalidInput,
    182 "execution info is missing",
    183 )
    184 }
    185 return validateExecutions(execution.Num(), execution.Msgs())
    186}
    187
    188// ParameterChangesInfos parses the execution messages and returns structured parameter change information.
    189// Each message is expected to be in format: pkgPath*EXE*function*EXE*params
    190//
    191// Returns:
    192// - []ParameterChangeInfo: slice of parsed parameter change information
    193// - error: validation error if any execution message is malformed
    194func (r *ProposalDataResolver) ParameterChangesInfos() ([]governance.ParameterChangeInfo, error) {
    195 infos := make([]governance.ParameterChangeInfo, 0)
    196
    197 // Return empty slice if no executions
    198 execution := r.Execution()
    199 if execution == nil || execution.Num() <= 0 {
    200 return infos, nil
    201 }
    202
    203 // Parse each execution message
    204 for _, msg := range execution.Msgs() {
    205 pkgPath, function, params, partCount := parseExecutionMessage(msg)
    206 if partCount != 3 {
    207 return nil, makeErrorWithDetails(
    208 errInvalidMessageFormat,
    209 ufmt.Sprintf("malformed execution message: expected 3 parts (pkgPath, function, params), got %d", partCount),
    210 )
    211 }
    212
    213 // Create parameter change info structure
    214 info := governance.NewParameterChangeInfo(pkgPath, function, params)
    215 infos = append(infos, info)
    216 }
    217
    218 return infos, nil
    219}
    220
    221// NewProposalTextData creates proposal data for a text proposal.
    222// Text proposals have no additional data requirements.
    223//
    224// Returns:
    225// - *ProposalData: proposal data configured for text proposal
    226func NewProposalTextData() *governance.ProposalData {
    227 return governance.NewProposalData(governance.Text, nil, nil)
    228}
    229
    230// NewProposalCommunityPoolSpendData creates proposal data for a community pool spend proposal.
    231// Automatically generates the execution message for the token transfer.
    232//
    233// Parameters:
    234// - tokenPath: path of the token to transfer
    235// - to: recipient address for the transfer
    236// - amount: amount of tokens to transfer
    237// - communityPoolPackagePath: package path of the community pool contract
    238//
    239// Returns:
    240// - *ProposalData: proposal data configured for community pool spending
    241func NewProposalCommunityPoolSpendData(
    242 tokenPath string,
    243 to address,
    244 amount int64,
    245 communityPoolPackagePath string,
    246) *governance.ProposalData {
    247 // Create execution message for the token transfer
    248 executionInfoMessage := makeExecuteMessage(
    249 communityPoolPackagePath,
    250 "TransferToken",
    251 []string{tokenPath, to.String(), utils.FormatInt(amount)},
    252 )
    253
    254 return governance.NewProposalData(
    255 governance.CommunityPoolSpend,
    256 governance.NewCommunityPoolSpendInfo(to, tokenPath, amount),
    257 governance.NewExecutionInfo(1, []string{executionInfoMessage}),
    258 )
    259}
    260
    261// NewProposalExecutionData creates proposal data for a parameter change proposal.
    262// Each message in executions should be formatted as <pkgPath>*EXE*<function>*EXE*<params>,
    263// separated by *GOV* when there are multiple messages.
    264//
    265// Parameters:
    266// - numToExecute: number of parameter changes to execute
    267// - executions: raw encoded execution string with parameter changes
    268//
    269// Returns:
    270// - *ProposalData: proposal data configured for parameter changes
    271func NewProposalExecutionData(numToExecute int64, executions string) *governance.ProposalData {
    272 return governance.NewProposalData(
    273 governance.ParameterChange,
    274 nil,
    275 governance.NewExecutionInfo(numToExecute, splitExecutionsRaw(executions)),
    276 )
    277}
    278
    279// makeExecuteMessage creates a message to execute a function.
    280// Message format: <pkgPath>*EXE*<function>*EXE*<params>.
    281func makeExecuteMessage(pkgPath, function string, params []string) string {
    282 messageParams := []string{
    283 pkgPath,
    284 function,
    285 strings.Join(params, ","),
    286 }
    287 return strings.Join(messageParams, parameterSeparator)
    288}
    289