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 }