@riocrypto/common 1.0.2584 → 1.0.2587

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.
@@ -2,6 +2,7 @@ import { Country } from "../types/country";
2
2
  import { DeferredPaymentType } from "../types/deferred-payment-type";
3
3
  import { Fiat } from "../types/fiat";
4
4
  import { FXProvider } from "../types/fx-provider";
5
+ import { FXTradingPolicies } from "../types/fx-trading-policy";
5
6
  import { Processor } from "../types/processor";
6
7
  import { Side } from "../types/side";
7
8
  import { TVFXDataProvider } from "../types/TV-FX-data-provider";
@@ -24,12 +25,6 @@ export interface RioSettingsUpdatedEvent {
24
25
  frozen: boolean;
25
26
  };
26
27
  };
27
- buyOrderAutomaticFXTradeLimit?: {
28
- [key: string]: number;
29
- };
30
- sellOrderAutomaticFXTradeLimit?: {
31
- [key: string]: number;
32
- };
33
28
  buyOrderAfterHoursExchangeRateMarkup?: {
34
29
  [key: string]: number;
35
30
  };
@@ -54,7 +49,7 @@ export interface RioSettingsUpdatedEvent {
54
49
  };
55
50
  };
56
51
  };
57
- fxExecutionThreshold?: number;
52
+ fxTradingPolicies?: FXTradingPolicies;
58
53
  defaultServiceFee?: {
59
54
  [key in Country]?: {
60
55
  [key in Side]?: number;
@@ -0,0 +1,11 @@
1
+ import { Country } from "../types/country";
2
+ import { Fiat } from "../types/fiat";
3
+ /**
4
+ * Returns the primary country whose local timezone "owns" a given
5
+ * fiat. Used by the FX trading-policy resolver to evaluate time-of-day
6
+ * windows in the currency's natural local time.
7
+ *
8
+ * This is intentionally a 1:1 mapping; there's no concept of a fiat
9
+ * being shared across multiple jurisdictions in our system today.
10
+ */
11
+ export declare const getCountryForFiat: (fiat: Fiat) => Country;
@@ -0,0 +1,28 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.getCountryForFiat = void 0;
4
+ const country_1 = require("../types/country");
5
+ const fiat_1 = require("../types/fiat");
6
+ /**
7
+ * Returns the primary country whose local timezone "owns" a given
8
+ * fiat. Used by the FX trading-policy resolver to evaluate time-of-day
9
+ * windows in the currency's natural local time.
10
+ *
11
+ * This is intentionally a 1:1 mapping; there's no concept of a fiat
12
+ * being shared across multiple jurisdictions in our system today.
13
+ */
14
+ const getCountryForFiat = (fiat) => {
15
+ switch (fiat) {
16
+ case fiat_1.Fiat.MXN:
17
+ return country_1.Country.Mexico;
18
+ case fiat_1.Fiat.PEN:
19
+ return country_1.Country.Peru;
20
+ case fiat_1.Fiat.COP:
21
+ return country_1.Country.Colombia;
22
+ case fiat_1.Fiat.USD:
23
+ return country_1.Country.UnitedStates;
24
+ default:
25
+ throw new Error(`Unsupported fiat: ${fiat}`);
26
+ }
27
+ };
28
+ exports.getCountryForFiat = getCountryForFiat;
package/build/index.d.ts CHANGED
@@ -387,6 +387,7 @@ export * from "./types/arbitrage-asset";
387
387
  export * from "./types/arbitrage-frequency";
388
388
  export * from "./types/arbitrage-provider";
389
389
  export * from "./types/fx-provider";
390
+ export * from "./types/fx-trading-policy";
390
391
  export * from "./types/liquidity-automation-frequency";
391
392
  export * from "./types/liquidity-automation";
392
393
  export * from "./types/liquidity-automation-type";
@@ -538,6 +539,7 @@ export * from "./helpers/is-overnight-or-weekend-mexico-city";
538
539
  export * from "./helpers/get-user-payout-vault-id";
539
540
  export * from "./helpers/should-add-one-day-to-settlement-date";
540
541
  export * from "./helpers/get-country-timezone";
542
+ export * from "./helpers/get-country-for-fiat";
541
543
  export * from "./helpers/get-days-between-agreed-two-way-settlement-date-and-payment-date";
542
544
  export * from "./helpers/get-days-until-two-way-settlement-date";
543
545
  export * from "./helpers/get-two-way-settlement-date-offset-from-date";
package/build/index.js CHANGED
@@ -403,6 +403,7 @@ __exportStar(require("./types/arbitrage-asset"), exports);
403
403
  __exportStar(require("./types/arbitrage-frequency"), exports);
404
404
  __exportStar(require("./types/arbitrage-provider"), exports);
405
405
  __exportStar(require("./types/fx-provider"), exports);
406
+ __exportStar(require("./types/fx-trading-policy"), exports);
406
407
  __exportStar(require("./types/liquidity-automation-frequency"), exports);
407
408
  __exportStar(require("./types/liquidity-automation"), exports);
408
409
  __exportStar(require("./types/liquidity-automation-type"), exports);
@@ -554,6 +555,7 @@ __exportStar(require("./helpers/is-overnight-or-weekend-mexico-city"), exports);
554
555
  __exportStar(require("./helpers/get-user-payout-vault-id"), exports);
555
556
  __exportStar(require("./helpers/should-add-one-day-to-settlement-date"), exports);
556
557
  __exportStar(require("./helpers/get-country-timezone"), exports);
558
+ __exportStar(require("./helpers/get-country-for-fiat"), exports);
557
559
  __exportStar(require("./helpers/get-days-between-agreed-two-way-settlement-date-and-payment-date"), exports);
558
560
  __exportStar(require("./helpers/get-days-until-two-way-settlement-date"), exports);
559
561
  __exportStar(require("./helpers/get-two-way-settlement-date-offset-from-date"), exports);
@@ -0,0 +1,123 @@
1
+ import { Fiat } from "./fiat";
2
+ import { FXProvider } from "./fx-provider";
3
+ import { Side } from "./side";
4
+ /**
5
+ * One amount band within a (fiat, settlement offset, side) policy.
6
+ *
7
+ * The band is interpreted as `[minAmount, maxAmount)` in the policy's fiat.
8
+ * Both bounds are required and finite. Operators that want a "catch-all
9
+ * upper tail" set `maxAmount` to a value larger than any plausible single
10
+ * trade for that fiat (e.g. 1,000,000,000) rather than leaving it
11
+ * unbounded - this avoids accidentally routing arbitrary-size trades
12
+ * through automation just because no upper bound was specified.
13
+ *
14
+ * `automatic` is only meaningful for providers that support a cosigner
15
+ * approval workflow (Emarkets, Transnetwork, StoneX). For Matching / Other
16
+ * the runtime always treats this band as automatic regardless of the
17
+ * stored value.
18
+ */
19
+ export interface FXTradingPolicyAmountRange {
20
+ minAmount: number;
21
+ maxAmount: number;
22
+ provider: FXProvider;
23
+ automatic: boolean;
24
+ }
25
+ /**
26
+ * One time-of-day window within a (fiat, settlement offset, side) policy.
27
+ *
28
+ * Times are minutes from midnight in the currency's country-local
29
+ * timezone, interpreted as `[startMinute, endMinute)`. The full set of
30
+ * windows must be contiguous and cover `[0, 1440)` (midnight to
31
+ * midnight) so every moment of the day maps to exactly one window. A
32
+ * window that needs to span midnight (e.g. an "after-hours" 22:00-06:00
33
+ * gate) is split into two rows with identical inner configuration.
34
+ *
35
+ * `executionThresholdMs` is the milliseconds an FX trade can dwell in
36
+ * PendingExecutionThreshold before checkExecutionThreshold transitions
37
+ * it for placement. It is per-time-window so operators can specify
38
+ * a different aggregation behavior during the day vs at night.
39
+ * Re-evaluated against the current time at every step in the trade's
40
+ * lifecycle (initial creation, cron sweep). A trade created during a
41
+ * 30s-aggregation window may sit in PendingExecutionThreshold; when the
42
+ * window flips to 0ms the next cron tick dispatches the trade.
43
+ *
44
+ * `byAmountRange` is the amount-range table that applies while this
45
+ * time window is active. First range starts at 0, ranges are ordered
46
+ * and strictly contiguous, and every range (including the last) has an
47
+ * explicit, finite `maxAmount`. Trades whose amount falls above the
48
+ * last range's cap fall through to the safe Other/manual fallback.
49
+ */
50
+ export interface FXTradingPolicyTimeRange {
51
+ startMinute: number;
52
+ endMinute: number;
53
+ executionThresholdMs: number;
54
+ byAmountRange: FXTradingPolicyAmountRange[];
55
+ }
56
+ /**
57
+ * Per-(fiat, settlement offset, side) trading rules.
58
+ *
59
+ * `byTimeRange` is the ordered list of time windows that govern routing
60
+ * and aggregation across a 24-hour day in the currency's country-local
61
+ * timezone. The resolver picks the window containing "now" and then
62
+ * uses that window's `executionThresholdMs` and `byAmountRange`.
63
+ */
64
+ export interface FXTradingSidePolicy {
65
+ byTimeRange: FXTradingPolicyTimeRange[];
66
+ }
67
+ export interface FXTradingPolicyBySide {
68
+ [Side.Buy]?: FXTradingSidePolicy;
69
+ [Side.Sell]?: FXTradingSidePolicy;
70
+ }
71
+ /**
72
+ * `default` applies whenever `byOffset[offset]` is not set for the
73
+ * requested (fiat, side). `byOffset` keys are stored as strings in Mongo
74
+ * (object property names) but always represent non-negative integer
75
+ * `twoWaySettlementDateOffset` values.
76
+ *
77
+ * Override semantics are all-or-nothing per side: if `byOffset[3].buy` is
78
+ * defined it fully replaces `default.buy` for offset 3 buy trades; nothing
79
+ * is merged field-by-field. Offsets that have no override fall back to
80
+ * `default` regardless of how distant they are from any configured
81
+ * override.
82
+ */
83
+ export interface FXTradingPoliciesForFiat {
84
+ default: FXTradingPolicyBySide;
85
+ byOffset?: {
86
+ [offset: number]: FXTradingPolicyBySide;
87
+ };
88
+ }
89
+ export type FXTradingPolicies = {
90
+ [key in Fiat]?: FXTradingPoliciesForFiat;
91
+ };
92
+ /**
93
+ * Result of resolving a (policy, amount) pair: the provider that should
94
+ * handle the trade and whether placement is automatic. Callers that need
95
+ * to know how the trade should be staged (Trading vs PendingApproval vs
96
+ * Completed) derive that from `{ provider, automatic }`.
97
+ *
98
+ * The runtime resolver (`resolveFXProviderForAmount` in common-server)
99
+ * returns `ResolvedFXPlacement` which adds the time-window-matched
100
+ * `executionThresholdMs`. Callers that only need to map a placement to
101
+ * the next FX-trade status (e.g. cosigner-notification, alternative
102
+ * approval) build a synthetic `ResolvedFXProvider` because the
103
+ * threshold is irrelevant to that decision.
104
+ */
105
+ export interface ResolvedFXProvider {
106
+ provider: FXProvider;
107
+ automatic: boolean;
108
+ }
109
+ /**
110
+ * Full output of `resolveFXProviderForAmount`. Adds the time-window's
111
+ * `executionThresholdMs` so callers (cron sweep, order-created
112
+ * listener) can decide whether to put the trade in
113
+ * PendingExecutionThreshold for aggregation or dispatch immediately.
114
+ *
115
+ * The threshold reflects the *current* time-of-day window in the
116
+ * currency's country-local timezone. Callers that retain a trade in
117
+ * PendingExecutionThreshold across a window boundary must re-resolve
118
+ * the threshold at sweep time - the rules of the now-active window
119
+ * apply, not the rules at creation time.
120
+ */
121
+ export interface ResolvedFXPlacement extends ResolvedFXProvider {
122
+ executionThresholdMs: number;
123
+ }
@@ -0,0 +1,3 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ const side_1 = require("./side");
@@ -1,6 +1,7 @@
1
1
  import { Country } from "./country";
2
2
  import { Fiat } from "./fiat";
3
3
  import { FXProvider } from "./fx-provider";
4
+ import { FXTradingPolicies } from "./fx-trading-policy";
4
5
  import { Processor } from "./processor";
5
6
  import { Side } from "./side";
6
7
  import { TVFXDataProvider } from "./TV-FX-data-provider";
@@ -9,12 +10,6 @@ export interface RioSettingsUpdate {
9
10
  afterHoursExchangeRateMarkup?: {
10
11
  [key: string]: number;
11
12
  };
12
- buyOrderAutomaticFXTradeLimit?: {
13
- [key: string]: number;
14
- };
15
- sellOrderAutomaticFXTradeLimit?: {
16
- [key: string]: number;
17
- };
18
13
  buyOrderAfterHoursExchangeRateMarkup?: {
19
14
  [key: string]: number;
20
15
  };
@@ -41,7 +36,7 @@ export interface RioSettingsUpdate {
41
36
  enabled: boolean;
42
37
  };
43
38
  };
44
- fxExecutionThreshold?: number;
39
+ fxTradingPolicies?: FXTradingPolicies;
45
40
  defaultServiceFee?: {
46
41
  [key in Country]?: {
47
42
  [key in Side]?: number;
@@ -3,6 +3,7 @@ import { DeferredPaymentType } from "./deferred-payment-type";
3
3
  import { EmarketsSettlementType } from "./emarkets-settlement-type";
4
4
  import { Fiat } from "./fiat";
5
5
  import { FXProvider } from "./fx-provider";
6
+ import { FXTradingPolicies } from "./fx-trading-policy";
6
7
  import { Processor } from "./processor";
7
8
  import { TransnetworkSettlementType } from "./transnetwork-settlement-type";
8
9
  import { Side } from "./side";
@@ -23,12 +24,6 @@ export interface RioSettings {
23
24
  frozen: boolean;
24
25
  };
25
26
  };
26
- buyOrderAutomaticFXTradeLimit: {
27
- [key: string]: number;
28
- };
29
- sellOrderAutomaticFXTradeLimit: {
30
- [key: string]: number;
31
- };
32
27
  buyOrderAfterHoursExchangeRateMarkup: {
33
28
  [key: string]: number;
34
29
  };
@@ -53,7 +48,14 @@ export interface RioSettings {
53
48
  };
54
49
  };
55
50
  };
56
- fxExecutionThreshold: number;
51
+ /**
52
+ * Per-(fiat, settlement offset, side) FX trading policies. Each side
53
+ * policy carries its own executionThresholdMs and an ordered list of
54
+ * amount ranges that map onto a provider and an automatic-vs-cosigner
55
+ * flag. Resolution is offset-aware: byOffset wins if set, otherwise
56
+ * default applies. See FXTradingSidePolicy for override semantics.
57
+ */
58
+ fxTradingPolicies?: FXTradingPolicies;
57
59
  defaultServiceFee: {
58
60
  [key in Country]?: {
59
61
  [key in Side]?: number;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@riocrypto/common",
3
- "version": "1.0.2584",
3
+ "version": "1.0.2587",
4
4
  "description": "",
5
5
  "main": "./build/index.js",
6
6
  "types": "./build/index.d.ts",