shufflecom-calculations 6.7.1 → 6.8.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.
- package/lib/index.d.ts +2 -0
- package/lib/index.js +7 -2
- package/lib/index.js.map +1 -1
- package/lib/sweep-stakes/derive-purchase-bonus-multiplier.d.ts +11 -0
- package/lib/sweep-stakes/derive-purchase-bonus-multiplier.js +33 -0
- package/lib/sweep-stakes/derive-purchase-bonus-multiplier.js.map +1 -0
- package/lib/sweep-stakes/sweep-stakes-package.d.ts +19 -0
- package/lib/sweep-stakes/sweep-stakes-package.js +48 -0
- package/lib/sweep-stakes/sweep-stakes-package.js.map +1 -0
- package/lib/tsconfig.tsbuildinfo +1 -1
- package/lib/types/wallet-product.type.d.ts +5 -0
- package/lib/types/wallet-product.type.js +10 -0
- package/lib/types/wallet-product.type.js.map +1 -0
- package/package.json +2 -2
- package/src/index.ts +2 -0
- package/src/sweep-stakes/derive-purchase-bonus-multiplier.spec.ts +50 -0
- package/src/sweep-stakes/derive-purchase-bonus-multiplier.ts +49 -0
- package/src/sweep-stakes/sweep-stakes-package.ts +49 -0
- package/src/types/wallet-product.type.ts +5 -0
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.WalletProduct = void 0;
|
|
4
|
+
var WalletProduct;
|
|
5
|
+
(function (WalletProduct) {
|
|
6
|
+
WalletProduct["CRYPTO_DEPOSIT"] = "CRYPTO_DEPOSIT";
|
|
7
|
+
WalletProduct["BUNDLE_PACKAGE"] = "BUNDLE_PACKAGE";
|
|
8
|
+
WalletProduct["GOLD_COIN_PACKAGE"] = "GOLD_COIN_PACKAGE";
|
|
9
|
+
})(WalletProduct || (exports.WalletProduct = WalletProduct = {}));
|
|
10
|
+
//# sourceMappingURL=wallet-product.type.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"wallet-product.type.js","sourceRoot":"","sources":["../../src/types/wallet-product.type.ts"],"names":[],"mappings":";;;AAAA,IAAY,aAIX;AAJD,WAAY,aAAa;IACvB,kDAAiC,CAAA;IACjC,kDAAiC,CAAA;IACjC,wDAAuC,CAAA;AACzC,CAAC,EAJW,aAAa,6BAAb,aAAa,QAIxB"}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "shufflecom-calculations",
|
|
3
|
-
"version": "6.
|
|
3
|
+
"version": "6.8.0",
|
|
4
4
|
"description": "",
|
|
5
5
|
"types": "lib/index.d.ts",
|
|
6
6
|
"main": "lib/index.js",
|
|
@@ -19,5 +19,5 @@
|
|
|
19
19
|
},
|
|
20
20
|
"author": "",
|
|
21
21
|
"license": "ISC",
|
|
22
|
-
"gitHead": "
|
|
22
|
+
"gitHead": "aa6d35e33a97dff5bb25838a0999b5afd4f97fa2"
|
|
23
23
|
}
|
package/src/index.ts
CHANGED
|
@@ -8,6 +8,8 @@ export { ChatMessageType, ChatMessage } from './utils/chat-message.type';
|
|
|
8
8
|
export { DatesCalculator } from './utils/dates-calculator';
|
|
9
9
|
export { VipBonusIssuanceStatus } from './utils/vip-bonus.type';
|
|
10
10
|
export { deriveBonusIssuances } from './utils/derive-vip-bonus';
|
|
11
|
+
export { derivePurchaseBonusMultiplier } from './sweep-stakes/derive-purchase-bonus-multiplier';
|
|
12
|
+
export { SweepStakePurchasePackageCalculator, SWEEP_STAKE_PURCHASE_PACKAGES } from './sweep-stakes/sweep-stakes-package';
|
|
11
13
|
export { convertBs58ToUuid, convertUuidToBs58 } from './utils/uuid-converter';
|
|
12
14
|
export { Dice, DiceDirection } from './games/dice';
|
|
13
15
|
export { Roulette } from './games/roulette';
|
|
@@ -0,0 +1,50 @@
|
|
|
1
|
+
import BigNumber from 'bignumber.js';
|
|
2
|
+
import { derivePurchaseBonusMultiplier } from './derive-purchase-bonus-multiplier';
|
|
3
|
+
|
|
4
|
+
const bonus = (usd: number, multiplier: BigNumber) => new BigNumber(usd).times(multiplier).decimalPlaces(2, BigNumber.ROUND_DOWN).toString();
|
|
5
|
+
|
|
6
|
+
describe('derivePurchaseBonusMultiplier', () => {
|
|
7
|
+
const ascBps = [
|
|
8
|
+
{ usdAmount: 50, percent: 4000 },
|
|
9
|
+
{ usdAmount: 10, percent: 3000 },
|
|
10
|
+
];
|
|
11
|
+
const ascRaw = [
|
|
12
|
+
{ usdAmount: 10, percent: 30 },
|
|
13
|
+
{ usdAmount: 50, percent: 40 },
|
|
14
|
+
];
|
|
15
|
+
const descBps = [
|
|
16
|
+
{ usdAmount: 10, percent: 4000 },
|
|
17
|
+
{ usdAmount: 50, percent: 3000 },
|
|
18
|
+
];
|
|
19
|
+
|
|
20
|
+
it('returns 0 with no anchors', () => {
|
|
21
|
+
expect(derivePurchaseBonusMultiplier('bps', { usdReadable: 15, anchorPoints: [] }).toNumber()).toBe(0);
|
|
22
|
+
});
|
|
23
|
+
|
|
24
|
+
it('returns 0 below the lowest anchor', () => {
|
|
25
|
+
expect(derivePurchaseBonusMultiplier('bps', { usdReadable: 5, anchorPoints: ascBps }).toNumber()).toBe(0);
|
|
26
|
+
});
|
|
27
|
+
|
|
28
|
+
it('returns the anchor percent on an exact anchor', () => {
|
|
29
|
+
expect(derivePurchaseBonusMultiplier('bps', { usdReadable: 10, anchorPoints: ascBps }).toNumber()).toBe(0.3);
|
|
30
|
+
expect(derivePurchaseBonusMultiplier('bps', { usdReadable: 50, anchorPoints: ascBps }).toNumber()).toBe(0.4);
|
|
31
|
+
});
|
|
32
|
+
|
|
33
|
+
it('caps at the highest anchor', () => {
|
|
34
|
+
expect(derivePurchaseBonusMultiplier('bps', { usdReadable: 500, anchorPoints: ascBps }).toNumber()).toBe(0.4);
|
|
35
|
+
});
|
|
36
|
+
|
|
37
|
+
it('interpolates increasing anchors (bps & raw give same result)', () => {
|
|
38
|
+
const m1 = derivePurchaseBonusMultiplier('bps', { usdReadable: 15, anchorPoints: ascBps });
|
|
39
|
+
const m2 = derivePurchaseBonusMultiplier('raw', { usdReadable: 15, anchorPoints: ascRaw });
|
|
40
|
+
expect(m1.toNumber()).toBe(0.3125);
|
|
41
|
+
expect(m2.toNumber()).toBe(0.3125);
|
|
42
|
+
expect(bonus(15, m1)).toBe('4.68');
|
|
43
|
+
});
|
|
44
|
+
|
|
45
|
+
it('interpolates decreasing anchors', () => {
|
|
46
|
+
const m = derivePurchaseBonusMultiplier('bps', { usdReadable: 15, anchorPoints: descBps });
|
|
47
|
+
expect(m.toNumber()).toBe(0.3875);
|
|
48
|
+
expect(bonus(15, m)).toBe('5.81');
|
|
49
|
+
});
|
|
50
|
+
});
|
|
@@ -0,0 +1,49 @@
|
|
|
1
|
+
import BigNumber from 'bignumber.js';
|
|
2
|
+
|
|
3
|
+
type PurchaseBonusPercentType = 'bps' | 'raw';
|
|
4
|
+
|
|
5
|
+
const PERCENT_DIVISOR: Record<PurchaseBonusPercentType, number> = {
|
|
6
|
+
bps: 10_000,
|
|
7
|
+
raw: 100,
|
|
8
|
+
};
|
|
9
|
+
|
|
10
|
+
export interface SweepStakePurchaseBonusAnchorPointSchema {
|
|
11
|
+
usdAmount: number;
|
|
12
|
+
percent: number;
|
|
13
|
+
}
|
|
14
|
+
|
|
15
|
+
/**
|
|
16
|
+
* Derives the purchase bonus multiplier for a deposit by linearly interpolating between anchor points.
|
|
17
|
+
*
|
|
18
|
+
* @param percentType - the unit that `anchorPoints[].percent` is stored in:
|
|
19
|
+
* - `'bps'`: basis points, where 10_000 = 100% (e.g. 250 = 2.5%). Stored/admin configured values use this.
|
|
20
|
+
* - `'raw'`: whole percent, where 100 = 100% (e.g. 2.5 = 2.5%).
|
|
21
|
+
*
|
|
22
|
+
* @returns the multiplier as a fraction (e.g. 0.025 for 2.5%), or 0 when the deposit is below the first anchor point.
|
|
23
|
+
*/
|
|
24
|
+
export function derivePurchaseBonusMultiplier(
|
|
25
|
+
percentType: PurchaseBonusPercentType,
|
|
26
|
+
{ usdReadable, anchorPoints }: { usdReadable: BigNumber.Value; anchorPoints: SweepStakePurchaseBonusAnchorPointSchema[] },
|
|
27
|
+
): BigNumber {
|
|
28
|
+
const deposit = new BigNumber(usdReadable);
|
|
29
|
+
if (anchorPoints.length === 0 || !deposit.isFinite() || deposit.lte(0)) return new BigNumber(0);
|
|
30
|
+
|
|
31
|
+
const divisor = PERCENT_DIVISOR[percentType];
|
|
32
|
+
const toMultiplier = (percent: BigNumber.Value) => new BigNumber(percent).div(divisor);
|
|
33
|
+
|
|
34
|
+
const sorted = [...anchorPoints].sort((a, b) => a.usdAmount - b.usdAmount);
|
|
35
|
+
const first = sorted[0];
|
|
36
|
+
const last = sorted[sorted.length - 1];
|
|
37
|
+
|
|
38
|
+
if (deposit.lt(first.usdAmount)) return new BigNumber(0);
|
|
39
|
+
if (deposit.gte(last.usdAmount)) return toMultiplier(last.percent);
|
|
40
|
+
|
|
41
|
+
// first <= deposit < last, so hiIndex is always >= 1 and lo.usdAmount <= deposit < hi.usdAmount
|
|
42
|
+
const hiIndex = sorted.findIndex(anchor => deposit.lt(anchor.usdAmount));
|
|
43
|
+
const lo = sorted[hiIndex - 1];
|
|
44
|
+
const hi = sorted[hiIndex];
|
|
45
|
+
|
|
46
|
+
const slope = new BigNumber(hi.percent).minus(lo.percent).div(hi.usdAmount - lo.usdAmount);
|
|
47
|
+
const pct = deposit.minus(lo.usdAmount).times(slope).plus(lo.percent);
|
|
48
|
+
return toMultiplier(pct);
|
|
49
|
+
}
|
|
@@ -0,0 +1,49 @@
|
|
|
1
|
+
import BigNumber from 'bignumber.js';
|
|
2
|
+
import { WalletProduct } from '../types/wallet-product.type';
|
|
3
|
+
|
|
4
|
+
export const SC_GC_BUNDLE_RATE = 10_000;
|
|
5
|
+
|
|
6
|
+
type SweepStakePurchasePackages = {
|
|
7
|
+
usdAmount: number;
|
|
8
|
+
product: WalletProduct.BUNDLE_PACKAGE | WalletProduct.GOLD_COIN_PACKAGE;
|
|
9
|
+
};
|
|
10
|
+
|
|
11
|
+
export const SWEEP_STAKE_PURCHASE_PACKAGES: SweepStakePurchasePackages[] = [
|
|
12
|
+
{ usdAmount: 5, product: WalletProduct.BUNDLE_PACKAGE },
|
|
13
|
+
{ usdAmount: 10, product: WalletProduct.BUNDLE_PACKAGE },
|
|
14
|
+
{ usdAmount: 20, product: WalletProduct.BUNDLE_PACKAGE },
|
|
15
|
+
{ usdAmount: 50, product: WalletProduct.BUNDLE_PACKAGE },
|
|
16
|
+
{ usdAmount: 100, product: WalletProduct.BUNDLE_PACKAGE },
|
|
17
|
+
{ usdAmount: 250, product: WalletProduct.BUNDLE_PACKAGE },
|
|
18
|
+
{ usdAmount: 500, product: WalletProduct.BUNDLE_PACKAGE },
|
|
19
|
+
{ usdAmount: 1000, product: WalletProduct.BUNDLE_PACKAGE },
|
|
20
|
+
{ usdAmount: 30, product: WalletProduct.GOLD_COIN_PACKAGE },
|
|
21
|
+
];
|
|
22
|
+
|
|
23
|
+
export class SweepStakePurchasePackageCalculator {
|
|
24
|
+
static usdToGc(usdAmount: BigNumber.Value): BigNumber {
|
|
25
|
+
return new BigNumber(usdAmount).times(SC_GC_BUNDLE_RATE);
|
|
26
|
+
}
|
|
27
|
+
|
|
28
|
+
static getPackageValue({ usdAmount, product }: { usdAmount: BigNumber.Value; product: WalletProduct }): { gc: BigNumber; sc: BigNumber } {
|
|
29
|
+
switch (product) {
|
|
30
|
+
case WalletProduct.BUNDLE_PACKAGE:
|
|
31
|
+
return {
|
|
32
|
+
gc: SweepStakePurchasePackageCalculator.usdToGc(usdAmount),
|
|
33
|
+
sc: new BigNumber(usdAmount),
|
|
34
|
+
};
|
|
35
|
+
case WalletProduct.GOLD_COIN_PACKAGE:
|
|
36
|
+
return {
|
|
37
|
+
gc: SweepStakePurchasePackageCalculator.usdToGc(usdAmount),
|
|
38
|
+
sc: new BigNumber(0),
|
|
39
|
+
};
|
|
40
|
+
case WalletProduct.CRYPTO_DEPOSIT:
|
|
41
|
+
return {
|
|
42
|
+
gc: new BigNumber(0),
|
|
43
|
+
sc: new BigNumber(0),
|
|
44
|
+
};
|
|
45
|
+
default:
|
|
46
|
+
return product satisfies never;
|
|
47
|
+
}
|
|
48
|
+
}
|
|
49
|
+
}
|