hive-stream 2.0.3 → 2.0.5
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.
- package/.env +3 -1
- package/.env.example +3 -2
- package/.travis.yml +11 -11
- package/LICENSE +21 -21
- package/README.md +238 -236
- package/dist/actions.d.ts +10 -9
- package/dist/actions.js +23 -15
- package/dist/actions.js.map +1 -1
- package/dist/adapters/base.adapter.d.ts +25 -21
- package/dist/adapters/base.adapter.js +49 -63
- package/dist/adapters/base.adapter.js.map +1 -1
- package/dist/adapters/mongodb.adapter.d.ts +37 -29
- package/dist/adapters/mongodb.adapter.js +158 -113
- package/dist/adapters/mongodb.adapter.js.map +1 -1
- package/dist/adapters/sqlite.adapter.d.ts +41 -23
- package/dist/adapters/sqlite.adapter.js +397 -121
- package/dist/adapters/sqlite.adapter.js.map +1 -1
- package/dist/api.d.ts +6 -0
- package/dist/api.js +56 -0
- package/dist/api.js.map +1 -0
- package/dist/config.d.ts +16 -14
- package/dist/config.js +18 -15
- package/dist/config.js.map +1 -1
- package/dist/contracts/coinflip.contract.d.ts +14 -0
- package/dist/contracts/coinflip.contract.js +95 -0
- package/dist/contracts/coinflip.contract.js.map +1 -0
- package/dist/contracts/dice.contract.d.ts +29 -29
- package/dist/contracts/dice.contract.js +155 -157
- package/dist/contracts/dice.contract.js.map +1 -1
- package/dist/contracts/lotto.contract.d.ts +20 -16
- package/dist/contracts/lotto.contract.js +246 -107
- package/dist/contracts/lotto.contract.js.map +1 -1
- package/dist/exchanges/bittrex.d.ts +6 -0
- package/dist/exchanges/bittrex.js +35 -0
- package/dist/exchanges/bittrex.js.map +1 -0
- package/dist/exchanges/exchange.d.ts +9 -0
- package/dist/exchanges/exchange.js +27 -0
- package/dist/exchanges/exchange.js.map +1 -0
- package/dist/hive-rates.d.ts +9 -0
- package/dist/hive-rates.js +76 -0
- package/dist/hive-rates.js.map +1 -0
- package/dist/index.d.ts +11 -10
- package/dist/index.js +32 -15
- package/dist/index.js.map +1 -1
- package/dist/streamer.d.ts +93 -70
- package/dist/streamer.js +545 -439
- package/dist/streamer.js.map +1 -1
- package/dist/test.d.ts +1 -1
- package/dist/test.js +25 -27
- package/dist/test.js.map +1 -1
- package/dist/types/hive-stream.d.ts +6 -6
- package/dist/types/hive-stream.js +2 -2
- package/dist/utils.d.ts +27 -14
- package/dist/utils.js +261 -85
- package/dist/utils.js.map +1 -1
- package/ecosystem.config.js +17 -17
- package/jest.config.js +8 -13
- package/package.json +48 -44
- package/test-contract-block.md +18 -18
- package/tests/adapters/sqlite.adapter.spec.ts +43 -0
- package/tests/contracts/coinflip.contract.spec.ts +132 -0
- package/tests/contracts/dice.contract.spec.ts +159 -156
- package/tests/contracts/entrants.json +728 -728
- package/tests/contracts/lotto.contract.spec.ts +323 -372
- package/tests/setup.ts +18 -20
- package/tests/streamer.spec.ts +151 -151
- package/tests/utils.spec.ts +94 -99
- package/tsconfig.build.json +22 -20
- package/tslint.json +20 -20
- package/wallaby.js +26 -0
- package/dist/adapters/file.adapter.d.ts +0 -8
- package/dist/adapters/file.adapter.js +0 -70
- package/dist/adapters/file.adapter.js.map +0 -1
- package/dist/test/setup.d.ts +0 -0
- package/dist/test/setup.js +0 -9
- package/dist/test/setup.js.map +0 -1
- package/dist/test/streamer.spec.d.ts +0 -1
- package/dist/test/streamer.spec.js +0 -145
- package/dist/test/streamer.spec.js.map +0 -1
- package/dist/test/utils.spec.d.ts +0 -1
- package/dist/test/utils.spec.js +0 -11
- package/dist/test/utils.spec.js.map +0 -1
- package/dist/tests/contracts/dice.contract.spec.d.ts +0 -1
- package/dist/tests/contracts/dice.contract.spec.js +0 -130
- package/dist/tests/contracts/dice.contract.spec.js.map +0 -1
- package/dist/tests/contracts/entrants.json +0 -729
- package/dist/tests/contracts/lotto.contract.spec.d.ts +0 -1
- package/dist/tests/contracts/lotto.contract.spec.js +0 -300
- package/dist/tests/contracts/lotto.contract.spec.js.map +0 -1
- package/dist/tests/setup.d.ts +0 -1
- package/dist/tests/setup.js +0 -19
- package/dist/tests/setup.js.map +0 -1
- package/dist/tests/streamer.spec.d.ts +0 -1
- package/dist/tests/streamer.spec.js +0 -123
- package/dist/tests/streamer.spec.js.map +0 -1
- package/dist/tests/utils.spec.d.ts +0 -1
- package/dist/tests/utils.spec.js +0 -87
- package/dist/tests/utils.spec.js.map +0 -1
- package/hive-stream.json +0 -1
package/dist/config.d.ts
CHANGED
|
@@ -1,14 +1,16 @@
|
|
|
1
|
-
export interface ConfigInterface {
|
|
2
|
-
ACTIVE_KEY: string;
|
|
3
|
-
POSTING_KEY: string;
|
|
4
|
-
JSON_ID: string;
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
1
|
+
export interface ConfigInterface {
|
|
2
|
+
ACTIVE_KEY: string;
|
|
3
|
+
POSTING_KEY: string;
|
|
4
|
+
JSON_ID: string;
|
|
5
|
+
HIVE_ENGINE_API: string;
|
|
6
|
+
HIVE_ENGINE_ID: string;
|
|
7
|
+
APP_NAME: string;
|
|
8
|
+
USERNAME: string;
|
|
9
|
+
PAYLOAD_IDENTIFIER: string;
|
|
10
|
+
LAST_BLOCK_NUMBER: number;
|
|
11
|
+
BLOCK_CHECK_INTERVAL: number;
|
|
12
|
+
BLOCKS_BEHIND_WARNING: number;
|
|
13
|
+
API_NODES: string[];
|
|
14
|
+
DEBUG_MODE: boolean;
|
|
15
|
+
}
|
|
16
|
+
export declare const Config: ConfigInterface;
|
package/dist/config.js
CHANGED
|
@@ -1,16 +1,19 @@
|
|
|
1
|
-
"use strict";
|
|
2
|
-
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
exports.Config =
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.Config = void 0;
|
|
4
|
+
exports.Config = {
|
|
5
|
+
ACTIVE_KEY: process.env.ACTIVE_KEY,
|
|
6
|
+
POSTING_KEY: process.env.POSTING_KEY,
|
|
7
|
+
JSON_ID: 'hivestream',
|
|
8
|
+
HIVE_ENGINE_API: 'https://api.hive-engine.com/rpc',
|
|
9
|
+
HIVE_ENGINE_ID: 'ssc-mainnet-hive',
|
|
10
|
+
APP_NAME: 'steem-stream',
|
|
11
|
+
PAYLOAD_IDENTIFIER: 'hivePayload',
|
|
12
|
+
USERNAME: '',
|
|
13
|
+
LAST_BLOCK_NUMBER: 42203941,
|
|
14
|
+
BLOCK_CHECK_INTERVAL: 1000,
|
|
15
|
+
BLOCKS_BEHIND_WARNING: 25,
|
|
16
|
+
API_NODES: ['https://anyx.io', 'https://api.hive.blog'],
|
|
17
|
+
DEBUG_MODE: true,
|
|
18
|
+
};
|
|
16
19
|
//# sourceMappingURL=config.js.map
|
package/dist/config.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"config.js","sourceRoot":"","sources":["../src/config.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"config.js","sourceRoot":"","sources":["../src/config.ts"],"names":[],"mappings":";;;AAgBa,QAAA,MAAM,GAAoB;IACnC,UAAU,EAAE,OAAO,CAAC,GAAG,CAAC,UAAU;IAClC,WAAW,EAAE,OAAO,CAAC,GAAG,CAAC,WAAW;IAEpC,OAAO,EAAE,YAAY;IAErB,eAAe,EAAE,iCAAiC;IAClD,cAAc,EAAE,kBAAkB;IAElC,QAAQ,EAAE,cAAc;IAExB,kBAAkB,EAAE,aAAa;IAEjC,QAAQ,EAAE,EAAE;IAEZ,iBAAiB,EAAE,QAAQ;IAE3B,oBAAoB,EAAE,IAAI;IAC1B,qBAAqB,EAAE,EAAE;IAEzB,SAAS,EAAE,CAAC,iBAAiB,EAAE,uBAAuB,CAAC;IAEvD,UAAU,EAAE,IAAI;CACnB,CAAC"}
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
export declare class CoinflipContract {
|
|
2
|
+
private _instance;
|
|
3
|
+
private adapter;
|
|
4
|
+
private blockNumber;
|
|
5
|
+
private blockId;
|
|
6
|
+
private previousBlockId;
|
|
7
|
+
private transactionId;
|
|
8
|
+
private create;
|
|
9
|
+
private updateBlockInfo;
|
|
10
|
+
flip(payload: any, { sender, amount }: {
|
|
11
|
+
sender: any;
|
|
12
|
+
amount: any;
|
|
13
|
+
}): Promise<void>;
|
|
14
|
+
}
|
|
@@ -0,0 +1,95 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
3
|
+
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
4
|
+
};
|
|
5
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
6
|
+
exports.CoinflipContract = void 0;
|
|
7
|
+
const seedrandom_1 = __importDefault(require("seedrandom"));
|
|
8
|
+
const uuid_1 = require("uuid");
|
|
9
|
+
const CONTRACT_NAME = 'coinflip';
|
|
10
|
+
const ACCOUNT = 'beggars';
|
|
11
|
+
const TOKEN_SYMBOL = 'HIVE';
|
|
12
|
+
const VALID_CURRENCIES = ['HIVE'];
|
|
13
|
+
const MAX_AMOUNT = 20;
|
|
14
|
+
function rng(previousBlockId, blockId, transactionId, serverSeed, clientSeed = '') {
|
|
15
|
+
const random = (0, seedrandom_1.default)(`${previousBlockId}${blockId}${transactionId}${clientSeed}${serverSeed}`).double();
|
|
16
|
+
const randomRoll = Math.floor(random * 2) + 1;
|
|
17
|
+
return randomRoll === 1 ? 'heads' : 'tails';
|
|
18
|
+
}
|
|
19
|
+
class CoinflipContract {
|
|
20
|
+
// tslint:disable-next-line: variable-name
|
|
21
|
+
_instance;
|
|
22
|
+
adapter;
|
|
23
|
+
blockNumber;
|
|
24
|
+
blockId;
|
|
25
|
+
previousBlockId;
|
|
26
|
+
transactionId;
|
|
27
|
+
create() {
|
|
28
|
+
this.adapter = this._instance.getAdapter();
|
|
29
|
+
}
|
|
30
|
+
updateBlockInfo(blockNumber, blockId, previousBlockId, transactionId) {
|
|
31
|
+
// Lifecycle method which sets block info
|
|
32
|
+
this.blockNumber = blockNumber;
|
|
33
|
+
this.blockId = blockId;
|
|
34
|
+
this.previousBlockId = previousBlockId;
|
|
35
|
+
this.transactionId = transactionId;
|
|
36
|
+
}
|
|
37
|
+
async flip(payload, { sender, amount }) {
|
|
38
|
+
const { guess, seed } = payload;
|
|
39
|
+
const VALID_GUESSES = ['heads', 'tails'];
|
|
40
|
+
const amountTrim = amount.split(' ');
|
|
41
|
+
const amountParsed = parseFloat(amountTrim[0]);
|
|
42
|
+
const amountCurrency = amountTrim[1].trim();
|
|
43
|
+
const transaction = await this._instance.getTransaction(this.blockNumber, this.transactionId);
|
|
44
|
+
const verify = await this._instance.verifyTransfer(transaction, sender, ACCOUNT, amount);
|
|
45
|
+
if (verify) {
|
|
46
|
+
// User sent an invalid currency
|
|
47
|
+
if (!VALID_CURRENCIES.includes(amountCurrency)) {
|
|
48
|
+
await this._instance.transferHiveTokens(ACCOUNT, sender, amountTrim[0], amountTrim[1], `[Refund] You sent an invalid currency.`);
|
|
49
|
+
return;
|
|
50
|
+
}
|
|
51
|
+
// User sent too much, refund the difference
|
|
52
|
+
if (amountParsed > MAX_AMOUNT) {
|
|
53
|
+
await this._instance.transferHiveTokens(ACCOUNT, sender, amountTrim[0], amountTrim[1], `[Refund] You sent too much.`);
|
|
54
|
+
return;
|
|
55
|
+
}
|
|
56
|
+
// Invalid guess
|
|
57
|
+
if (!VALID_GUESSES.includes(guess)) {
|
|
58
|
+
await this._instance.transferHiveTokens(ACCOUNT, sender, amountTrim[0], amountTrim[1], `[Refund] Invalid guess. Please only send heads or tails.`);
|
|
59
|
+
return;
|
|
60
|
+
}
|
|
61
|
+
const serverSeed = (0, uuid_1.v4)();
|
|
62
|
+
const generatedGuess = rng(this.previousBlockId, this.blockId, this.transactionId, serverSeed, seed ?? '');
|
|
63
|
+
if (generatedGuess === guess) {
|
|
64
|
+
await this.adapter.addEvent(new Date(), CONTRACT_NAME, 'flip', payload, {
|
|
65
|
+
action: 'transfer',
|
|
66
|
+
data: {
|
|
67
|
+
date: new Date(),
|
|
68
|
+
guess,
|
|
69
|
+
serverSeed,
|
|
70
|
+
previousBlockId: this.previousBlockId,
|
|
71
|
+
blockId: this.blockId,
|
|
72
|
+
transactionId: this.transactionId,
|
|
73
|
+
userWon: 'true'
|
|
74
|
+
}
|
|
75
|
+
});
|
|
76
|
+
await this._instance.transferHiveTokens(ACCOUNT, sender, (amountParsed * 2).toFixed(3), amountTrim[1], `[Winner] | Guess: ${guess} | Server Roll: ${generatedGuess} | Previous block id: ${this.previousBlockId} | BlockID: ${this.blockId} | Trx ID: ${this.transactionId} | Server Seed: ${serverSeed}`);
|
|
77
|
+
return;
|
|
78
|
+
}
|
|
79
|
+
await this.adapter.addEvent(new Date(), CONTRACT_NAME, 'flip', payload, {
|
|
80
|
+
action: 'transfer',
|
|
81
|
+
data: {
|
|
82
|
+
guess,
|
|
83
|
+
serverSeed,
|
|
84
|
+
previousBlockId: this.previousBlockId,
|
|
85
|
+
blockId: this.blockId,
|
|
86
|
+
transactionId: this.transactionId,
|
|
87
|
+
userWon: 'false'
|
|
88
|
+
}
|
|
89
|
+
});
|
|
90
|
+
await this._instance.transferHiveTokens(ACCOUNT, sender, '0.001', amountTrim[1], `[Lost] | Guess: ${guess} | Server Roll: ${generatedGuess} | Previous block id: ${this.previousBlockId} | BlockID: ${this.blockId} | Trx ID: ${this.transactionId} | Server Seed: ${serverSeed}`);
|
|
91
|
+
}
|
|
92
|
+
}
|
|
93
|
+
}
|
|
94
|
+
exports.CoinflipContract = CoinflipContract;
|
|
95
|
+
//# sourceMappingURL=coinflip.contract.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"coinflip.contract.js","sourceRoot":"","sources":["../../src/contracts/coinflip.contract.ts"],"names":[],"mappings":"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"}
|
|
@@ -1,29 +1,29 @@
|
|
|
1
|
-
export declare class DiceContract {
|
|
2
|
-
private _instance;
|
|
3
|
-
private blockNumber;
|
|
4
|
-
private blockId;
|
|
5
|
-
private previousBlockId;
|
|
6
|
-
private transactionId;
|
|
7
|
-
private create;
|
|
8
|
-
private destroy;
|
|
9
|
-
private updateBlockInfo;
|
|
10
|
-
/**
|
|
11
|
-
* Get Balance
|
|
12
|
-
*
|
|
13
|
-
* Helper method for getting the contract account balance. In the case of our dice contract
|
|
14
|
-
* we want to make sure the account has enough money to pay out any bets
|
|
15
|
-
*
|
|
16
|
-
* @returns number
|
|
17
|
-
*/
|
|
18
|
-
private getBalance;
|
|
19
|
-
/**
|
|
20
|
-
* Roll
|
|
21
|
-
*
|
|
22
|
-
* Automatically called when a custom JSON action matches the following method
|
|
23
|
-
*
|
|
24
|
-
* @param payload
|
|
25
|
-
* @param param1 - sender and amount
|
|
26
|
-
*/
|
|
27
|
-
private roll;
|
|
28
|
-
private testauto;
|
|
29
|
-
}
|
|
1
|
+
export declare class DiceContract {
|
|
2
|
+
private _instance;
|
|
3
|
+
private blockNumber;
|
|
4
|
+
private blockId;
|
|
5
|
+
private previousBlockId;
|
|
6
|
+
private transactionId;
|
|
7
|
+
private create;
|
|
8
|
+
private destroy;
|
|
9
|
+
private updateBlockInfo;
|
|
10
|
+
/**
|
|
11
|
+
* Get Balance
|
|
12
|
+
*
|
|
13
|
+
* Helper method for getting the contract account balance. In the case of our dice contract
|
|
14
|
+
* we want to make sure the account has enough money to pay out any bets
|
|
15
|
+
*
|
|
16
|
+
* @returns number
|
|
17
|
+
*/
|
|
18
|
+
private getBalance;
|
|
19
|
+
/**
|
|
20
|
+
* Roll
|
|
21
|
+
*
|
|
22
|
+
* Automatically called when a custom JSON action matches the following method
|
|
23
|
+
*
|
|
24
|
+
* @param payload
|
|
25
|
+
* @param param1 - sender and amount
|
|
26
|
+
*/
|
|
27
|
+
private roll;
|
|
28
|
+
private testauto;
|
|
29
|
+
}
|
|
@@ -1,158 +1,156 @@
|
|
|
1
|
-
"use strict";
|
|
2
|
-
var
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
const
|
|
17
|
-
const
|
|
18
|
-
const
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
const
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
this.
|
|
45
|
-
this.
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
*
|
|
51
|
-
*
|
|
52
|
-
*
|
|
53
|
-
*
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
const
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
*
|
|
70
|
-
*
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
//
|
|
82
|
-
const
|
|
83
|
-
//
|
|
84
|
-
const
|
|
85
|
-
//
|
|
86
|
-
|
|
87
|
-
//
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
// Get the
|
|
94
|
-
const
|
|
95
|
-
//
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
//
|
|
112
|
-
const
|
|
113
|
-
//
|
|
114
|
-
const
|
|
115
|
-
//
|
|
116
|
-
const
|
|
117
|
-
//
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
}
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
}
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
}
|
|
157
|
-
exports.DiceContract = DiceContract;
|
|
1
|
+
"use strict";
|
|
2
|
+
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
3
|
+
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
4
|
+
};
|
|
5
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
6
|
+
exports.DiceContract = void 0;
|
|
7
|
+
const seedrandom_1 = __importDefault(require("seedrandom"));
|
|
8
|
+
const bignumber_js_1 = __importDefault(require("bignumber.js"));
|
|
9
|
+
const CONTRACT_NAME = 'hivedice';
|
|
10
|
+
const ACCOUNT = 'beggars';
|
|
11
|
+
const TOKEN_SYMBOL = 'HIVE';
|
|
12
|
+
const HOUSE_EDGE = 0.05;
|
|
13
|
+
const MIN_BET = 1;
|
|
14
|
+
const MAX_BET = 10;
|
|
15
|
+
// Random Number Generator
|
|
16
|
+
const rng = (previousBlockId, blockId, transactionId) => {
|
|
17
|
+
const random = (0, seedrandom_1.default)(`${previousBlockId}${blockId}${transactionId}`).double();
|
|
18
|
+
const randomRoll = Math.floor(random * 100) + 1;
|
|
19
|
+
return randomRoll;
|
|
20
|
+
};
|
|
21
|
+
// Valid betting currencies
|
|
22
|
+
const VALID_CURRENCIES = ['HIVE'];
|
|
23
|
+
class DiceContract {
|
|
24
|
+
// tslint:disable-next-line: variable-name
|
|
25
|
+
_instance;
|
|
26
|
+
blockNumber;
|
|
27
|
+
blockId;
|
|
28
|
+
previousBlockId;
|
|
29
|
+
transactionId;
|
|
30
|
+
create() {
|
|
31
|
+
// Runs every time register is called on this contract
|
|
32
|
+
// Do setup logic and code in here (creating a database, etc)
|
|
33
|
+
}
|
|
34
|
+
destroy() {
|
|
35
|
+
// Runs every time unregister is run for this contract
|
|
36
|
+
// Close database connections, write to a database with state, etc
|
|
37
|
+
}
|
|
38
|
+
// Updates the contract with information about the current block
|
|
39
|
+
// This is a method automatically called if it exists
|
|
40
|
+
updateBlockInfo(blockNumber, blockId, previousBlockId, transactionId) {
|
|
41
|
+
// Lifecycle method which sets block info
|
|
42
|
+
this.blockNumber = blockNumber;
|
|
43
|
+
this.blockId = blockId;
|
|
44
|
+
this.previousBlockId = previousBlockId;
|
|
45
|
+
this.transactionId = transactionId;
|
|
46
|
+
}
|
|
47
|
+
/**
|
|
48
|
+
* Get Balance
|
|
49
|
+
*
|
|
50
|
+
* Helper method for getting the contract account balance. In the case of our dice contract
|
|
51
|
+
* we want to make sure the account has enough money to pay out any bets
|
|
52
|
+
*
|
|
53
|
+
* @returns number
|
|
54
|
+
*/
|
|
55
|
+
async getBalance() {
|
|
56
|
+
const account = await this._instance['client'].database.getAccounts([ACCOUNT]);
|
|
57
|
+
if (account?.[0]) {
|
|
58
|
+
const balance = account[0].balance.split(' ');
|
|
59
|
+
const amount = balance[0];
|
|
60
|
+
return parseFloat(amount);
|
|
61
|
+
}
|
|
62
|
+
return null;
|
|
63
|
+
}
|
|
64
|
+
/**
|
|
65
|
+
* Roll
|
|
66
|
+
*
|
|
67
|
+
* Automatically called when a custom JSON action matches the following method
|
|
68
|
+
*
|
|
69
|
+
* @param payload
|
|
70
|
+
* @param param1 - sender and amount
|
|
71
|
+
*/
|
|
72
|
+
async roll(payload, { sender, amount }) {
|
|
73
|
+
try {
|
|
74
|
+
// Destructure the values from the payload
|
|
75
|
+
const { roll } = payload;
|
|
76
|
+
// The amount is formatted like 100 HIVE
|
|
77
|
+
// The value is the first part, the currency symbol is the second
|
|
78
|
+
const amountTrim = amount.split(' ');
|
|
79
|
+
// Parse the numeric value as a real value
|
|
80
|
+
const amountParsed = parseFloat(amountTrim[0]);
|
|
81
|
+
// Format the amount to 3 decimal places
|
|
82
|
+
const amountFormatted = parseFloat(amountTrim[0]).toFixed(3);
|
|
83
|
+
// Trim any space from the currency symbol
|
|
84
|
+
const amountCurrency = amountTrim[1].trim();
|
|
85
|
+
// console.log(`Roll: ${roll}
|
|
86
|
+
// Amount parsed: ${amountParsed}
|
|
87
|
+
// Amount formatted: ${amountFormatted}
|
|
88
|
+
// Currency: ${amountCurrency}`);
|
|
89
|
+
// Get the transaction from the blockchain
|
|
90
|
+
const transaction = await this._instance.getTransaction(this.blockNumber, this.transactionId);
|
|
91
|
+
// Call the verifyTransfer method to confirm the transfer happened
|
|
92
|
+
const verify = await this._instance.verifyTransfer(transaction, sender, 'beggars', amount);
|
|
93
|
+
// Get the balance of our contract account
|
|
94
|
+
const balance = await this.getBalance();
|
|
95
|
+
// Transfer is valid
|
|
96
|
+
if (verify) {
|
|
97
|
+
// Server balance is less than the max bet, cancel and refund
|
|
98
|
+
if (balance < MAX_BET) {
|
|
99
|
+
// Send back what was sent, the server is broke
|
|
100
|
+
await this._instance.transferHiveTokens(ACCOUNT, sender, amountTrim[0], amountTrim[1], `[Refund] The server could not fufill your bet.`);
|
|
101
|
+
return;
|
|
102
|
+
}
|
|
103
|
+
// Bet amount is valid
|
|
104
|
+
if (amountParsed >= MIN_BET && amountParsed <= MAX_BET) {
|
|
105
|
+
// Validate roll is valid
|
|
106
|
+
if ((roll >= 2 && roll <= 96) && VALID_CURRENCIES.includes(amountCurrency)) {
|
|
107
|
+
// Roll a random value
|
|
108
|
+
const random = rng(this.previousBlockId, this.blockId, this.transactionId);
|
|
109
|
+
// Calculate the multiplier percentage
|
|
110
|
+
const multiplier = new bignumber_js_1.default(1).minus(HOUSE_EDGE).multipliedBy(100).dividedBy(roll);
|
|
111
|
+
// Calculate the number of tokens won
|
|
112
|
+
const tokensWon = new bignumber_js_1.default(amountParsed).multipliedBy(multiplier).toFixed(3, bignumber_js_1.default.ROUND_DOWN);
|
|
113
|
+
// Memo that shows in users memo when they win
|
|
114
|
+
const winningMemo = `You won ${tokensWon} ${TOKEN_SYMBOL}. Roll: ${random}, Your guess: ${roll}`;
|
|
115
|
+
// Memo that shows in users memo when they lose
|
|
116
|
+
const losingMemo = `You lost ${amountParsed} ${TOKEN_SYMBOL}. Roll: ${random}, Your guess: ${roll}`;
|
|
117
|
+
// User won more than the server can afford, refund the bet amount
|
|
118
|
+
if (parseFloat(tokensWon) > balance) {
|
|
119
|
+
await this._instance.transferHiveTokens(ACCOUNT, sender, amountTrim[0], amountTrim[1], `[Refund] The server could not fufill your bet.`);
|
|
120
|
+
return;
|
|
121
|
+
}
|
|
122
|
+
// If random value is less than roll
|
|
123
|
+
if (random < roll) {
|
|
124
|
+
await this._instance.transferHiveTokens(ACCOUNT, sender, tokensWon, TOKEN_SYMBOL, winningMemo);
|
|
125
|
+
}
|
|
126
|
+
else {
|
|
127
|
+
await this._instance.transferHiveTokens(ACCOUNT, sender, '0.001', TOKEN_SYMBOL, losingMemo);
|
|
128
|
+
}
|
|
129
|
+
}
|
|
130
|
+
else {
|
|
131
|
+
// Invalid bet parameters, refund the user their bet
|
|
132
|
+
await this._instance.transferHiveTokens(ACCOUNT, sender, amountTrim[0], amountTrim[1], `[Refund] Invalid bet params.`);
|
|
133
|
+
}
|
|
134
|
+
}
|
|
135
|
+
else {
|
|
136
|
+
try {
|
|
137
|
+
// We need to refund the user
|
|
138
|
+
await this._instance.transferHiveTokens(ACCOUNT, sender, amountTrim[0], amountTrim[1], `[Refund] You sent an invalid bet amount.`);
|
|
139
|
+
}
|
|
140
|
+
catch (e) {
|
|
141
|
+
console.log(e);
|
|
142
|
+
}
|
|
143
|
+
}
|
|
144
|
+
}
|
|
145
|
+
}
|
|
146
|
+
catch (e) {
|
|
147
|
+
throw e;
|
|
148
|
+
}
|
|
149
|
+
}
|
|
150
|
+
// Called by our time-based action
|
|
151
|
+
testauto() {
|
|
152
|
+
console.log('test');
|
|
153
|
+
}
|
|
154
|
+
}
|
|
155
|
+
exports.DiceContract = DiceContract;
|
|
158
156
|
//# sourceMappingURL=dice.contract.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"dice.contract.js","sourceRoot":"","sources":["../../src/contracts/dice.contract.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"dice.contract.js","sourceRoot":"","sources":["../../src/contracts/dice.contract.ts"],"names":[],"mappings":"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"}
|