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 }