@riocrypto/common-server 1.0.2765 → 1.0.2768
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/build/clients/axios-with-logging.js +2 -1
- package/build/clients/cluster-client.d.ts +49 -1
- package/build/clients/cluster-client.js +112 -0
- package/build/index.d.ts +2 -0
- package/build/index.js +2 -0
- package/build/models/external-trade.d.ts +26 -0
- package/build/models/external-trade.js +15 -0
- package/build/models/stonex-fx-trade.d.ts +78 -0
- package/build/models/stonex-fx-trade.js +148 -0
- package/build/models/stonex-log.d.ts +21 -0
- package/build/models/stonex-log.js +46 -0
- package/package.json +2 -2
|
@@ -86,7 +86,7 @@ function buildAxiosWithLogging() {
|
|
|
86
86
|
}
|
|
87
87
|
return response;
|
|
88
88
|
}, (error) => {
|
|
89
|
-
var _a, _b, _c;
|
|
89
|
+
var _a, _b, _c, _d;
|
|
90
90
|
// Combine and log the response error details without headers
|
|
91
91
|
let logMessage = `Response Error: url=${maskUrl((_a = error.config) === null || _a === void 0 ? void 0 : _a.url)}, message=${error.message}`;
|
|
92
92
|
if (error.response) {
|
|
@@ -96,6 +96,7 @@ function buildAxiosWithLogging() {
|
|
|
96
96
|
return Promise.reject({
|
|
97
97
|
message: logMessage,
|
|
98
98
|
status: (_c = error.response) === null || _c === void 0 ? void 0 : _c.status,
|
|
99
|
+
data: (_d = error.response) === null || _d === void 0 ? void 0 : _d.data,
|
|
99
100
|
});
|
|
100
101
|
});
|
|
101
102
|
return axiosWithLogging;
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { Quote, Fiat, Crypto, BitsoBankAccount, Side, Country, Order, CryptoAddress, BankAccount, AuthRole, Auth, ImportOrderData, TreasuryProvider, FXProvider, EmarketsFXTrade, ExternalTradingAlgorithm, ExternalTrade, ExternalTradeType, ExternalTradingProvider, ExternalTradingAlgorithmType, STPMXNWithdrawal, AuthPermission, DeferredPaymentType, TwoWaySettlementType, OrderType, EmarketsSettlementType, EmarketsOrderType, BulkBankPayout, BulkCryptoPayout, BulkBankPayment, BulkCryptoPayment, OrderStatus, TWAPSession, TransnetworkFXTrade, TransnetworkSettlementType, TransnetworkOrderType, AuthMethod } from "@riocrypto/common";
|
|
1
|
+
import { Quote, Fiat, Crypto, BitsoBankAccount, Side, Country, Order, CryptoAddress, BankAccount, AuthRole, Auth, ImportOrderData, TreasuryProvider, FXProvider, EmarketsFXTrade, ExternalTradingAlgorithm, ExternalTrade, ExternalTradeType, ExternalTradingProvider, ExternalTradingAlgorithmType, STPMXNWithdrawal, AuthPermission, DeferredPaymentType, TwoWaySettlementType, OrderType, EmarketsSettlementType, EmarketsOrderType, BulkBankPayout, BulkCryptoPayout, BulkBankPayment, BulkCryptoPayment, OrderStatus, TWAPSession, TransnetworkFXTrade, TransnetworkSettlementType, TransnetworkOrderType, AuthMethod, StonexFXTrade } from "@riocrypto/common";
|
|
2
2
|
import { STPMXNWithdrawalDoc } from "../models/STP-mxn-withdrawal";
|
|
3
3
|
declare class ClusterClient {
|
|
4
4
|
private baseUrl;
|
|
@@ -235,6 +235,54 @@ declare class ClusterClient {
|
|
|
235
235
|
minClipSize: number;
|
|
236
236
|
interval: number;
|
|
237
237
|
}>;
|
|
238
|
+
createStonexTrade(data: {
|
|
239
|
+
symbol: string;
|
|
240
|
+
side: string;
|
|
241
|
+
quantity: number;
|
|
242
|
+
valueDate?: string;
|
|
243
|
+
fiat?: string;
|
|
244
|
+
tradeKey: string;
|
|
245
|
+
}): Promise<StonexFXTrade>;
|
|
246
|
+
takeStonexQuote(tradeId: string, side: "buy" | "sell", tradeKey: string): Promise<StonexFXTrade>;
|
|
247
|
+
cancelStonexTrade(tradeId: string): Promise<StonexFXTrade>;
|
|
248
|
+
updateStonexOrder(tradeId: string, params: {
|
|
249
|
+
quantity?: number;
|
|
250
|
+
price?: number;
|
|
251
|
+
stopPx?: number;
|
|
252
|
+
timeInForce?: string;
|
|
253
|
+
tradeKey: string;
|
|
254
|
+
}): Promise<StonexFXTrade>;
|
|
255
|
+
placeStonexDirectOrder(params: {
|
|
256
|
+
symbol: string;
|
|
257
|
+
side: string;
|
|
258
|
+
quantity: number;
|
|
259
|
+
ordType: string;
|
|
260
|
+
timeInForce: string;
|
|
261
|
+
currency: string;
|
|
262
|
+
price?: number;
|
|
263
|
+
stopPx?: number;
|
|
264
|
+
valueDate?: string;
|
|
265
|
+
execInst?: string;
|
|
266
|
+
tradeKey: string;
|
|
267
|
+
}): Promise<StonexFXTrade>;
|
|
268
|
+
getStonexTrade(tradeId: string): Promise<StonexFXTrade>;
|
|
269
|
+
getStonexTradeByKey(tradeKey: string): Promise<StonexFXTrade | null>;
|
|
270
|
+
getStonexTrades(offset: number, limit: number): Promise<{
|
|
271
|
+
data: StonexFXTrade[];
|
|
272
|
+
hasMore: boolean;
|
|
273
|
+
}>;
|
|
274
|
+
getValueDates(country?: string): Promise<Record<string, string>>;
|
|
275
|
+
getStonexStatus(): Promise<{
|
|
276
|
+
order: string;
|
|
277
|
+
md: string;
|
|
278
|
+
spotRate: {
|
|
279
|
+
bid?: number;
|
|
280
|
+
offer?: number;
|
|
281
|
+
} | null;
|
|
282
|
+
}>;
|
|
283
|
+
sendStonexCommand(command: string): Promise<{
|
|
284
|
+
message: string;
|
|
285
|
+
}>;
|
|
238
286
|
}
|
|
239
287
|
export declare const buildClusterClient: () => Promise<ClusterClient>;
|
|
240
288
|
export {};
|
|
@@ -791,6 +791,118 @@ class ClusterClient {
|
|
|
791
791
|
return response.data;
|
|
792
792
|
});
|
|
793
793
|
}
|
|
794
|
+
// ─── StoneX FIX ───────────────────────────────────────────────────
|
|
795
|
+
createStonexTrade(data) {
|
|
796
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
797
|
+
const { tradeKey } = data;
|
|
798
|
+
const response = yield this.axios.post(`${this.baseUrl}/api/stonex/create-quote-stream`, data, {
|
|
799
|
+
headers: {
|
|
800
|
+
"x-cluster-api-key": this.clusterApiKey,
|
|
801
|
+
"X-Trade-Key": tradeKey,
|
|
802
|
+
},
|
|
803
|
+
});
|
|
804
|
+
return response.data;
|
|
805
|
+
});
|
|
806
|
+
}
|
|
807
|
+
takeStonexQuote(tradeId, side, tradeKey) {
|
|
808
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
809
|
+
const response = yield this.axios.post(`${this.baseUrl}/api/stonex/take-quote/${tradeId}`, { side, tradeKey }, {
|
|
810
|
+
headers: {
|
|
811
|
+
"x-cluster-api-key": this.clusterApiKey,
|
|
812
|
+
"X-Trade-Key": tradeKey,
|
|
813
|
+
},
|
|
814
|
+
});
|
|
815
|
+
return response.data;
|
|
816
|
+
});
|
|
817
|
+
}
|
|
818
|
+
cancelStonexTrade(tradeId) {
|
|
819
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
820
|
+
const response = yield this.axios.post(`${this.baseUrl}/api/stonex/cancel-trade/${tradeId}`, {}, { headers: { "x-cluster-api-key": this.clusterApiKey } });
|
|
821
|
+
return response.data;
|
|
822
|
+
});
|
|
823
|
+
}
|
|
824
|
+
updateStonexOrder(tradeId, params) {
|
|
825
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
826
|
+
const { tradeKey } = params;
|
|
827
|
+
const response = yield this.axios.post(`${this.baseUrl}/api/stonex/update-order/${tradeId}`, params, {
|
|
828
|
+
headers: {
|
|
829
|
+
"x-cluster-api-key": this.clusterApiKey,
|
|
830
|
+
"X-Trade-Key": tradeKey,
|
|
831
|
+
},
|
|
832
|
+
});
|
|
833
|
+
return response.data;
|
|
834
|
+
});
|
|
835
|
+
}
|
|
836
|
+
placeStonexDirectOrder(params) {
|
|
837
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
838
|
+
const { tradeKey } = params;
|
|
839
|
+
const response = yield this.axios.post(`${this.baseUrl}/api/stonex/place-order`, params, {
|
|
840
|
+
headers: {
|
|
841
|
+
"x-cluster-api-key": this.clusterApiKey,
|
|
842
|
+
"X-Trade-Key": tradeKey,
|
|
843
|
+
},
|
|
844
|
+
});
|
|
845
|
+
return response.data;
|
|
846
|
+
});
|
|
847
|
+
}
|
|
848
|
+
getStonexTrade(tradeId) {
|
|
849
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
850
|
+
const response = yield this.axios.get(`${this.baseUrl}/api/stonex/trades/${tradeId}`, { headers: { "x-cluster-api-key": this.clusterApiKey } });
|
|
851
|
+
return response.data;
|
|
852
|
+
});
|
|
853
|
+
}
|
|
854
|
+
// Reconcile helper: look up a Stonex trade by caller-supplied trade key.
|
|
855
|
+
// Returns null when the key has no matching trade (the server either
|
|
856
|
+
// never received the request or failed before persisting). External-trading
|
|
857
|
+
// calls this before stamping a local trade as Failed so a lost HTTP
|
|
858
|
+
// response does not desync the two systems.
|
|
859
|
+
getStonexTradeByKey(tradeKey) {
|
|
860
|
+
var _a;
|
|
861
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
862
|
+
try {
|
|
863
|
+
const response = yield this.axios.get(`${this.baseUrl}/api/stonex/trades/by-trade-key/${encodeURIComponent(tradeKey)}`, { headers: { "x-cluster-api-key": this.clusterApiKey } });
|
|
864
|
+
return response.data;
|
|
865
|
+
}
|
|
866
|
+
catch (err) {
|
|
867
|
+
if (typeof err === "object" &&
|
|
868
|
+
err !== null &&
|
|
869
|
+
"response" in err &&
|
|
870
|
+
((_a = err.response) === null || _a === void 0 ? void 0 : _a.status) === 404) {
|
|
871
|
+
return null;
|
|
872
|
+
}
|
|
873
|
+
throw err;
|
|
874
|
+
}
|
|
875
|
+
});
|
|
876
|
+
}
|
|
877
|
+
getStonexTrades(offset, limit) {
|
|
878
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
879
|
+
const response = yield this.axios.get(`${this.baseUrl}/api/stonex/trades?offset=${offset}&limit=${limit}`, { headers: { "x-cluster-api-key": this.clusterApiKey } });
|
|
880
|
+
return response.data;
|
|
881
|
+
});
|
|
882
|
+
}
|
|
883
|
+
getValueDates(country) {
|
|
884
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
885
|
+
const url = country
|
|
886
|
+
? `${this.baseUrl}/api/stonex/value-dates?country=${country}`
|
|
887
|
+
: `${this.baseUrl}/api/stonex/value-dates`;
|
|
888
|
+
const response = yield this.axios.get(url, {
|
|
889
|
+
headers: { "x-cluster-api-key": this.clusterApiKey },
|
|
890
|
+
});
|
|
891
|
+
return response.data;
|
|
892
|
+
});
|
|
893
|
+
}
|
|
894
|
+
getStonexStatus() {
|
|
895
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
896
|
+
const response = yield this.axios.get(`${this.baseUrl}/api/stonex/status`, { headers: { "x-cluster-api-key": this.clusterApiKey } });
|
|
897
|
+
return response.data;
|
|
898
|
+
});
|
|
899
|
+
}
|
|
900
|
+
sendStonexCommand(command) {
|
|
901
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
902
|
+
const response = yield this.axios.post(`${this.baseUrl}/api/stonex/command`, { command }, { headers: { "x-cluster-api-key": this.clusterApiKey } });
|
|
903
|
+
return response.data;
|
|
904
|
+
});
|
|
905
|
+
}
|
|
794
906
|
}
|
|
795
907
|
const buildClusterClient = () => __awaiter(void 0, void 0, void 0, function* () {
|
|
796
908
|
// Retrieve secrets asynchronously
|
package/build/index.d.ts
CHANGED
|
@@ -102,6 +102,8 @@ export * from "./models/bulk-bank-payout";
|
|
|
102
102
|
export * from "./models/bulk-crypto-payout";
|
|
103
103
|
export * from "./models/twap-settlement";
|
|
104
104
|
export * from "./models/transnetwork-fx-trade";
|
|
105
|
+
export * from "./models/stonex-fx-trade";
|
|
106
|
+
export * from "./models/stonex-log";
|
|
105
107
|
export * from "./models/inbound-bank-deposit";
|
|
106
108
|
export * from "./models/inbound-crypto-deposit";
|
|
107
109
|
export * from "./models/order-log";
|
package/build/index.js
CHANGED
|
@@ -118,6 +118,8 @@ __exportStar(require("./models/bulk-bank-payout"), exports);
|
|
|
118
118
|
__exportStar(require("./models/bulk-crypto-payout"), exports);
|
|
119
119
|
__exportStar(require("./models/twap-settlement"), exports);
|
|
120
120
|
__exportStar(require("./models/transnetwork-fx-trade"), exports);
|
|
121
|
+
__exportStar(require("./models/stonex-fx-trade"), exports);
|
|
122
|
+
__exportStar(require("./models/stonex-log"), exports);
|
|
121
123
|
__exportStar(require("./models/inbound-bank-deposit"), exports);
|
|
122
124
|
__exportStar(require("./models/inbound-crypto-deposit"), exports);
|
|
123
125
|
__exportStar(require("./models/order-log"), exports);
|
|
@@ -3,6 +3,7 @@ import { Mongoose, Model, Document, HydratedDocument } from "mongoose";
|
|
|
3
3
|
interface ExternalTradeAttrs {
|
|
4
4
|
createdAt: Date;
|
|
5
5
|
providerOrderId?: string;
|
|
6
|
+
tradeKey?: string;
|
|
6
7
|
type: ExternalTradeType;
|
|
7
8
|
side: Side;
|
|
8
9
|
provider: ExternalTradingProvider;
|
|
@@ -21,6 +22,18 @@ interface ExternalTradeAttrs {
|
|
|
21
22
|
emarkets?: {
|
|
22
23
|
settlementType?: EmarketsSettlementType;
|
|
23
24
|
};
|
|
25
|
+
stonex?: {
|
|
26
|
+
valueDate?: Date;
|
|
27
|
+
quoteReqId?: string;
|
|
28
|
+
bidPx?: number;
|
|
29
|
+
offerPx?: number;
|
|
30
|
+
clOrdId?: string;
|
|
31
|
+
text?: string;
|
|
32
|
+
ordType?: string;
|
|
33
|
+
amountReceived?: number;
|
|
34
|
+
stopPx?: number;
|
|
35
|
+
takeQuoteTradeKey?: string;
|
|
36
|
+
};
|
|
24
37
|
};
|
|
25
38
|
externalTradingAlgorithmId?: string;
|
|
26
39
|
arbitrageSessionId?: string;
|
|
@@ -29,6 +42,7 @@ interface ExternalTradeAttrs {
|
|
|
29
42
|
interface ExternalTradeDoc extends Document {
|
|
30
43
|
createdAt: Date;
|
|
31
44
|
providerOrderId?: string;
|
|
45
|
+
tradeKey?: string;
|
|
32
46
|
type: ExternalTradeType;
|
|
33
47
|
side: Side;
|
|
34
48
|
amountType: ExternalTradeAmountType;
|
|
@@ -48,6 +62,18 @@ interface ExternalTradeDoc extends Document {
|
|
|
48
62
|
emarkets?: {
|
|
49
63
|
settlementType?: EmarketsSettlementType;
|
|
50
64
|
};
|
|
65
|
+
stonex?: {
|
|
66
|
+
valueDate?: Date;
|
|
67
|
+
quoteReqId?: string;
|
|
68
|
+
bidPx?: number;
|
|
69
|
+
offerPx?: number;
|
|
70
|
+
clOrdId?: string;
|
|
71
|
+
text?: string;
|
|
72
|
+
ordType?: string;
|
|
73
|
+
amountReceived?: number;
|
|
74
|
+
stopPx?: number;
|
|
75
|
+
takeQuoteTradeKey?: string;
|
|
76
|
+
};
|
|
51
77
|
};
|
|
52
78
|
externalTradingAlgorithmId?: string;
|
|
53
79
|
arbitrageSessionId?: string;
|
|
@@ -14,6 +14,9 @@ const buildExternalTrade = (mongoose) => {
|
|
|
14
14
|
providerOrderId: {
|
|
15
15
|
type: String,
|
|
16
16
|
},
|
|
17
|
+
tradeKey: {
|
|
18
|
+
type: String,
|
|
19
|
+
},
|
|
17
20
|
requestedAmountType: {
|
|
18
21
|
type: String,
|
|
19
22
|
required: true,
|
|
@@ -87,6 +90,18 @@ const buildExternalTrade = (mongoose) => {
|
|
|
87
90
|
},
|
|
88
91
|
},
|
|
89
92
|
});
|
|
93
|
+
// Partial unique compound index: guarantees at most one ExternalTrade per
|
|
94
|
+
// (provider, tradeKey) pair. Legacy rows without tradeKey are
|
|
95
|
+
// excluded by the partial filter, so no backfill is required.
|
|
96
|
+
ExternalTradeSchema.index({ provider: 1, tradeKey: 1 }, {
|
|
97
|
+
unique: true,
|
|
98
|
+
partialFilterExpression: { tradeKey: { $type: "string" } },
|
|
99
|
+
});
|
|
100
|
+
// Defense-in-depth: at most one ExternalTrade per (provider, providerOrderId).
|
|
101
|
+
ExternalTradeSchema.index({ provider: 1, providerOrderId: 1 }, {
|
|
102
|
+
unique: true,
|
|
103
|
+
partialFilterExpression: { providerOrderId: { $type: "string" } },
|
|
104
|
+
});
|
|
90
105
|
ExternalTradeSchema.statics.build = (attrs) => {
|
|
91
106
|
return new ExternalTrade(attrs);
|
|
92
107
|
};
|
|
@@ -0,0 +1,78 @@
|
|
|
1
|
+
import { Fiat, Side, StonexFXTradeStatus, StonexSettlementType } from "@riocrypto/common";
|
|
2
|
+
import { Mongoose, Model, Document } from "mongoose";
|
|
3
|
+
interface StonexFXTradeAttrs {
|
|
4
|
+
createdAt: Date;
|
|
5
|
+
status: StonexFXTradeStatus;
|
|
6
|
+
side: Side;
|
|
7
|
+
fiat: Fiat;
|
|
8
|
+
symbol: string;
|
|
9
|
+
amountToTrade: number;
|
|
10
|
+
amountReceived?: number;
|
|
11
|
+
actualPrice?: number;
|
|
12
|
+
limitPrice?: number;
|
|
13
|
+
settlementType?: StonexSettlementType;
|
|
14
|
+
valueDate?: string;
|
|
15
|
+
clOrdId?: string;
|
|
16
|
+
quoteReqId?: string;
|
|
17
|
+
quoteId?: string;
|
|
18
|
+
bidPx?: number;
|
|
19
|
+
offerPx?: number;
|
|
20
|
+
validUntilTime?: string;
|
|
21
|
+
exchangeOrderId?: string;
|
|
22
|
+
execId?: string;
|
|
23
|
+
text?: string;
|
|
24
|
+
ordType?: string;
|
|
25
|
+
timeInForce?: string;
|
|
26
|
+
stopPx?: number;
|
|
27
|
+
execInst?: string;
|
|
28
|
+
minQty?: number;
|
|
29
|
+
maxShow?: number;
|
|
30
|
+
expireTime?: string;
|
|
31
|
+
leavesQty?: number;
|
|
32
|
+
avgPx?: number;
|
|
33
|
+
tradeKey?: string;
|
|
34
|
+
takeQuoteTradeKey?: string;
|
|
35
|
+
fixSubmitted?: boolean;
|
|
36
|
+
submitAttempts?: number;
|
|
37
|
+
}
|
|
38
|
+
interface StonexFXTradeDoc extends Document {
|
|
39
|
+
id: string;
|
|
40
|
+
createdAt: Date;
|
|
41
|
+
status: StonexFXTradeStatus;
|
|
42
|
+
side: Side;
|
|
43
|
+
fiat: Fiat;
|
|
44
|
+
symbol: string;
|
|
45
|
+
amountToTrade: number;
|
|
46
|
+
amountReceived?: number;
|
|
47
|
+
actualPrice?: number;
|
|
48
|
+
limitPrice?: number;
|
|
49
|
+
settlementType?: StonexSettlementType;
|
|
50
|
+
valueDate?: string;
|
|
51
|
+
clOrdId?: string;
|
|
52
|
+
quoteReqId?: string;
|
|
53
|
+
quoteId?: string;
|
|
54
|
+
bidPx?: number;
|
|
55
|
+
offerPx?: number;
|
|
56
|
+
validUntilTime?: string;
|
|
57
|
+
exchangeOrderId?: string;
|
|
58
|
+
execId?: string;
|
|
59
|
+
text?: string;
|
|
60
|
+
ordType?: string;
|
|
61
|
+
timeInForce?: string;
|
|
62
|
+
stopPx?: number;
|
|
63
|
+
execInst?: string;
|
|
64
|
+
minQty?: number;
|
|
65
|
+
maxShow?: number;
|
|
66
|
+
expireTime?: string;
|
|
67
|
+
leavesQty?: number;
|
|
68
|
+
avgPx?: number;
|
|
69
|
+
tradeKey?: string;
|
|
70
|
+
takeQuoteTradeKey?: string;
|
|
71
|
+
fixSubmitted?: boolean;
|
|
72
|
+
submitAttempts?: number;
|
|
73
|
+
}
|
|
74
|
+
interface StonexFXTradeModel extends Model<StonexFXTradeDoc> {
|
|
75
|
+
build(attrs: StonexFXTradeAttrs): StonexFXTradeDoc;
|
|
76
|
+
}
|
|
77
|
+
declare const buildStonexFXTrade: (mongoose: Mongoose) => StonexFXTradeModel;
|
|
78
|
+
export { buildStonexFXTrade, StonexFXTradeDoc, StonexFXTradeAttrs };
|
|
@@ -0,0 +1,148 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.buildStonexFXTrade = void 0;
|
|
4
|
+
const buildStonexFXTrade = (mongoose) => {
|
|
5
|
+
if (mongoose.models.StonexFXTrade) {
|
|
6
|
+
return mongoose.model("StonexFXTrade");
|
|
7
|
+
}
|
|
8
|
+
const StonexFXTradeSchema = new mongoose.Schema({
|
|
9
|
+
createdAt: {
|
|
10
|
+
type: Date,
|
|
11
|
+
required: true,
|
|
12
|
+
},
|
|
13
|
+
status: {
|
|
14
|
+
type: String,
|
|
15
|
+
required: true,
|
|
16
|
+
},
|
|
17
|
+
side: {
|
|
18
|
+
type: String,
|
|
19
|
+
required: true,
|
|
20
|
+
},
|
|
21
|
+
fiat: {
|
|
22
|
+
type: String,
|
|
23
|
+
required: true,
|
|
24
|
+
},
|
|
25
|
+
symbol: {
|
|
26
|
+
type: String,
|
|
27
|
+
required: true,
|
|
28
|
+
},
|
|
29
|
+
amountToTrade: {
|
|
30
|
+
type: Number,
|
|
31
|
+
required: true,
|
|
32
|
+
},
|
|
33
|
+
amountReceived: {
|
|
34
|
+
type: Number,
|
|
35
|
+
},
|
|
36
|
+
actualPrice: {
|
|
37
|
+
type: Number,
|
|
38
|
+
},
|
|
39
|
+
limitPrice: {
|
|
40
|
+
type: Number,
|
|
41
|
+
},
|
|
42
|
+
settlementType: {
|
|
43
|
+
type: String,
|
|
44
|
+
},
|
|
45
|
+
valueDate: {
|
|
46
|
+
type: String,
|
|
47
|
+
},
|
|
48
|
+
clOrdId: {
|
|
49
|
+
type: String,
|
|
50
|
+
},
|
|
51
|
+
quoteReqId: {
|
|
52
|
+
type: String,
|
|
53
|
+
},
|
|
54
|
+
quoteId: {
|
|
55
|
+
type: String,
|
|
56
|
+
},
|
|
57
|
+
bidPx: {
|
|
58
|
+
type: Number,
|
|
59
|
+
},
|
|
60
|
+
offerPx: {
|
|
61
|
+
type: Number,
|
|
62
|
+
},
|
|
63
|
+
validUntilTime: {
|
|
64
|
+
type: String,
|
|
65
|
+
},
|
|
66
|
+
exchangeOrderId: {
|
|
67
|
+
type: String,
|
|
68
|
+
},
|
|
69
|
+
execId: {
|
|
70
|
+
type: String,
|
|
71
|
+
},
|
|
72
|
+
text: {
|
|
73
|
+
type: String,
|
|
74
|
+
},
|
|
75
|
+
ordType: {
|
|
76
|
+
type: String,
|
|
77
|
+
},
|
|
78
|
+
timeInForce: {
|
|
79
|
+
type: String,
|
|
80
|
+
},
|
|
81
|
+
stopPx: {
|
|
82
|
+
type: Number,
|
|
83
|
+
},
|
|
84
|
+
execInst: {
|
|
85
|
+
type: String,
|
|
86
|
+
},
|
|
87
|
+
minQty: {
|
|
88
|
+
type: Number,
|
|
89
|
+
},
|
|
90
|
+
maxShow: {
|
|
91
|
+
type: Number,
|
|
92
|
+
},
|
|
93
|
+
expireTime: {
|
|
94
|
+
type: String,
|
|
95
|
+
},
|
|
96
|
+
leavesQty: {
|
|
97
|
+
type: Number,
|
|
98
|
+
},
|
|
99
|
+
avgPx: {
|
|
100
|
+
type: Number,
|
|
101
|
+
},
|
|
102
|
+
tradeKey: {
|
|
103
|
+
type: String,
|
|
104
|
+
},
|
|
105
|
+
takeQuoteTradeKey: {
|
|
106
|
+
type: String,
|
|
107
|
+
},
|
|
108
|
+
fixSubmitted: {
|
|
109
|
+
type: Boolean,
|
|
110
|
+
default: false,
|
|
111
|
+
},
|
|
112
|
+
submitAttempts: {
|
|
113
|
+
type: Number,
|
|
114
|
+
default: 0,
|
|
115
|
+
},
|
|
116
|
+
metadata: {
|
|
117
|
+
type: Map,
|
|
118
|
+
of: mongoose.Schema.Types.Mixed,
|
|
119
|
+
},
|
|
120
|
+
}, {
|
|
121
|
+
toJSON: {
|
|
122
|
+
transform(doc, ret) {
|
|
123
|
+
ret.id = ret._id.valueOf();
|
|
124
|
+
delete ret._id;
|
|
125
|
+
delete ret.__v;
|
|
126
|
+
},
|
|
127
|
+
},
|
|
128
|
+
});
|
|
129
|
+
// Partial unique index: only docs with a string tradeKey are indexed,
|
|
130
|
+
// so existing docs (no field) don't collide. Guarantees at most one StonexFXTrade
|
|
131
|
+
// per caller-supplied trade key.
|
|
132
|
+
StonexFXTradeSchema.index({ tradeKey: 1 }, {
|
|
133
|
+
unique: true,
|
|
134
|
+
partialFilterExpression: { tradeKey: { $type: "string" } },
|
|
135
|
+
});
|
|
136
|
+
StonexFXTradeSchema.index({ takeQuoteTradeKey: 1 }, {
|
|
137
|
+
unique: true,
|
|
138
|
+
partialFilterExpression: {
|
|
139
|
+
takeQuoteTradeKey: { $type: "string" },
|
|
140
|
+
},
|
|
141
|
+
});
|
|
142
|
+
StonexFXTradeSchema.statics.build = (attrs) => {
|
|
143
|
+
return new StonexFXTrade(attrs);
|
|
144
|
+
};
|
|
145
|
+
const StonexFXTrade = mongoose.model("StonexFXTrade", StonexFXTradeSchema);
|
|
146
|
+
return StonexFXTrade;
|
|
147
|
+
};
|
|
148
|
+
exports.buildStonexFXTrade = buildStonexFXTrade;
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
import { Mongoose, Model, Document } from "mongoose";
|
|
2
|
+
interface StonexLogAttrs {
|
|
3
|
+
timestamp: Date;
|
|
4
|
+
direction: "inbound" | "outbound";
|
|
5
|
+
session: "order" | "quote";
|
|
6
|
+
msgType: string;
|
|
7
|
+
data: string;
|
|
8
|
+
}
|
|
9
|
+
interface StonexLogDoc extends Document {
|
|
10
|
+
id: string;
|
|
11
|
+
timestamp: Date;
|
|
12
|
+
direction: "inbound" | "outbound";
|
|
13
|
+
session: "order" | "quote";
|
|
14
|
+
msgType: string;
|
|
15
|
+
data: string;
|
|
16
|
+
}
|
|
17
|
+
interface StonexLogModel extends Model<StonexLogDoc> {
|
|
18
|
+
build(attrs: StonexLogAttrs): StonexLogDoc;
|
|
19
|
+
}
|
|
20
|
+
declare const buildStonexLog: (mongoose: Mongoose) => StonexLogModel;
|
|
21
|
+
export { buildStonexLog, StonexLogDoc, StonexLogAttrs };
|
|
@@ -0,0 +1,46 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.buildStonexLog = void 0;
|
|
4
|
+
const buildStonexLog = (mongoose) => {
|
|
5
|
+
if (mongoose.models.StonexLog) {
|
|
6
|
+
return mongoose.model("StonexLog");
|
|
7
|
+
}
|
|
8
|
+
const StonexLogSchema = new mongoose.Schema({
|
|
9
|
+
timestamp: {
|
|
10
|
+
type: Date,
|
|
11
|
+
required: true,
|
|
12
|
+
},
|
|
13
|
+
direction: {
|
|
14
|
+
type: String,
|
|
15
|
+
required: true,
|
|
16
|
+
enum: ["inbound", "outbound"],
|
|
17
|
+
},
|
|
18
|
+
session: {
|
|
19
|
+
type: String,
|
|
20
|
+
required: true,
|
|
21
|
+
enum: ["order", "quote"],
|
|
22
|
+
},
|
|
23
|
+
msgType: {
|
|
24
|
+
type: String,
|
|
25
|
+
required: true,
|
|
26
|
+
},
|
|
27
|
+
data: {
|
|
28
|
+
type: String,
|
|
29
|
+
required: true,
|
|
30
|
+
},
|
|
31
|
+
}, {
|
|
32
|
+
toJSON: {
|
|
33
|
+
transform(doc, ret) {
|
|
34
|
+
ret.id = ret._id.valueOf();
|
|
35
|
+
delete ret._id;
|
|
36
|
+
delete ret.__v;
|
|
37
|
+
},
|
|
38
|
+
},
|
|
39
|
+
});
|
|
40
|
+
StonexLogSchema.statics.build = (attrs) => {
|
|
41
|
+
return new StonexLog(attrs);
|
|
42
|
+
};
|
|
43
|
+
const StonexLog = mongoose.model("StonexLog", StonexLogSchema);
|
|
44
|
+
return StonexLog;
|
|
45
|
+
};
|
|
46
|
+
exports.buildStonexLog = buildStonexLog;
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@riocrypto/common-server",
|
|
3
|
-
"version": "1.0.
|
|
3
|
+
"version": "1.0.2768",
|
|
4
4
|
"description": "",
|
|
5
5
|
"main": "./build/index.js",
|
|
6
6
|
"types": "./build/index.d.ts",
|
|
@@ -24,7 +24,7 @@
|
|
|
24
24
|
"@google-cloud/secret-manager": "^5.6.0",
|
|
25
25
|
"@google-cloud/storage": "^7.19.0",
|
|
26
26
|
"@hyperdx/node-opentelemetry": "^0.10.3",
|
|
27
|
-
"@riocrypto/common": "1.0.
|
|
27
|
+
"@riocrypto/common": "1.0.2565",
|
|
28
28
|
"@slack/web-api": "^7.15.0",
|
|
29
29
|
"@types/express": "^4.17.25",
|
|
30
30
|
"axios": "1.13.6",
|