This commit is contained in:
r8zavetr8v 2024-06-04 00:54:17 +03:00
parent 1e50887b27
commit 842b8c7b6f
27 changed files with 250 additions and 93 deletions

View File

@ -33,6 +33,8 @@ services:
build:
context: ../chain-api
dockerfile: ../chain-api/Dockerfile
ports:
- 3000:3000
networks:
- blockd-net
- syslog

View File

@ -26,6 +26,7 @@ require (
github.com/Microsoft/go-winio v0.6.1 // indirect
github.com/StackExchange/wmi v1.2.1 // indirect
github.com/ajg/form v1.5.1 // indirect
github.com/alitto/pond v1.8.3 // indirect
github.com/beorn7/perks v1.0.1 // indirect
github.com/bits-and-blooms/bitset v1.10.0 // indirect
github.com/btcsuite/btcd/btcec/v2 v2.2.0 // indirect

View File

@ -51,6 +51,8 @@ github.com/alecthomas/template v0.0.0-20190718012654-fb15b899a751/go.mod h1:LOuy
github.com/alecthomas/units v0.0.0-20151022065526-2efee857e7cf/go.mod h1:ybxpYRFXyAe+OPACYpWeL0wqObRcbAqCMya13uyzqw0=
github.com/alecthomas/units v0.0.0-20190717042225-c3de453c63f4/go.mod h1:ybxpYRFXyAe+OPACYpWeL0wqObRcbAqCMya13uyzqw0=
github.com/alecthomas/units v0.0.0-20190924025748-f65c72e2690d/go.mod h1:rBZYJk541a8SKzHPHnH3zbiI+7dagKZ0cgpgrD7Fyho=
github.com/alitto/pond v1.8.3 h1:ydIqygCLVPqIX/USe5EaV/aSRXTRXDEI9JwuDdu+/xs=
github.com/alitto/pond v1.8.3/go.mod h1:CmvIIGd5jKLasGI3D87qDkQxjzChdKMmnXMg3fG6M6Q=
github.com/beorn7/perks v0.0.0-20180321164747-3a771d992973/go.mod h1:Dwedo/Wpr24TaqPxmxbtue+5NUziq4I4S80YR8gNf3Q=
github.com/beorn7/perks v1.0.0/go.mod h1:KWe93zE9D1o94FZ5RNwFwVgaQK1VOXiVxmqh+CedLV8=
github.com/beorn7/perks v1.0.1 h1:VlbKKnNfV8bJzeqoa4cOKqO6bYr3WgKZxO8Z16+hsOM=

View File

@ -3,17 +3,17 @@ package factory
import (
"log/slog"
"github.com/emochka2007/block-accounting/internal/infrastructure/repository/auth"
"github.com/emochka2007/block-accounting/internal/infrastructure/repository/cache"
orepo "github.com/emochka2007/block-accounting/internal/infrastructure/repository/organizations"
txRepo "github.com/emochka2007/block-accounting/internal/infrastructure/repository/transactions"
urepo "github.com/emochka2007/block-accounting/internal/infrastructure/repository/users"
"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"
"github.com/emochka2007/block-accounting/internal/usecase/interactors/users"
"github.com/emochka2007/block-accounting/internal/usecase/repository/auth"
"github.com/emochka2007/block-accounting/internal/usecase/repository/cache"
orepo "github.com/emochka2007/block-accounting/internal/usecase/repository/organizations"
txRepo "github.com/emochka2007/block-accounting/internal/usecase/repository/transactions"
urepo "github.com/emochka2007/block-accounting/internal/usecase/repository/users"
)
func provideUsersInteractor(

View File

@ -6,6 +6,7 @@ import (
"github.com/google/wire"
"github.com/emochka2007/block-accounting/internal/infrastructure/repository/auth"
"github.com/emochka2007/block-accounting/internal/interface/rest"
"github.com/emochka2007/block-accounting/internal/interface/rest/controllers"
"github.com/emochka2007/block-accounting/internal/interface/rest/presenters"
@ -16,7 +17,6 @@ import (
"github.com/emochka2007/block-accounting/internal/usecase/interactors/organizations"
"github.com/emochka2007/block-accounting/internal/usecase/interactors/transactions"
"github.com/emochka2007/block-accounting/internal/usecase/interactors/users"
"github.com/emochka2007/block-accounting/internal/usecase/repository/auth"
)
var interfaceSet wire.ProviderSet = wire.NewSet(

View File

@ -4,12 +4,12 @@ import (
"database/sql"
"log/slog"
"github.com/emochka2007/block-accounting/internal/infrastructure/repository/auth"
"github.com/emochka2007/block-accounting/internal/infrastructure/repository/cache"
"github.com/emochka2007/block-accounting/internal/infrastructure/repository/organizations"
"github.com/emochka2007/block-accounting/internal/infrastructure/repository/transactions"
"github.com/emochka2007/block-accounting/internal/infrastructure/repository/users"
"github.com/emochka2007/block-accounting/internal/pkg/config"
"github.com/emochka2007/block-accounting/internal/usecase/repository/auth"
"github.com/emochka2007/block-accounting/internal/usecase/repository/cache"
"github.com/emochka2007/block-accounting/internal/usecase/repository/organizations"
"github.com/emochka2007/block-accounting/internal/usecase/repository/transactions"
"github.com/emochka2007/block-accounting/internal/usecase/repository/users"
"github.com/redis/go-redis/v9"
)

View File

@ -4,9 +4,9 @@
package factory
import (
"github.com/emochka2007/block-accounting/internal/infrastructure/repository"
"github.com/emochka2007/block-accounting/internal/pkg/config"
"github.com/emochka2007/block-accounting/internal/service"
"github.com/emochka2007/block-accounting/internal/usecase/repository"
"github.com/google/wire"
)

View File

@ -9,7 +9,7 @@ package factory
import (
"github.com/emochka2007/block-accounting/internal/pkg/config"
"github.com/emochka2007/block-accounting/internal/service"
"github.com/emochka2007/block-accounting/internal/usecase/repository"
"github.com/emochka2007/block-accounting/internal/infrastructure/repository"
)
// Injectors from wire.go:

View File

@ -0,0 +1 @@
// todo move chain api client here

View File

@ -8,9 +8,9 @@ import (
"time"
sq "github.com/Masterminds/squirrel"
"github.com/emochka2007/block-accounting/internal/infrastructure/repository/users"
"github.com/emochka2007/block-accounting/internal/pkg/models"
sqltools "github.com/emochka2007/block-accounting/internal/pkg/sqlutils"
"github.com/emochka2007/block-accounting/internal/usecase/repository/users"
"github.com/google/uuid"
"golang.org/x/sync/errgroup"
)

View File

@ -8,9 +8,9 @@ import (
"time"
sq "github.com/Masterminds/squirrel"
"github.com/emochka2007/block-accounting/internal/infrastructure/repository/organizations"
"github.com/emochka2007/block-accounting/internal/pkg/models"
sqltools "github.com/emochka2007/block-accounting/internal/pkg/sqlutils"
"github.com/emochka2007/block-accounting/internal/usecase/repository/organizations"
"github.com/google/uuid"
)

View File

@ -11,6 +11,7 @@ import (
"strings"
"time"
"github.com/emochka2007/block-accounting/internal/infrastructure/repository/auth"
"github.com/emochka2007/block-accounting/internal/interface/rest/domain"
"github.com/emochka2007/block-accounting/internal/interface/rest/presenters"
"github.com/emochka2007/block-accounting/internal/pkg/bip39"
@ -19,7 +20,6 @@ import (
"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/users"
"github.com/emochka2007/block-accounting/internal/usecase/repository/auth"
"github.com/go-chi/chi/v5"
)

View File

@ -343,7 +343,18 @@ func (c *transactionsController) ListPayrolls(w http.ResponseWriter, r *http.Req
}
func (c *transactionsController) SetSalary(w http.ResponseWriter, r *http.Request) ([]byte, error) {
// req, err := presenters.CreateRequest[domain.]()
_, err := presenters.CreateRequest[domain.SetSalaryRequest](r)
if err != nil {
return nil, fmt.Errorf("error build set salary request. %w", err)
}
ctx, cancel := context.WithTimeout(r.Context(), 5*time.Second)
defer cancel()
// todo fill params
if err := c.chainInteractor.SetSalary(ctx, chain.SetSalaryParams{}); err != nil {
return nil, fmt.Errorf("error create new salary. %w", err)
}
return presenters.ResponseOK()
}

View File

@ -0,0 +1,61 @@
package logger
import (
"io"
"log/slog"
"os"
)
type LoggerBuilder struct {
local bool
addSource bool
lvl slog.Level
writers []io.Writer
}
func (b *LoggerBuilder) WithWriter(w io.Writer) *LoggerBuilder {
b.writers = append(b.writers, w)
return b
}
func (b *LoggerBuilder) WithLevel(l slog.Level) *LoggerBuilder {
b.lvl = l
return b
}
func (b *LoggerBuilder) Local() *LoggerBuilder {
b.local = true
return b
}
func (b *LoggerBuilder) WithSource() *LoggerBuilder {
b.addSource = true
return b
}
func (b *LoggerBuilder) Build() *slog.Logger {
if len(b.writers) == 0 {
b.writers = append(b.writers, os.Stdout)
}
w := io.MultiWriter(b.writers...)
if b.local {
opts := PrettyHandlerOptions{
SlogOpts: &slog.HandlerOptions{
Level: b.lvl,
AddSource: b.addSource,
},
}
handler := opts.NewPrettyHandler(w)
return slog.New(handler)
}
return newLogger(b.lvl, w)
}

View File

@ -3,61 +3,11 @@ package logger
import (
"io"
"log/slog"
"os"
)
type LoggerBuilder struct {
local bool
addSource bool
lvl slog.Level
writers []io.Writer
}
func (b *LoggerBuilder) WithWriter(w io.Writer) *LoggerBuilder {
b.writers = append(b.writers, w)
return b
}
func (b *LoggerBuilder) WithLevel(l slog.Level) *LoggerBuilder {
b.lvl = l
return b
}
func (b *LoggerBuilder) Local() *LoggerBuilder {
b.local = true
return b
}
func (b *LoggerBuilder) WithSource() *LoggerBuilder {
b.addSource = true
return b
}
func (b *LoggerBuilder) Build() *slog.Logger {
if len(b.writers) == 0 {
b.writers = append(b.writers, os.Stdout)
}
w := io.MultiWriter(b.writers...)
if b.local {
opts := PrettyHandlerOptions{
SlogOpts: &slog.HandlerOptions{
Level: b.lvl,
AddSource: b.addSource,
},
}
handler := opts.NewPrettyHandler(w)
return slog.New(handler)
}
return newLogger(b.lvl, w)
// todo add levels Trace, Emergency
type Logger struct {
*slog.Logger
}
func newLogger(lvl slog.Level, w io.Writer) *slog.Logger {

View File

@ -0,0 +1 @@
package usecase

View File

@ -10,11 +10,12 @@ import (
"net/http"
"time"
"github.com/emochka2007/block-accounting/internal/infrastructure/repository/transactions"
"github.com/emochka2007/block-accounting/internal/pkg/config"
"github.com/emochka2007/block-accounting/internal/pkg/ctxmeta"
"github.com/emochka2007/block-accounting/internal/pkg/logger"
"github.com/emochka2007/block-accounting/internal/pkg/models"
"github.com/emochka2007/block-accounting/internal/usecase/repository/transactions"
"github.com/emochka2007/block-accounting/internal/usecase/interactors/organizations"
"github.com/ethereum/go-ethereum/common"
"github.com/google/uuid"
)
@ -27,23 +28,27 @@ type ChainInteractor interface {
PayrollDeploy(ctx context.Context, params PayrollDeployParams) error
ListPayrolls(ctx context.Context, params ListPayrollsParams) ([]models.Payroll, error)
SetSalary(ctx context.Context, params SetSalaryParams) error
}
type chainInteractor struct {
log *slog.Logger
config config.Config
txRepository transactions.Repository
log *slog.Logger
config config.Config
txRepository transactions.Repository
organizationsInteractor organizations.OrganizationsInteractor
}
func NewChainInteractor(
log *slog.Logger,
config config.Config,
txRepository transactions.Repository,
organizationsInteractor organizations.OrganizationsInteractor,
) ChainInteractor {
return &chainInteractor{
log: log,
config: config,
txRepository: txRepository,
log: log,
config: config,
txRepository: txRepository,
organizationsInteractor: organizationsInteractor,
}
}
@ -94,7 +99,7 @@ func (i *chainInteractor) NewMultisig(ctx context.Context, params NewMultisigPar
return fmt.Errorf("error fetch organization id from context. %w", err)
}
go func() {
go func() { // TODO remove this subroutine shit and replace it with worker pools
pid := uuid.Must(uuid.NewV7()).String()
startTime := time.Now()
@ -103,7 +108,7 @@ func (i *chainInteractor) NewMultisig(ctx context.Context, params NewMultisigPar
slog.String("pid", pid),
)
doneCh := make(chan struct{})
doneCh := make(chan struct{}, 1)
defer func() {
if err := recover(); err != nil {
@ -152,6 +157,7 @@ func (i *chainInteractor) NewMultisig(ctx context.Context, params NewMultisigPar
req.Header.Add("Content-Type", "application/json")
req.Header.Add("X-Seed", common.Bytes2Hex(user.Seed()))
// TODO replace http.DefaultClient with custom ChainAPi client from infrastructure/ethapi mod
resp, err := http.DefaultClient.Do(req)
if err != nil {
i.log.Error(
@ -250,6 +256,7 @@ func (i *chainInteractor) PubKey(ctx context.Context, user *models.User) ([]byte
req.Header.Add("X-Seed", common.Bytes2Hex(user.Seed()))
req.Header.Add("Content-Type", "application/json")
// TODO replace http.DefaultClient with custom ChainAPi client from infrastructure/ethapi mod
resp, err := http.DefaultClient.Do(req)
if err != nil {
return nil, fmt.Errorf("error fetch pub address. %w", err)
@ -336,7 +343,7 @@ func (i *chainInteractor) PayrollDeploy(
return fmt.Errorf("error marshal request body. %w", err)
}
go func() {
go func() { // TODO remove this subroutine shit and replace it with worker pools
pid := uuid.Must(uuid.NewV7()).String()
startTime := time.Now()
@ -345,7 +352,7 @@ func (i *chainInteractor) PayrollDeploy(
slog.String("pid", pid),
)
doneCh := make(chan struct{})
doneCh := make(chan struct{}, 1)
defer func() {
if err := recover(); err != nil {
@ -361,7 +368,7 @@ func (i *chainInteractor) PayrollDeploy(
select {
case <-doneCh:
i.log.Info(
"new paroll worker done",
"new payroll worker done",
slog.String("pid", pid),
slog.Time("started at", startTime),
slog.Time("done at", time.Now()),
@ -401,6 +408,7 @@ func (i *chainInteractor) PayrollDeploy(
req.Header.Add("Content-Type", "application/json")
req.Header.Add("X-Seed", common.Bytes2Hex(user.Seed()))
// TODO replace http.DefaultClient with custom ChainAPi client from infrastructure/ethapi mod
resp, err := http.DefaultClient.Do(req)
if err != nil {
i.log.Error(
@ -513,14 +521,15 @@ func (i *chainInteractor) ListPayrolls(
return payrolls, nil
}
type NewSalaryParams struct {
OrganizationID uuid.UUID
EmployeeID uuid.UUID
type SetSalaryParams struct {
PayrollID uuid.UUID
EmployeeID uuid.UUID
Salary float64
}
func (i *chainInteractor) NewSalary(
func (i *chainInteractor) SetSalary(
ctx context.Context,
params NewSalaryParams,
params SetSalaryParams,
) error {
user, err := ctxmeta.User(ctx)
if err != nil {
@ -533,10 +542,129 @@ func (i *chainInteractor) NewSalary(
}
i.log.Debug(
"not implemented",
"SetSalary",
slog.String("org id", organizationID.String()),
slog.Any("user", user),
)
payrolls, err := i.ListPayrolls(ctx, ListPayrollsParams{
IDs: []uuid.UUID{params.PayrollID},
OrganizationID: organizationID,
})
if err != nil {
return fmt.Errorf("error fetch payroll. %w", err)
}
if len(payrolls) == 0 {
return fmt.Errorf("error payroll not found. %w", err)
}
payroll := payrolls[0]
multisigs, err := i.ListMultisigs(ctx, ListMultisigsParams{
IDs: uuid.UUIDs{payroll.MultisigID},
OrganizationID: organizationID,
})
if err != nil {
return fmt.Errorf("error fetch multisig. %w", err)
}
if len(multisigs) == 0 {
return fmt.Errorf("error multisig not found. %w", err)
}
multisig := multisigs[0]
employee, err := i.organizationsInteractor.Participant(ctx, organizations.ParticipantParams{
ID: params.EmployeeID,
OrganizationID: organizationID,
EmployeesOnly: true,
})
if err != nil {
return fmt.Errorf("error fetch employee from repository. %w", err)
}
if employee.GetEmployee() == nil {
return fmt.Errorf("error employee is nil")
}
go func() {
defer func() {
if err := recover(); err != nil {
i.log.Error("worker paniced!", slog.Any("panic", err))
}
// doneCh <- struct{}{}
// close(doneCh)
}()
ctx, cancel := context.WithTimeout(context.TODO(), 2*time.Minute)
defer cancel()
maddr := common.Bytes2Hex(multisig.Address)
if maddr[0] != 0 && maddr[1] != 'x' {
maddr = "0x" + maddr
}
caddr := common.Bytes2Hex(payroll.Address)
if caddr[0] != 0 && caddr[1] != 'x' {
caddr = "0x" + caddr
}
eaddr := common.Bytes2Hex(employee.GetEmployee().WalletAddress)
if caddr[0] != 0 && caddr[1] != 'x' {
caddr = "0x" + caddr
}
bodyMap := map[string]any{
"multiSigWallet": maddr,
"contractAddress": caddr,
"employeeAddress": eaddr,
"salary": params.Salary,
}
bodyRaw, err := json.Marshal(&bodyMap)
if err != nil {
i.log.Error(
"error marshal request body",
logger.Err(err),
)
return
}
req, err := http.NewRequestWithContext(
ctx,
http.MethodPost,
i.config.ChainAPI.Host+"/salaries/set-salary",
bytes.NewBuffer(bodyRaw),
)
if err != nil {
i.log.Error(
"error build request",
logger.Err(err),
)
return
}
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 {
i.log.Error(
"error do request",
logger.Err(err),
)
return
}
defer resp.Body.Close()
// todo parse body
}()
return nil
}

View File

@ -8,9 +8,9 @@ import (
"fmt"
"time"
"github.com/emochka2007/block-accounting/internal/infrastructure/repository/auth"
"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/auth"
"github.com/golang-jwt/jwt/v5"
"github.com/google/uuid"
)

View File

@ -9,12 +9,12 @@ import (
"log/slog"
"time"
"github.com/emochka2007/block-accounting/internal/infrastructure/repository/cache"
"github.com/emochka2007/block-accounting/internal/infrastructure/repository/organizations"
"github.com/emochka2007/block-accounting/internal/pkg/ctxmeta"
"github.com/emochka2007/block-accounting/internal/pkg/hdwallet"
"github.com/emochka2007/block-accounting/internal/pkg/logger"
"github.com/emochka2007/block-accounting/internal/pkg/models"
"github.com/emochka2007/block-accounting/internal/usecase/repository/cache"
"github.com/emochka2007/block-accounting/internal/usecase/repository/organizations"
"github.com/ethereum/go-ethereum/common"
"github.com/google/uuid"
)

View File

@ -8,11 +8,11 @@ import (
"log/slog"
"time"
"github.com/emochka2007/block-accounting/internal/infrastructure/repository/transactions"
"github.com/emochka2007/block-accounting/internal/pkg/ctxmeta"
"github.com/emochka2007/block-accounting/internal/pkg/models"
"github.com/emochka2007/block-accounting/internal/usecase/interactors/chain"
"github.com/emochka2007/block-accounting/internal/usecase/interactors/organizations"
"github.com/emochka2007/block-accounting/internal/usecase/repository/transactions"
"github.com/google/uuid"
)

View File

@ -7,10 +7,10 @@ import (
"log/slog"
"time"
"github.com/emochka2007/block-accounting/internal/infrastructure/repository/users"
"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"
)