github.com/mysteriumnetwork/node@v0.0.0-20240516044423-365054f76801/tequilapi/endpoints/node.go (about)

     1  /*
     2   * Copyright (C) 2021 The "MysteriumNetwork/node" Authors.
     3   *
     4   * This program is free software: you can redistribute it and/or modify
     5   * it under the terms of the GNU General Public License as published by
     6   * the Free Software Foundation, either version 3 of the License, or
     7   * (at your option) any later version.
     8   *
     9   * This program is distributed in the hope that it will be useful,
    10   * but WITHOUT ANY WARRANTY; without even the implied warranty of
    11   * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
    12   * GNU General Public License for more details.
    13   *
    14   * You should have received a copy of the GNU General Public License
    15   * along with this program.  If not, see <http://www.gnu.org/licenses/>.
    16   */
    17  
    18  package endpoints
    19  
    20  import (
    21  	"math/big"
    22  	"net/http"
    23  	"strconv"
    24  
    25  	"github.com/gin-gonic/gin"
    26  	"github.com/rs/zerolog/log"
    27  
    28  	"github.com/mysteriumnetwork/go-rest/apierror"
    29  	"github.com/mysteriumnetwork/payments/units"
    30  
    31  	"github.com/mysteriumnetwork/node/core/node"
    32  	"github.com/mysteriumnetwork/node/tequilapi/contract"
    33  	"github.com/mysteriumnetwork/node/tequilapi/launchpad"
    34  	"github.com/mysteriumnetwork/node/tequilapi/utils"
    35  )
    36  
    37  type nodeMonitoringAgent interface {
    38  	Statuses() (node.MonitoringAgentStatuses, error)
    39  	Sessions(rangeTime string) ([]node.SessionItem, error)
    40  	TransferredData(rangeTime string) (node.TransferredData, error)
    41  	SessionsCount(rangeTime string) (node.SessionsCount, error)
    42  	ConsumersCount(rangeTime string) (node.ConsumersCount, error)
    43  	EarningsSeries(rangeTime string) (node.EarningsSeries, error)
    44  	SessionsSeries(rangeTime string) (node.SessionsSeries, error)
    45  	TransferredDataSeries(rangeTime string) (node.TransferredDataSeries, error)
    46  	ProviderActivityStats() (node.ActivityStats, error)
    47  	ProviderQuality() (node.QualityInfo, error)
    48  	EarningsPerService() (node.EarningsPerService, error)
    49  }
    50  
    51  // NodeEndpoint struct represents endpoints about node status
    52  type NodeEndpoint struct {
    53  	nodeStatusProvider  nodeStatusProvider
    54  	nodeMonitoringAgent nodeMonitoringAgent
    55  	launchpadAPI        *launchpad.API
    56  }
    57  
    58  // NewNodeEndpoint creates and returns node endpoints
    59  func NewNodeEndpoint(nodeStatusProvider nodeStatusProvider, nodeMonitoringAgent nodeMonitoringAgent) *NodeEndpoint {
    60  	return &NodeEndpoint{
    61  		nodeStatusProvider:  nodeStatusProvider,
    62  		nodeMonitoringAgent: nodeMonitoringAgent,
    63  		launchpadAPI:        launchpad.New(),
    64  	}
    65  }
    66  
    67  // NodeStatus Status provides Node proposal status
    68  // swagger:operation GET /node/monitoring-status provider NodeStatus
    69  //
    70  //	---
    71  //	summary: Provides Node proposal status
    72  //	description: Node Status as seen by monitoring agent
    73  //	responses:
    74  //	  200:
    75  //	    description: Node status ("passed"/"failed"/"pending)
    76  //	    schema:
    77  //	      "$ref": "#/definitions/NodeStatusResponse"
    78  func (ne *NodeEndpoint) NodeStatus(c *gin.Context) {
    79  	utils.WriteAsJSON(contract.NodeStatusResponse{Status: ne.nodeStatusProvider.Status()}, c.Writer)
    80  }
    81  
    82  // MonitoringAgentStatuses Statuses from monitoring agent
    83  // swagger:operation GET /node/monitoring-agent-statuses provider MonitoringAgentStatuses
    84  //
    85  //	---
    86  //	summary: Provides Node connectivity statuses from monitoring agent
    87  //	description: Node connectivity statuses as seen by monitoring agent
    88  //	responses:
    89  //	  200:
    90  //	    description: Monitoring agent statuses ("success"/"cancelled"/"connect_drop/"connect_fail/"internet_fail)
    91  //	    schema:
    92  //	      "$ref": "#/definitions/MonitoringAgentResponse"
    93  func (ne *NodeEndpoint) MonitoringAgentStatuses(c *gin.Context) {
    94  	res, err := ne.nodeMonitoringAgent.Statuses()
    95  	if err != nil {
    96  		utils.WriteAsJSON(contract.MonitoringAgentResponse{Error: err.Error()}, c.Writer, http.StatusInternalServerError)
    97  		return
    98  	}
    99  
   100  	utils.WriteAsJSON(contract.MonitoringAgentResponse{Statuses: res}, c.Writer)
   101  }
   102  
   103  // GetProviderSessions A list of sessions metrics during a period of time
   104  // swagger:operation GET /node/provider/sessions provider GetProviderSessions
   105  //
   106  //	---
   107  //	summary: Provides Node sessions data during a period of time
   108  //	description: Node sessions metrics during a period of time
   109  //	parameters:
   110  //	  - in: query
   111  //	    name: range
   112  //	    description: period of time ("1d", "7d", "30d")
   113  //	    type: string
   114  //	responses:
   115  //	  200:
   116  //	    description: Provider sessions list
   117  //	    schema:
   118  //	      "$ref": "#/definitions/ProviderSessionsResponse"
   119  //	  400:
   120  //	    description: Failed to parse or request validation failed
   121  //	    schema:
   122  //	      "$ref": "#/definitions/APIError"
   123  //	  500:
   124  //	    description: Internal server error
   125  //	    schema:
   126  //	      "$ref": "#/definitions/APIError"
   127  func (ne *NodeEndpoint) GetProviderSessions(c *gin.Context) {
   128  	rangeTime := c.Query("range")
   129  
   130  	switch rangeTime {
   131  	case "1d", "7d", "30d":
   132  	default:
   133  		c.Error(apierror.BadRequest("Invalid time range", contract.ErrorCodeProviderSessions))
   134  		return
   135  	}
   136  
   137  	res, err := ne.nodeMonitoringAgent.Sessions(rangeTime)
   138  	if err != nil {
   139  		c.Error(apierror.Internal("Could not get provider sessions list: "+err.Error(), contract.ErrorCodeProviderSessions))
   140  		return
   141  	}
   142  
   143  	utils.WriteAsJSON(contract.NewProviderSessionsResponse(res), c.Writer)
   144  }
   145  
   146  // GetProviderTransferredData A number of bytes transferred during a period of time
   147  // swagger:operation GET /node/provider/transferred-data provider GetProviderTransferredData
   148  //
   149  //	---
   150  //	summary: Provides total traffic served by the provider during a period of time
   151  //	description: Node transferred data during a period of time
   152  //	parameters:
   153  //	  - in: query
   154  //	    name: range
   155  //	    description: period of time ("1d", "7d", "30d")
   156  //	    type: string
   157  //	responses:
   158  //	  200:
   159  //	    description: Provider transferred data
   160  //	    schema:
   161  //	      "$ref": "#/definitions/ProviderTransferredDataResponse"
   162  //	  400:
   163  //	    description: Failed to parse or request validation failed
   164  //	    schema:
   165  //	      "$ref": "#/definitions/APIError"
   166  //	  500:
   167  //	    description: Internal server error
   168  //	    schema:
   169  //	      "$ref": "#/definitions/APIError"
   170  func (ne *NodeEndpoint) GetProviderTransferredData(c *gin.Context) {
   171  	rangeTime := c.Query("range")
   172  
   173  	switch rangeTime {
   174  	case "1d", "7d", "30d":
   175  	default:
   176  		c.Error(apierror.BadRequest("Invalid time range", contract.ErrorCodeProviderTransferredData))
   177  		return
   178  	}
   179  
   180  	res, err := ne.nodeMonitoringAgent.TransferredData(rangeTime)
   181  	if err != nil {
   182  		c.Error(apierror.Internal("Could not get provider transferred data: "+err.Error(), contract.ErrorCodeProviderTransferredData))
   183  		return
   184  	}
   185  
   186  	utils.WriteAsJSON(contract.ProviderTransferredDataResponse{Bytes: res.Bytes}, c.Writer)
   187  }
   188  
   189  // GetProviderSessionsCount A number of sessions during a period of time
   190  // swagger:operation GET /node/provider/sessions-count provider GetProviderSessionsCount
   191  //
   192  //	---
   193  //	summary: Provides Node sessions number during a period of time
   194  //	description: Node sessions count during a period of time
   195  //	parameters:
   196  //	  - in: query
   197  //	    name: range
   198  //	    description: period of time ("1d", "7d", "30d")
   199  //	    type: string
   200  //	responses:
   201  //	  200:
   202  //	    description: Provider sessions count
   203  //	    schema:
   204  //	      "$ref": "#/definitions/ProviderSessionsCountResponse"
   205  //	  400:
   206  //	    description: Failed to parse or request validation failed
   207  //	    schema:
   208  //	      "$ref": "#/definitions/APIError"
   209  //	  500:
   210  //	    description: Internal server error
   211  //	    schema:
   212  //	      "$ref": "#/definitions/APIError"
   213  func (ne *NodeEndpoint) GetProviderSessionsCount(c *gin.Context) {
   214  	rangeTime := c.Query("range")
   215  
   216  	switch rangeTime {
   217  	case "1d", "7d", "30d":
   218  	default:
   219  		c.Error(apierror.BadRequest("Invalid time range", contract.ErrorCodeProviderSessionsCount))
   220  		return
   221  	}
   222  
   223  	res, err := ne.nodeMonitoringAgent.SessionsCount(rangeTime)
   224  	if err != nil {
   225  		c.Error(apierror.Internal("Could not get provider sessions count: "+err.Error(), contract.ErrorCodeProviderSessionsCount))
   226  		return
   227  	}
   228  
   229  	utils.WriteAsJSON(contract.ProviderSessionsCountResponse{Count: res.Count}, c.Writer)
   230  }
   231  
   232  // GetProviderConsumersCount A number of consumers served during a period of time
   233  // swagger:operation GET /node/provider/consumers-count provider GetProviderConsumersCount
   234  //
   235  //	---
   236  //	summary: Provides Node consumers number served during a period of time
   237  //	description: Node unique consumers count served during a period of time.
   238  //	parameters:
   239  //	  - in: query
   240  //	    name: range
   241  //	    description: period of time ("1d", "7d", "30d")
   242  //	    type: string
   243  //	responses:
   244  //	  200:
   245  //	   description: Provider consumers count
   246  //	   schema:
   247  //	    "$ref": "#/definitions/ProviderConsumersCountResponse"
   248  //	  400:
   249  //	   description: Failed to parse or request validation failed
   250  //	   schema:
   251  //	    "$ref": "#/definitions/APIError"
   252  //	  500:
   253  //	   description: Internal server error
   254  //	   schema:
   255  //	    "$ref": "#/definitions/APIError"
   256  func (ne *NodeEndpoint) GetProviderConsumersCount(c *gin.Context) {
   257  	rangeTime := c.Query("range")
   258  
   259  	switch rangeTime {
   260  	case "1d", "7d", "30d":
   261  	default:
   262  		c.Error(apierror.BadRequest("Invalid time range", contract.ErrorCodeProviderConsumersCount))
   263  		return
   264  	}
   265  
   266  	res, err := ne.nodeMonitoringAgent.ConsumersCount(rangeTime)
   267  	if err != nil {
   268  		c.Error(apierror.Internal("Could not get provider consumers count: "+err.Error(), contract.ErrorCodeProviderConsumersCount))
   269  		return
   270  	}
   271  
   272  	utils.WriteAsJSON(contract.ProviderConsumersCountResponse{Count: res.Count}, c.Writer)
   273  }
   274  
   275  // GetProviderEarningsSeries A time series metrics of earnings during a period of time
   276  // swagger:operation GET /node/provider/series/earnings provider GetProviderEarningsSeries
   277  //
   278  //	---
   279  //	summary: Provides Node  time series metrics of earnings during a period of time
   280  //	description: Node time series metrics of earnings during a period of time.
   281  //	parameters:
   282  //	  - in: query
   283  //	    name: range
   284  //	    description: period of time ("1d", "7d", "30d")
   285  //	    type: string
   286  //	responses:
   287  //	  200:
   288  //	   description: Provider time series metrics of MYSTT earnings
   289  //	   schema:
   290  //	    "$ref": "#/definitions/ProviderEarningsSeriesResponse"
   291  //	  400:
   292  //	   description: Failed to parse or request validation failed
   293  //	   schema:
   294  //	    "$ref": "#/definitions/APIError"
   295  //	  500:
   296  //	   description: Internal server error
   297  //	   schema:
   298  //	    "$ref": "#/definitions/APIError"
   299  func (ne *NodeEndpoint) GetProviderEarningsSeries(c *gin.Context) {
   300  	rangeTime := c.Query("range")
   301  
   302  	switch rangeTime {
   303  	case "1d", "7d", "30d":
   304  	default:
   305  		c.Error(apierror.BadRequest("Invalid time range", contract.ErrorCodeProviderEarningsSeries))
   306  		return
   307  	}
   308  
   309  	res, err := ne.nodeMonitoringAgent.EarningsSeries(rangeTime)
   310  	if err != nil {
   311  		c.Error(apierror.Internal("Could not get provider earnings series: "+err.Error(), contract.ErrorCodeProviderEarningsSeries))
   312  		return
   313  	}
   314  
   315  	utils.WriteAsJSON(res, c.Writer)
   316  }
   317  
   318  // GetProviderSessionsSeries A time series metrics of sessions started during a period of time
   319  // swagger:operation GET /node/provider/series/sessions provider GetProviderSessionsSeries
   320  //
   321  //	---
   322  //	summary: Provides Node data series metrics of sessions started during a period of time
   323  //	description: Node time series metrics of sessions started during a period of time.
   324  //	parameters:
   325  //	  - in: query
   326  //	    name: range
   327  //	    description: period of time ("1d", "7d", "30d")
   328  //	    type: string
   329  //	responses:
   330  //	  200:
   331  //	   description: Provider time series metrics of started sessions
   332  //	   schema:
   333  //	    "$ref": "#/definitions/ProviderSessionsSeriesResponse"
   334  //	  400:
   335  //	   description: Failed to parse or request validation failed
   336  //	   schema:
   337  //	    "$ref": "#/definitions/APIError"
   338  //	  500:
   339  //	   description: Internal server error
   340  //	   schema:
   341  //	    "$ref": "#/definitions/APIError"
   342  func (ne *NodeEndpoint) GetProviderSessionsSeries(c *gin.Context) {
   343  	rangeTime := c.Query("range")
   344  
   345  	switch rangeTime {
   346  	case "1d", "7d", "30d":
   347  	default:
   348  		c.Error(apierror.BadRequest("Invalid time range", contract.ErrorCodeProviderSessionsSeries))
   349  		return
   350  	}
   351  
   352  	res, err := ne.nodeMonitoringAgent.SessionsSeries(rangeTime)
   353  	if err != nil {
   354  		c.Error(apierror.Internal("Could not get provider sessions series: "+err.Error(), contract.ErrorCodeProviderSessionsSeries))
   355  		return
   356  	}
   357  
   358  	utils.WriteAsJSON(res, c.Writer)
   359  }
   360  
   361  // GetProviderTransferredDataSeries A time series metrics of transferred bytes during a period of time
   362  // swagger:operation GET /node/provider/series/data provider GetProviderTransferredDataSeries
   363  //
   364  //	---
   365  //	summary: Provides Node data series metrics of transferred bytes
   366  //	description: Node data series metrics of transferred bytes during a period of time.
   367  //	parameters:
   368  //	  - in: query
   369  //	    name: range
   370  //	    description: period of time ("1d", "7d", "30d")
   371  //	    type: string
   372  //	responses:
   373  //	  200:
   374  //	   description: Provider time series metrics of transferred bytes
   375  //	   schema:
   376  //	    "$ref": "#/definitions/ProviderTransferredDataSeriesResponse"
   377  //	  400:
   378  //	   description: Failed to parse or request validation failed
   379  //	   schema:
   380  //	    "$ref": "#/definitions/APIError"
   381  //	  500:
   382  //	   description: Internal server error
   383  //	   schema:
   384  //	    "$ref": "#/definitions/APIError"
   385  func (ne *NodeEndpoint) GetProviderTransferredDataSeries(c *gin.Context) {
   386  	rangeTime := c.Query("range")
   387  
   388  	switch rangeTime {
   389  	case "1d", "7d", "30d":
   390  	default:
   391  		c.Error(apierror.BadRequest("Invalid time range", contract.ErrorCodeProviderTransferredDataSeries))
   392  		return
   393  	}
   394  
   395  	res, err := ne.nodeMonitoringAgent.TransferredDataSeries(rangeTime)
   396  	if err != nil {
   397  		c.Error(apierror.Internal("Could not get provider transferred data series: "+err.Error(), contract.ErrorCodeProviderTransferredDataSeries))
   398  		return
   399  	}
   400  
   401  	utils.WriteAsJSON(res, c.Writer)
   402  }
   403  
   404  // GetProviderQuality a quality of provider
   405  // swagger:operation GET /node/provider/quality provider GetProviderQuality
   406  //
   407  //	---
   408  //	summary: Provides Node quality
   409  //	description: Node connectivity quality
   410  //	responses:
   411  //	  200:
   412  //	    description: Provider quality
   413  //	    schema:
   414  //	      "$ref": "#/definitions/QualityInfoResponse"
   415  //	  400:
   416  //	    description: Failed to parse or request validation failed
   417  //	    schema:
   418  //	      "$ref": "#/definitions/APIError"
   419  //	  500:
   420  //	    description: Internal server error
   421  //	    schema:
   422  //	      "$ref": "#/definitions/APIError"
   423  func (ne *NodeEndpoint) GetProviderQuality(c *gin.Context) {
   424  	res, err := ne.nodeMonitoringAgent.ProviderQuality()
   425  	if err != nil {
   426  		c.Error(apierror.Internal("Could not get provider quality: "+err.Error(), contract.ErrorCodeProviderQuality))
   427  		return
   428  	}
   429  
   430  	utils.WriteAsJSON(res, c.Writer)
   431  }
   432  
   433  // GetProviderActivityStats is an activity stats of provider
   434  // swagger:operation GET /node/provider/activity-stats provider GetProviderActivityStats
   435  //
   436  //	---
   437  //	summary: Provides Node activity stats
   438  //	description: Node activity stats
   439  //	responses:
   440  //	  200:
   441  //	    description: Provider activity stats
   442  //	    schema:
   443  //	      "$ref": "#/definitions/ActivityStatsResponse"
   444  //	  400:
   445  //	    description: Failed to parse or request validation failed
   446  //	    schema:
   447  //	      "$ref": "#/definitions/APIError"
   448  //	  500:
   449  //	    description: Internal server error
   450  //	    schema:
   451  //	      "$ref": "#/definitions/APIError"
   452  func (ne *NodeEndpoint) GetProviderActivityStats(c *gin.Context) {
   453  
   454  	res, err := ne.nodeMonitoringAgent.ProviderActivityStats()
   455  	if err != nil {
   456  		c.Error(apierror.Internal("Could not get provider activity stats: "+err.Error(), contract.ErrorCodeProviderActivityStats))
   457  		return
   458  	}
   459  
   460  	utils.WriteAsJSON(res, c.Writer)
   461  }
   462  
   463  // GetLatestRelease retrieves information about the latest node release
   464  // swagger:operation GET /node/latest-release node GetLatestRelease
   465  //
   466  //	---
   467  //	summary: Latest Node release information
   468  //	description: Checks for latest Node release package and retrieves its information
   469  //	responses:
   470  //	  200:
   471  //	   description: Latest Node release information
   472  //	   schema:
   473  //	    "$ref": "#/definitions/LatestReleaseResponse"
   474  //	  500:
   475  //	   description: Failed to retrieve latest Node release information
   476  //	   schema:
   477  //	    "$ref": "#/definitions/APIError"
   478  func (ne *NodeEndpoint) GetLatestRelease(c *gin.Context) {
   479  	version, err := ne.launchpadAPI.LatestPublishedReleaseVersion()
   480  	if err != nil {
   481  		c.Error(apierror.Internal("Could not fetch latest release information", contract.ErrorCodeLatestReleaseInformation))
   482  		log.Error().Err(err).Msg("Could not fetch latest release information")
   483  		return
   484  	}
   485  
   486  	utils.WriteAsJSON(contract.LatestReleaseResponse{Version: version}, c.Writer)
   487  }
   488  
   489  // GetProviderServiceEarnings Node earnings per service and total earnings in the all network
   490  // swagger:operation GET /node/provider/service-earnings provider GetProviderServiceEarnings
   491  //
   492  //	---
   493  //	summary: Provides Node earnings per service and total earnings in the all network
   494  //	description: Node earnings per service and total earnings in the all network.
   495  //	responses:
   496  //	  200:
   497  //	   description: earnings per service and total earnings
   498  //	   schema:
   499  //	    "$ref": "#/definitions/EarningsPerServiceResponse"
   500  //	  400:
   501  //	   description: Failed to parse or request validation failed
   502  //	   schema:
   503  //	    "$ref": "#/definitions/APIError"
   504  //	  500:
   505  //	   description: Internal server error
   506  //	   schema:
   507  //	    "$ref": "#/definitions/APIError"
   508  func (ne *NodeEndpoint) GetProviderServiceEarnings(c *gin.Context) {
   509  	res, err := ne.nodeMonitoringAgent.EarningsPerService()
   510  	if err != nil {
   511  		c.Error(apierror.Internal("Could not get provider service earnings: "+err.Error(), contract.ErrorCodeProviderServiceEarnings))
   512  		return
   513  	}
   514  	public, _ := strconv.ParseFloat(res.EarningsPublic, 64)
   515  	vpn, _ := strconv.ParseFloat(res.EarningsVPN, 64)
   516  	scraping, _ := strconv.ParseFloat(res.EarningsScraping, 64)
   517  	dvpn, _ := strconv.ParseFloat(res.EarningsDVPN, 64)
   518  
   519  	totalPublic, _ := strconv.ParseFloat(res.TotalEarningsPublic, 64)
   520  	totalVPN, _ := strconv.ParseFloat(res.TotalEarningsVPN, 64)
   521  	totalScraping, _ := strconv.ParseFloat(res.TotalEarningsScraping, 64)
   522  	totalDVPN, _ := strconv.ParseFloat(res.TotalEarningsDVPN, 64)
   523  
   524  	publicTokens := units.FloatEthToBigIntWei(public)
   525  	vpnTokens := units.FloatEthToBigIntWei(vpn)
   526  	scrapingTokens := units.FloatEthToBigIntWei(scraping)
   527  	dvpnTokens := units.FloatEthToBigIntWei(dvpn)
   528  
   529  	totalPublicTokens := units.FloatEthToBigIntWei(totalPublic)
   530  	totalVPNTokens := units.FloatEthToBigIntWei(totalVPN)
   531  	totalScrapingTokens := units.FloatEthToBigIntWei(totalScraping)
   532  	totalDVPNTokens := units.FloatEthToBigIntWei(totalDVPN)
   533  
   534  	totalTokens := new(big.Int)
   535  	totalTokens.Add(publicTokens, vpnTokens)
   536  	totalTokens.Add(totalTokens, scrapingTokens)
   537  	totalTokens.Add(totalTokens, dvpnTokens)
   538  
   539  	data := contract.EarningsPerServiceResponse{
   540  		EarningsPublic:        contract.NewTokens(publicTokens),
   541  		EarningsVPN:           contract.NewTokens(vpnTokens),
   542  		EarningsScraping:      contract.NewTokens(scrapingTokens),
   543  		EarningsDVPN:          contract.NewTokens(dvpnTokens),
   544  		EarningsTotal:         contract.NewTokens(totalTokens),
   545  		TotalEarningsPublic:   contract.NewTokens(totalPublicTokens),
   546  		TotalEarningsVPN:      contract.NewTokens(totalVPNTokens),
   547  		TotalEarningsScraping: contract.NewTokens(totalScrapingTokens),
   548  		TotalEarningsDVPN:     contract.NewTokens(totalDVPNTokens),
   549  	}
   550  
   551  	utils.WriteAsJSON(data, c.Writer)
   552  }
   553  
   554  // AddRoutesForNode adds nat routes to given router
   555  func AddRoutesForNode(nodeStatusProvider nodeStatusProvider, nodeMonitoringAgent nodeMonitoringAgent) func(*gin.Engine) error {
   556  	nodeEndpoints := NewNodeEndpoint(nodeStatusProvider, nodeMonitoringAgent)
   557  
   558  	return func(e *gin.Engine) error {
   559  		nodeGroup := e.Group("/node")
   560  		{
   561  			nodeGroup.GET("/monitoring-status", nodeEndpoints.NodeStatus)
   562  			nodeGroup.GET("/monitoring-agent-statuses", nodeEndpoints.MonitoringAgentStatuses)
   563  			nodeGroup.GET("/provider/sessions", nodeEndpoints.GetProviderSessions)
   564  			nodeGroup.GET("/provider/transferred-data", nodeEndpoints.GetProviderTransferredData)
   565  			nodeGroup.GET("/provider/sessions-count", nodeEndpoints.GetProviderSessionsCount)
   566  			nodeGroup.GET("/provider/consumers-count", nodeEndpoints.GetProviderConsumersCount)
   567  			nodeGroup.GET("/provider/series/earnings", nodeEndpoints.GetProviderEarningsSeries)
   568  			nodeGroup.GET("/provider/series/sessions", nodeEndpoints.GetProviderSessionsSeries)
   569  			nodeGroup.GET("/provider/series/data", nodeEndpoints.GetProviderTransferredDataSeries)
   570  			nodeGroup.GET("/provider/service-earnings", nodeEndpoints.GetProviderServiceEarnings)
   571  			nodeGroup.GET("/latest-release", nodeEndpoints.GetLatestRelease)
   572  			nodeGroup.GET("/provider/quality", nodeEndpoints.GetProviderQuality)
   573  			nodeGroup.GET("/provider/activity-stats", nodeEndpoints.GetProviderActivityStats)
   574  		}
   575  		return nil
   576  	}
   577  }