block-accounting/backend/internal/usecase/interactors/chain/chain.go

153 lines
3.2 KiB
Go
Raw Normal View History

2024-05-24 17:44:24 +00:00
package chain
import (
2024-05-24 22:45:56 +00:00
"bytes"
2024-05-24 17:44:24 +00:00
"context"
2024-05-24 22:45:56 +00:00
"encoding/json"
"fmt"
2024-05-24 23:39:32 +00:00
"io"
2024-05-24 22:45:56 +00:00
"log/slog"
"net/http"
2024-05-24 17:44:24 +00:00
2024-05-24 22:45:56 +00:00
"github.com/emochka2007/block-accounting/internal/pkg/config"
"github.com/emochka2007/block-accounting/internal/pkg/models"
2024-05-24 17:44:24 +00:00
"github.com/emochka2007/block-accounting/internal/usecase/interactors/users"
"github.com/emochka2007/block-accounting/internal/usecase/repository/transactions"
2024-05-24 22:45:56 +00:00
"github.com/ethereum/go-ethereum/common"
2024-05-24 17:44:24 +00:00
)
type ChainInteractor interface {
2024-05-24 22:45:56 +00:00
NewMultisig(ctx context.Context, params NewMultisigParams) error
2024-05-24 17:44:24 +00:00
}
type chainInteractor struct {
2024-05-24 22:45:56 +00:00
log *slog.Logger
config config.Config
2024-05-24 17:44:24 +00:00
txRepository transactions.Repository
usersInteractor users.UsersInteractor
}
2024-05-24 22:45:56 +00:00
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,
}
}
2024-05-24 17:44:24 +00:00
type NewMultisigParams struct {
2024-05-24 22:45:56 +00:00
OwnersPKs []string
Confirmations int
2024-05-24 17:44:24 +00:00
}
2024-05-24 22:45:56 +00:00
func (i *chainInteractor) NewMultisig(ctx context.Context, params NewMultisigParams) error {
deployAddr := i.config.ChainAPI.Host + "/multi-sig/deploy"
i.log.Debug(
"deploy multisig",
slog.String("endpoint", deployAddr),
slog.Any("params", params),
)
requestBody, err := json.Marshal(map[string]any{
"owners": params.OwnersPKs,
"confirmations": params.Confirmations,
})
if err != nil {
return fmt.Errorf("error marshal request body. %w", err)
}
body := bytes.NewBuffer(requestBody)
doneCh := make(chan struct{})
errCh := make(chan error)
go func() {
resp, err := http.Post(http.MethodPost, deployAddr, body)
if err != nil {
i.log.Error(
"error send deploy multisig request",
slog.String("endpoint", deployAddr),
slog.Any("params", params),
)
errCh <- fmt.Errorf("error build new multisig request. %w", err)
return
}
defer resp.Body.Close()
i.log.Debug(
"deploy multisig response",
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()
}
}
2024-05-24 23:39:32 +00:00
func (i *chainInteractor) PubKey(ctx context.Context, user *models.User) ([]byte, error) {
pubAddr := i.config.ChainAPI.Host + "/address-from-seed"
2024-05-24 22:45:56 +00:00
doneCh := make(chan struct{})
errCh := make(chan error)
2024-05-24 23:39:32 +00:00
requestBody, err := json.Marshal(map[string]any{
"seedPhrase": user.Mnemonic,
})
if err != nil {
return nil, fmt.Errorf("error marshal request body. %w", err)
}
body := bytes.NewBuffer(requestBody)
var pubKeyStr string
2024-05-24 22:45:56 +00:00
go func() {
2024-05-24 23:39:32 +00:00
resp, err := http.Post(pubAddr, "application/json", body)
if err != nil {
errCh <- fmt.Errorf("error fetch pub address. %w", err)
return
}
defer resp.Body.Close()
respBody, err := io.ReadAll(resp.Body)
if err != nil {
errCh <- fmt.Errorf("error read resp body. %w", err)
return
}
pubKeyStr = string(respBody)
doneCh <- struct{}{}
2024-05-24 22:45:56 +00:00
}()
2024-05-24 17:44:24 +00:00
2024-05-24 22:45:56 +00:00
select {
case err := <-errCh:
2024-05-24 23:39:32 +00:00
return nil, err
2024-05-24 22:45:56 +00:00
case <-doneCh:
2024-05-24 23:39:32 +00:00
return common.Hex2Bytes(pubKeyStr), nil
2024-05-24 22:45:56 +00:00
case <-ctx.Done():
2024-05-24 23:39:32 +00:00
return nil, ctx.Err()
2024-05-24 22:45:56 +00:00
}
2024-05-24 17:44:24 +00:00
}