github.com/machinefi/w3bstream@v1.6.5-rc9.0.20240426031326-b8c7c4876e72/pkg/modules/operator/operator.go (about)

     1  package operator
     2  
     3  import (
     4  	"context"
     5  	"crypto/ed25519"
     6  
     7  	solcommon "github.com/blocto/solana-go-sdk/common"
     8  	"github.com/ethereum/go-ethereum/common"
     9  	"github.com/ethereum/go-ethereum/crypto"
    10  
    11  	confid "github.com/machinefi/w3bstream/pkg/depends/conf/id"
    12  	"github.com/machinefi/w3bstream/pkg/depends/kit/sqlx"
    13  	"github.com/machinefi/w3bstream/pkg/enums"
    14  	"github.com/machinefi/w3bstream/pkg/errors/status"
    15  	"github.com/machinefi/w3bstream/pkg/models"
    16  	"github.com/machinefi/w3bstream/pkg/modules/projectoperator"
    17  	"github.com/machinefi/w3bstream/pkg/types"
    18  )
    19  
    20  const DefaultOperatorName = "default"
    21  
    22  func GetBySFID(ctx context.Context, id types.SFID) (*models.Operator, error) {
    23  	d := types.MustMgrDBExecutorFromContext(ctx)
    24  	m := &models.Operator{RelOperator: models.RelOperator{OperatorID: id}}
    25  
    26  	if err := m.FetchByOperatorID(d); err != nil {
    27  		if sqlx.DBErr(err).IsNotFound() {
    28  			return nil, status.OperatorNotFound
    29  		}
    30  		return nil, status.DatabaseError.StatusErr().WithDesc(err.Error())
    31  	}
    32  	return m, nil
    33  }
    34  
    35  func GetDetailBySFID(ctx context.Context, id types.SFID) (*Detail, error) {
    36  	o, err := GetBySFID(ctx, id)
    37  	if err != nil {
    38  		return nil, err
    39  	}
    40  	return convDetail(o)
    41  }
    42  
    43  func GetByAccountAndName(ctx context.Context, accountID types.SFID, name string) (*models.Operator, error) {
    44  	d := types.MustMgrDBExecutorFromContext(ctx)
    45  	m := &models.Operator{
    46  		OperatorInfo: models.OperatorInfo{Name: name},
    47  		RelAccount:   models.RelAccount{AccountID: accountID},
    48  	}
    49  
    50  	if err := m.FetchByAccountIDAndName(d); err != nil {
    51  		if sqlx.DBErr(err).IsNotFound() {
    52  			return nil, status.OperatorNotFound
    53  		}
    54  		return nil, status.DatabaseError.StatusErr().WithDesc(err.Error())
    55  	}
    56  	return m, nil
    57  }
    58  
    59  func GetDetailByAccountAndName(ctx context.Context, accountID types.SFID, name string) (*Detail, error) {
    60  	o, err := GetByAccountAndName(ctx, accountID, name)
    61  	if err != nil {
    62  		return nil, err
    63  	}
    64  	return convDetail(o)
    65  }
    66  
    67  func RemoveBySFID(ctx context.Context, id types.SFID) error {
    68  	d := types.MustMgrDBExecutorFromContext(ctx)
    69  	m := &models.Operator{RelOperator: models.RelOperator{OperatorID: id}}
    70  
    71  	occupied, err := projectoperator.IsOperatorOccupied(ctx, id)
    72  	if err != nil {
    73  		return err
    74  	}
    75  	if occupied {
    76  		return status.OccupiedOperator
    77  	}
    78  
    79  	if err := m.DeleteByOperatorID(d); err != nil {
    80  		return status.DatabaseError.StatusErr().WithDesc(err.Error())
    81  	}
    82  	return nil
    83  }
    84  
    85  func Create(ctx context.Context, r *CreateReq) (*models.Operator, error) {
    86  	d := types.MustMgrDBExecutorFromContext(ctx)
    87  	id := confid.MustSFIDGeneratorFromContext(ctx).MustGenSFID()
    88  	acc := types.MustAccountFromContext(ctx)
    89  
    90  	op := &models.Operator{
    91  		RelAccount:  models.RelAccount{AccountID: acc.AccountID},
    92  		RelOperator: models.RelOperator{OperatorID: id},
    93  		OperatorInfo: models.OperatorInfo{
    94  			Name:         r.Name,
    95  			PrivateKey:   r.PrivateKey,
    96  			PaymasterKey: r.PaymasterKey,
    97  			Type:         r.Type,
    98  		},
    99  	}
   100  
   101  	if err := op.Create(d); err != nil {
   102  		if sqlx.DBErr(err).IsConflict() {
   103  			return nil, status.OperatorConflict
   104  		}
   105  		return nil, status.DatabaseError.StatusErr().WithDesc(err.Error())
   106  	}
   107  	return op, nil
   108  }
   109  
   110  func ListByCond(ctx context.Context, r *CondArgs) ([]models.Operator, error) {
   111  	var (
   112  		d = types.MustMgrDBExecutorFromContext(ctx)
   113  		m = &models.Operator{}
   114  	)
   115  	data, err := m.List(d, r.Condition())
   116  	if err != nil {
   117  		return nil, status.DatabaseError.StatusErr().WithDesc(err.Error())
   118  	}
   119  	return data, nil
   120  }
   121  
   122  func List(ctx context.Context, r *ListReq) (*ListRsp, error) {
   123  	var (
   124  		d = types.MustMgrDBExecutorFromContext(ctx)
   125  		m = &models.Operator{}
   126  
   127  		err  error
   128  		ret  = &ListRsp{}
   129  		cond = r.Condition()
   130  		adds = r.Additions()
   131  	)
   132  
   133  	ret.Data, err = m.List(d, cond, adds...)
   134  	if err != nil {
   135  		return nil, status.DatabaseError.StatusErr().WithDesc(err.Error())
   136  	}
   137  	ret.Total, err = m.Count(d, cond)
   138  	if err != nil {
   139  		return nil, status.DatabaseError.StatusErr().WithDesc(err.Error())
   140  	}
   141  	return ret, nil
   142  }
   143  
   144  func ListDetail(ctx context.Context, r *ListReq) (*ListDetailRsp, error) {
   145  	var (
   146  		d = types.MustMgrDBExecutorFromContext(ctx)
   147  		m = &models.Operator{}
   148  
   149  		err  error
   150  		ret  = &ListDetailRsp{}
   151  		cond = r.Condition()
   152  		adds = r.Additions()
   153  	)
   154  
   155  	data, err := m.List(d, cond, adds...)
   156  	if err != nil {
   157  		return nil, status.DatabaseError.StatusErr().WithDesc(err.Error())
   158  	}
   159  	ret.Total, err = m.Count(d, cond)
   160  	if err != nil {
   161  		return nil, status.DatabaseError.StatusErr().WithDesc(err.Error())
   162  	}
   163  
   164  	for i := range data {
   165  		detail, err := convDetail(&data[i])
   166  		if err != nil {
   167  			return nil, err
   168  		}
   169  		ret.Data = append(ret.Data, *detail)
   170  	}
   171  
   172  	return ret, nil
   173  }
   174  
   175  func convDetail(d *models.Operator) (*Detail, error) {
   176  	var address string
   177  	if d.Type == enums.OPERATOR_KEY__ECDSA {
   178  		prvkey, err := crypto.HexToECDSA(d.PrivateKey)
   179  		if err != nil {
   180  			return nil, err
   181  		}
   182  		pubkey := crypto.PubkeyToAddress(prvkey.PublicKey)
   183  		address = pubkey.Hex()
   184  	} else {
   185  		b := common.FromHex(d.PrivateKey)
   186  		prik := ed25519.PrivateKey(b)
   187  		pubk := solcommon.PublicKeyFromBytes(prik.Public().(ed25519.PublicKey))
   188  		address = pubk.ToBase58()
   189  	}
   190  
   191  	return &Detail{
   192  		Operator: *d,
   193  		Address:  address,
   194  	}, nil
   195  }