polkamarkets-js 1.0.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (2) hide show
  1. package/package.json +15 -0
  2. package/polkamarkets.js +422 -0
package/package.json ADDED
@@ -0,0 +1,15 @@
1
+ {
2
+ "name": "polkamarkets-js",
3
+ "version": "1.0.0",
4
+ "description": "Polkamarkets Javascript SDK",
5
+ "engines": {
6
+ "node": "^14.15.0"
7
+ },
8
+ "dependencies": {
9
+ "bepro-js": "bepronetwork/bepro-js#feature/prediction-markets"
10
+ },
11
+ "main": "polkamarkets.js",
12
+ "repository": "https://github.com/Polkamarkets/polkamarkets-js",
13
+ "author": "Ricardo Marques <ricardo@polkamarkets.com>",
14
+ "license": "MIT"
15
+ }
@@ -0,0 +1,422 @@
1
+ import * as realitioLib from '@reality.eth/reality-eth-lib/formatters/question';
2
+ import * as beprojs from 'bepro-js';
3
+ export default class Polkamarkets {
4
+ constructor(web3Provider, web3EventsProvider = null) {
5
+ // bepro app
6
+ this.bepro = new beprojs.Application({ web3Provider, web3EventsProvider });
7
+ this.bepro.start();
8
+
9
+ // bepro smart contract instances
10
+ this.contracts = {};
11
+
12
+ // indicates if user has already done a successful metamask login
13
+ this.loggedIn = false;
14
+
15
+ // user eth address
16
+ this.address = '';
17
+ }
18
+
19
+ getPredictionMarketContract(contractAddress) {
20
+ this.contracts.pm = this.bepro.getPredictionMarketContract({ contractAddress });
21
+ }
22
+
23
+ getERC20Contract(contractAddress) {
24
+ this.contracts.erc20 = this.bepro.getERC20Contract({ contractAddress });
25
+ }
26
+
27
+ getRealitioERC20Contract(contractAddress) {
28
+ this.contracts.realitio = this.bepro.getRealitioERC20Contract({ contractAddress });
29
+ }
30
+
31
+ // returns wether wallet is connected to service or not
32
+ async isLoggedIn() {
33
+ return this.bepro.isLoggedIn();
34
+ }
35
+
36
+ async login() {
37
+ if (this.loggedIn) return true;
38
+
39
+ try {
40
+ this.loggedIn = await this.bepro.login();
41
+ // successful login
42
+ if (this.loggedIn) {
43
+ this.address = await this.getAddress();
44
+ // TODO: set this in bepro
45
+ this.bepro.web3.eth.defaultAccount = this.address;
46
+ // re-fetching contracts
47
+ this.getContracts();
48
+ }
49
+ } catch (e) {
50
+ // should be non-blocking
51
+ return false;
52
+ }
53
+
54
+ return this.loggedIn;
55
+ }
56
+
57
+ async getAddress() {
58
+ if (this.address) return this.address;
59
+
60
+ return this.bepro.getAddress() || '';
61
+ }
62
+
63
+ async getBalance() {
64
+ if (!this.address) return 0;
65
+
66
+ // returns user balance in ETH
67
+ const balance = await this.bepro.getETHBalance();
68
+
69
+ return parseFloat(balance) || 0;
70
+ }
71
+
72
+ // PredictionMarket contract functions
73
+
74
+ async getMinimumRequiredBalance() {
75
+ const requiredBalance = await this.contracts.pm.getMinimumRequiredBalance();
76
+
77
+ return requiredBalance;
78
+ }
79
+
80
+ async getMarketFee() {
81
+ const fee = await this.contracts.pm.getFee();
82
+
83
+ return fee;
84
+ }
85
+
86
+ async createMarket(
87
+ name,
88
+ image,
89
+ duration,
90
+ outcomes,
91
+ category,
92
+ ethAmount
93
+ ) {
94
+ // ensuring user has wallet connected
95
+ await this.login();
96
+
97
+ const response = await this.contracts.pm.createMarket({
98
+ name,
99
+ image,
100
+ duration,
101
+ outcomes,
102
+ category,
103
+ ethAmount,
104
+ oracleAddress: this.address
105
+ });
106
+
107
+ return response;
108
+ }
109
+
110
+ async buy(
111
+ marketId,
112
+ outcomeId,
113
+ ethAmount,
114
+ minOutcomeSharesToBuy
115
+ ) {
116
+ // ensuring user has wallet connected
117
+ await this.login();
118
+
119
+ const response = await this.contracts.pm.buy({
120
+ marketId,
121
+ outcomeId,
122
+ ethAmount,
123
+ minOutcomeSharesToBuy
124
+ });
125
+
126
+ return response;
127
+ }
128
+
129
+ async sell(
130
+ marketId,
131
+ outcomeId,
132
+ ethAmount,
133
+ maxOutcomeSharesToSell
134
+ ) {
135
+ // ensuring user has wallet connected
136
+ await this.login();
137
+
138
+ const response = await this.contracts.pm.sell({
139
+ marketId,
140
+ outcomeId,
141
+ ethAmount,
142
+ maxOutcomeSharesToSell
143
+ });
144
+
145
+ return response;
146
+ }
147
+
148
+ async addLiquidity(marketId, ethAmount) {
149
+ // ensuring user has wallet connected
150
+ await this.login();
151
+
152
+ const response = await this.contracts.pm.addLiquidity({
153
+ marketId,
154
+ ethAmount
155
+ });
156
+
157
+ return response;
158
+ }
159
+
160
+ async removeLiquidity(marketId, shares) {
161
+ // ensuring user has wallet connected
162
+ await this.login();
163
+
164
+ const response = await this.contracts.pm.removeLiquidity({
165
+ marketId,
166
+ shares
167
+ });
168
+
169
+ return response;
170
+ }
171
+
172
+ async claimWinnings(marketId) {
173
+ // ensuring user has wallet connected
174
+ await this.login();
175
+
176
+ const response = await this.contracts.pm.claimWinnings({
177
+ marketId
178
+ });
179
+
180
+ return response;
181
+ }
182
+
183
+ async claimVoidedOutcomeShares(marketId, outcomeId) {
184
+ // ensuring user has wallet connected
185
+ await this.login();
186
+
187
+ const response = await this.contracts.pm.claimVoidedOutcomeShares({
188
+ marketId,
189
+ outcomeId
190
+ });
191
+
192
+ return response;
193
+ }
194
+
195
+ async claimLiquidity(marketId) {
196
+ // ensuring user has wallet connected
197
+ await this.login();
198
+
199
+ const response = await this.contracts.pm.claimLiquidity({
200
+ marketId
201
+ });
202
+
203
+ return response;
204
+ }
205
+
206
+ async getMarketData(marketId) {
207
+ // ensuring user has wallet connected
208
+ await this.login();
209
+
210
+ const marketData = await this.contracts.pm.getMarketData({ marketId });
211
+
212
+ marketData.outcomes = await Promise.all(
213
+ marketData.outcomeIds.map(async outcomeId => {
214
+ const outcomeData = await this.contracts.pm.getOutcomeData({
215
+ marketId,
216
+ outcomeId
217
+ });
218
+
219
+ return outcomeData;
220
+ })
221
+ );
222
+
223
+ return marketData;
224
+ }
225
+
226
+ async getMarketPrices(marketId) {
227
+ // ensuring user has wallet connected
228
+ await this.login();
229
+
230
+ const response = await this.contracts.pm.getMarketPrices({ marketId });
231
+
232
+ return response;
233
+ }
234
+
235
+ async getPortfolio() {
236
+ // ensuring user has wallet connected
237
+ if (!this.address) return {};
238
+
239
+ const response = await this.contracts.pm.getMyPortfolio();
240
+
241
+ return response;
242
+ }
243
+
244
+ async getActions() {
245
+ // ensuring user has wallet connected
246
+ if (!this.address) return [];
247
+
248
+ const response = await this.contracts.pm.getMyActions();
249
+
250
+ return response;
251
+ }
252
+
253
+ async resolveMarket(marketId) {
254
+ // ensuring user has wallet connected
255
+ await this.login();
256
+
257
+ const response = await this.contracts.pm.resolveMarketOutcome({
258
+ marketId
259
+ });
260
+
261
+ return response;
262
+ }
263
+
264
+ // ERC20 contract functions
265
+
266
+ async getERC20Balance() {
267
+ if (!this.address) return 0;
268
+
269
+ // TODO improve this: ensuring erc20 contract is initialized
270
+ // eslint-disable-next-line no-underscore-dangle
271
+ await this.contracts.erc20.__init__();
272
+
273
+ // returns user balance in ETH
274
+ const balance = await this.contracts.erc20.getTokenAmount(this.address);
275
+
276
+ return parseFloat(balance) || 0;
277
+ }
278
+
279
+ async approveERC20(address, amount) {
280
+ // ensuring user has wallet connected
281
+ await this.login();
282
+
283
+ // ensuring erc20 contract is initialized
284
+ // eslint-disable-next-line no-underscore-dangle
285
+ await this.contracts.erc20.__init__();
286
+
287
+ const response = await this.contracts.erc20.approve({
288
+ address,
289
+ amount
290
+ });
291
+
292
+ return response;
293
+ }
294
+
295
+ async calcBuyAmount(marketId, outcomeId, ethAmount) {
296
+ const response = await this.contracts.pm.calcBuyAmount({
297
+ marketId,
298
+ outcomeId,
299
+ ethAmount
300
+ });
301
+
302
+ return response;
303
+ }
304
+
305
+ async calcSellAmount(
306
+ marketId,
307
+ outcomeId,
308
+ ethAmount
309
+ ) {
310
+ const response = await this.contracts.pm.calcSellAmount({
311
+ marketId,
312
+ outcomeId,
313
+ ethAmount
314
+ });
315
+
316
+ return response;
317
+ }
318
+
319
+ // Realitio contract functions
320
+
321
+ async isRealitioERC20Approved() {
322
+ if (!this.address) return false;
323
+
324
+ // TODO improve this: ensuring erc20 contract is initialized
325
+ // eslint-disable-next-line no-underscore-dangle
326
+ await this.contracts.erc20.__init__();
327
+
328
+ // returns user balance in ETH
329
+ const isApproved = await this.contracts.erc20.isApproved({
330
+ address: this.address,
331
+ amount: 1,
332
+ spenderAddress: this.contracts.realitio.getAddress()
333
+ });
334
+
335
+ return isApproved;
336
+ }
337
+
338
+ async approveRealitioERC20() {
339
+ // ensuring user has wallet connected
340
+ await this.login();
341
+
342
+ if (!this.address) return false;
343
+
344
+ // TODO improve this: ensuring erc20 contract is initialized
345
+ // eslint-disable-next-line no-underscore-dangle
346
+ await this.contracts.erc20.__init__();
347
+
348
+ return this.approveERC20(
349
+ this.contracts.realitio.getAddress(),
350
+ 2 ** 128 - 1
351
+ );
352
+ }
353
+
354
+ async getQuestionBonds(questionId, user = null) {
355
+ const bonds = await this.contracts.realitio.getQuestionBondsByAnswer({
356
+ questionId,
357
+ user
358
+ });
359
+
360
+ // mapping answer ids to outcome ids
361
+ Object.keys(bonds).forEach(answerId => {
362
+ const outcomeId = Number(
363
+ realitioLib.bytes32ToString(answerId, { type: 'int' })
364
+ );
365
+ bonds[outcomeId] = bonds[answerId];
366
+ delete bonds[answerId];
367
+ });
368
+
369
+ return bonds;
370
+ }
371
+
372
+ async placeBond(questionId, outcomeId, amount) {
373
+ // ensuring user has wallet connected
374
+ await this.login();
375
+
376
+ // translating outcome id to answerId
377
+ const answerId = realitioLib.answerToBytes32(outcomeId, { type: 'int' });
378
+
379
+ const response = await this.contracts.realitio.submitAnswerERC20({
380
+ questionId,
381
+ answerId,
382
+ amount
383
+ });
384
+
385
+ return response;
386
+ }
387
+
388
+ async claimWinningsAndWithdraw(questionId) {
389
+ // ensuring user has wallet connected
390
+ await this.login();
391
+
392
+ const response = await this.contracts.realitio.claimWinningsAndWithdraw({
393
+ questionId
394
+ });
395
+
396
+ return response;
397
+ }
398
+
399
+ async getBonds() {
400
+ // ensuring user has wallet connected
401
+ if (!this.address) return {};
402
+
403
+ const bonds = await this.contracts.realitio.getMyBonds();
404
+
405
+ return bonds;
406
+ }
407
+
408
+ async getBondActions() {
409
+ // ensuring user has wallet connected
410
+ if (!this.address) return [];
411
+
412
+ const response = await this.contracts.realitio.getMyActions();
413
+
414
+ return response;
415
+ }
416
+
417
+ async getQuestion(questionId) {
418
+ const question = await this.contracts.realitio.getQuestion({ questionId });
419
+
420
+ return question;
421
+ }
422
+ }