@@ -19,6 +19,7 @@ import (
19
19
"github.com/lib/pq"
20
20
_ "github.com/lib/pq"
21
21
"github.com/rs/xid"
22
+ "gorm.io/gorm"
22
23
23
24
"github.com/stakwork/sphinx-tribes/auth"
24
25
"github.com/stakwork/sphinx-tribes/utils"
@@ -2202,3 +2203,157 @@ func (db database) GetBountiesByWorkspaceAndTimeRange(workspaceId string, startD
2202
2203
2203
2204
return bounties , err
2204
2205
}
2206
+
2207
+ func (db database ) CreateBountyStake (stake BountyStake ) (* BountyStake , error ) {
2208
+ if stake .BountyID == 0 {
2209
+ return nil , errors .New ("bounty ID is required" )
2210
+ }
2211
+
2212
+ if stake .HunterPubKey == "" {
2213
+ return nil , errors .New ("hunter public key is required" )
2214
+ }
2215
+
2216
+ if stake .Amount <= 0 {
2217
+ return nil , errors .New ("stake amount must be greater than zero" )
2218
+ }
2219
+
2220
+ bounty := db .GetBounty (stake .BountyID )
2221
+ if bounty .ID == 0 {
2222
+ return nil , errors .New ("bounty not found" )
2223
+ }
2224
+
2225
+ if ! bounty .IsStakable {
2226
+ return nil , errors .New ("bounty is not stakable" )
2227
+ }
2228
+
2229
+ if stake .Amount < bounty .StakeMin {
2230
+ return nil , fmt .Errorf ("stake amount must be at least %d" , bounty .StakeMin )
2231
+ }
2232
+
2233
+ if bounty .CurrentStakers >= bounty .MaxStakers {
2234
+ return nil , errors .New ("maximum number of stakers reached for this bounty" )
2235
+ }
2236
+
2237
+ if stake .Status == "" {
2238
+ stake .Status = StakeStatusNew
2239
+ }
2240
+
2241
+ if err := db .db .Create (& stake ).Error ; err != nil {
2242
+ return nil , fmt .Errorf ("failed to create bounty stake: %w" , err )
2243
+ }
2244
+
2245
+ if err := db .db .Model (& NewBounty {}).Where ("id = ?" , stake .BountyID ).
2246
+ Update ("current_stakers" , gorm .Expr ("current_stakers + 1" )).Error ; err != nil {
2247
+ return nil , fmt .Errorf ("failed to update bounty stakers count: %w" , err )
2248
+ }
2249
+
2250
+ return & stake , nil
2251
+ }
2252
+
2253
+ func (db database ) GetAllBountyStakes () ([]BountyStake , error ) {
2254
+ var stakes []BountyStake
2255
+ if err := db .db .Find (& stakes ).Error ; err != nil {
2256
+ return nil , fmt .Errorf ("failed to retrieve bounty stakes: %w" , err )
2257
+ }
2258
+ return stakes , nil
2259
+ }
2260
+
2261
+ func (db database ) GetBountyStakesByBountyID (bountyID uint ) ([]BountyStake , error ) {
2262
+ var stakes []BountyStake
2263
+ if err := db .db .Where ("bounty_id = ?" , bountyID ).Find (& stakes ).Error ; err != nil {
2264
+ return nil , fmt .Errorf ("failed to retrieve stakes for bounty %d: %w" , bountyID , err )
2265
+ }
2266
+ return stakes , nil
2267
+ }
2268
+
2269
+ func (db database ) GetBountyStakeByID (stakeID uuid.UUID ) (* BountyStake , error ) {
2270
+ var stake BountyStake
2271
+ if err := db .db .Where ("id = ?" , stakeID ).First (& stake ).Error ; err != nil {
2272
+ if errors .Is (err , gorm .ErrRecordNotFound ) {
2273
+ return nil , fmt .Errorf ("stake with ID %s not found" , stakeID )
2274
+ }
2275
+ return nil , fmt .Errorf ("failed to retrieve stake with ID %s: %w" , stakeID , err )
2276
+ }
2277
+ return & stake , nil
2278
+ }
2279
+
2280
+ func (db database ) GetBountyStakesByHunterPubKey (hunterPubKey string ) ([]BountyStake , error ) {
2281
+ var stakes []BountyStake
2282
+ if err := db .db .Where ("hunter_pub_key = ?" , hunterPubKey ).Find (& stakes ).Error ; err != nil {
2283
+ return nil , fmt .Errorf ("failed to retrieve stakes for hunter %s: %w" , hunterPubKey , err )
2284
+ }
2285
+ return stakes , nil
2286
+ }
2287
+
2288
+ func (db database ) UpdateBountyStake (stakeID uuid.UUID , updates map [string ]interface {}) (* BountyStake , error ) {
2289
+
2290
+ stake , err := db .GetBountyStakeByID (stakeID )
2291
+ if err != nil {
2292
+ return nil , err
2293
+ }
2294
+
2295
+ if statusVal , ok := updates ["status" ]; ok {
2296
+ status , ok := statusVal .(StakeStatus )
2297
+ if ! ok {
2298
+ statusStr , ok := statusVal .(string )
2299
+ if ok {
2300
+ status = StakeStatus (statusStr )
2301
+ } else {
2302
+ return nil , errors .New ("invalid status type" )
2303
+ }
2304
+ }
2305
+
2306
+ if status == StakeStatusActive && stake .StakedAt == nil {
2307
+ now := time .Now ()
2308
+ updates ["staked_at" ] = now
2309
+ }
2310
+
2311
+ if status == StakeStatusReturned && stake .ReturnedAt == nil {
2312
+ now := time .Now ()
2313
+ updates ["returned_at" ] = now
2314
+
2315
+ if err := db .db .Model (& NewBounty {}).Where ("id = ?" , stake .BountyID ).
2316
+ Update ("current_stakers" , gorm .Expr ("current_stakers - 1" )).Error ; err != nil {
2317
+ return nil , fmt .Errorf ("failed to update bounty stakers count: %w" , err )
2318
+ }
2319
+ }
2320
+ }
2321
+
2322
+ if err := db .db .Model (& BountyStake {}).Where ("id = ?" , stakeID ).Updates (updates ).Error ; err != nil {
2323
+ return nil , fmt .Errorf ("failed to update stake with ID %s: %w" , stakeID , err )
2324
+ }
2325
+
2326
+ return db .GetBountyStakeByID (stakeID )
2327
+ }
2328
+
2329
+ func (db database ) DeleteBountyStake (stakeID uuid.UUID ) error {
2330
+
2331
+ stake , err := db .GetBountyStakeByID (stakeID )
2332
+ if err != nil {
2333
+ return err
2334
+ }
2335
+
2336
+ tx := db .db .Begin ()
2337
+ if tx .Error != nil {
2338
+ return fmt .Errorf ("failed to begin transaction: %w" , tx .Error )
2339
+ }
2340
+
2341
+ if err := tx .Delete (& BountyStake {}, "id = ?" , stakeID ).Error ; err != nil {
2342
+ tx .Rollback ()
2343
+ return fmt .Errorf ("failed to delete stake with ID %s: %w" , stakeID , err )
2344
+ }
2345
+
2346
+ if stake .StakedAt != nil && stake .ReturnedAt == nil {
2347
+ if err := tx .Model (& NewBounty {}).Where ("id = ?" , stake .BountyID ).
2348
+ Update ("current_stakers" , gorm .Expr ("current_stakers - 1" )).Error ; err != nil {
2349
+ tx .Rollback ()
2350
+ return fmt .Errorf ("failed to update bounty stakers count: %w" , err )
2351
+ }
2352
+ }
2353
+
2354
+ if err := tx .Commit ().Error ; err != nil {
2355
+ return fmt .Errorf ("failed to commit transaction: %w" , err )
2356
+ }
2357
+
2358
+ return nil
2359
+ }
0 commit comments