@moneypot/hub 1.9.0-dev.2 → 1.9.0-dev.4

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.
@@ -0,0 +1,9 @@
1
+ export declare function formatCurrency(amount: number, currency: {
2
+ displayUnitScale: number;
3
+ displayUnitName: string;
4
+ }, options?: {
5
+ excludeUnit?: boolean;
6
+ }): string;
7
+ export declare function pluralize(word: string, count: number, suffix?: string): string;
8
+ export declare function getDecimalPlaces(displayUnitScale: number): number;
9
+ export declare function truncateDecimalPrecision(value: number, decimals: number): number;
@@ -0,0 +1,40 @@
1
+ export function formatCurrency(amount, currency, options = {
2
+ excludeUnit: false,
3
+ }) {
4
+ const decimalPlaces = getDecimalPlaces(currency.displayUnitScale);
5
+ const scaledAmount = amount / (currency.displayUnitScale || 1);
6
+ const truncatedAmount = truncateDecimalPrecision(scaledAmount, decimalPlaces);
7
+ const formatter = new Intl.NumberFormat("en-US", {
8
+ minimumFractionDigits: decimalPlaces,
9
+ maximumFractionDigits: decimalPlaces,
10
+ useGrouping: true,
11
+ });
12
+ const formatted = formatter.format(truncatedAmount);
13
+ if (options.excludeUnit) {
14
+ return formatted;
15
+ }
16
+ return `${formatted} ${pluralize(currency.displayUnitName, truncatedAmount)}`;
17
+ }
18
+ export function pluralize(word, count, suffix = "s") {
19
+ return count === 1 ? word : word + suffix;
20
+ }
21
+ export function getDecimalPlaces(displayUnitScale) {
22
+ return displayUnitScale < 10 ? 0 : Math.log10(displayUnitScale);
23
+ }
24
+ export function truncateDecimalPrecision(value, decimals) {
25
+ if (decimals < 0) {
26
+ throw new Error("Decimals must be a non-negative integer");
27
+ }
28
+ if (!Number.isFinite(value)) {
29
+ return value;
30
+ }
31
+ const str = value.toString();
32
+ const dotIndex = str.indexOf(".");
33
+ if (dotIndex === -1) {
34
+ return value;
35
+ }
36
+ const truncatedStr = decimals === 0
37
+ ? str.substring(0, dotIndex)
38
+ : str.substring(0, dotIndex + decimals + 1);
39
+ return parseFloat(truncatedStr);
40
+ }
@@ -8,6 +8,7 @@ import { dbInsertHubHash, dbLockHubHashChain, } from "../hash-chain/db-hash-chai
8
8
  import { getIntermediateHash, getPreimageHash, } from "../hash-chain/get-hash.js";
9
9
  import { makeFinalHash, pickRandomOutcome } from "../hash-chain/util.js";
10
10
  import { logger } from "../logger.js";
11
+ import { formatCurrency } from "../format-currency.js";
11
12
  const FLOAT_EPSILON = 1e-10;
12
13
  function sum(ns) {
13
14
  return ns.reduce((a, b) => a + b, 0);
@@ -154,7 +155,7 @@ export function MakeOutcomeBetPlugin({ betConfigs }) {
154
155
  const dbCurrency = await superuserPool
155
156
  .query({
156
157
  text: `
157
- SELECT key
158
+ SELECT key, display_unit_name, display_unit_scale
158
159
  FROM hub.currency
159
160
  WHERE key = $1
160
161
  AND casino_id = $2
@@ -192,7 +193,7 @@ export function MakeOutcomeBetPlugin({ betConfigs }) {
192
193
  const maxProfitMultiplier = Math.max(...input.outcomes.map((o) => o.profit));
193
194
  const maxPayout = input.wager * maxProfitMultiplier;
194
195
  if (maxPayout > dbHouseBankroll.amount) {
195
- throw new GraphQLError(`House cannot cover potential payout (${maxPayout}). Bankroll: ${dbHouseBankroll.amount}`);
196
+ throw new GraphQLError(`House cannot cover potential payout (${maxPayout} units). Bankroll: ${dbHouseBankroll.amount} units`);
196
197
  }
197
198
  const riskLimitsResult = RiskLimitsSchema.safeParse(betConfig.riskPolicy
198
199
  ? betConfig.riskPolicy({
@@ -208,11 +209,23 @@ export function MakeOutcomeBetPlugin({ betConfigs }) {
208
209
  const riskLimits = riskLimitsResult.data;
209
210
  if (riskLimits.maxWager != null &&
210
211
  input.wager > riskLimits.maxWager) {
211
- throw new GraphQLError(`Wager exceeds limit (${riskLimits.maxWager}). Your wager: ${input.wager}`);
212
+ throw new GraphQLError(`Wager exceeds limit (${formatCurrency(riskLimits.maxWager, {
213
+ displayUnitName: dbCurrency.display_unit_name,
214
+ displayUnitScale: dbCurrency.display_unit_scale,
215
+ })}). Your wager: ${formatCurrency(input.wager, {
216
+ displayUnitName: dbCurrency.display_unit_name,
217
+ displayUnitScale: dbCurrency.display_unit_scale,
218
+ })}`);
212
219
  }
213
220
  if (riskLimits.maxPayout != null &&
214
221
  maxPayout > riskLimits.maxPayout) {
215
- throw new GraphQLError(`Payout exceeds limit (${riskLimits.maxPayout}). Your payout: ${maxPayout}`);
222
+ throw new GraphQLError(`Payout exceeds limit (${formatCurrency(riskLimits.maxPayout, {
223
+ displayUnitName: dbCurrency.display_unit_name,
224
+ displayUnitScale: dbCurrency.display_unit_scale,
225
+ })}). Your payout: ${formatCurrency(maxPayout, {
226
+ displayUnitName: dbCurrency.display_unit_name,
227
+ displayUnitScale: dbCurrency.display_unit_scale,
228
+ })}`);
216
229
  }
217
230
  const dbHashChain = await dbLockHubHashChain(pgClient, {
218
231
  userId: session.user_id,
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@moneypot/hub",
3
- "version": "1.9.0-dev.2",
3
+ "version": "1.9.0-dev.4",
4
4
  "author": "moneypot.com",
5
5
  "homepage": "https://moneypot.com/hub",
6
6
  "keywords": [