github.com/decred/politeia@v1.4.0/politeiawww/api/pi/v1/v1.go (about)

     1  // Copyright (c) 2020-2022 The Decred developers
     2  // Use of this source code is governed by an ISC
     3  // license that can be found in the LICENSE file.
     4  
     5  package v1
     6  
     7  import "fmt"
     8  
     9  const (
    10  	// APIRoute is prefixed onto all routes defined in this package.
    11  	APIRoute = "/pi/v1"
    12  
    13  	// RoutePolicy returns the policy for the pi API.
    14  	RoutePolicy = "/policy"
    15  
    16  	// RouteSetBillingStatus sets the proposal's billing status.
    17  	RouteSetBillingStatus = "/setbillingstatus"
    18  
    19  	// RouteBillingStatusChanges returns the proposal's billing status changes.
    20  	RouteBillingStatusChanges = "/billingstatuschanges"
    21  
    22  	// RouteSummaries returns the proposal summary for a page of
    23  	// records.
    24  	RouteSummaries = "/summaries"
    25  )
    26  
    27  // ErrorCodeT represents a user error code.
    28  type ErrorCodeT uint32
    29  
    30  const (
    31  	// ErrorCodeInvalid is an invalid error code.
    32  	ErrorCodeInvalid ErrorCodeT = 0
    33  
    34  	// ErrorCodeInputInvalid is returned when there is an error
    35  	// while prasing a command payload.
    36  	ErrorCodeInputInvalid ErrorCodeT = 1
    37  
    38  	// ErrorCodePublicKeyInvalid is returned when a public key is
    39  	// invalid.
    40  	ErrorCodePublicKeyInvalid ErrorCodeT = 2
    41  
    42  	// ErrorCodeRecordTokenInvalid is returned when a record token is
    43  	// invalid.
    44  	ErrorCodeRecordTokenInvalid ErrorCodeT = 3
    45  
    46  	// ErrorCodeRecordNotFound is returned when no record was found.
    47  	ErrorCodeRecordNotFound ErrorCodeT = 4
    48  
    49  	// ErrorCodePageSizeExceeded is returned when the request's page size
    50  	// exceeds the maximum page size of the request.
    51  	ErrorCodePageSizeExceeded ErrorCodeT = 5
    52  
    53  	// ErrorCodeLast is used by unit tests to verify that all error codes have
    54  	// a human readable entry in the ErrorCodes map. This error will never be
    55  	// returned.
    56  	ErrorCodeLast ErrorCodeT = 6
    57  )
    58  
    59  var (
    60  	// ErrorCodes contains the human readable errors.
    61  	ErrorCodes = map[ErrorCodeT]string{
    62  		ErrorCodeInvalid:            "error invalid",
    63  		ErrorCodeInputInvalid:       "input invalid",
    64  		ErrorCodePublicKeyInvalid:   "public key invalid",
    65  		ErrorCodeRecordTokenInvalid: "record token invalid",
    66  		ErrorCodeRecordNotFound:     "record not found",
    67  		ErrorCodePageSizeExceeded:   "page size exceeded",
    68  	}
    69  )
    70  
    71  // UserErrorReply is the reply that the server returns when it encounters an
    72  // error that is caused by something that the user did (malformed input, bad
    73  // timing, etc). The HTTP status code will be 400.
    74  type UserErrorReply struct {
    75  	ErrorCode    ErrorCodeT `json:"errorcode"`
    76  	ErrorContext string     `json:"errorcontext,omitempty"`
    77  }
    78  
    79  // Error satisfies the error interface.
    80  func (e UserErrorReply) Error() string {
    81  	return fmt.Sprintf("user error code: %v", e.ErrorCode)
    82  }
    83  
    84  // PluginErrorReply is the reply that the server returns when it encounters
    85  // a plugin error.
    86  type PluginErrorReply struct {
    87  	PluginID     string `json:"pluginid"`
    88  	ErrorCode    uint32 `json:"errorcode"`
    89  	ErrorContext string `json:"errorcontext,omitempty"`
    90  }
    91  
    92  // Error satisfies the error interface.
    93  func (e PluginErrorReply) Error() string {
    94  	return fmt.Sprintf("plugin %v error code: %v", e.PluginID, e.ErrorCode)
    95  }
    96  
    97  // ServerErrorReply is the reply that the server returns when it encounters an
    98  // unrecoverable error while executing a command. The HTTP status code will be
    99  // 500 and the ErrorCode field will contain a UNIX timestamp that the user can
   100  // provide to the server admin to track down the error details in the logs.
   101  type ServerErrorReply struct {
   102  	ErrorCode int64 `json:"errorcode"`
   103  }
   104  
   105  // Error satisfies the error interface.
   106  func (e ServerErrorReply) Error() string {
   107  	return fmt.Sprintf("server error: %v", e.ErrorCode)
   108  }
   109  
   110  // Policy requests the policy settings for the pi API. It includes the policy
   111  // guidlines for the contents of a proposal record.
   112  type Policy struct{}
   113  
   114  // PolicyReply is the reply to the Policy command.
   115  //
   116  // NOTE: NameLengthMin, NameLengthMax, NameSupportedChars are not consistent
   117  // with the field names in the pi plugin where they defined as titleLengthMin,
   118  // titleLengthMax & titleSupportedChars as they are now used to verify both
   119  // the proposal name and the proposal author update title.
   120  // We have not updated the field names here to avoid introducing breaking
   121  // changes.
   122  type PolicyReply struct {
   123  	TextFileSizeMax              uint32   `json:"textfilesizemax"` // In bytes
   124  	ImageFileCountMax            uint32   `json:"imagefilecountmax"`
   125  	ImageFileSizeMax             uint32   `json:"imagefilesizemax"` // In bytes
   126  	NameLengthMin                uint32   `json:"namelengthmin"`    // In characters
   127  	NameLengthMax                uint32   `json:"namelengthmax"`    // In characters
   128  	NameSupportedChars           []string `json:"namesupportedchars"`
   129  	AmountMin                    uint64   `json:"amountmin"`    // In cents
   130  	AmountMax                    uint64   `json:"amountmax"`    // In cents
   131  	StartDateMin                 int64    `json:"startdatemin"` // Seconds from current time
   132  	EndDateMax                   int64    `json:"enddatemax"`   // Seconds from current time
   133  	Domains                      []string `json:"domains"`
   134  	SummariesPageSize            uint32   `json:"summariespagesize"`
   135  	BillingStatusChangesPageSize uint32   `json:"billingstatuschangespagesize"`
   136  	BillingStatusChangesMax      uint32   `json:"billingstatuschangesmax"`
   137  }
   138  
   139  const (
   140  	// FileNameIndexFile is the file name of the proposal markdown
   141  	// file that contains the main proposal contents. All proposal
   142  	// submissions must contain an index file.
   143  	FileNameIndexFile = "index.md"
   144  
   145  	// FileNameProposalMetadata is the file name of the user submitted
   146  	// ProposalMetadata. All proposal submissions must contain a
   147  	// proposal metadata file.
   148  	FileNameProposalMetadata = "proposalmetadata.json"
   149  
   150  	// FileNameVoteMetadata is the file name of the user submitted
   151  	// VoteMetadata. This file will only be present when proposals
   152  	// are hosting or participating in certain types of votes.
   153  	FileNameVoteMetadata = "votemetadata.json"
   154  )
   155  
   156  // ProposalMetadata contains metadata that is specified by the user on proposal
   157  // submission.
   158  type ProposalMetadata struct {
   159  	Name      string `json:"name"`      // Proposal name
   160  	Amount    uint64 `json:"amount"`    // Funding amount in cents
   161  	StartDate int64  `json:"startdate"` // Start date, Unix time
   162  	EndDate   int64  `json:"enddate"`   // Estimated end date, Unix time
   163  	Domain    string `json:"domain"`    // Proposal domain
   164  
   165  	// LegacyToken will only be set for legacy proposals that have been imported
   166  	// from the deprecated git backend into the tstore backend. The LegacyToken
   167  	// corresponds to the original token that was assigned to the proposal during
   168  	// submission to the git backed. This token is not used for anything in the
   169  	// current tstore backend, but can be used to lookup the proposal's original
   170  	// timestamps in the legacy proposal git repo. The proposal is assigned a
   171  	// new token by the tstore backend on import. An error is returned if this
   172  	// field is attempted to be set during normal proposal submissions.
   173  	LegacyToken string `json:"legacytoken,omitempty"`
   174  }
   175  
   176  // VoteMetadata is metadata that is specified by the user on proposal
   177  // submission in order to host or participate in a runoff vote.
   178  type VoteMetadata struct {
   179  	// LinkBy is set when the user intends for the proposal to be the
   180  	// parent proposal in a runoff vote. It is a UNIX timestamp that
   181  	// serves as the deadline for other proposals to declare their
   182  	// intent to participate in the runoff vote.
   183  	LinkBy int64 `json:"linkby,omitempty"`
   184  
   185  	// LinkTo is the censorship token of a runoff vote parent proposal.
   186  	// It is set when a proposal is being submitted as a vote options
   187  	// in the runoff vote.
   188  	LinkTo string `json:"linkto,omitempty"`
   189  }
   190  
   191  // BillingStatusT represents the billing status of a proposal that has been
   192  // approved by the Decred stakeholders.
   193  type BillingStatusT uint32
   194  
   195  const (
   196  	// BillingStatusInvalid is an invalid billing status.
   197  	BillingStatusInvalid BillingStatusT = 0
   198  
   199  	// BillingStatusActive represents a proposal that was approved by
   200  	// the Decred stakeholders and is being actively billed against.
   201  	BillingStatusActive BillingStatusT = 1
   202  
   203  	// BillingStatusClosed represents a proposal that was approved by
   204  	// the Decred stakeholders, but has been closed by an admin prior
   205  	// to the proposal being completed. The most common reason for this
   206  	// is because a proposal author failed to deliver on the work that
   207  	// was funded in the proposal. A closed proposal can no longer be
   208  	// billed against.
   209  	BillingStatusClosed BillingStatusT = 2
   210  
   211  	// BillingStatusCompleted represents a proposal that was approved
   212  	// by the Decred stakeholders and has been successfully completed.
   213  	// A completed proposal can no longer be billed against. A proposal
   214  	// is marked as completed by an admin.
   215  	BillingStatusCompleted BillingStatusT = 3
   216  
   217  	// BillingStatusLast unit test only.
   218  	BillingStatusLast BillingStatusT = 4
   219  )
   220  
   221  var (
   222  	// BillingStatuses contains the human readable billing statuses.
   223  	BillingStatuses = map[BillingStatusT]string{
   224  		BillingStatusInvalid:   "invalid",
   225  		BillingStatusActive:    "active",
   226  		BillingStatusClosed:    "closed",
   227  		BillingStatusCompleted: "completed",
   228  	}
   229  )
   230  
   231  // BillingStatusChange represents the structure that is saved to disk when
   232  // a proposal has its billing status updated. Some billing status changes
   233  // require a reason to be given. Only admins can update the billing status
   234  // of a proposal.
   235  //
   236  // PublicKey is the admin public key that can be used to verify the signature.
   237  //
   238  // Signature is the admin signature of the Token+Status+Reason.
   239  //
   240  // Receipt is the server signature of the admin signature.
   241  //
   242  // The PublicKey, Signature, and Receipt are all hex encoded and use the
   243  // ed25519 signature scheme.
   244  type BillingStatusChange struct {
   245  	Token     string         `json:"token"`
   246  	Status    BillingStatusT `json:"status"`
   247  	Reason    string         `json:"reason,omitempty"`
   248  	PublicKey string         `json:"publickey"`
   249  	Signature string         `json:"signature"`
   250  	Receipt   string         `json:"receipt"`
   251  	Timestamp int64          `json:"timestamp"` // Unix timestamp
   252  }
   253  
   254  // SetBillingStatus sets the billing status of a proposal. Some billing status
   255  // changes require a reason to be given. Only admins can update the billing
   256  // status of a proposal.
   257  //
   258  // PublicKey is the admin public key that can be used to verify the signature.
   259  //
   260  // Signature is the admin signature of the Token+Status+Reason.
   261  //
   262  // The PublicKey and Signature are hex encoded and use the ed25519 signature
   263  // scheme.
   264  type SetBillingStatus struct {
   265  	Token     string         `json:"token"`
   266  	Status    BillingStatusT `json:"status"`
   267  	Reason    string         `json:"reason,omitempty"`
   268  	PublicKey string         `json:"publickey"`
   269  	Signature string         `json:"signature"`
   270  }
   271  
   272  // SetBillingStatusReply is the reply to the SetBillingStatus command.
   273  //
   274  // Receipt is the server signature of the client signature. It is hex encoded
   275  // and uses the ed25519 signature scheme.
   276  type SetBillingStatusReply struct {
   277  	Receipt   string `json:"receipt"`
   278  	Timestamp int64  `json:"timestamp"` // Unix timestamp
   279  }
   280  
   281  const (
   282  	// BillingStatusChangesPageSize is the maximum number of billing status
   283  	// changes that can be requested at any one time.
   284  	//
   285  	// NOTE: This is DEPRECATED and will be deleted as part of the next major
   286  	// release. Use the API's Policy route to retrieve the routes page sizes.
   287  	BillingStatusChangesPageSize uint32 = 5
   288  )
   289  
   290  // BillingStatusChanges requests the billing status changes for the provided
   291  // proposal tokens.
   292  type BillingStatusChanges struct {
   293  	Tokens []string `json:"tokens"`
   294  }
   295  
   296  // BillingStatusChangesReply is the reply to the BillingStatusChanges command.
   297  //
   298  // BillingStatusChanges contains the billing status changes for each of the
   299  // provided tokens. The map will not contain an entry for any tokens that
   300  // did not correspond to an actual proposal. It is the callers responsibility
   301  // to ensure that the billing status changes are returned for all provided
   302  // tokens.
   303  type BillingStatusChangesReply struct {
   304  	BillingStatusChanges map[string][]BillingStatusChange `json:"billingstatuschanges"`
   305  }
   306  
   307  const (
   308  	// ProposalUpdateHint is the hint that is included in a comment's
   309  	// ExtraDataHint field to indicate that the comment is an update
   310  	// from the proposal author.
   311  	ProposalUpdateHint = "proposalupdate"
   312  )
   313  
   314  // ProposalUpdateMetadata contains the metadata that is attached to a comment
   315  // in the comment's ExtraData field to indicate that the comment is an update
   316  // from the proposal author.
   317  type ProposalUpdateMetadata struct {
   318  	Title string `json:"title"`
   319  }
   320  
   321  const (
   322  	// SummariesPageSize is the maximum number of proposal summaries that
   323  	// can be requested at any one time.
   324  	//
   325  	// NOTE: This is DEPRECATED and will be deleted as part of the next major
   326  	// release. Use the API's Policy route to retrieve the routes page sizes.
   327  	SummariesPageSize uint32 = 5
   328  )
   329  
   330  // Summaries requests the proposal summaries for the provided proposal tokens.
   331  type Summaries struct {
   332  	Tokens []string `json:"tokens"`
   333  }
   334  
   335  // SummariesReply is the reply to the Summaries command.
   336  //
   337  // Summaries field contains a proposal summary for each of the provided tokens.
   338  // The map will not contain an entry for any tokens that did not correspond
   339  // to an actual proposal. It is the callers responsibility to ensure that a
   340  // summary is returned for all provided tokens.
   341  type SummariesReply struct {
   342  	Summaries map[string]Summary `json:"summaries"` // [token]Summary
   343  }
   344  
   345  // Summary summarizes proposal information.
   346  //
   347  // Status field is the string value of the PropStatusT type which is defined
   348  // along with all of it's possible values in the pi plugin API.
   349  type Summary struct {
   350  	Status string `json:"status"`
   351  }