chain interactor updates

This commit is contained in:
r8zavetr8v 2024-05-25 16:00:21 +03:00
parent 471de27582
commit 223ad9c31e
6 changed files with 137 additions and 86 deletions

View File

@ -38,6 +38,10 @@ func main() {
&cli.StringFlag{
Name: "jwt-secret",
},
&cli.StringFlag{
Name: "chain-api-url",
Value: "http://localhost:3000",
},
// rest
&cli.StringFlag{
@ -108,6 +112,9 @@ func main() {
CacheUser: c.String("cache-user"),
CacheSecret: c.String("cache-secret"),
},
ChainAPI: config.ChainAPIConfig{
Host: c.String("chain-api-url"),
},
}
fmt.Println(config)

View File

@ -4,6 +4,7 @@ import (
"log/slog"
"github.com/emochka2007/block-accounting/internal/pkg/config"
"github.com/emochka2007/block-accounting/internal/usecase/interactors/chain"
"github.com/emochka2007/block-accounting/internal/usecase/interactors/jwt"
"github.com/emochka2007/block-accounting/internal/usecase/interactors/organizations"
"github.com/emochka2007/block-accounting/internal/usecase/interactors/transactions"
@ -18,8 +19,9 @@ import (
func provideUsersInteractor(
log *slog.Logger,
usersRepo urepo.Repository,
chainInteractor chain.ChainInteractor,
) users.UsersInteractor {
return users.NewUsersInteractor(log.WithGroup("users-interactor"), usersRepo)
return users.NewUsersInteractor(log.WithGroup("users-interactor"), usersRepo, chainInteractor)
}
func provideJWTInteractor(
@ -49,3 +51,11 @@ func provideTxInteractor(
orgInteractor,
)
}
func provideChainInteractor(
log *slog.Logger,
config config.Config,
txRepository txRepo.Repository,
) chain.ChainInteractor {
return chain.NewChainInteractor(log, config, txRepository)
}

View File

@ -22,6 +22,7 @@ func ProvideService(c config.Config) (service.Service, func(), error) {
provideOrganizationsRepository,
provideOrganizationsInteractor,
provideTxInteractor,
provideChainInteractor,
provideAuthRepository,
provideJWTInteractor,
interfaceSet,

View File

@ -1,6 +1,6 @@
// Code generated by Wire. DO NOT EDIT.
//go:generate go run github.com/google/wire/cmd/wire
//go:generate go run -mod=mod github.com/google/wire/cmd/wire
//go:build !wireinject
// +build !wireinject
@ -21,7 +21,9 @@ func ProvideService(c config.Config) (service.Service, func(), error) {
return nil, nil, err
}
usersRepository := provideUsersRepository(db)
usersInteractor := provideUsersInteractor(logger, usersRepository)
transactionsRepository := provideTxRepository(db)
chainInteractor := provideChainInteractor(logger, c, transactionsRepository)
usersInteractor := provideUsersInteractor(logger, usersRepository, chainInteractor)
authRepository := provideAuthRepository(db)
jwtInteractor := provideJWTInteractor(c, usersInteractor, authRepository)
authPresenter := provideAuthPresenter(jwtInteractor)
@ -32,7 +34,6 @@ func ProvideService(c config.Config) (service.Service, func(), error) {
organizationsInteractor := provideOrganizationsInteractor(logger, organizationsRepository, cache)
organizationsPresenter := provideOrganizationsPresenter()
organizationsController := provideOrganizationsController(logger, organizationsInteractor, organizationsPresenter)
transactionsRepository := provideTxRepository(db)
transactionsInteractor := provideTxInteractor(logger, transactionsRepository, organizationsInteractor)
transactionsController := provideTxController(logger, transactionsInteractor)
participantsController := provideParticipantsController(logger, organizationsInteractor, usersInteractor)

View File

@ -10,34 +10,33 @@ import (
"net/http"
"github.com/emochka2007/block-accounting/internal/pkg/config"
"github.com/emochka2007/block-accounting/internal/pkg/ctxmeta"
"github.com/emochka2007/block-accounting/internal/pkg/models"
"github.com/emochka2007/block-accounting/internal/usecase/interactors/users"
"github.com/emochka2007/block-accounting/internal/usecase/repository/transactions"
"github.com/ethereum/go-ethereum/common"
)
type ChainInteractor interface {
NewMultisig(ctx context.Context, params NewMultisigParams) error
PubKey(ctx context.Context, user *models.User) ([]byte, error)
SalaryDeploy(ctx context.Context, firtsAdmin models.OrganizationParticipant) error
}
type chainInteractor struct {
log *slog.Logger
config config.Config
txRepository transactions.Repository
usersInteractor users.UsersInteractor
}
func NewChainInteractor(
log *slog.Logger,
config config.Config,
txRepository transactions.Repository,
usersInteractor users.UsersInteractor,
) ChainInteractor {
return &chainInteractor{
log: log,
config: config,
txRepository: txRepository,
usersInteractor: usersInteractor,
}
}
@ -47,11 +46,11 @@ type NewMultisigParams struct {
}
func (i *chainInteractor) NewMultisig(ctx context.Context, params NewMultisigParams) error {
deployAddr := i.config.ChainAPI.Host + "/multi-sig/deploy"
endpoint := i.config.ChainAPI.Host + "/multi-sig/deploy"
i.log.Debug(
"deploy multisig",
slog.String("endpoint", deployAddr),
slog.String("endpoint", endpoint),
slog.Any("params", params),
)
@ -63,23 +62,30 @@ func (i *chainInteractor) NewMultisig(ctx context.Context, params NewMultisigPar
return fmt.Errorf("error marshal request body. %w", err)
}
user, err := ctxmeta.User(ctx)
if err != nil {
return fmt.Errorf("error fetch user from context. %w", err)
}
body := bytes.NewBuffer(requestBody)
doneCh := make(chan struct{})
req, err := http.NewRequestWithContext(ctx, http.MethodPost, endpoint, body)
if err != nil {
return fmt.Errorf("error build request. %w", err)
}
errCh := make(chan error)
req.Header.Add("Content-Type", "application/json")
req.Header.Add("X-Seed", common.Bytes2Hex(user.Seed()))
go func() {
resp, err := http.Post(http.MethodPost, deployAddr, body)
resp, err := http.DefaultClient.Do(req)
if err != nil {
i.log.Error(
"error send deploy multisig request",
slog.String("endpoint", deployAddr),
slog.String("endpoint", endpoint),
slog.Any("params", params),
)
errCh <- fmt.Errorf("error build new multisig request. %w", err)
return
return fmt.Errorf("error build new multisig request. %w", err)
}
defer resp.Body.Close()
@ -89,27 +95,12 @@ func (i *chainInteractor) NewMultisig(ctx context.Context, params NewMultisigPar
slog.Int("code", resp.StatusCode),
)
if _, ok := <-doneCh; ok {
doneCh <- struct{}{}
}
}()
select {
case err := <-errCh:
return err
case <-doneCh:
return nil
case <-ctx.Done():
return ctx.Err()
}
}
func (i *chainInteractor) PubKey(ctx context.Context, user *models.User) ([]byte, error) {
pubAddr := i.config.ChainAPI.Host + "/address-from-seed"
doneCh := make(chan struct{})
errCh := make(chan error)
requestBody, err := json.Marshal(map[string]any{
"seedPhrase": user.Mnemonic,
})
@ -119,34 +110,67 @@ func (i *chainInteractor) PubKey(ctx context.Context, user *models.User) ([]byte
body := bytes.NewBuffer(requestBody)
var pubKeyStr string
go func() {
resp, err := http.Post(pubAddr, "application/json", body)
req, err := http.NewRequestWithContext(ctx, http.MethodPost, pubAddr, body)
if err != nil {
errCh <- fmt.Errorf("error fetch pub address. %w", err)
return
return nil, fmt.Errorf("error build request. %w", err)
}
req.Header.Add("Content-Type", "application/json")
resp, err := http.DefaultClient.Do(req)
if err != nil {
return nil, fmt.Errorf("error fetch pub address. %w", err)
}
defer resp.Body.Close()
respBody, err := io.ReadAll(resp.Body)
if err != nil {
errCh <- fmt.Errorf("error read resp body. %w", err)
return
return nil, fmt.Errorf("error read resp body. %w", err)
}
pubKeyStr = string(respBody)
pubKeyStr := string(respBody)[2:]
doneCh <- struct{}{}
}()
select {
case err := <-errCh:
return nil, err
case <-doneCh:
return common.Hex2Bytes(pubKeyStr), nil
case <-ctx.Done():
return nil, ctx.Err()
}
}
func (i *chainInteractor) SalaryDeploy(ctx context.Context, firtsAdmin models.OrganizationParticipant) error {
user, err := ctxmeta.User(ctx)
if err != nil {
return fmt.Errorf("error fetch user from context. %w", err)
}
if user.Id() != firtsAdmin.Id() || firtsAdmin.GetUser() == nil {
return fmt.Errorf("error unauthorized access")
}
requestBody, err := json.Marshal(map[string]any{
"authorizedWallet": common.Bytes2Hex(user.Seed()),
})
if err != nil {
return fmt.Errorf("error marshal request body. %w", err)
}
body := bytes.NewBuffer(requestBody)
endpoint := i.config.ChainAPI.Host + "/salaries/deploy"
req, err := http.NewRequestWithContext(ctx, http.MethodPost, endpoint, body)
if err != nil {
return fmt.Errorf("error build request. %w", err)
}
req.Header.Add("Content-Type", "application/json")
req.Header.Add("X-Seed", common.Bytes2Hex(user.Seed()))
resp, err := http.DefaultClient.Do(req)
if err != nil {
return fmt.Errorf("error fetch deploy salary contract. %w", err)
}
defer resp.Body.Close()
return nil
}
// func (i *chainInteractor)

View File

@ -9,6 +9,7 @@ import (
"github.com/emochka2007/block-accounting/internal/pkg/hdwallet"
"github.com/emochka2007/block-accounting/internal/pkg/models"
"github.com/emochka2007/block-accounting/internal/usecase/interactors/chain"
"github.com/emochka2007/block-accounting/internal/usecase/repository/users"
"github.com/google/uuid"
)
@ -54,15 +55,18 @@ type UsersInteractor interface {
type usersInteractor struct {
log *slog.Logger
usersRepo users.Repository
chainInteractor chain.ChainInteractor
}
func NewUsersInteractor(
log *slog.Logger,
usersRepo users.Repository,
chainInteractor chain.ChainInteractor,
) UsersInteractor {
return &usersInteractor{
log: log,
usersRepo: usersRepo,
chainInteractor: chainInteractor,
}
}
@ -88,9 +92,13 @@ func (i *usersInteractor) Create(ctx context.Context, params CreateParams) (*mod
Telegram: params.Tg,
}
// TODO fetch user PK from chain-api
pk, err := i.chainInteractor.PubKey(ctx, user)
if err != nil {
// todo пока мокнуть
return nil, fmt.Errorf("error fetch user pub key. %w", err)
}
user.PK = []byte{0x01} // todo remove
user.PK = pk
if err = i.usersRepo.Create(ctx, user); err != nil {
return nil, fmt.Errorf("error create new user. %w", err)