shufflecom-calculations 1.7.0 → 1.7.2
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/lib/{packages/shuffle-calculations/src/games → games}/blackjack.js +2 -2
- package/lib/games/blackjack.js.map +1 -0
- package/lib/games/cardGames.js.map +1 -0
- package/lib/games/crash.js.map +1 -0
- package/lib/games/dice.js.map +1 -0
- package/lib/games/hilo.js.map +1 -0
- package/lib/{packages/shuffle-calculations/src/games → games}/keno.js +12 -4
- package/lib/games/keno.js.map +1 -0
- package/lib/games/limbo.js.map +1 -0
- package/lib/games/mines.js.map +1 -0
- package/lib/{packages/shuffle-calculations/src/games → games}/plinko.js +28 -10
- package/lib/games/plinko.js.map +1 -0
- package/lib/games/roulette.js.map +1 -0
- package/lib/games/tower.d.ts +20 -0
- package/lib/games/tower.js +84 -0
- package/lib/games/tower.js.map +1 -0
- package/lib/games/wheel.js.map +1 -0
- package/lib/index.js.map +1 -0
- package/lib/regex/index.js.map +1 -0
- package/lib/tsconfig.tsbuildinfo +1 -1
- package/lib/utils/airdrop.js.map +1 -0
- package/lib/utils/betradar-outcome.enum.js.map +1 -0
- package/lib/utils/calculate-payout.js.map +1 -0
- package/lib/{packages/shuffle-calculations/src/utils → utils}/calculate-sports-payout.d.ts +2 -2
- package/lib/utils/calculate-sports-payout.js +102 -0
- package/lib/utils/calculate-sports-payout.js.map +1 -0
- package/lib/utils/chain.js.map +1 -0
- package/lib/utils/chat-message.type.js.map +1 -0
- package/lib/utils/dates-calculator.js.map +1 -0
- package/lib/{packages/shuffle-calculations/src/utils → utils}/derive-vip-bonus.d.ts +1 -1
- package/lib/{packages/shuffle-calculations/src/utils → utils}/derive-vip-bonus.js +13 -6
- package/lib/utils/derive-vip-bonus.js.map +1 -0
- package/lib/utils/edge.js.map +1 -0
- package/lib/utils/factorial.js.map +1 -0
- package/lib/utils/getChatMessageLength.js.map +1 -0
- package/lib/utils/getExternalTxLinkOfChain.js.map +1 -0
- package/lib/utils/hex-to-bytes.js.map +1 -0
- package/lib/utils/ncr.js.map +1 -0
- package/lib/utils/odds.js.map +1 -0
- package/lib/{packages/shuffle-calculations/src/utils → utils}/uuid-converter.d.ts +1 -1
- package/lib/utils/uuid-converter.js.map +1 -0
- package/lib/{packages/shuffle-calculations/src/utils → utils}/vip-bonus.type.d.ts +2 -2
- package/lib/utils/vip-bonus.type.js.map +1 -0
- package/package.json +2 -2
- package/src/games/blackjack.ts +2 -2
- package/src/games/keno.ts +14 -4
- package/src/games/plinko.ts +32 -10
- package/src/games/tower.spec.ts +213 -0
- package/src/games/tower.ts +107 -0
- package/src/utils/betradar-outcome.enum.ts +9 -0
- package/src/utils/calculate-sports-payout.ts +103 -47
- package/src/utils/derive-vip-bonus.spec.ts +1 -1
- package/src/utils/derive-vip-bonus.ts +16 -8
- package/src/utils/uuid-converter.ts +1 -1
- package/src/utils/vip-bonus.type.ts +2 -2
- package/lib/libs/betradar/src/shared/enums/betradar-outcome.enum.js.map +0 -1
- package/lib/packages/shuffle-calculations/src/games/blackjack.js.map +0 -1
- package/lib/packages/shuffle-calculations/src/games/cardGames.js.map +0 -1
- package/lib/packages/shuffle-calculations/src/games/crash.js.map +0 -1
- package/lib/packages/shuffle-calculations/src/games/dice.js.map +0 -1
- package/lib/packages/shuffle-calculations/src/games/hilo.js.map +0 -1
- package/lib/packages/shuffle-calculations/src/games/keno.js.map +0 -1
- package/lib/packages/shuffle-calculations/src/games/limbo.js.map +0 -1
- package/lib/packages/shuffle-calculations/src/games/mines.js.map +0 -1
- package/lib/packages/shuffle-calculations/src/games/plinko.js.map +0 -1
- package/lib/packages/shuffle-calculations/src/games/roulette.js.map +0 -1
- package/lib/packages/shuffle-calculations/src/games/wheel.js.map +0 -1
- package/lib/packages/shuffle-calculations/src/index.js.map +0 -1
- package/lib/packages/shuffle-calculations/src/regex/index.js.map +0 -1
- package/lib/packages/shuffle-calculations/src/utils/airdrop.js.map +0 -1
- package/lib/packages/shuffle-calculations/src/utils/calculate-payout.js.map +0 -1
- package/lib/packages/shuffle-calculations/src/utils/calculate-sports-payout.js +0 -89
- package/lib/packages/shuffle-calculations/src/utils/calculate-sports-payout.js.map +0 -1
- package/lib/packages/shuffle-calculations/src/utils/chain.js.map +0 -1
- package/lib/packages/shuffle-calculations/src/utils/chat-message.type.js.map +0 -1
- package/lib/packages/shuffle-calculations/src/utils/dates-calculator.js.map +0 -1
- package/lib/packages/shuffle-calculations/src/utils/derive-vip-bonus.js.map +0 -1
- package/lib/packages/shuffle-calculations/src/utils/edge.js.map +0 -1
- package/lib/packages/shuffle-calculations/src/utils/factorial.js.map +0 -1
- package/lib/packages/shuffle-calculations/src/utils/getChatMessageLength.js.map +0 -1
- package/lib/packages/shuffle-calculations/src/utils/getExternalTxLinkOfChain.js.map +0 -1
- package/lib/packages/shuffle-calculations/src/utils/hex-to-bytes.js.map +0 -1
- package/lib/packages/shuffle-calculations/src/utils/ncr.js.map +0 -1
- package/lib/packages/shuffle-calculations/src/utils/odds.js.map +0 -1
- package/lib/packages/shuffle-calculations/src/utils/uuid-converter.js.map +0 -1
- package/lib/packages/shuffle-calculations/src/utils/vip-bonus.type.js.map +0 -1
- /package/lib/{packages/shuffle-calculations/src/games → games}/blackjack.d.ts +0 -0
- /package/lib/{packages/shuffle-calculations/src/games → games}/cardGames.d.ts +0 -0
- /package/lib/{packages/shuffle-calculations/src/games → games}/cardGames.js +0 -0
- /package/lib/{packages/shuffle-calculations/src/games → games}/crash.d.ts +0 -0
- /package/lib/{packages/shuffle-calculations/src/games → games}/crash.js +0 -0
- /package/lib/{packages/shuffle-calculations/src/games → games}/dice.d.ts +0 -0
- /package/lib/{packages/shuffle-calculations/src/games → games}/dice.js +0 -0
- /package/lib/{packages/shuffle-calculations/src/games → games}/hilo.d.ts +0 -0
- /package/lib/{packages/shuffle-calculations/src/games → games}/hilo.js +0 -0
- /package/lib/{packages/shuffle-calculations/src/games → games}/keno.d.ts +0 -0
- /package/lib/{packages/shuffle-calculations/src/games → games}/limbo.d.ts +0 -0
- /package/lib/{packages/shuffle-calculations/src/games → games}/limbo.js +0 -0
- /package/lib/{packages/shuffle-calculations/src/games → games}/mines.d.ts +0 -0
- /package/lib/{packages/shuffle-calculations/src/games → games}/mines.js +0 -0
- /package/lib/{packages/shuffle-calculations/src/games → games}/plinko.d.ts +0 -0
- /package/lib/{packages/shuffle-calculations/src/games → games}/roulette.d.ts +0 -0
- /package/lib/{packages/shuffle-calculations/src/games → games}/roulette.js +0 -0
- /package/lib/{packages/shuffle-calculations/src/games → games}/wheel.d.ts +0 -0
- /package/lib/{packages/shuffle-calculations/src/games → games}/wheel.js +0 -0
- /package/lib/{packages/shuffle-calculations/src/index.d.ts → index.d.ts} +0 -0
- /package/lib/{packages/shuffle-calculations/src/index.js → index.js} +0 -0
- /package/lib/{packages/shuffle-calculations/src/regex → regex}/index.d.ts +0 -0
- /package/lib/{packages/shuffle-calculations/src/regex → regex}/index.js +0 -0
- /package/lib/{packages/shuffle-calculations/src/utils → utils}/airdrop.d.ts +0 -0
- /package/lib/{packages/shuffle-calculations/src/utils → utils}/airdrop.js +0 -0
- /package/lib/{libs/betradar/src/shared/enums → utils}/betradar-outcome.enum.d.ts +0 -0
- /package/lib/{libs/betradar/src/shared/enums → utils}/betradar-outcome.enum.js +0 -0
- /package/lib/{packages/shuffle-calculations/src/utils → utils}/calculate-payout.d.ts +0 -0
- /package/lib/{packages/shuffle-calculations/src/utils → utils}/calculate-payout.js +0 -0
- /package/lib/{packages/shuffle-calculations/src/utils → utils}/chain.d.ts +0 -0
- /package/lib/{packages/shuffle-calculations/src/utils → utils}/chain.js +0 -0
- /package/lib/{packages/shuffle-calculations/src/utils → utils}/chat-message.type.d.ts +0 -0
- /package/lib/{packages/shuffle-calculations/src/utils → utils}/chat-message.type.js +0 -0
- /package/lib/{packages/shuffle-calculations/src/utils → utils}/dates-calculator.d.ts +0 -0
- /package/lib/{packages/shuffle-calculations/src/utils → utils}/dates-calculator.js +0 -0
- /package/lib/{packages/shuffle-calculations/src/utils → utils}/edge.d.ts +0 -0
- /package/lib/{packages/shuffle-calculations/src/utils → utils}/edge.js +0 -0
- /package/lib/{packages/shuffle-calculations/src/utils → utils}/factorial.d.ts +0 -0
- /package/lib/{packages/shuffle-calculations/src/utils → utils}/factorial.js +0 -0
- /package/lib/{packages/shuffle-calculations/src/utils → utils}/getChatMessageLength.d.ts +0 -0
- /package/lib/{packages/shuffle-calculations/src/utils → utils}/getChatMessageLength.js +0 -0
- /package/lib/{packages/shuffle-calculations/src/utils → utils}/getExternalTxLinkOfChain.d.ts +0 -0
- /package/lib/{packages/shuffle-calculations/src/utils → utils}/getExternalTxLinkOfChain.js +0 -0
- /package/lib/{packages/shuffle-calculations/src/utils → utils}/hex-to-bytes.d.ts +0 -0
- /package/lib/{packages/shuffle-calculations/src/utils → utils}/hex-to-bytes.js +0 -0
- /package/lib/{packages/shuffle-calculations/src/utils → utils}/ncr.d.ts +0 -0
- /package/lib/{packages/shuffle-calculations/src/utils → utils}/ncr.js +0 -0
- /package/lib/{packages/shuffle-calculations/src/utils → utils}/odds.d.ts +0 -0
- /package/lib/{packages/shuffle-calculations/src/utils → utils}/odds.js +0 -0
- /package/lib/{packages/shuffle-calculations/src/utils → utils}/uuid-converter.js +0 -0
- /package/lib/{packages/shuffle-calculations/src/utils → utils}/vip-bonus.type.js +0 -0
|
@@ -6,7 +6,7 @@ Object.defineProperty(exports, "__esModule", { value: true });
|
|
|
6
6
|
exports.updateBonusIssuanceStatus = exports.deriveBonusIssuances = void 0;
|
|
7
7
|
const dayjs_1 = __importDefault(require("dayjs"));
|
|
8
8
|
const isSameOrAfter_1 = __importDefault(require("dayjs/plugin/isSameOrAfter"));
|
|
9
|
-
const
|
|
9
|
+
const lodash_1 = require("lodash");
|
|
10
10
|
const bignumber_js_1 = __importDefault(require("bignumber.js"));
|
|
11
11
|
const vip_bonus_type_1 = require("./vip-bonus.type");
|
|
12
12
|
dayjs_1.default.extend(isSameOrAfter_1.default);
|
|
@@ -17,13 +17,20 @@ function deriveBonusIssuances(vipBonus) {
|
|
|
17
17
|
const claims = vipBonus.bonusClaims;
|
|
18
18
|
const bonusCreatedAt = (0, dayjs_1.default)(vipBonus.createdAt);
|
|
19
19
|
const now = (0, dayjs_1.default)();
|
|
20
|
-
return (0,
|
|
21
|
-
const claim = claims.find((claim) => claim.occurrenceIndex == occurrenceIndex);
|
|
22
|
-
const expiryDate = vipBonus.type === vip_bonus_type_1.VipBonusType.RELOADED
|
|
23
|
-
|
|
20
|
+
return (0, lodash_1.range)(1, vipBonus.occurrence + 1).map((occurrenceIndex) => {
|
|
21
|
+
const claim = claims === null || claims === void 0 ? void 0 : claims.find((claim) => claim.occurrenceIndex == occurrenceIndex);
|
|
22
|
+
const expiryDate = vipBonus.type === vip_bonus_type_1.VipBonusType.RELOADED
|
|
23
|
+
? getReloadExpiryDate(bonusCreatedAt, vipBonus.cadence, occurrenceIndex).toISOString()
|
|
24
|
+
: vipBonus.endAt;
|
|
25
|
+
const availableDate = vipBonus.type === vip_bonus_type_1.VipBonusType.RELOADED
|
|
26
|
+
? getReloadExpiryDate(bonusCreatedAt, vipBonus.cadence, occurrenceIndex - 1).toISOString()
|
|
27
|
+
: vipBonus.createdAt;
|
|
24
28
|
return updateBonusIssuanceStatus({
|
|
25
29
|
currency: vipBonus.currency,
|
|
26
|
-
amount: new bignumber_js_1.default(vipBonus.amount)
|
|
30
|
+
amount: new bignumber_js_1.default(vipBonus.amount)
|
|
31
|
+
.dividedBy(vipBonus.occurrence)
|
|
32
|
+
.decimalPlaces(8, bignumber_js_1.default.ROUND_DOWN)
|
|
33
|
+
.toFixed(),
|
|
27
34
|
occurrenceIndex,
|
|
28
35
|
expiryDate,
|
|
29
36
|
availableDate,
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"derive-vip-bonus.js","sourceRoot":"","sources":["../../src/utils/derive-vip-bonus.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"edge.js","sourceRoot":"","sources":["../../src/utils/edge.ts"],"names":[],"mappings":";;;;;;AAAA,gEAAqC;AAErC,MAAM,SAAS,GAAG,KAAK,CAAC;AAExB,MAAM,oBAAoB,GAAG,GAAG,CAAC;AAEjC,SAAgB,uBAAuB,CAAC,IAAY;IAClD,IAAI,IAAI,GAAG,oBAAoB,EAAE,CAAC;QAChC,MAAM,IAAI,KAAK,CAAC,2CAA2C,CAAC,CAAC;IAC/D,CAAC;IAED,OAAO,IAAI,sBAAS,CAAC,SAAS,CAAC,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC,SAAS,CAAC,SAAS,CAAC,CAAC;AACnE,CAAC;AAND,0DAMC"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"factorial.js","sourceRoot":"","sources":["../../src/utils/factorial.ts"],"names":[],"mappings":";;;;;;AAAA,gEAAqC;AAErC,MAAM,KAAK,GAAG,CAAC,IAAI,sBAAS,CAAC,CAAC,CAAC,CAAC,CAAC;AACjC,SAAgB,SAAS,CAAC,GAAW;IACnC,IAAI,CAAC,MAAM,CAAC,SAAS,CAAC,GAAG,CAAC,IAAI,GAAG,GAAG,CAAC,EAAE,CAAC;QACtC,MAAM,IAAI,KAAK,CAAC,eAAe,GAAG,8CAA8C,CAAC,CAAC;IACpF,CAAC;IAED,MAAM,KAAK,GAAG,IAAI,sBAAS,CAAC,GAAG,CAAC,CAAC;IAEjC,IAAI,CAAC,KAAK,CAAC,GAAG,CAAC,EAAE,CAAC;QAChB,KAAK,CAAC,GAAG,CAAC,GAAG,KAAK,CAAC,YAAY,CAAC,SAAS,CAAC,GAAG,GAAG,CAAC,CAAC,CAAC,CAAC;IACtD,CAAC;IACD,OAAO,KAAK,CAAC,GAAG,CAAC,CAAC;AACpB,CAAC;AAXD,8BAWC"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"getChatMessageLength.js","sourceRoot":"","sources":["../../src/utils/getChatMessageLength.ts"],"names":[],"mappings":";;;AAAA,oCAAgD;AAEnC,QAAA,eAAe,GAAG,GAAG,CAAC;AAI5B,MAAM,oBAAoB,GAAG,CAAC,OAAe,EAAE,EAAE;IACtD,MAAM,cAAc,GAAa,OAAO,CAAC,KAAK,CAAC,4BAAoB,CAAC,IAAI,EAAE,CAAC;IAE3E,MAAM,gBAAgB,GAAG,cAAc,CAAC,MAAM,CAAC,CAAC,GAAG,EAAE,IAAI,EAAE,EAAE;;QAE3D,MAAM,CAAC,EAAE,OAAO,EAAE,EAAE,CAAC,GAAG,MAAA,IAAI,CAAC,KAAK,CAAC,IAAI,MAAM,CAAC,4BAAoB,EAAE,GAAG,CAAC,CAAC,mCAAI,CAAC,EAAE,EAAE,EAAE,EAAE,CAAC,CAAC;QACxF,IAAI,OAAO,KAAK,EAAE,EAAE,CAAC;YACnB,OAAO,GAAG,CAAC;QACb,CAAC;QAED,OAAO,GAAG,GAAG,CAAC,OAAO,CAAC,MAAM,GAAG,CAAC,CAAC,CAAC;IACpC,CAAC,EAAE,CAAC,CAAC,CAAC;IAEN,OAAO,OAAO,CAAC,IAAI,EAAE,CAAC,MAAM,GAAG,gBAAgB,CAAC;AAClD,CAAC,CAAC;AAdW,QAAA,oBAAoB,wBAc/B"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"getExternalTxLinkOfChain.js","sourceRoot":"","sources":["../../src/utils/getExternalTxLinkOfChain.ts"],"names":[],"mappings":";;;AAAA,mCAAgC;AAEnB,QAAA,wBAAwB,GAA0B;IAC7D,CAAC,aAAK,CAAC,QAAQ,CAAC,EAAE,uCAAuC;IACzD,CAAC,aAAK,CAAC,OAAO,CAAC,EAAE,kDAAkD;IACnE,CAAC,aAAK,CAAC,QAAQ,CAAC,EAAE,sDAAsD;IACxE,CAAC,aAAK,CAAC,IAAI,CAAC,EAAE,kDAAkD;IAChE,CAAC,aAAK,CAAC,aAAa,CAAC,EAAE,mCAAmC;IAC1D,CAAC,aAAK,CAAC,GAAG,CAAC,EAAE,8CAA8C;IAC3D,CAAC,aAAK,CAAC,MAAM,CAAC,EAAE,sDAAsD;IACtE,CAAC,aAAK,CAAC,IAAI,CAAC,EAAE,sDAAsD;IACpE,CAAC,aAAK,CAAC,mBAAmB,CAAC,EAAE,uCAAuC;IACpE,CAAC,aAAK,CAAC,GAAG,CAAC,EAAE,uCAAuC;IACpD,CAAC,aAAK,CAAC,KAAK,CAAC,EAAE,wCAAwC;CACxD,CAAC;AAEW,QAAA,wBAAwB,GAA0B;IAC7D,CAAC,aAAK,CAAC,QAAQ,CAAC,EAAE,gCAAgC;IAClD,CAAC,aAAK,CAAC,OAAO,CAAC,EAAE,0CAA0C;IAC3D,CAAC,aAAK,CAAC,QAAQ,CAAC,EAAE,sDAAsD;IACxE,CAAC,aAAK,CAAC,IAAI,CAAC,EAAE,2CAA2C;IACzD,CAAC,aAAK,CAAC,aAAa,CAAC,EAAE,mCAAmC;IAC1D,CAAC,aAAK,CAAC,GAAG,CAAC,EAAE,+BAA+B;IAC5C,CAAC,aAAK,CAAC,MAAM,CAAC,EAAE,uCAAuC;IACvD,CAAC,aAAK,CAAC,IAAI,CAAC,EAAE,sDAAsD;IACpE,CAAC,aAAK,CAAC,mBAAmB,CAAC,EAAE,+BAA+B;IAC5D,CAAC,aAAK,CAAC,GAAG,CAAC,EAAE,+BAA+B;IAC5C,CAAC,aAAK,CAAC,KAAK,CAAC,EAAE,gCAAgC;CAChD,CAAC;AAEW,QAAA,6BAA6B,GAA0B;IAClE,CAAC,aAAK,CAAC,QAAQ,CAAC,EAAE,+CAA+C;IACjE,CAAC,aAAK,CAAC,OAAO,CAAC,EAAE,iEAAiE;IAClF,CAAC,aAAK,CAAC,QAAQ,CAAC,EAAE,8DAA8D;IAChF,CAAC,aAAK,CAAC,IAAI,CAAC,EAAE,iDAAiD;IAC/D,CAAC,aAAK,CAAC,aAAa,CAAC,EAAE,kDAAkD;IACzE,CAAC,aAAK,CAAC,GAAG,CAAC,EAAE,6CAA6C;IAC1D,CAAC,aAAK,CAAC,MAAM,CAAC,EAAE,8DAA8D;IAC9E,CAAC,aAAK,CAAC,IAAI,CAAC,EAAE,8DAA8D;IAC5E,CAAC,aAAK,CAAC,mBAAmB,CAAC,EAAE,+CAA+C;IAC5E,CAAC,aAAK,CAAC,GAAG,CAAC,EAAE,+CAA+C;IAC5D,CAAC,aAAK,CAAC,KAAK,CAAC,EAAE,gDAAgD;CAChE,CAAC;AAEW,QAAA,6BAA6B,GAA0B;IAClE,CAAC,aAAK,CAAC,QAAQ,CAAC,EAAE,wCAAwC;IAC1D,CAAC,aAAK,CAAC,OAAO,CAAC,EAAE,iEAAiE;IAClF,CAAC,aAAK,CAAC,QAAQ,CAAC,EAAE,8DAA8D;IAChF,CAAC,aAAK,CAAC,IAAI,CAAC,EAAE,0CAA0C;IACxD,CAAC,aAAK,CAAC,aAAa,CAAC,EAAE,2CAA2C;IAClE,CAAC,aAAK,CAAC,GAAG,CAAC,EAAE,uCAAuC;IACpD,CAAC,aAAK,CAAC,MAAM,CAAC,EAAE,+CAA+C;IAC/D,CAAC,aAAK,CAAC,IAAI,CAAC,EAAE,8DAA8D;IAC5E,CAAC,aAAK,CAAC,mBAAmB,CAAC,EAAE,uCAAuC;IACpE,CAAC,aAAK,CAAC,GAAG,CAAC,EAAE,uCAAuC;IACpD,CAAC,aAAK,CAAC,KAAK,CAAC,EAAE,wCAAwC;CACxD,CAAC;AAEK,MAAM,wBAAwB,GAAG,CAAC,IAAY,EAAE,KAAY,EAAE,SAAkB,KAAK,EAAE,EAAE;IAC9F,MAAM,gBAAgB,GAAG,MAAM,CAAC,CAAC,CAAC,gCAAwB,CAAC,CAAC,CAAC,gCAAwB,CAAC;IAEtF,MAAM,GAAG,GAAG,gBAAgB,CAAC,KAAK,CAAC,CAAC;IAEpC,OAAO,GAAG,CAAC,OAAO,CAAC,QAAQ,EAAE,IAAI,CAAC,CAAC;AACrC,CAAC,CAAC;AANW,QAAA,wBAAwB,4BAMnC;AAEK,MAAM,sBAAsB,GAAG,CAAC,OAAe,EAAE,KAAY,EAAE,SAAkB,KAAK,EAAE,EAAE;IAC/F,MAAM,qBAAqB,GAAG,MAAM,CAAC,CAAC,CAAC,qCAA6B,CAAC,CAAC,CAAC,qCAA6B,CAAC;IAErG,MAAM,GAAG,GAAG,qBAAqB,CAAC,KAAK,CAAC,CAAC;IAEzC,OAAO,GAAG,CAAC,OAAO,CAAC,WAAW,EAAE,OAAO,CAAC,CAAC;AAC3C,CAAC,CAAC;AANW,QAAA,sBAAsB,0BAMjC"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"hex-to-bytes.js","sourceRoot":"","sources":["../../src/utils/hex-to-bytes.ts"],"names":[],"mappings":";;;AAAA,SAAgB,UAAU,CAAC,MAAc;IACvC,IAAI,CAAC,MAAM,EAAE,CAAC;QACZ,OAAO,IAAI,UAAU,EAAE,CAAC;IAC1B,CAAC;IAED,MAAM,CAAC,GAAG,EAAE,CAAC;IACb,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,MAAM,CAAC,MAAM,EAAE,CAAC,IAAI,CAAC,EAAE,CAAC;QAC1C,CAAC,CAAC,IAAI,CAAC,QAAQ,CAAC,MAAM,CAAC,SAAS,CAAC,CAAC,EAAE,CAAC,GAAG,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC;IACnD,CAAC;IAED,OAAO,IAAI,UAAU,CAAC,CAAC,CAAC,CAAC;AAC3B,CAAC;AAXD,gCAWC"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"ncr.js","sourceRoot":"","sources":["../../src/utils/ncr.ts"],"names":[],"mappings":";;;;;;AAAA,gEAAqC;AACrC,2CAAwC;AAExC,SAAgB,GAAG,CAAC,CAAS,EAAE,CAAS;IACtC,OAAO,IAAA,qBAAS,EAAC,CAAC,CAAC;SAChB,SAAS,CAAC,IAAA,qBAAS,EAAC,CAAC,CAAC,CAAC;SACvB,SAAS,CAAC,IAAA,qBAAS,EAAC,IAAI,sBAAS,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,QAAQ,EAAE,CAAC,CAAC,CAAC;AAChE,CAAC;AAJD,kBAIC"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"odds.js","sourceRoot":"","sources":["../../src/utils/odds.ts"],"names":[],"mappings":";;;;;;AAAA,gEAAqC;AAErC,SAAgB,qBAAqB,CAAC,aAAwB,EAAE,eAA0B,EAAE,EAAE,GAAG,CAAC;IAChG,OAAO,aAAa,CAAC,SAAS,CAAC,eAAe,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,aAAa,CAAC,EAAE,EAAE,sBAAS,CAAC,UAAU,CAAC,CAAC;AAClG,CAAC;AAFD,sDAEC;AAED,SAAgB,qBAAqB,CAAC,IAAY;IAChD,MAAM,QAAQ,GAAG,IAAI,sBAAS,CAAC,IAAI,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC;IAC9C,OAAO;QACL,aAAa,EAAE,IAAI,sBAAS,CAAC,QAAQ,CAAC,CAAC,YAAY,CAAC,GAAG,CAAC;QACxD,eAAe,EAAE,IAAI,sBAAS,CAAC,GAAG,CAAC;KACpC,CAAC;AACJ,CAAC;AAND,sDAMC"}
|
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
export declare function convertUuidToBs58(uuidValue: string): string;
|
|
1
|
+
export declare function convertUuidToBs58(uuidValue: string): string | null;
|
|
2
2
|
export declare function convertBs58ToUuid(bs58Value: string, silenceErrors?: boolean): string;
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"uuid-converter.js","sourceRoot":"","sources":["../../src/utils/uuid-converter.ts"],"names":[],"mappings":";;;;;;AAAA,gDAAwB;AAExB,MAAM,aAAa,GAAG,CAAC,CAAS,EAAE,EAAE,CAAC,GAAG,CAAC,CAAC,SAAS,CAAC,CAAC,EAAE,CAAC,CAAC,IAAI,CAAC,CAAC,SAAS,CAAC,CAAC,EAAE,EAAE,CAAC,IAAI,CAAC,CAAC,SAAS,CAAC,EAAE,EAAE,EAAE,CAAC,IAAI,CAAC,CAAC,SAAS,CAAC,EAAE,EAAE,EAAE,CAAC,IAAI,CAAC,CAAC,SAAS,CAAC,EAAE,CAAC,EAAE,CAAC;AAEnJ,SAAgB,iBAAiB,CAAC,SAAiB;IACjD,IAAI,CAAC,SAAS,EAAE,CAAC;QACf,OAAO,IAAI,CAAC;IACd,CAAC;IAED,MAAM,iBAAiB,GAAG,SAAS,CAAC,OAAO,CAAC,IAAI,EAAE,EAAE,CAAC,CAAC;IAEtD,MAAM,IAAI,GAAG,MAAM,CAAC,IAAI,CAAC,iBAAiB,EAAE,KAAK,CAAC,CAAC;IAEnD,OAAO,cAAI,CAAC,MAAM,CAAC,UAAU,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC,CAAC;AAC5C,CAAC;AAVD,8CAUC;AAED,SAAgB,iBAAiB,CAAC,SAAiB,EAAE,aAAa,GAAG,IAAI;IACvE,IAAI,CAAC;QACH,MAAM,KAAK,GAAG,cAAI,CAAC,MAAM,CAAC,SAAS,CAAC,CAAC;QAErC,MAAM,QAAQ,GAAG,MAAM,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC,QAAQ,CAAC,KAAK,CAAC,CAAC;QAEpD,OAAO,aAAa,CAAC,QAAQ,CAAC,CAAC;IACjC,CAAC;IAAC,OAAO,CAAC,EAAE,CAAC;QACX,IAAI,aAAa,EAAE,CAAC;YAElB,OAAO,SAAS,CAAC;QACnB,CAAC;aAAM,CAAC;YACN,MAAM,CAAC,CAAC;QACV,CAAC;IACH,CAAC;AACH,CAAC;AAfD,8CAeC"}
|
|
@@ -4,7 +4,7 @@ export interface VipBonusIssuanceModel {
|
|
|
4
4
|
occurrenceIndex: number;
|
|
5
5
|
expiryDate?: string;
|
|
6
6
|
availableDate?: string;
|
|
7
|
-
status
|
|
7
|
+
status: VipBonusIssuanceStatus | null;
|
|
8
8
|
}
|
|
9
9
|
export interface VipBonusPartial {
|
|
10
10
|
type: VipBonusType;
|
|
@@ -12,7 +12,7 @@ export interface VipBonusPartial {
|
|
|
12
12
|
amount: string;
|
|
13
13
|
cadence?: number | null;
|
|
14
14
|
occurrence: number;
|
|
15
|
-
cancelledAt
|
|
15
|
+
cancelledAt: string | null;
|
|
16
16
|
createdAt: string;
|
|
17
17
|
endAt: string;
|
|
18
18
|
bonusClaims?: VipBonusIssuanceModel[] | null;
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"vip-bonus.type.js","sourceRoot":"","sources":["../../src/utils/vip-bonus.type.ts"],"names":[],"mappings":";;;AAqBA,IAAY,sBAMX;AAND,WAAY,sBAAsB;IAChC,iDAAuB,CAAA;IACvB,yDAA+B,CAAA;IAC/B,6CAAmB,CAAA;IACnB,iDAAuB,CAAA;IACvB,6CAAmB,CAAA;AACrB,CAAC,EANW,sBAAsB,sCAAtB,sBAAsB,QAMjC;AAED,IAAY,YAGX;AAHD,WAAY,YAAY;IACtB,iCAAiB,CAAA;IACjB,qCAAqB,CAAA;AACvB,CAAC,EAHW,YAAY,4BAAZ,YAAY,QAGvB"}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "shufflecom-calculations",
|
|
3
|
-
"version": "1.7.
|
|
3
|
+
"version": "1.7.2",
|
|
4
4
|
"description": "",
|
|
5
5
|
"types": "lib/index.d.ts",
|
|
6
6
|
"main": "lib/index.js",
|
|
@@ -14,5 +14,5 @@
|
|
|
14
14
|
},
|
|
15
15
|
"author": "",
|
|
16
16
|
"license": "ISC",
|
|
17
|
-
"gitHead": "
|
|
17
|
+
"gitHead": "fd01724e6a722efba07c4d7cc5419ec1611d5bb0"
|
|
18
18
|
}
|
package/src/games/blackjack.ts
CHANGED
|
@@ -366,11 +366,11 @@ export class Blackjack {
|
|
|
366
366
|
|
|
367
367
|
const { perfectPair, twentyOnePlusThree } = Blackjack.calcSideBetWins(data.dealerHand[0], playerHand);
|
|
368
368
|
|
|
369
|
-
if (perfectPairPayout[perfectPair] && data.perfectPairAmount.gt(0)) {
|
|
369
|
+
if (perfectPair && perfectPairPayout[perfectPair] && data.perfectPairAmount.gt(0)) {
|
|
370
370
|
perfectPairPayoutAmt = data.perfectPairAmount.times(perfectPairPayout[perfectPair]);
|
|
371
371
|
}
|
|
372
372
|
|
|
373
|
-
if (twentyOnePlusThreePayout[twentyOnePlusThree] && data.twentyOnePlusThreeAmount.gt(0)) {
|
|
373
|
+
if (twentyOnePlusThree && twentyOnePlusThreePayout[twentyOnePlusThree] && data.twentyOnePlusThreeAmount.gt(0)) {
|
|
374
374
|
twentyOnePlusThreePayoutAmt = data.twentyOnePlusThreeAmount.times(twentyOnePlusThreePayout[twentyOnePlusThree]);
|
|
375
375
|
}
|
|
376
376
|
|
package/src/games/keno.ts
CHANGED
|
@@ -117,8 +117,14 @@ export class Keno {
|
|
|
117
117
|
}
|
|
118
118
|
|
|
119
119
|
static calculateMultiplier(risk: KenoRiskLevel, selectedTiles: number[], results: number[]) {
|
|
120
|
-
const matchedTiles = results.filter(
|
|
121
|
-
|
|
120
|
+
const matchedTiles = results.filter(result => selectedTiles.includes(result));
|
|
121
|
+
const config = this.configs().find(config => config.tiles === selectedTiles.length);
|
|
122
|
+
|
|
123
|
+
if (!config) {
|
|
124
|
+
throw new Error(`No configuration found for ${selectedTiles.length} tiles`);
|
|
125
|
+
}
|
|
126
|
+
|
|
127
|
+
return new BigNumber(config.payout[risk][matchedTiles.length] ?? 0);
|
|
122
128
|
}
|
|
123
129
|
|
|
124
130
|
static getResults(hexStr: string[], rows: number): number[] {
|
|
@@ -137,7 +143,9 @@ export class Keno {
|
|
|
137
143
|
position = position.plus(new BigNumber(value).dividedBy(BYTE_TOTAL.pow(j + 1)));
|
|
138
144
|
}
|
|
139
145
|
|
|
140
|
-
position = position
|
|
146
|
+
position = position
|
|
147
|
+
.multipliedBy(TOTAL_TILES.minus(new BigNumber(8 * counter + i)))
|
|
148
|
+
.integerValue(BigNumber.ROUND_DOWN);
|
|
141
149
|
|
|
142
150
|
results.push(grids.splice(position.toNumber(), 1)[0] + 1); // (0 to 39) + 1 = 1 + 40
|
|
143
151
|
}
|
|
@@ -147,6 +155,8 @@ export class Keno {
|
|
|
147
155
|
}
|
|
148
156
|
|
|
149
157
|
static getChance({ correctPicks, picked }: { correctPicks: number; picked: number }) {
|
|
150
|
-
return new BigNumber(nCr(10, correctPicks))
|
|
158
|
+
return new BigNumber(nCr(10, correctPicks))
|
|
159
|
+
.multipliedBy(nCr(30, picked - correctPicks))
|
|
160
|
+
.dividedBy(new BigNumber(nCr(40, picked)));
|
|
151
161
|
}
|
|
152
162
|
}
|
package/src/games/plinko.ts
CHANGED
|
@@ -67,25 +67,39 @@ const plinkoConfigs: PlinkConfig[] = [
|
|
|
67
67
|
{
|
|
68
68
|
rows: 14,
|
|
69
69
|
payout: {
|
|
70
|
-
[PlinkoRiskLevel.LOW_RISK]: [
|
|
70
|
+
[PlinkoRiskLevel.LOW_RISK]: [
|
|
71
|
+
7.1, 4, 1.9, 1.4, 1.3, 1.1, 1, 0.5, 1, 1.1, 1.3, 1.4, 1.9, 4, 7.1,
|
|
72
|
+
],
|
|
71
73
|
[PlinkoRiskLevel.MEDIUM_RISK]: [58, 15, 7, 4, 1.9, 1, 0.5, 0.2, 0.5, 1, 1.9, 4, 7, 15, 58],
|
|
72
|
-
[PlinkoRiskLevel.HIGH_RISK]: [
|
|
74
|
+
[PlinkoRiskLevel.HIGH_RISK]: [
|
|
75
|
+
420, 56, 18, 5, 1.9, 0.3, 0.2, 0.2, 0.2, 0.3, 1.9, 5, 18, 56, 420,
|
|
76
|
+
],
|
|
73
77
|
},
|
|
74
78
|
},
|
|
75
79
|
{
|
|
76
80
|
rows: 15,
|
|
77
81
|
payout: {
|
|
78
82
|
[PlinkoRiskLevel.LOW_RISK]: [15, 8, 3, 2, 1.5, 1.1, 1, 0.7, 0.7, 1, 1.1, 1.5, 2, 3, 8, 15],
|
|
79
|
-
[PlinkoRiskLevel.MEDIUM_RISK]: [
|
|
80
|
-
|
|
83
|
+
[PlinkoRiskLevel.MEDIUM_RISK]: [
|
|
84
|
+
88, 18, 11, 5, 3, 1.3, 0.5, 0.3, 0.3, 0.5, 1.3, 3, 5, 11, 18, 88,
|
|
85
|
+
],
|
|
86
|
+
[PlinkoRiskLevel.HIGH_RISK]: [
|
|
87
|
+
620, 83, 27, 8, 3, 0.5, 0.2, 0.2, 0.2, 0.2, 0.5, 3, 8, 27, 83, 620,
|
|
88
|
+
],
|
|
81
89
|
},
|
|
82
90
|
},
|
|
83
91
|
{
|
|
84
92
|
rows: 16,
|
|
85
93
|
payout: {
|
|
86
|
-
[PlinkoRiskLevel.LOW_RISK]: [
|
|
87
|
-
|
|
88
|
-
|
|
94
|
+
[PlinkoRiskLevel.LOW_RISK]: [
|
|
95
|
+
16, 9, 2, 1.4, 1.4, 1.2, 1.1, 1, 0.5, 1, 1.1, 1.2, 1.4, 1.4, 2, 9, 16,
|
|
96
|
+
],
|
|
97
|
+
[PlinkoRiskLevel.MEDIUM_RISK]: [
|
|
98
|
+
110, 41, 10, 5, 3, 1.5, 1, 0.5, 0.3, 0.5, 1, 1.5, 3, 5, 10, 41, 110,
|
|
99
|
+
],
|
|
100
|
+
[PlinkoRiskLevel.HIGH_RISK]: [
|
|
101
|
+
1000, 130, 26, 9, 4, 2, 0.2, 0.2, 0.2, 0.2, 0.2, 2, 4, 9, 26, 130, 1000,
|
|
102
|
+
],
|
|
89
103
|
},
|
|
90
104
|
},
|
|
91
105
|
];
|
|
@@ -103,17 +117,25 @@ export class Plinko {
|
|
|
103
117
|
}
|
|
104
118
|
|
|
105
119
|
static calculateChances(rows: number): BigNumber[] {
|
|
106
|
-
return
|
|
120
|
+
return Object.keys(Array(rows + 1)).map(position =>
|
|
121
|
+
this.calculateChance(rows, parseInt(position)),
|
|
122
|
+
);
|
|
107
123
|
}
|
|
108
124
|
|
|
109
125
|
static calculateMultiplier(risk: PlinkoRiskLevel, rows: number, results: number[]) {
|
|
110
126
|
const position = results.reduce((sum, result) => sum + result, 0);
|
|
111
|
-
|
|
127
|
+
const config = this.configs().find(config => config.rows === rows);
|
|
128
|
+
|
|
129
|
+
if (!config) {
|
|
130
|
+
throw new Error(`No configuration found for ${rows} rows`);
|
|
131
|
+
}
|
|
132
|
+
|
|
133
|
+
return new BigNumber(config.payout[risk][position]);
|
|
112
134
|
}
|
|
113
135
|
|
|
114
136
|
static getResults(hexStr: string[], rows: number): number[] {
|
|
115
137
|
const results: number[] = [];
|
|
116
|
-
hexStr.map(hexToBytes).every(
|
|
138
|
+
hexStr.map(hexToBytes).every(gameResultBytes => {
|
|
117
139
|
// Need 4 bytes to calculate each result
|
|
118
140
|
for (let i = 0; i < 8; i++) {
|
|
119
141
|
if (results.length >= rows) {
|
|
@@ -0,0 +1,213 @@
|
|
|
1
|
+
import { createHmac } from 'crypto';
|
|
2
|
+
import { TOWER_TOTAL_ROWS, Tower, TOWER_DIFFICULTY_TO_CONFIG, TowerDifficulty } from './tower';
|
|
3
|
+
|
|
4
|
+
const edgeBps = 200;
|
|
5
|
+
|
|
6
|
+
const resultMultipliers = {
|
|
7
|
+
[TowerDifficulty.EASY]: [1.31, 1.74, 2.32, 3.1, 4.13, 5.51, 7.34, 9.79, 13.05],
|
|
8
|
+
[TowerDifficulty.MEDIUM]: [1.47, 2.21, 3.31, 4.96, 7.44, 11.16, 16.74, 25.12, 37.67],
|
|
9
|
+
[TowerDifficulty.HARD]: [1.96, 3.92, 7.84, 15.68, 31.36, 62.72, 125.44, 250.88, 501.76],
|
|
10
|
+
[TowerDifficulty.EXPERT]: [2.94, 8.82, 26.46, 79.38, 238.14, 714.42, 2143.26, 6429.78, 19289.34],
|
|
11
|
+
[TowerDifficulty.MASTER]: [
|
|
12
|
+
3.92, 15.68, 62.72, 250.88, 1003.52, 4014.08, 16056.32, 64225.28, 256901.12,
|
|
13
|
+
],
|
|
14
|
+
};
|
|
15
|
+
|
|
16
|
+
describe('Tower', () => {
|
|
17
|
+
it('be able to calculate the correct multiplier', () => {
|
|
18
|
+
Object.keys(resultMultipliers).forEach(difficulty => {
|
|
19
|
+
const multiplierArr = resultMultipliers[difficulty as TowerDifficulty];
|
|
20
|
+
multiplierArr.forEach((multiplier, index) => {
|
|
21
|
+
expect(
|
|
22
|
+
Tower.calculateMultiplierBN(difficulty as TowerDifficulty, index + 1, edgeBps).toFixed(2),
|
|
23
|
+
).toBe(multiplier.toFixed(2));
|
|
24
|
+
});
|
|
25
|
+
});
|
|
26
|
+
});
|
|
27
|
+
|
|
28
|
+
it('tower provably', () => {
|
|
29
|
+
const gameSeeds = [
|
|
30
|
+
{
|
|
31
|
+
serverSeed: 'da5a4cd5eca04d91d36569207265bd79d2989a19378eea897399755f2c9b83e6',
|
|
32
|
+
clientSeed: '7qkHqOhx-F',
|
|
33
|
+
nonce: '1',
|
|
34
|
+
rounds: Math.floor(
|
|
35
|
+
(TOWER_DIFFICULTY_TO_CONFIG[TowerDifficulty.EASY].count * TOWER_TOTAL_ROWS.toNumber()) /
|
|
36
|
+
8 +
|
|
37
|
+
1,
|
|
38
|
+
),
|
|
39
|
+
difficulty: TowerDifficulty.EASY,
|
|
40
|
+
results: [
|
|
41
|
+
[0, 2, 3],
|
|
42
|
+
[0, 1, 2],
|
|
43
|
+
[0, 1, 2],
|
|
44
|
+
[0, 1, 3],
|
|
45
|
+
[0, 2, 3],
|
|
46
|
+
[1, 2, 3],
|
|
47
|
+
[0, 2, 3],
|
|
48
|
+
[1, 2, 3],
|
|
49
|
+
[0, 1, 3],
|
|
50
|
+
],
|
|
51
|
+
},
|
|
52
|
+
{
|
|
53
|
+
serverSeed: 'da5a4cd5eca04d91d36569207265bd79d2989a19378eea897399755f2c9b83e6',
|
|
54
|
+
clientSeed: '7qkHqOhx-F',
|
|
55
|
+
nonce: '6',
|
|
56
|
+
rounds: Math.floor(
|
|
57
|
+
(TOWER_DIFFICULTY_TO_CONFIG[TowerDifficulty.EASY].count * TOWER_TOTAL_ROWS.toNumber()) /
|
|
58
|
+
8 +
|
|
59
|
+
1,
|
|
60
|
+
),
|
|
61
|
+
difficulty: TowerDifficulty.EASY,
|
|
62
|
+
results: [
|
|
63
|
+
[0, 1, 2],
|
|
64
|
+
[0, 2, 3],
|
|
65
|
+
[0, 1, 2],
|
|
66
|
+
[1, 2, 3],
|
|
67
|
+
[0, 1, 3],
|
|
68
|
+
[0, 1, 3],
|
|
69
|
+
[0, 1, 2],
|
|
70
|
+
[1, 2, 3],
|
|
71
|
+
[0, 1, 2],
|
|
72
|
+
],
|
|
73
|
+
},
|
|
74
|
+
{
|
|
75
|
+
serverSeed: 'da5a4cd5eca04d91d36569207265bd79d2989a19378eea897399755f2c9b83e6',
|
|
76
|
+
clientSeed: '7qkHqOhx-F',
|
|
77
|
+
nonce: '13',
|
|
78
|
+
rounds: Math.floor(
|
|
79
|
+
(TOWER_DIFFICULTY_TO_CONFIG[TowerDifficulty.MEDIUM].count * TOWER_TOTAL_ROWS.toNumber()) /
|
|
80
|
+
8 +
|
|
81
|
+
1,
|
|
82
|
+
),
|
|
83
|
+
difficulty: TowerDifficulty.MEDIUM,
|
|
84
|
+
results: [
|
|
85
|
+
[0, 1],
|
|
86
|
+
[1, 2],
|
|
87
|
+
[0, 1],
|
|
88
|
+
[0, 2],
|
|
89
|
+
[0, 2],
|
|
90
|
+
[1, 2],
|
|
91
|
+
[0, 1],
|
|
92
|
+
[0, 2],
|
|
93
|
+
[0, 2],
|
|
94
|
+
],
|
|
95
|
+
},
|
|
96
|
+
{
|
|
97
|
+
serverSeed: 'da5a4cd5eca04d91d36569207265bd79d2989a19378eea897399755f2c9b83e6',
|
|
98
|
+
clientSeed: '7qkHqOhx-F',
|
|
99
|
+
nonce: '17',
|
|
100
|
+
rounds: Math.floor(
|
|
101
|
+
(TOWER_DIFFICULTY_TO_CONFIG[TowerDifficulty.MEDIUM].count * TOWER_TOTAL_ROWS.toNumber()) /
|
|
102
|
+
8 +
|
|
103
|
+
1,
|
|
104
|
+
),
|
|
105
|
+
difficulty: TowerDifficulty.MEDIUM,
|
|
106
|
+
results: [
|
|
107
|
+
[0, 2],
|
|
108
|
+
[0, 1],
|
|
109
|
+
[0, 1],
|
|
110
|
+
[0, 1],
|
|
111
|
+
[0, 1],
|
|
112
|
+
[1, 2],
|
|
113
|
+
[0, 1],
|
|
114
|
+
[1, 2],
|
|
115
|
+
[0, 2],
|
|
116
|
+
],
|
|
117
|
+
},
|
|
118
|
+
{
|
|
119
|
+
serverSeed: 'da5a4cd5eca04d91d36569207265bd79d2989a19378eea897399755f2c9b83e6',
|
|
120
|
+
clientSeed: '7qkHqOhx-F',
|
|
121
|
+
nonce: '27',
|
|
122
|
+
rounds: Math.floor(
|
|
123
|
+
(TOWER_DIFFICULTY_TO_CONFIG[TowerDifficulty.HARD].count * TOWER_TOTAL_ROWS.toNumber()) /
|
|
124
|
+
8 +
|
|
125
|
+
1,
|
|
126
|
+
),
|
|
127
|
+
difficulty: TowerDifficulty.HARD,
|
|
128
|
+
results: [[1], [0], [0], [1], [1], [0], [1], [1], [1]],
|
|
129
|
+
},
|
|
130
|
+
{
|
|
131
|
+
serverSeed: 'da5a4cd5eca04d91d36569207265bd79d2989a19378eea897399755f2c9b83e6',
|
|
132
|
+
clientSeed: '7qkHqOhx-F',
|
|
133
|
+
nonce: '30',
|
|
134
|
+
rounds: Math.floor(
|
|
135
|
+
(TOWER_DIFFICULTY_TO_CONFIG[TowerDifficulty.HARD].count * TOWER_TOTAL_ROWS.toNumber()) /
|
|
136
|
+
8 +
|
|
137
|
+
1,
|
|
138
|
+
),
|
|
139
|
+
difficulty: TowerDifficulty.HARD,
|
|
140
|
+
results: [[0], [1], [0], [1], [1], [1], [1], [0], [0]],
|
|
141
|
+
},
|
|
142
|
+
{
|
|
143
|
+
serverSeed: 'da5a4cd5eca04d91d36569207265bd79d2989a19378eea897399755f2c9b83e6',
|
|
144
|
+
clientSeed: '7qkHqOhx-F',
|
|
145
|
+
nonce: '35',
|
|
146
|
+
rounds: Math.floor(
|
|
147
|
+
(TOWER_DIFFICULTY_TO_CONFIG[TowerDifficulty.EXPERT].count * TOWER_TOTAL_ROWS.toNumber()) /
|
|
148
|
+
8 +
|
|
149
|
+
1,
|
|
150
|
+
),
|
|
151
|
+
difficulty: TowerDifficulty.EXPERT,
|
|
152
|
+
results: [[1], [0], [1], [0], [1], [0], [1], [2], [2]],
|
|
153
|
+
},
|
|
154
|
+
{
|
|
155
|
+
serverSeed: 'da5a4cd5eca04d91d36569207265bd79d2989a19378eea897399755f2c9b83e6',
|
|
156
|
+
clientSeed: '7qkHqOhx-F',
|
|
157
|
+
nonce: '40',
|
|
158
|
+
rounds: Math.floor(
|
|
159
|
+
(TOWER_DIFFICULTY_TO_CONFIG[TowerDifficulty.EXPERT].count * TOWER_TOTAL_ROWS.toNumber()) /
|
|
160
|
+
8 +
|
|
161
|
+
1,
|
|
162
|
+
),
|
|
163
|
+
difficulty: TowerDifficulty.EXPERT,
|
|
164
|
+
results: [[1], [1], [2], [1], [0], [2], [0], [2], [2]],
|
|
165
|
+
},
|
|
166
|
+
{
|
|
167
|
+
serverSeed: 'da5a4cd5eca04d91d36569207265bd79d2989a19378eea897399755f2c9b83e6',
|
|
168
|
+
clientSeed: '7qkHqOhx-F',
|
|
169
|
+
nonce: '42',
|
|
170
|
+
rounds: Math.floor(
|
|
171
|
+
(TOWER_DIFFICULTY_TO_CONFIG[TowerDifficulty.MASTER].count * TOWER_TOTAL_ROWS.toNumber()) /
|
|
172
|
+
8 +
|
|
173
|
+
1,
|
|
174
|
+
),
|
|
175
|
+
difficulty: TowerDifficulty.MASTER,
|
|
176
|
+
results: [[3], [3], [3], [1], [3], [3], [2], [3], [2]],
|
|
177
|
+
},
|
|
178
|
+
{
|
|
179
|
+
serverSeed: 'da5a4cd5eca04d91d36569207265bd79d2989a19378eea897399755f2c9b83e6',
|
|
180
|
+
clientSeed: '7qkHqOhx-F',
|
|
181
|
+
nonce: '48',
|
|
182
|
+
rounds: Math.floor(
|
|
183
|
+
(TOWER_DIFFICULTY_TO_CONFIG[TowerDifficulty.MASTER].count * TOWER_TOTAL_ROWS.toNumber()) /
|
|
184
|
+
8 +
|
|
185
|
+
1,
|
|
186
|
+
),
|
|
187
|
+
difficulty: TowerDifficulty.MASTER,
|
|
188
|
+
results: [[1], [2], [0], [3], [0], [3], [0], [2], [3]],
|
|
189
|
+
},
|
|
190
|
+
];
|
|
191
|
+
|
|
192
|
+
gameSeeds.forEach(e => {
|
|
193
|
+
const resultHex = generateDigestHex(e);
|
|
194
|
+
const results = Tower.getResults(resultHex, e.difficulty);
|
|
195
|
+
expect(results).toEqual(e.results);
|
|
196
|
+
});
|
|
197
|
+
});
|
|
198
|
+
});
|
|
199
|
+
|
|
200
|
+
function generateDigestHex({
|
|
201
|
+
serverSeed,
|
|
202
|
+
clientSeed,
|
|
203
|
+
nonce,
|
|
204
|
+
rounds,
|
|
205
|
+
}: { serverSeed: string; clientSeed: string; nonce: string; rounds: number }): string[] {
|
|
206
|
+
const results = Array.from(Array(rounds).keys()).map(round => {
|
|
207
|
+
const hmac = createHmac('sha256', serverSeed);
|
|
208
|
+
hmac.update(`${clientSeed}:${nonce}:${round}`);
|
|
209
|
+
return hmac.digest('hex');
|
|
210
|
+
});
|
|
211
|
+
|
|
212
|
+
return results;
|
|
213
|
+
}
|
|
@@ -0,0 +1,107 @@
|
|
|
1
|
+
import BigNumber from 'bignumber.js';
|
|
2
|
+
import { hexToBytes } from '../utils/hex-to-bytes';
|
|
3
|
+
import { calculateEdgeMultiplier } from '../utils/edge';
|
|
4
|
+
|
|
5
|
+
const BYTE_PER_HEXSTR = 32;
|
|
6
|
+
const BYTE_TOTAL = new BigNumber(256);
|
|
7
|
+
export const TOWER_TOTAL_ROWS = new BigNumber(9);
|
|
8
|
+
|
|
9
|
+
type DifficultyConfig = {
|
|
10
|
+
count: number; // Number of safe tiles in each row
|
|
11
|
+
columns: number;
|
|
12
|
+
};
|
|
13
|
+
|
|
14
|
+
export enum TowerDifficulty {
|
|
15
|
+
EASY = 'EASY',
|
|
16
|
+
MEDIUM = 'MEDIUM',
|
|
17
|
+
HARD = 'HARD',
|
|
18
|
+
EXPERT = 'EXPERT',
|
|
19
|
+
MASTER = 'MASTER',
|
|
20
|
+
}
|
|
21
|
+
|
|
22
|
+
export const TOWER_DIFFICULTY_TO_CONFIG: Record<TowerDifficulty, DifficultyConfig> = {
|
|
23
|
+
[TowerDifficulty.EASY]: {
|
|
24
|
+
count: 3,
|
|
25
|
+
columns: 4,
|
|
26
|
+
},
|
|
27
|
+
[TowerDifficulty.MEDIUM]: {
|
|
28
|
+
count: 2,
|
|
29
|
+
columns: 3,
|
|
30
|
+
},
|
|
31
|
+
[TowerDifficulty.HARD]: {
|
|
32
|
+
count: 1,
|
|
33
|
+
columns: 2,
|
|
34
|
+
},
|
|
35
|
+
[TowerDifficulty.EXPERT]: {
|
|
36
|
+
count: 1,
|
|
37
|
+
columns: 3,
|
|
38
|
+
},
|
|
39
|
+
[TowerDifficulty.MASTER]: {
|
|
40
|
+
count: 1,
|
|
41
|
+
columns: 4,
|
|
42
|
+
},
|
|
43
|
+
};
|
|
44
|
+
|
|
45
|
+
export class Tower {
|
|
46
|
+
static getResults(hexStr: string[], difficulty: TowerDifficulty) {
|
|
47
|
+
const results: number[][] = [];
|
|
48
|
+
const towerConfig = TOWER_DIFFICULTY_TO_CONFIG[difficulty];
|
|
49
|
+
|
|
50
|
+
const gameResultBytesArr = hexStr.map(hexToBytes);
|
|
51
|
+
|
|
52
|
+
for (let i = 0; i < TOWER_TOTAL_ROWS.toNumber(); i++) {
|
|
53
|
+
const columIndexes = Array.from(Array(towerConfig.columns).keys());
|
|
54
|
+
let result: number[] = [];
|
|
55
|
+
|
|
56
|
+
// Need towerConfig.count numbers for each row
|
|
57
|
+
for (let j = 0; j < towerConfig.count; j++) {
|
|
58
|
+
let position = new BigNumber(0);
|
|
59
|
+
|
|
60
|
+
// Need 4 bytes to calculate each position
|
|
61
|
+
for (let k = 0; k < 4; k++) {
|
|
62
|
+
const index = 4 * towerConfig.count * i + 4 * j + k;
|
|
63
|
+
const value =
|
|
64
|
+
gameResultBytesArr[Math.floor(index / BYTE_PER_HEXSTR)][index % BYTE_PER_HEXSTR];
|
|
65
|
+
|
|
66
|
+
position = position.plus(new BigNumber(value).dividedBy(BYTE_TOTAL.pow(k + 1)));
|
|
67
|
+
}
|
|
68
|
+
|
|
69
|
+
position = position
|
|
70
|
+
.multipliedBy(towerConfig.columns - j)
|
|
71
|
+
.integerValue(BigNumber.ROUND_DOWN);
|
|
72
|
+
result.push(columIndexes.splice(position.toNumber(), 1)[0]);
|
|
73
|
+
}
|
|
74
|
+
|
|
75
|
+
result = result.sort((a, b) => a - b);
|
|
76
|
+
results.push(result);
|
|
77
|
+
}
|
|
78
|
+
|
|
79
|
+
return results;
|
|
80
|
+
}
|
|
81
|
+
|
|
82
|
+
static calculateMultiplierBN(
|
|
83
|
+
difficulty: TowerDifficulty,
|
|
84
|
+
noOfWinningRows: number,
|
|
85
|
+
edgeBps: number,
|
|
86
|
+
) {
|
|
87
|
+
if (noOfWinningRows <= 0) {
|
|
88
|
+
return new BigNumber(0);
|
|
89
|
+
}
|
|
90
|
+
|
|
91
|
+
const columns = TOWER_DIFFICULTY_TO_CONFIG[difficulty].columns;
|
|
92
|
+
|
|
93
|
+
const winChancePerRow =
|
|
94
|
+
([TowerDifficulty.EASY, TowerDifficulty.MEDIUM].includes(difficulty) ? columns - 1 : 1) /
|
|
95
|
+
columns;
|
|
96
|
+
|
|
97
|
+
const winChance = BigNumber(winChancePerRow).pow(noOfWinningRows);
|
|
98
|
+
|
|
99
|
+
return winChance.pow(-1).multipliedBy(calculateEdgeMultiplier(edgeBps));
|
|
100
|
+
}
|
|
101
|
+
|
|
102
|
+
static isLoss(results: number[][], selected: number, currentRow: number) {
|
|
103
|
+
const result = results[currentRow];
|
|
104
|
+
|
|
105
|
+
return !result.includes(selected);
|
|
106
|
+
}
|
|
107
|
+
}
|