github.com/NpoolPlatform/chain-middleware@v0.0.0-20240228100535-eb1bcf896eb9/pkg/mw/coin/create.go (about) 1 package coin 2 3 import ( 4 "context" 5 "fmt" 6 7 npool "github.com/NpoolPlatform/message/npool/chain/mw/v1/coin" 8 9 chainbasecrud "github.com/NpoolPlatform/chain-middleware/pkg/crud/chain" 10 basecrud "github.com/NpoolPlatform/chain-middleware/pkg/crud/coin" 11 extracrud "github.com/NpoolPlatform/chain-middleware/pkg/crud/coin/extra" 12 settingcrud "github.com/NpoolPlatform/chain-middleware/pkg/crud/coin/setting" 13 redis2 "github.com/NpoolPlatform/go-service-framework/pkg/redis" 14 basetypes "github.com/NpoolPlatform/message/npool/basetypes/v1" 15 16 "github.com/NpoolPlatform/chain-middleware/pkg/db" 17 "github.com/NpoolPlatform/chain-middleware/pkg/db/ent" 18 "github.com/NpoolPlatform/libent-cruder/pkg/cruder" 19 20 "github.com/google/uuid" 21 ) 22 23 type createHandler struct { 24 *Handler 25 } 26 27 func (h *createHandler) createChainBase(ctx context.Context, tx *ent.Tx) error { 28 if h.ChainType == nil { 29 return nil 30 } 31 conds := &chainbasecrud.Conds{ 32 Name: &cruder.Cond{Op: cruder.EQ, Val: *h.ChainType}, 33 } 34 if h.ENV != nil { 35 conds.ENV = &cruder.Cond{Op: cruder.EQ, Val: *h.ENV} 36 } 37 if h.ChainID != nil { 38 conds.ChainID = &cruder.Cond{Op: cruder.EQ, Val: *h.ChainID} 39 } 40 41 stm, err := chainbasecrud.SetQueryConds(tx.ChainBase.Query(), conds) 42 if err != nil { 43 return err 44 } 45 46 info, err := stm.Only(ctx) 47 if err != nil { 48 if !ent.IsNotFound(err) { 49 return err 50 } 51 } 52 if info != nil { 53 return nil 54 } 55 56 if _, err := chainbasecrud.CreateSet( 57 tx.ChainBase.Create(), 58 &chainbasecrud.Req{ 59 Name: h.ChainType, 60 NativeUnit: h.ChainNativeUnit, 61 AtomicUnit: h.ChainAtomicUnit, 62 UnitExp: h.ChainUnitExp, 63 ENV: h.ENV, 64 ChainID: h.ChainID, 65 Nickname: h.ChainNickname, 66 GasType: h.GasType, 67 }, 68 ).Save(ctx); err != nil { 69 return err 70 } 71 return nil 72 } 73 74 func (h *createHandler) createNativeCoinBase(ctx context.Context, tx *ent.Tx) error { 75 if h.ChainNativeCoinName == nil { 76 h.FeeCoinTypeID = h.EntID 77 return nil 78 } 79 if *h.ChainNativeUnit == *h.Unit { 80 h.FeeCoinTypeID = h.EntID 81 return nil 82 } 83 84 stm, err := basecrud.SetQueryConds( 85 tx.CoinBase.Query(), 86 &basecrud.Conds{ 87 Name: &cruder.Cond{Op: cruder.EQ, Val: *h.ChainNativeCoinName}, 88 ENV: &cruder.Cond{Op: cruder.EQ, Val: *h.ENV}, 89 }, 90 ) 91 if err != nil { 92 return err 93 } 94 95 info, err := stm.Only(ctx) 96 if err != nil { 97 if !ent.IsNotFound(err) { 98 return err 99 } 100 } 101 102 if info == nil { 103 info, err = basecrud.CreateSet( 104 tx.CoinBase.Create(), 105 &basecrud.Req{ 106 Name: h.ChainNativeCoinName, 107 Unit: h.ChainNativeUnit, 108 ENV: h.ENV, 109 }, 110 ).Save(ctx) 111 if err != nil { 112 return err 113 } 114 } 115 116 h.FeeCoinTypeID = &info.EntID 117 118 return nil 119 } 120 func (h *createHandler) createCoinBase(ctx context.Context, tx *ent.Tx) error { 121 stm, err := basecrud.SetQueryConds( 122 tx.CoinBase.Query(), 123 &basecrud.Conds{ 124 Name: &cruder.Cond{Op: cruder.EQ, Val: *h.Name}, 125 ENV: &cruder.Cond{Op: cruder.EQ, Val: *h.ENV}, 126 }, 127 ) 128 if err != nil { 129 return err 130 } 131 132 info, err := stm.Only(ctx) 133 if err != nil { 134 if !ent.IsNotFound(err) { 135 return err 136 } 137 } 138 if info != nil { 139 h.EntID = &info.EntID 140 return nil 141 } 142 143 if _, err := basecrud.CreateSet( 144 tx.CoinBase.Create(), 145 &basecrud.Req{ 146 EntID: h.EntID, 147 Name: h.Name, 148 Logo: h.Logo, 149 Presale: h.Presale, 150 Unit: h.Unit, 151 ENV: h.ENV, 152 ReservedAmount: h.ReservedAmount, 153 ForPay: h.ForPay, 154 }, 155 ).Save(ctx); err != nil { 156 return err 157 } 158 return nil 159 } 160 161 func (h *createHandler) createNativeCoinExtra(ctx context.Context, tx *ent.Tx) error { 162 if h.FeeCoinTypeID == nil { 163 return nil 164 } 165 166 stm, err := extracrud.SetQueryConds( 167 tx.CoinExtra.Query(), 168 &extracrud.Conds{ 169 CoinTypeID: &cruder.Cond{Op: cruder.EQ, Val: *h.FeeCoinTypeID}, 170 }, 171 ) 172 if err != nil { 173 return err 174 } 175 176 info, err := stm.Only(ctx) 177 if err != nil { 178 if !ent.IsNotFound(err) { 179 return err 180 } 181 } 182 if info != nil { 183 return nil 184 } 185 186 if _, err := extracrud.CreateSet( 187 tx.CoinExtra.Create(), 188 &extracrud.Req{ 189 CoinTypeID: h.FeeCoinTypeID, 190 }, 191 ).Save(ctx); err != nil { 192 return err 193 } 194 return nil 195 } 196 197 func (h *createHandler) createCoinExtra(ctx context.Context, tx *ent.Tx) error { 198 stm, err := extracrud.SetQueryConds( 199 tx.CoinExtra.Query(), 200 &extracrud.Conds{ 201 CoinTypeID: &cruder.Cond{Op: cruder.EQ, Val: *h.EntID}, 202 }, 203 ) 204 if err != nil { 205 return err 206 } 207 208 info, err := stm.Only(ctx) 209 if err != nil { 210 if !ent.IsNotFound(err) { 211 return err 212 } 213 } 214 if info != nil { 215 return nil 216 } 217 218 if _, err := extracrud.CreateSet( 219 tx.CoinExtra.Create(), 220 &extracrud.Req{ 221 CoinTypeID: h.EntID, 222 HomePage: h.HomePage, 223 Specs: h.Specs, 224 }, 225 ).Save(ctx); err != nil { 226 return err 227 } 228 return nil 229 } 230 231 func (h *createHandler) createNativeCoinSetting(ctx context.Context, tx *ent.Tx) error { 232 if h.FeeCoinTypeID == nil { 233 return nil 234 } 235 236 stm, err := settingcrud.SetQueryConds( 237 tx.Setting.Query(), 238 &settingcrud.Conds{ 239 CoinTypeID: &cruder.Cond{Op: cruder.EQ, Val: *h.FeeCoinTypeID}, 240 }, 241 ) 242 if err != nil { 243 return err 244 } 245 246 info, err := stm.Only(ctx) 247 if err != nil { 248 if !ent.IsNotFound(err) { 249 return err 250 } 251 } 252 if info != nil { 253 return nil 254 } 255 256 if _, err := settingcrud.CreateSet( 257 tx.Setting.Create(), 258 &settingcrud.Req{ 259 CoinTypeID: h.FeeCoinTypeID, 260 FeeCoinTypeID: h.FeeCoinTypeID, 261 }, 262 ).Save(ctx); err != nil { 263 return err 264 } 265 return nil 266 } 267 268 func (h *createHandler) createCoinSetting(ctx context.Context, tx *ent.Tx) error { 269 stm, err := settingcrud.SetQueryConds( 270 tx.Setting.Query(), 271 &settingcrud.Conds{ 272 CoinTypeID: &cruder.Cond{Op: cruder.EQ, Val: *h.EntID}, 273 }, 274 ) 275 if err != nil { 276 return err 277 } 278 279 info, err := stm.Only(ctx) 280 if err != nil { 281 if !ent.IsNotFound(err) { 282 return err 283 } 284 } 285 if info != nil { 286 return nil 287 } 288 289 if _, err := settingcrud.CreateSet( 290 tx.Setting.Create(), 291 &settingcrud.Req{ 292 CoinTypeID: h.EntID, 293 FeeCoinTypeID: h.FeeCoinTypeID, 294 WithdrawFeeByStableUSD: h.WithdrawFeeByStableUSD, 295 WithdrawFeeAmount: h.WithdrawFeeAmount, 296 CollectFeeAmount: h.CollectFeeAmount, 297 HotWalletFeeAmount: h.HotWalletFeeAmount, 298 LowFeeAmount: h.LowFeeAmount, 299 HotLowFeeAmount: h.HotLowFeeAmount, 300 HotWalletAccountAmount: h.HotWalletAccountAmount, 301 PaymentAccountCollectAmount: h.PaymentAccountCollectAmount, 302 LeastTransferAmount: h.LeastTransferAmount, 303 NeedMemo: h.NeedMemo, 304 RefreshCurrency: h.RefreshCurrency, 305 CheckNewAddressBalance: h.CheckNewAddressBalance, 306 }, 307 ).Save(ctx); err != nil { 308 return err 309 } 310 return nil 311 } 312 313 func (h *Handler) CreateCoin(ctx context.Context) (*npool.Coin, error) { 314 if h.Name == nil { 315 return nil, fmt.Errorf("invalid coinname") 316 } 317 if h.Unit == nil { 318 return nil, fmt.Errorf("invalid coinunit") 319 } 320 if h.ENV == nil { 321 return nil, fmt.Errorf("invalid coinenv") 322 } 323 324 lockKey := fmt.Sprintf( 325 "%v:%v:%v", 326 basetypes.Prefix_PrefixCreateCoin, 327 *h.Name, 328 *h.ENV, 329 ) 330 if err := redis2.TryLock(lockKey, 0); err != nil { 331 return nil, err 332 } 333 defer func() { 334 _ = redis2.Unlock(lockKey) 335 }() 336 337 id := uuid.New() 338 if h.EntID == nil { 339 h.EntID = &id 340 } 341 342 handler := &createHandler{ 343 Handler: h, 344 } 345 346 err := db.WithTx(ctx, func(_ctx context.Context, tx *ent.Tx) error { 347 if err := handler.createChainBase(_ctx, tx); err != nil { 348 return err 349 } 350 if err := handler.createNativeCoinBase(_ctx, tx); err != nil { 351 return err 352 } 353 if err := handler.createNativeCoinExtra(_ctx, tx); err != nil { 354 return err 355 } 356 if err := handler.createNativeCoinSetting(_ctx, tx); err != nil { 357 return err 358 } 359 if err := handler.createCoinBase(_ctx, tx); err != nil { 360 return err 361 } 362 if err := handler.createCoinExtra(_ctx, tx); err != nil { 363 return err 364 } 365 if err := handler.createCoinSetting(_ctx, tx); err != nil { 366 return err 367 } 368 return nil 369 }) 370 if err != nil { 371 return nil, err 372 } 373 374 return h.GetCoin(ctx) 375 }