github.com/DapperCollectives/CAST/backend@v0.0.0-20230921221157-1350c8be7c96/main/strategies/custom_script.go (about) 1 package strategies 2 3 import ( 4 "fmt" 5 6 "github.com/DapperCollectives/CAST/backend/main/models" 7 "github.com/DapperCollectives/CAST/backend/main/shared" 8 "github.com/rs/zerolog/log" 9 ) 10 11 type CustomScript struct { 12 shared.StrategyStruct 13 DB *shared.Database 14 } 15 16 func (cs *CustomScript) FetchBalance( 17 balance *models.Balance, 18 p *models.Proposal, 19 ) (*models.Balance, error) { 20 21 v := models.Vote{Proposal_id: balance.Proposal_id, Addr: balance.Addr} 22 vb := &models.VoteWithBalance{ 23 NFTs: []*models.NFT{}, 24 Vote: v, 25 } 26 27 var c models.Community 28 if err := c.GetCommunityByProposalId(cs.DB, balance.Proposal_id); err != nil { 29 return nil, err 30 } 31 32 strategy, err := models.MatchStrategyByProposal(*c.Strategies, *p.Strategy) 33 if err != nil { 34 log.Error().Err(err).Msg("Unable to find strategy for contract.") 35 return nil, err 36 } 37 38 if strategy.Contract.Script == nil { 39 log.Error().Msg("No custom script name field was found for contract.") 40 } 41 42 if err := cs.queryNFTs(*vb, strategy, balance); err != nil { 43 return nil, err 44 } 45 46 return balance, nil 47 } 48 49 func (cs *CustomScript) queryNFTs( 50 vb models.VoteWithBalance, 51 strategy models.Strategy, 52 balance *models.Balance, 53 ) error { 54 scriptName := cs.FlowAdapter.CustomScriptsMap[*strategy.Contract.Script].Src 55 scriptPath := fmt.Sprintf("./main/cadence/scripts/custom/%s", scriptName) 56 57 nftIds, err := cs.FlowAdapter.GetNFTIds( 58 balance.Addr, 59 &strategy.Contract, 60 scriptPath, 61 ) 62 if err != nil { 63 return err 64 } 65 66 for _, nftId := range nftIds { 67 nft := &models.NFT{ 68 ID: nftId, 69 } 70 vb.NFTs = append(vb.NFTs, nft) 71 } 72 73 doesExist, err := models.DoesNFTExist(cs.DB, &vb) 74 if err != nil { 75 return err 76 } 77 78 //only if the NFT ID is not already in the DB, 79 //do we add the balance 80 if !doesExist && err == nil { 81 err = models.CreateUserNFTRecord(cs.DB, &vb) 82 balance.NFTCount = len(vb.NFTs) 83 } 84 85 return err 86 } 87 88 func (cs *CustomScript) TallyVotes( 89 votes []*models.VoteWithBalance, 90 r *models.ProposalResults, 91 proposal *models.Proposal, 92 ) (models.ProposalResults, error) { 93 94 for _, vote := range votes { 95 if len(vote.NFTs) != 0 { 96 var voteWeight float64 97 98 voteWeight, err := cs.GetVoteWeightForBalance(vote, proposal) 99 if err != nil { 100 return models.ProposalResults{}, err 101 } 102 103 r.Results[vote.Choice] += int(voteWeight) 104 r.Results_float[vote.Choice] += voteWeight 105 } 106 } 107 108 return *r, nil 109 } 110 111 func (cs *CustomScript) GetVoteWeightForBalance( 112 vote *models.VoteWithBalance, 113 proposal *models.Proposal, 114 ) (float64, error) { 115 nftIds, err := models.GetUserNFTs(cs.DB, vote) 116 if err != nil { 117 log.Error().Err(err).Msg("error in GetVoteWeightForBalance for Custom Script strategy") 118 return 0.00, err 119 } 120 121 if proposal.Max_weight != nil && float64(len(nftIds)) > *proposal.Max_weight { 122 return *proposal.Max_weight, nil 123 } 124 125 return float64(len(nftIds)), nil 126 } 127 128 func (cs *CustomScript) GetVotes( 129 votes []*models.VoteWithBalance, 130 proposal *models.Proposal, 131 ) ([]*models.VoteWithBalance, error) { 132 for _, vote := range votes { 133 weight, err := cs.GetVoteWeightForBalance(vote, proposal) 134 if err != nil { 135 return nil, err 136 } 137 vote.Weight = &weight 138 } 139 140 return votes, nil 141 } 142 143 func (cs *CustomScript) RequiresSnapshot() bool { 144 return false 145 } 146 147 func (cs *CustomScript) InitStrategy( 148 f *shared.FlowAdapter, 149 db *shared.Database, 150 ) { 151 cs.FlowAdapter = f 152 cs.DB = db 153 }