github.com/mysteriumnetwork/node@v0.0.0-20240516044423-365054f76801/identity/registry/transactor.go (about)

     1  /*
     2   * Copyright (C) 2019 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 registry
    19  
    20  import (
    21  	"encoding/hex"
    22  	"fmt"
    23  	"math/big"
    24  	"strings"
    25  	"time"
    26  
    27  	"github.com/ethereum/go-ethereum/common"
    28  	"github.com/mysteriumnetwork/payments/client"
    29  	pc "github.com/mysteriumnetwork/payments/crypto"
    30  	"github.com/mysteriumnetwork/payments/registration"
    31  	"github.com/pkg/errors"
    32  	"github.com/rs/zerolog/log"
    33  
    34  	"github.com/mysteriumnetwork/node/eventbus"
    35  	"github.com/mysteriumnetwork/node/identity"
    36  	"github.com/mysteriumnetwork/node/requests"
    37  )
    38  
    39  // AppTopicTransactorRegistration represents the registration topic to which events regarding registration attempts on transactor will occur
    40  const AppTopicTransactorRegistration = "transactor_identity_registration"
    41  
    42  type channelProvider interface {
    43  	GetProviderChannel(chainID int64, hermesAddress common.Address, addressToCheck common.Address, pending bool) (client.ProviderChannel, error)
    44  	GetLastRegistryNonce(chainID int64, registry common.Address) (*big.Int, error)
    45  }
    46  
    47  // AddressProvider provides sc addresses.
    48  type AddressProvider interface {
    49  	GetActiveChannelImplementation(chainID int64) (common.Address, error)
    50  	GetActiveHermes(chainID int64) (common.Address, error)
    51  	GetRegistryAddress(chainID int64) (common.Address, error)
    52  	GetKnownHermeses(chainID int64) ([]common.Address, error)
    53  	GetChannelImplementationForHermes(chainID int64, hermes common.Address) (common.Address, error)
    54  	GetMystAddress(chainID int64) (common.Address, error)
    55  }
    56  
    57  type feeType uint8
    58  
    59  const (
    60  	settleFeeType        feeType = iota
    61  	registrationFeeType          = 1
    62  	stakeDecreaseFeeType         = 2
    63  )
    64  
    65  type feeCacher struct {
    66  	validityDuration time.Duration
    67  	feesMap          map[int64]map[feeType]feeCache
    68  }
    69  
    70  type feeCache struct {
    71  	FeesResponse
    72  	CacheValidUntil time.Time
    73  }
    74  
    75  func newFeeCacher(validityDuration time.Duration) *feeCacher {
    76  	return &feeCacher{
    77  		validityDuration: validityDuration,
    78  		feesMap:          make(map[int64]map[feeType]feeCache),
    79  	}
    80  }
    81  
    82  func (f *feeCacher) getCachedFee(chainId int64, feeType feeType) *FeesResponse {
    83  	if chainFees, ok := f.feesMap[chainId]; ok {
    84  		if fees, ok := chainFees[feeType]; ok {
    85  			if fees.CacheValidUntil.After(time.Now()) {
    86  				return &fees.FeesResponse
    87  			}
    88  		}
    89  	}
    90  	return nil
    91  }
    92  
    93  func (f *feeCacher) cacheFee(chainId int64, ftype feeType, response FeesResponse) {
    94  	_, ok := f.feesMap[chainId]
    95  	if !ok {
    96  		f.feesMap[chainId] = make(map[feeType]feeCache)
    97  	}
    98  	cacheExpiration := time.Now().Add(f.validityDuration)
    99  	feeCache := feeCache{
   100  		FeesResponse:    response,
   101  		CacheValidUntil: cacheExpiration,
   102  	}
   103  	if feeCache.CacheValidUntil.After(response.ValidUntil) {
   104  		feeCache.CacheValidUntil = response.ValidUntil
   105  	}
   106  	f.feesMap[chainId][ftype] = feeCache
   107  }
   108  
   109  // Transactor allows for convenient calls to the transactor service
   110  type Transactor struct {
   111  	httpClient      *requests.HTTPClient
   112  	endpointAddress string
   113  	signerFactory   identity.SignerFactory
   114  	publisher       eventbus.Publisher
   115  	bc              channelProvider
   116  	addresser       AddressProvider
   117  	feeCache        *feeCacher
   118  }
   119  
   120  // NewTransactor creates and returns new Transactor instance
   121  func NewTransactor(httpClient *requests.HTTPClient, endpointAddress string, addresser AddressProvider, signerFactory identity.SignerFactory, publisher eventbus.Publisher, bc channelProvider, feesValidTime time.Duration) *Transactor {
   122  	return &Transactor{
   123  		httpClient:      httpClient,
   124  		endpointAddress: endpointAddress,
   125  		signerFactory:   signerFactory,
   126  		addresser:       addresser,
   127  		publisher:       publisher,
   128  		bc:              bc,
   129  		feeCache:        newFeeCacher(feesValidTime),
   130  	}
   131  }
   132  
   133  // FeesResponse represents fees applied by Transactor
   134  type FeesResponse struct {
   135  	Fee        *big.Int  `json:"fee"`
   136  	ValidUntil time.Time `json:"valid_until"`
   137  }
   138  
   139  // IsValid returns false if the fee has already expired and should be re-requested
   140  func (fr FeesResponse) IsValid() bool {
   141  	return time.Now().UTC().Before(fr.ValidUntil.UTC())
   142  }
   143  
   144  // IdentityRegistrationRequest represents the identity registration request body
   145  type IdentityRegistrationRequest struct {
   146  	RegistryAddress string `json:"registryAddress"`
   147  	HermesID        string `json:"hermesID"`
   148  	// Stake is used by Provider, default 0
   149  	Stake *big.Int `json:"stake"`
   150  	// Fee: negotiated fee with transactor
   151  	Fee *big.Int `json:"fee"`
   152  	// Beneficiary: Provider channelID by default, optionally set during Identity registration.
   153  	// Can be updated later through transactor. We can check it's value directly from SC.
   154  	// Its a cache out address
   155  	Beneficiary string `json:"beneficiary"`
   156  	// Signature from fields above
   157  	Signature string `json:"signature"`
   158  	Identity  string `json:"identity"`
   159  	ChainID   int64  `json:"chainID"`
   160  }
   161  
   162  // PromiseSettlementRequest represents the settlement request body
   163  type PromiseSettlementRequest struct {
   164  	HermesID      string   `json:"hermesID"`
   165  	ChannelID     string   `json:"channelID"`
   166  	Amount        *big.Int `json:"amount"`
   167  	TransactorFee *big.Int `json:"fee"`
   168  	Preimage      string   `json:"preimage"`
   169  	Signature     string   `json:"signature"`
   170  	ProviderID    string   `json:"providerID"`
   171  	ChainID       int64    `json:"chainID"`
   172  }
   173  
   174  // FetchRegistrationFees fetches current transactor registration fees
   175  func (t *Transactor) FetchRegistrationFees(chainID int64) (FeesResponse, error) {
   176  	cachedFees := t.feeCache.getCachedFee(chainID, registrationFeeType)
   177  	if cachedFees != nil {
   178  		return *cachedFees, nil
   179  	}
   180  
   181  	f := FeesResponse{}
   182  	req, err := requests.NewGetRequest(t.endpointAddress, fmt.Sprintf("fee/%v/register", chainID), nil)
   183  	if err != nil {
   184  		return f, errors.Wrap(err, "failed to fetch transactor fees")
   185  	}
   186  
   187  	err = t.httpClient.DoRequestAndParseResponse(req, &f)
   188  	if err == nil {
   189  		t.feeCache.cacheFee(chainID, registrationFeeType, f)
   190  	}
   191  	return f, err
   192  }
   193  
   194  // FetchSettleFees fetches current transactor settlement fees
   195  func (t *Transactor) FetchSettleFees(chainID int64) (FeesResponse, error) {
   196  	cachedFees := t.feeCache.getCachedFee(chainID, settleFeeType)
   197  	if cachedFees != nil {
   198  		return *cachedFees, nil
   199  	}
   200  
   201  	f := FeesResponse{}
   202  	req, err := requests.NewGetRequest(t.endpointAddress, fmt.Sprintf("fee/%v/settle", chainID), nil)
   203  	if err != nil {
   204  		return f, errors.Wrap(err, "failed to fetch transactor fees")
   205  	}
   206  
   207  	err = t.httpClient.DoRequestAndParseResponse(req, &f)
   208  	if err == nil {
   209  		t.feeCache.cacheFee(chainID, settleFeeType, f)
   210  	}
   211  	return f, err
   212  }
   213  
   214  // FetchStakeDecreaseFee fetches current transactor stake decrease fees.
   215  func (t *Transactor) FetchStakeDecreaseFee(chainID int64) (FeesResponse, error) {
   216  	cachedFees := t.feeCache.getCachedFee(chainID, stakeDecreaseFeeType)
   217  	if cachedFees != nil {
   218  		return *cachedFees, nil
   219  	}
   220  
   221  	f := FeesResponse{}
   222  	req, err := requests.NewGetRequest(t.endpointAddress, fmt.Sprintf("fee/%v/stake/decrease", chainID), nil)
   223  	if err != nil {
   224  		return f, errors.Wrap(err, "failed to fetch transactor fees")
   225  	}
   226  
   227  	err = t.httpClient.DoRequestAndParseResponse(req, &f)
   228  	if err == nil {
   229  		t.feeCache.cacheFee(chainID, stakeDecreaseFeeType, f)
   230  	}
   231  	return f, err
   232  }
   233  
   234  // CombinedFeesResponse represents the combined fees response.
   235  type CombinedFeesResponse struct {
   236  	Current    Fees      `json:"current"`
   237  	Last       Fees      `json:"last"`
   238  	ServerTime time.Time `json:"server_time"`
   239  }
   240  
   241  // Fees represents fees for a given time frame.
   242  type Fees struct {
   243  	DecreaseStake *big.Int  `json:"decreaseStake"`
   244  	Settle        *big.Int  `json:"settle"`
   245  	Register      *big.Int  `json:"register"`
   246  	ValidUntil    time.Time `json:"valid_until"`
   247  }
   248  
   249  // FetchCombinedFees fetches current transactor fees.
   250  func (t *Transactor) FetchCombinedFees(chainID int64) (CombinedFeesResponse, error) {
   251  	f := CombinedFeesResponse{}
   252  	req, err := requests.NewGetRequest(t.endpointAddress, fmt.Sprintf("fee/%v", chainID), nil)
   253  	if err != nil {
   254  		return f, errors.Wrap(err, "failed to fetch transactor fees")
   255  	}
   256  
   257  	err = t.httpClient.DoRequestAndParseResponse(req, &f)
   258  	return f, err
   259  }
   260  
   261  // SettleAndRebalance requests the transactor to settle and rebalance the given channel
   262  func (t *Transactor) SettleAndRebalance(hermesID, providerID string, promise pc.Promise) (string, error) {
   263  	payload := PromiseSettlementRequest{
   264  		HermesID:      hermesID,
   265  		ProviderID:    providerID,
   266  		ChannelID:     hex.EncodeToString(promise.ChannelID),
   267  		Amount:        promise.Amount,
   268  		TransactorFee: promise.Fee,
   269  		Preimage:      hex.EncodeToString(promise.R),
   270  		Signature:     hex.EncodeToString(promise.Signature),
   271  		ChainID:       promise.ChainID,
   272  	}
   273  
   274  	req, err := requests.NewPostRequest(t.endpointAddress, "identity/settle_and_rebalance", payload)
   275  	if err != nil {
   276  		return "", errors.Wrap(err, "failed to create settle and rebalance request")
   277  	}
   278  	res := SettleResponse{}
   279  	return res.ID, t.httpClient.DoRequestAndParseResponse(req, &res)
   280  }
   281  
   282  func (t *Transactor) registerIdentity(endpoint string, id string, stake, fee *big.Int, beneficiary string, chainID int64) error {
   283  	regReq, err := t.fillIdentityRegistrationRequest(id, stake, fee, beneficiary, chainID)
   284  	if err != nil {
   285  		return errors.Wrap(err, "failed to fill in identity request")
   286  	}
   287  
   288  	err = t.validateRegisterIdentityRequest(regReq)
   289  	if err != nil {
   290  		return errors.Wrap(err, "identity request validation failed")
   291  	}
   292  
   293  	req, err := requests.NewPostRequest(t.endpointAddress, endpoint, regReq)
   294  	if err != nil {
   295  		return errors.Wrap(err, "failed to create RegisterIdentity request")
   296  	}
   297  
   298  	err = t.httpClient.DoRequest(req)
   299  	if err != nil {
   300  		return err
   301  	}
   302  
   303  	// This is left as a synchronous call on purpose.
   304  	// We need to notify registry before returning.
   305  	t.publisher.Publish(AppTopicTransactorRegistration, regReq)
   306  
   307  	return nil
   308  }
   309  
   310  type identityRegistrationRequestWithToken struct {
   311  	IdentityRegistrationRequest
   312  	Token string `json:"token"`
   313  }
   314  
   315  func (t *Transactor) registerIdentityWithReferralToken(id string, stake *big.Int, beneficiary string, token string, chainID int64) error {
   316  	regReq, err := t.fillIdentityRegistrationRequest(id, stake, new(big.Int), beneficiary, chainID)
   317  	if err != nil {
   318  		return errors.Wrap(err, "failed to fill in identity request")
   319  	}
   320  
   321  	err = t.validateRegisterIdentityRequest(regReq)
   322  	if err != nil {
   323  		return errors.Wrap(err, "identity request validation failed")
   324  	}
   325  
   326  	r := identityRegistrationRequestWithToken{
   327  		IdentityRegistrationRequest: regReq,
   328  		Token:                       token,
   329  	}
   330  
   331  	req, err := requests.NewPostRequest(t.endpointAddress, "identity/register/referer", r)
   332  	if err != nil {
   333  		return errors.Wrap(err, "failed to create RegisterIdentity request")
   334  	}
   335  
   336  	err = t.httpClient.DoRequest(req)
   337  	if err != nil {
   338  		return err
   339  	}
   340  
   341  	// This is left as a synchronous call on purpose.
   342  	// We need to notify registry before returning.
   343  	t.publisher.Publish(AppTopicTransactorRegistration, regReq)
   344  
   345  	return nil
   346  }
   347  
   348  // TokenRewardResponse represents the token reward response.
   349  type TokenRewardResponse struct {
   350  	Reward *big.Int `json:"reward"`
   351  }
   352  
   353  // RegisterIdentity instructs Transactor to register identity on behalf of a client identified by 'id'
   354  func (t *Transactor) RegisterIdentity(id string, stake, fee *big.Int, beneficiary string, chainID int64, referralToken *string) error {
   355  	if referralToken == nil {
   356  		return t.registerIdentity("identity/register", id, stake, fee, beneficiary, chainID)
   357  	}
   358  
   359  	return t.registerIdentityWithReferralToken(id, stake, beneficiary, *referralToken, chainID)
   360  }
   361  
   362  // RegisterProviderIdentity instructs Transactor to register Provider on behalf of a client identified by 'id'
   363  func (t *Transactor) RegisterProviderIdentity(id string, stake, fee *big.Int, beneficiary string, chainID int64, referralToken *string) error {
   364  	if referralToken == nil {
   365  		return t.registerIdentity("identity/register/provider", id, stake, fee, beneficiary, chainID)
   366  	}
   367  
   368  	return t.registerIdentityWithReferralToken(id, stake, beneficiary, *referralToken, chainID)
   369  }
   370  
   371  func (t *Transactor) fillIdentityRegistrationRequest(id string, stake, fee *big.Int, beneficiary string, chainID int64) (IdentityRegistrationRequest, error) {
   372  	registry, err := t.addresser.GetRegistryAddress(chainID)
   373  	if err != nil {
   374  		return IdentityRegistrationRequest{}, err
   375  	}
   376  
   377  	hermes, err := t.addresser.GetActiveHermes(chainID)
   378  	if err != nil {
   379  		return IdentityRegistrationRequest{}, err
   380  	}
   381  
   382  	chimp, err := t.addresser.GetActiveChannelImplementation(chainID)
   383  	if err != nil {
   384  		return IdentityRegistrationRequest{}, err
   385  	}
   386  
   387  	regReq := IdentityRegistrationRequest{
   388  		RegistryAddress: registry.Hex(),
   389  		HermesID:        hermes.Hex(),
   390  		Stake:           stake,
   391  		Fee:             fee,
   392  		Beneficiary:     beneficiary,
   393  		ChainID:         chainID,
   394  	}
   395  
   396  	if regReq.Stake == nil {
   397  		regReq.Stake = big.NewInt(0)
   398  	}
   399  
   400  	if regReq.Fee == nil {
   401  		fees, err := t.FetchRegistrationFees(chainID)
   402  		if err != nil {
   403  			return IdentityRegistrationRequest{}, errors.Wrap(err, "could not get registration fees")
   404  		}
   405  		regReq.Fee = fees.Fee
   406  	}
   407  
   408  	if regReq.Beneficiary == "" {
   409  		channelAddress, err := pc.GenerateChannelAddress(id, hermes.Hex(), registry.Hex(), chimp.Hex())
   410  		if err != nil {
   411  			return IdentityRegistrationRequest{}, errors.Wrap(err, "failed to calculate channel address")
   412  		}
   413  
   414  		regReq.Beneficiary = channelAddress
   415  	}
   416  
   417  	signer := t.signerFactory(identity.FromAddress(id))
   418  
   419  	sig, err := t.signRegistrationRequest(signer, regReq)
   420  	if err != nil {
   421  		return IdentityRegistrationRequest{}, errors.Wrap(err, "failed to sign identity registration request")
   422  	}
   423  
   424  	signatureHex := common.Bytes2Hex(sig)
   425  	regReq.Signature = strings.ToLower(fmt.Sprintf("0x%v", signatureHex))
   426  	regReq.Identity = id
   427  
   428  	return regReq, nil
   429  }
   430  
   431  func (t *Transactor) getReferralTokenRequest(id common.Address) (pc.ReferralTokenRequest, error) {
   432  	signature, err := t.signerFactory(identity.FromAddress(id.Hex())).Sign(id.Bytes())
   433  	return pc.ReferralTokenRequest{
   434  		Identity:  id,
   435  		Signature: hex.EncodeToString(signature.Bytes()),
   436  	}, err
   437  }
   438  
   439  func (t *Transactor) validateRegisterIdentityRequest(regReq IdentityRegistrationRequest) error {
   440  	if regReq.HermesID == "" {
   441  		return errors.New("HermesID is required")
   442  	}
   443  	if regReq.RegistryAddress == "" {
   444  		return errors.New("RegistryAddress is required")
   445  	}
   446  	return nil
   447  }
   448  
   449  func (t *Transactor) signRegistrationRequest(signer identity.Signer, regReq IdentityRegistrationRequest) ([]byte, error) {
   450  	req := registration.Request{
   451  		RegistryAddress: strings.ToLower(regReq.RegistryAddress),
   452  		HermesID:        strings.ToLower(regReq.HermesID),
   453  		Stake:           regReq.Stake,
   454  		Fee:             regReq.Fee,
   455  		Beneficiary:     strings.ToLower(regReq.Beneficiary),
   456  		ChainID:         regReq.ChainID,
   457  	}
   458  
   459  	message := req.GetMessage()
   460  
   461  	signature, err := signer.Sign(message)
   462  	if err != nil {
   463  		return nil, errors.Wrap(err, "failed to sign a registration request")
   464  	}
   465  
   466  	err = pc.ReformatSignatureVForBC(signature.Bytes())
   467  	if err != nil {
   468  		return nil, errors.Wrap(err, "signature reformat failed")
   469  	}
   470  
   471  	return signature.Bytes(), nil
   472  }
   473  
   474  // OpenChannelRequest represents the open consumer channel request body
   475  type OpenChannelRequest struct {
   476  	TransactorFee   *big.Int `json:"transactorFee"`
   477  	Signature       string   `json:"signature"`
   478  	HermesID        string   `json:"hermesID"`
   479  	ChainID         int64    `json:"chainID"`
   480  	RegistryAddress string   `json:"registry_address"`
   481  }
   482  
   483  // sign OpenChannelRequest by identity's signer
   484  func (t *Transactor) signOpenChannelRequest(signer identity.Signer, req *OpenChannelRequest) error {
   485  	r := registration.OpenConsumerChannelRequest{
   486  		ChainID:         req.ChainID,
   487  		HermesID:        req.HermesID,
   488  		TransactorFee:   req.TransactorFee,
   489  		RegistryAddress: req.RegistryAddress,
   490  	}
   491  	message := r.GetMessage()
   492  
   493  	signature, err := signer.Sign(message)
   494  	if err != nil {
   495  		return fmt.Errorf("failed to sign a open channel request: %w", err)
   496  	}
   497  
   498  	err = pc.ReformatSignatureVForBC(signature.Bytes())
   499  	if err != nil {
   500  		return fmt.Errorf("signature reformat failed: %w", err)
   501  	}
   502  
   503  	signatureHex := common.Bytes2Hex(signature.Bytes())
   504  	req.Signature = strings.ToLower(fmt.Sprintf("0x%v", signatureHex))
   505  
   506  	return nil
   507  }
   508  
   509  // create request for open  channel
   510  func (t *Transactor) createOpenChannelRequest(chainID int64, id, hermesID, registryAddress string) (OpenChannelRequest, error) {
   511  	request := OpenChannelRequest{
   512  		TransactorFee:   new(big.Int),
   513  		HermesID:        hermesID,
   514  		ChainID:         chainID,
   515  		RegistryAddress: registryAddress,
   516  	}
   517  
   518  	signer := t.signerFactory(identity.FromAddress(id))
   519  	err := t.signOpenChannelRequest(signer, &request)
   520  	if err != nil {
   521  		return request, fmt.Errorf("failed to sign open channel request: %w", err)
   522  	}
   523  
   524  	return request, nil
   525  }
   526  
   527  // OpenChannel opens payment channel for consumer for certain Hermes
   528  func (t *Transactor) OpenChannel(chainID int64, id, hermesID, registryAddress string) error {
   529  	endpoint := "channel/open"
   530  	request, err := t.createOpenChannelRequest(chainID, id, hermesID, registryAddress)
   531  	if err != nil {
   532  		return fmt.Errorf("failed to create open channel request: %w", err)
   533  	}
   534  
   535  	req, err := requests.NewPostRequest(t.endpointAddress, endpoint, request)
   536  	if err != nil {
   537  		return fmt.Errorf("failed to do open channel request: %w", err)
   538  	}
   539  
   540  	return t.httpClient.DoRequest(req)
   541  }
   542  
   543  // ChannelStatusRequest request for channel status
   544  type ChannelStatusRequest struct {
   545  	Identity        string `json:"identity"`
   546  	HermesID        string `json:"hermesID"`
   547  	ChainID         int64  `json:"chainID"`
   548  	RegistryAddress string `json:"registry_address"`
   549  }
   550  
   551  // ChannelStatus represents status of the channel
   552  type ChannelStatus = string
   553  
   554  const (
   555  	// ChannelStatusNotFound channel is not opened and the request was not sent
   556  	ChannelStatusNotFound = ChannelStatus("not_found")
   557  	// ChannelStatusOpen channel successfully opened
   558  	ChannelStatusOpen = ChannelStatus("open")
   559  	// ChannelStatusFail channel open transaction fails
   560  	ChannelStatusFail = ChannelStatus("fail")
   561  	// ChannelStatusInProgress channel opening is in progress
   562  	ChannelStatusInProgress = ChannelStatus("in_progress")
   563  )
   564  
   565  // ChannelStatusResponse represents response with channel status
   566  type ChannelStatusResponse struct {
   567  	Status ChannelStatus `json:"status"`
   568  }
   569  
   570  // ChannelStatus check the status of the channel
   571  func (t *Transactor) ChannelStatus(chainID int64, id, hermesID, registryAddress string) (ChannelStatusResponse, error) {
   572  	endpoint := "channel/status"
   573  	request := ChannelStatusRequest{
   574  		HermesID:        hermesID,
   575  		Identity:        id,
   576  		ChainID:         chainID,
   577  		RegistryAddress: registryAddress,
   578  	}
   579  
   580  	req, err := requests.NewPostRequest(t.endpointAddress, endpoint, request)
   581  	if err != nil {
   582  		return ChannelStatusResponse{}, fmt.Errorf("failed to create channel status request: %w", err)
   583  	}
   584  
   585  	res := ChannelStatusResponse{}
   586  	err = t.httpClient.DoRequestAndParseResponse(req, &res)
   587  	if err != nil {
   588  		return ChannelStatusResponse{}, fmt.Errorf("failed to do channel status request: %w", err)
   589  	}
   590  
   591  	return res, nil
   592  }
   593  
   594  // SettleWithBeneficiaryRequest represent the request for setting new beneficiary address.
   595  type SettleWithBeneficiaryRequest struct {
   596  	Promise     PromiseSettlementRequest
   597  	Beneficiary string   `json:"beneficiary"`
   598  	Nonce       *big.Int `json:"nonce"`
   599  	Signature   string   `json:"signature"`
   600  	ProviderID  string   `json:"providerID"`
   601  	ChainID     int64    `json:"chainID"`
   602  	Registry    string   `json:"registry"`
   603  }
   604  
   605  // QueueResponse represents the queue response from transactor.
   606  type QueueResponse struct {
   607  	ID    string `json:"id"`
   608  	Hash  string `json:"tx_hash"`
   609  	State string `json:"state"`
   610  	Error string `json:"error"`
   611  }
   612  
   613  // GetQueueStatus returns the queued transaction status from transactor.
   614  func (t *Transactor) GetQueueStatus(ID string) (QueueResponse, error) {
   615  	req, err := requests.NewGetRequest(t.endpointAddress, fmt.Sprintf("queue/%v", ID), nil)
   616  	if err != nil {
   617  		return QueueResponse{}, fmt.Errorf("failed to create RegisterIdentity request %w", err)
   618  	}
   619  	res := QueueResponse{}
   620  	return res, t.httpClient.DoRequestAndParseResponse(req, &res)
   621  }
   622  
   623  // SettleResponse represents the settle response from transactor.
   624  type SettleResponse struct {
   625  	ID string `json:"id"`
   626  }
   627  
   628  // SettleWithBeneficiary instructs Transactor to set beneficiary on behalf of a client identified by 'id'
   629  func (t *Transactor) SettleWithBeneficiary(id, beneficiary, hermesID string, promise pc.Promise) (string, error) {
   630  	registry, err := t.addresser.GetRegistryAddress(promise.ChainID)
   631  	if err != nil {
   632  		return "", err
   633  	}
   634  
   635  	signedReq, err := t.fillSetBeneficiaryRequest(promise.ChainID, id, beneficiary, registry.Hex())
   636  	if err != nil {
   637  		return "", fmt.Errorf("failed to fill in set beneficiary request: %w", err)
   638  	}
   639  
   640  	payload := SettleWithBeneficiaryRequest{
   641  		Promise: PromiseSettlementRequest{
   642  			HermesID:      hermesID,
   643  			ChannelID:     hex.EncodeToString(promise.ChannelID),
   644  			Amount:        promise.Amount,
   645  			TransactorFee: promise.Fee,
   646  			Preimage:      hex.EncodeToString(promise.R),
   647  			Signature:     hex.EncodeToString(promise.Signature),
   648  			ChainID:       promise.ChainID,
   649  			ProviderID:    id,
   650  		},
   651  		Beneficiary: signedReq.Beneficiary,
   652  		Nonce:       signedReq.Nonce,
   653  		Signature:   signedReq.Signature,
   654  		ProviderID:  id,
   655  		ChainID:     promise.ChainID,
   656  		Registry:    registry.Hex(),
   657  	}
   658  
   659  	req, err := requests.NewPostRequest(t.endpointAddress, "identity/settle_with_beneficiary", payload)
   660  	if err != nil {
   661  		return "", fmt.Errorf("failed to create RegisterIdentity request %w", err)
   662  	}
   663  
   664  	res := SettleResponse{}
   665  	return res.ID, t.httpClient.DoRequestAndParseResponse(req, &res)
   666  }
   667  
   668  func (t *Transactor) fillSetBeneficiaryRequest(chainID int64, id, beneficiary, registry string) (pc.SetBeneficiaryRequest, error) {
   669  	nonce, err := t.bc.GetLastRegistryNonce(chainID, common.HexToAddress(registry))
   670  	if err != nil {
   671  		return pc.SetBeneficiaryRequest{}, fmt.Errorf("failed to get last registry nonce: %w", err)
   672  	}
   673  
   674  	regReq := pc.SetBeneficiaryRequest{
   675  		ChainID:     chainID,
   676  		Registry:    registry,
   677  		Beneficiary: strings.ToLower(beneficiary),
   678  		Identity:    id,
   679  		Nonce:       new(big.Int).Add(nonce, big.NewInt(1)),
   680  	}
   681  
   682  	signer := t.signerFactory(identity.FromAddress(id))
   683  
   684  	sig, err := t.signSetBeneficiaryRequest(signer, regReq)
   685  	if err != nil {
   686  		return pc.SetBeneficiaryRequest{}, fmt.Errorf("failed to sign set beneficiary request: %w", err)
   687  	}
   688  
   689  	signatureHex := common.Bytes2Hex(sig)
   690  	regReq.Signature = strings.ToLower(fmt.Sprintf("0x%v", signatureHex))
   691  
   692  	return regReq, nil
   693  }
   694  
   695  func (t *Transactor) signSetBeneficiaryRequest(signer identity.Signer, req pc.SetBeneficiaryRequest) ([]byte, error) {
   696  	message := req.GetMessage()
   697  
   698  	signature, err := signer.Sign(message)
   699  	if err != nil {
   700  		return nil, fmt.Errorf("failed to sign set beneficiary request: %w", err)
   701  	}
   702  
   703  	err = pc.ReformatSignatureVForBC(signature.Bytes())
   704  	if err != nil {
   705  		return nil, fmt.Errorf("signature reformat failed: %w", err)
   706  	}
   707  
   708  	return signature.Bytes(), nil
   709  }
   710  
   711  // TransactorRegistrationEntryStatus represents the registration status.
   712  type TransactorRegistrationEntryStatus string
   713  
   714  const (
   715  	// TransactorRegistrationEntryStatusCreated tells us that the registration is created.
   716  	TransactorRegistrationEntryStatusCreated = TransactorRegistrationEntryStatus("created")
   717  	// TransactorRegistrationEntryStatusPriceIncreased tells us that registration was requeued with an increased price.
   718  	TransactorRegistrationEntryStatusPriceIncreased = TransactorRegistrationEntryStatus("priceIncreased")
   719  	// TransactorRegistrationEntryStatusFailed tells us that the registration has failed.
   720  	TransactorRegistrationEntryStatusFailed = TransactorRegistrationEntryStatus("failed")
   721  	// TransactorRegistrationEntryStatusSucceed tells us that the registration has succeeded.
   722  	TransactorRegistrationEntryStatusSucceed = TransactorRegistrationEntryStatus("succeed")
   723  )
   724  
   725  // TransactorStatusResponse represents the current registration status.
   726  type TransactorStatusResponse struct {
   727  	IdentityID   string                            `json:"identity_id"`
   728  	Status       TransactorRegistrationEntryStatus `json:"status"`
   729  	TxHash       string                            `json:"tx_hash"`
   730  	CreatedAt    time.Time                         `json:"created_at"`
   731  	UpdatedAt    time.Time                         `json:"updated_at"`
   732  	BountyAmount *big.Int                          `json:"bounty_amount"`
   733  	ChainID      int64                             `json:"chain_id"`
   734  }
   735  
   736  // FetchRegistrationStatus fetches current transactor registration status for given identity.
   737  func (t *Transactor) FetchRegistrationStatus(id string) ([]TransactorStatusResponse, error) {
   738  	req, err := requests.NewGetRequest(t.endpointAddress, fmt.Sprintf("identity/%v/status", id), nil)
   739  	if err != nil {
   740  		return nil, fmt.Errorf("failed to fetch transactor registration status: %w", err)
   741  	}
   742  
   743  	var resp []TransactorStatusResponse
   744  	return resp, t.httpClient.DoRequestAndParseResponse(req, &resp)
   745  }
   746  
   747  // SettleIntoStake requests the transactor to settle and transfer the balance to stake.
   748  func (t *Transactor) SettleIntoStake(hermesID, providerID string, promise pc.Promise) (string, error) {
   749  	payload := PromiseSettlementRequest{
   750  		HermesID:      hermesID,
   751  		ChannelID:     hex.EncodeToString(promise.ChannelID),
   752  		Amount:        promise.Amount,
   753  		TransactorFee: promise.Fee,
   754  		Preimage:      hex.EncodeToString(promise.R),
   755  		Signature:     hex.EncodeToString(promise.Signature),
   756  		ProviderID:    providerID,
   757  		ChainID:       promise.ChainID,
   758  	}
   759  
   760  	req, err := requests.NewPostRequest(t.endpointAddress, "identity/settle/into_stake", payload)
   761  	if err != nil {
   762  		return "", errors.Wrap(err, "failed to create settle into stake request")
   763  	}
   764  	res := SettleResponse{}
   765  	return res.ID, t.httpClient.DoRequestAndParseResponse(req, &res)
   766  }
   767  
   768  // EligibilityResponse shows if one is eligible for free registration.
   769  type EligibilityResponse struct {
   770  	Eligible bool `json:"eligible"`
   771  }
   772  
   773  // GetFreeProviderRegistrationEligibility determines if there are any free provider registrations available.
   774  func (t *Transactor) GetFreeProviderRegistrationEligibility() (bool, error) {
   775  	e := EligibilityResponse{}
   776  
   777  	req, err := requests.NewGetRequest(t.endpointAddress, "identity/register/provider/eligibility", nil)
   778  	if err != nil {
   779  		return false, errors.Wrap(err, "failed to fetch registration eligibility")
   780  	}
   781  
   782  	err = t.httpClient.DoRequestAndParseResponse(req, &e)
   783  	return e.Eligible, err
   784  }
   785  
   786  // GetFreeRegistrationEligibility determines if the identity is eligible for free registration.
   787  func (t *Transactor) GetFreeRegistrationEligibility(identity identity.Identity) (bool, error) {
   788  	e := EligibilityResponse{}
   789  
   790  	req, err := requests.NewGetRequest(t.endpointAddress, fmt.Sprintf("identity/register/eligibility/%v", identity.Address), nil)
   791  	if err != nil {
   792  		return false, errors.Wrap(err, "failed to fetch registration eligibility")
   793  	}
   794  
   795  	err = t.httpClient.DoRequestAndParseResponse(req, &e)
   796  	return e.Eligible, err
   797  }
   798  
   799  // PayAndSettlePayload represents the pay and settle payload.
   800  type PayAndSettlePayload struct {
   801  	PromiseSettlementRequest
   802  	Beneficiary          string `json:"beneficiary"`
   803  	BeneficiarySignature string `json:"beneficiarySignature"`
   804  }
   805  
   806  // PayAndSettle requests the transactor to withdraw money into l1.
   807  func (t *Transactor) PayAndSettle(hermesID, providerID string, promise pc.Promise, beneficiary string, beneficiarySignature string) (string, error) {
   808  	payload := PayAndSettlePayload{
   809  		PromiseSettlementRequest: PromiseSettlementRequest{
   810  			HermesID:      hermesID,
   811  			ChannelID:     hex.EncodeToString(promise.ChannelID),
   812  			Amount:        promise.Amount,
   813  			TransactorFee: promise.Fee,
   814  			Preimage:      hex.EncodeToString(promise.R),
   815  			Signature:     hex.EncodeToString(promise.Signature),
   816  			ProviderID:    providerID,
   817  			ChainID:       promise.ChainID,
   818  		},
   819  		Beneficiary:          beneficiary,
   820  		BeneficiarySignature: beneficiarySignature,
   821  	}
   822  
   823  	req, err := requests.NewPostRequest(t.endpointAddress, "identity/pay_and_settle", payload)
   824  	if err != nil {
   825  		return "", errors.Wrap(err, "failed to create pay and settle request")
   826  	}
   827  	res := SettleResponse{}
   828  	return res.ID, t.httpClient.DoRequestAndParseResponse(req, &res)
   829  }
   830  
   831  // DecreaseProviderStakeRequest represents all the parameters required for decreasing provider stake.
   832  type DecreaseProviderStakeRequest struct {
   833  	ChannelID     string `json:"channel_id,omitempty"`
   834  	Nonce         uint64 `json:"nonce,omitempty"`
   835  	HermesID      string `json:"hermes_id,omitempty"`
   836  	Amount        uint64 `json:"amount,omitempty"`
   837  	TransactorFee uint64 `json:"transactor_fee,omitempty"`
   838  	Signature     string `json:"signature,omitempty"`
   839  	ChainID       int64  `json:"chain_id"`
   840  	ProviderID    string `json:"providerID"`
   841  }
   842  
   843  // DecreaseStake requests the transactor to decrease stake.
   844  func (t *Transactor) DecreaseStake(id string, chainID int64, amount, transactorFee *big.Int) error {
   845  	payload, err := t.fillDecreaseStakeRequest(id, chainID, amount, transactorFee)
   846  	if err != nil {
   847  		return errors.Wrap(err, "failed to fill decrease stake request")
   848  	}
   849  
   850  	log.Debug().Msgf("req chid %v", payload.ChannelID)
   851  
   852  	req, err := requests.NewPostRequest(t.endpointAddress, "stake/decrease", payload)
   853  	if err != nil {
   854  		return errors.Wrap(err, "failed to create decrease stake request")
   855  	}
   856  	return t.httpClient.DoRequest(req)
   857  }
   858  
   859  func (t *Transactor) fillDecreaseStakeRequest(id string, chainID int64, amount, transactorFee *big.Int) (DecreaseProviderStakeRequest, error) {
   860  	hermes, err := t.addresser.GetActiveHermes(chainID)
   861  	if err != nil {
   862  		return DecreaseProviderStakeRequest{}, err
   863  	}
   864  	ch, err := t.bc.GetProviderChannel(chainID, hermes, common.HexToAddress(id), false)
   865  	if err != nil {
   866  		return DecreaseProviderStakeRequest{}, fmt.Errorf("failed to get provider channel: %w", err)
   867  	}
   868  
   869  	addr, err := pc.GenerateProviderChannelID(id, hermes.Hex())
   870  	if err != nil {
   871  		return DecreaseProviderStakeRequest{}, fmt.Errorf("failed to generate provider channel ID: %w", err)
   872  	}
   873  
   874  	bytes := common.FromHex(addr)
   875  	chid := [32]byte{}
   876  	copy(chid[:], bytes)
   877  
   878  	req := pc.DecreaseProviderStakeRequest{
   879  		ChannelID:     chid,
   880  		Nonce:         ch.LastUsedNonce.Add(ch.LastUsedNonce, big.NewInt(1)),
   881  		HermesID:      hermes,
   882  		Amount:        amount,
   883  		TransactorFee: transactorFee,
   884  		ChainID:       chainID,
   885  	}
   886  	signer := t.signerFactory(identity.FromAddress(id))
   887  	signature, err := signer.Sign(req.GetMessage())
   888  	if err != nil {
   889  		return DecreaseProviderStakeRequest{}, fmt.Errorf("failed to sign set decrease stake request: %w", err)
   890  	}
   891  
   892  	err = pc.ReformatSignatureVForBC(signature.Bytes())
   893  	if err != nil {
   894  		return DecreaseProviderStakeRequest{}, fmt.Errorf("signature reformat failed: %w", err)
   895  	}
   896  	signatureHex := common.Bytes2Hex(signature.Bytes())
   897  	regReq := DecreaseProviderStakeRequest{
   898  		Signature:     signatureHex,
   899  		ChannelID:     common.Bytes2Hex(req.ChannelID[:]),
   900  		Nonce:         req.Nonce.Uint64(),
   901  		HermesID:      req.HermesID.Hex(),
   902  		Amount:        req.Amount.Uint64(),
   903  		TransactorFee: req.TransactorFee.Uint64(),
   904  		ChainID:       req.ChainID,
   905  		ProviderID:    id,
   906  	}
   907  	return regReq, nil
   908  }