@@ -11,6 +11,7 @@ const {
1111 getIPFSProofFromPayload,
1212} = require ( "../../utils" ) ;
1313
14+ const axios = require ( "axios" ) ;
1415const { uploadToIPFS } = require ( "../../services/ipfs.service" ) ;
1516const DaoModel = require ( "../../db/models/Dao.model" ) ;
1617const TokenModel = require ( "../../db/models/Token.model" ) ;
@@ -21,6 +22,85 @@ const { getEthCurrentBlockNumber, getEthTotalSupply } = require("../../utils-eth
2122
2223const ObjectId = require ( "mongodb" ) . ObjectId ;
2324
25+ async function _getPollData ( mode = "lite" , {
26+ daoId, network, tokenAddress = null , authorAddress = null , payloadBytes = null
27+ } ) {
28+ if ( ! network ?. startsWith ( "etherlink" ) )
29+ throw new Error ( "Network is not supported" ) ;
30+
31+ const currentTime = new Date ( ) . valueOf ( ) ;
32+
33+ if ( mode == "onchain" ) {
34+
35+ console . log ( "tokenAddress" , tokenAddress )
36+ const [ userTokenBalance , tokenTotalSupply , block ] = await Promise . all ( [
37+ axios . get ( `https://testnet.explorer.etherlink.com/api/v2/tokens/${ tokenAddress } /holders` ) . then ( res => res . data ) . catch ( err => ( { error : err . message } ) ) ,
38+ axios . get ( `https://testnet.explorer.etherlink.com/api/v2/tokens/${ tokenAddress } ` ) . then ( res => res . data ) . catch ( err => ( { error : err . message } ) ) ,
39+ getEthCurrentBlockNumber ( network ) . catch ( err => ( { error : err . message } ) )
40+ ] ) ;
41+
42+ console . log ( JSON . stringify ( { userTokenBalance, tokenTotalSupply, block} , null , 2 ) ) ;
43+
44+ const payloadBytesHash = md5 ( payloadBytes ) ;
45+ const doesPollExists = await PollModel . findOne ( { payloadBytesHash } ) ;
46+ if ( doesPollExists )
47+ throw new Error ( "Invalid Signature, Poll already exists" ) ;
48+
49+
50+ return {
51+ startTime : currentTime ,
52+ referenceBlock : block ,
53+ totalSupplyAtReferenceBlock : tokenTotalSupply . total_supply ,
54+ payloadBytesHash,
55+ doesPollExists
56+ }
57+ }
58+ else {
59+
60+ const dao = await DaoModel . findById ( daoId ) ;
61+ if ( ! dao ) throw new Error ( "DAO Does not exist" ) ;
62+
63+ const token = await TokenModel . findOne ( { tokenAddress : dao . tokenAddress } ) ;
64+ if ( ! token ) throw new Error ( "DAO Token Does not exist in system" ) ;
65+
66+ const block = await getEthCurrentBlockNumber ( dao . network ) ;
67+ const totalSupply = await getEthTotalSupply (
68+ dao . network ,
69+ dao . tokenAddress ,
70+ block
71+ ) ;
72+ // TODO: @ashutoshpw To be Implemented
73+ // const userVotingPowerAtCurrentLevel =
74+ // await getUserTotalVotingPowerAtReferenceBlock(
75+ // dao.network,
76+ // dao.tokenAddress,
77+ // dao.daoContract,
78+ // token.tokenID,
79+ // block,
80+ // author
81+ // );
82+
83+ // if (userVotingPowerAtCurrentLevel.eq(0) && dao.requiredTokenOwnership) {
84+ // throw new Error(
85+ // "User Doesnt have balance at this level to create proposal"
86+ // );
87+ // }
88+ const payloadBytesHash = md5 ( payloadBytes ) ;
89+ const doesPollExists = await PollModel . findOne ( { payloadBytesHash } ) ;
90+ if ( doesPollExists )
91+ throw new Error ( "Invalid Signature, Poll already exists" ) ;
92+
93+ return {
94+ daoId,
95+ startTime : currentTime ,
96+ referenceBlock : block ,
97+ totalSupplyAtReferenceBlock : totalSupply ,
98+ payloadBytesHash,
99+ doesPollExists
100+ }
101+ }
102+ }
103+
24104const getPollById = async ( req , response ) => {
25105 const { id } = req . params ;
26106
@@ -29,7 +109,11 @@ const getPollById = async (req, response) => {
29109 let pollId = { _id : ObjectId ( id ) } ;
30110
31111 const result = await db_connect . collection ( "Polls" ) . findOne ( pollId ) ;
32- response . json ( result ) ;
112+ response . json ( {
113+ ...result ,
114+ name : result . name ?. replace ( / < [ ^ > ] * > / g, '' ) ,
115+ description : result . description ?. replace ( / < [ ^ > ] * > / g, '' ) ,
116+ } ) ;
33117 } catch ( error ) {
34118 console . log ( "error: " , error ) ;
35119 response . status ( 400 ) . send ( {
@@ -65,18 +149,21 @@ const addPoll = async (req, response) => {
65149
66150 if ( network ?. startsWith ( "etherlink" ) ) {
67151 try {
68- const payload = req . payloadObj ;
152+ let payload = req . payloadObj ;
153+ if ( ! payload ) {
154+ payload = getInputFromSigPayload ( payloadBytes ) ;
155+ }
69156 const {
70157 choices,
71- daoID,
72158 name,
73159 description,
74160 externalLink,
75161 endTime,
76162 votingStrategy,
77163 isXTZ,
78164 } = payload ;
79-
165+ const daoID = payload ?. daoID || payload ?. daoId ;
166+ console . log ( "Payload" , payload )
80167 if ( choices . length === 0 ) {
81168 throw new Error ( "No choices sent in the request" ) ;
82169 }
@@ -94,43 +181,29 @@ const addPoll = async (req, response) => {
94181 throw new Error ( "Duplicate choices found" ) ;
95182 }
96183
97- const dao = await DaoModel . findById ( daoID ) ;
98- if ( ! dao ) throw new Error ( "DAO Does not exist" ) ;
99-
100- const token = await TokenModel . findOne ( { tokenAddress : dao . tokenAddress } ) ;
101- if ( ! token ) throw new Error ( "DAO Token Does not exist in system" ) ;
184+ /**
185+ * @ashutoshpw
186+ *
187+ * For Offchain Debate
188+ * - Get token Addresswithin the payload
189+ * = Get the User Token Balance by following API: https://testnet.explorer.etherlink.com/api/v2/tokens/0xBDAc0fBE8cf84eA51cB9436719f6074dA474ef5D/holders
190+ * - Get token Total Supplyw ith this: https://testnet.explorer.etherlink.com/api/v2/tokens/0xBDAc0fBE8cf84eA51cB9436719f6074dA474ef5D
191+ */
102192
103- const block = await getEthCurrentBlockNumber ( dao . network ) ;
104193 const author = publicKey ;
105- const startTime = currentTime ;
106- const totalSupply = await getEthTotalSupply (
107- dao . network ,
108- dao . tokenAddress ,
109- block
110- ) ;
111194
112- // TODO: @ashutoshpw To be Implemented
113- // const userVotingPowerAtCurrentLevel =
114- // await getUserTotalVotingPowerAtReferenceBlock(
115- // dao.network,
116- // dao.tokenAddress,
117- // dao.daoContract,
118- // token.tokenID,
119- // block,
120- // author
121- // );
122-
123- // if (userVotingPowerAtCurrentLevel.eq(0) && dao.requiredTokenOwnership) {
124- // throw new Error(
125- // "User Doesnt have balance at this level to create proposal"
126- // );
127- // }
195+ const daoMode = daoID ?. startsWith ( "0x" ) ? "onchain" : "lite" ;
196+ const { startTime, referenceBlock, totalSupplyAtReferenceBlock, payloadBytesHash, doesPollExists} = await _getPollData ( daoMode , {
197+ daoId : daoID ,
198+ network,
199+ authorAddress : publicKey ,
200+ tokenAddress : payload ?. tokenAddress ,
201+ payloadBytes
202+ } ) ;
128203
129- const payloadBytesHash = md5 ( payloadBytes ) ;
130- const doesPollExists = await PollModel . findOne ( { payloadBytesHash } ) ;
131- if ( doesPollExists )
204+ if ( doesPollExists )
132205 throw new Error ( "Invalid Signature, Poll already exists" ) ;
133-
206+
134207 const PollData = {
135208 name,
136209 author,
@@ -139,10 +212,11 @@ const addPoll = async (req, response) => {
139212 startTime,
140213 endTime,
141214 daoID,
142- referenceBlock : block ,
143- totalSupplyAtReferenceBlock : totalSupply ,
215+ referenceBlock,
216+ totalSupplyAtReferenceBlock,
144217 signature,
145- votingStrategy,
218+ votingStrategy : payload ?. votingStrategy || 0 ,
219+ isXTZ : payload ?. isXTZ || false ,
146220 payloadBytes,
147221 payloadBytesHash,
148222 cidLink : "" ,
@@ -159,14 +233,35 @@ const addPoll = async (req, response) => {
159233 } ;
160234 } ) ;
161235
162- await ChoiceModel . insertMany ( choicesData ) ;
236+ const choicesObj = await ChoiceModel . insertMany ( choicesData ) ;
237+ const choicesIds = choicesObj . map ( choice => choice . _id ) ;
238+ console . log ( { choicesIds} )
163239
164- await DaoModel . updateOne (
165- { _id : ObjectId ( daoID ) } ,
166- {
167- $push : { polls : pollId } ,
168- }
240+ await PollModel . updateOne (
241+ { _id : pollId } ,
242+ { $set : { choices : choicesIds } }
169243 ) ;
244+
245+ if ( daoMode == "lite" ) {
246+ await DaoModel . updateOne (
247+ { _id : ObjectId ( daoID ) } ,
248+ {
249+ $push : { polls : pollId } ,
250+ }
251+ ) ;
252+ } else {
253+ await DaoModel . findOneAndUpdate (
254+ { address : daoID } ,
255+ {
256+ name : daoID ,
257+ tokenAddress : payload ?. tokenAddress ,
258+ tokenType :"erc20" ,
259+ $push : { polls : pollId } ,
260+ votingAddressesCount : 0 // TODO: @ashutoshpw
261+ } ,
262+ { upsert : true , new : true }
263+ ) ;
264+ }
170265 return response . status ( 200 ) . send ( {
171266 message : "Poll Created Successfully" ,
172267 pollId,
0 commit comments