@usherlabs/cex-broker 0.2.9 → 0.2.11
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/dist/commands/cli.js +231 -293
- package/dist/helpers/constants.d.ts +30 -0
- package/dist/helpers/index.d.ts +7 -17
- package/dist/index.js +232 -294
- package/dist/index.js.map +7 -10
- package/dist/proto/node.descriptor.ts +2 -1
- package/dist/proto/node.proto +1 -0
- package/dist/schemas/action-payloads.d.ts +6 -3
- package/package.json +1 -1
- package/dist/proto/cex_broker/Action.d.ts +0 -17
- package/dist/proto/cex_broker/ActionRequest.d.ts +0 -17
- package/dist/proto/cex_broker/ActionResponse.d.ts +0 -8
- package/dist/proto/cex_broker/SubscribeRequest.d.ts +0 -17
- package/dist/proto/cex_broker/SubscribeResponse.d.ts +0 -14
- package/dist/proto/cex_broker/SubscriptionType.d.ts +0 -11
- package/dist/proto/cex_broker/cex_service.d.ts +0 -28
- package/dist/proto/node.d.ts +0 -20
- package/dist/proto/node.descriptor.d.ts +0 -124
package/dist/commands/cli.js
CHANGED
|
@@ -310995,6 +310995,45 @@ var CCXT_METHODS_WITH_VERITY = [
|
|
|
310995
310995
|
"fetchWithdrawal",
|
|
310996
310996
|
"fetchAccountId"
|
|
310997
310997
|
];
|
|
310998
|
+
var Action = {
|
|
310999
|
+
NoAction: 0,
|
|
311000
|
+
Deposit: 1,
|
|
311001
|
+
Withdraw: 2,
|
|
311002
|
+
CreateOrder: 3,
|
|
311003
|
+
GetOrderDetails: 4,
|
|
311004
|
+
CancelOrder: 5,
|
|
311005
|
+
FetchBalances: 6,
|
|
311006
|
+
FetchDepositAddresses: 7,
|
|
311007
|
+
FetchTicker: 8,
|
|
311008
|
+
FetchCurrency: 9,
|
|
311009
|
+
Call: 10,
|
|
311010
|
+
FetchAccountId: 11,
|
|
311011
|
+
FetchFees: 12,
|
|
311012
|
+
InternalTransfer: 13
|
|
311013
|
+
};
|
|
311014
|
+
var SubscriptionType = {
|
|
311015
|
+
NO_ACTION: 0,
|
|
311016
|
+
ORDERBOOK: 1,
|
|
311017
|
+
TRADES: 2,
|
|
311018
|
+
TICKER: 3,
|
|
311019
|
+
OHLCV: 4,
|
|
311020
|
+
BALANCE: 5,
|
|
311021
|
+
ORDERS: 6
|
|
311022
|
+
};
|
|
311023
|
+
function createEnumNameMap(enumValues) {
|
|
311024
|
+
return Object.fromEntries(Object.entries(enumValues).map(([name, value]) => [value, name]));
|
|
311025
|
+
}
|
|
311026
|
+
var actionNames = createEnumNameMap(Action);
|
|
311027
|
+
var subscriptionTypeNames = createEnumNameMap(SubscriptionType);
|
|
311028
|
+
function getActionName(action) {
|
|
311029
|
+
return typeof action === "number" ? actionNames[action] ?? `unknown_${action}` : `unknown_${action ?? "undefined"}`;
|
|
311030
|
+
}
|
|
311031
|
+
function getSubscriptionTypeName(subscriptionType) {
|
|
311032
|
+
return subscriptionTypeNames[subscriptionType] ?? `unknown_${subscriptionType}`;
|
|
311033
|
+
}
|
|
311034
|
+
function resolveSubscriptionType(type2) {
|
|
311035
|
+
return type2 === undefined || type2 === SubscriptionType.NO_ACTION ? SubscriptionType.ORDERBOOK : type2;
|
|
311036
|
+
}
|
|
310998
311037
|
|
|
310999
311038
|
// node_modules/@loglayer/plugin-opentelemetry/dist/index.mjs
|
|
311000
311039
|
var import_api = __toESM(require_src5(), 1);
|
|
@@ -313495,16 +313534,18 @@ if (process.env.LOG_LEVEL !== "debug") {
|
|
|
313495
313534
|
var log = baseLogger;
|
|
313496
313535
|
|
|
313497
313536
|
// src/helpers/index.ts
|
|
313498
|
-
class
|
|
313499
|
-
|
|
313500
|
-
|
|
313501
|
-
|
|
313502
|
-
}
|
|
313503
|
-
function isMasterBrokerAccount(account) {
|
|
313504
|
-
return account.label === "primary" || account.role === "master";
|
|
313537
|
+
class BrokerAccountPreconditionError extends Error {
|
|
313538
|
+
constructor(message) {
|
|
313539
|
+
super(message);
|
|
313540
|
+
this.name = "BrokerAccountPreconditionError";
|
|
313541
|
+
}
|
|
313505
313542
|
}
|
|
313506
|
-
function
|
|
313507
|
-
|
|
313543
|
+
function requireDestinationEmail(dest, transferType) {
|
|
313544
|
+
const email = dest.email?.trim();
|
|
313545
|
+
if (!email) {
|
|
313546
|
+
throw new BrokerAccountPreconditionError(`Destination account '${dest.label}' requires an email configured for ${transferType} transfers`);
|
|
313547
|
+
}
|
|
313548
|
+
return email;
|
|
313508
313549
|
}
|
|
313509
313550
|
function authenticateRequest(call, whitelistIps) {
|
|
313510
313551
|
const clientIp = call.getPeer().split(":")[0];
|
|
@@ -313826,81 +313867,50 @@ function validateWithdraw(policy, exchange, network, recipientAddress, _amount,
|
|
|
313826
313867
|
}
|
|
313827
313868
|
return { valid: true };
|
|
313828
313869
|
}
|
|
313829
|
-
function
|
|
313830
|
-
const raw = selector2?.trim().toLowerCase() ?? defaultSelector;
|
|
313831
|
-
if (raw === "current") {
|
|
313832
|
-
return getCurrentBrokerSelector(metadata);
|
|
313833
|
-
}
|
|
313834
|
-
if (raw === "primary") {
|
|
313835
|
-
return "primary";
|
|
313836
|
-
}
|
|
313837
|
-
const secondaryMatch = raw.match(/^secondary:(\d+)$/);
|
|
313838
|
-
if (secondaryMatch) {
|
|
313839
|
-
return `secondary:${secondaryMatch[1]}`;
|
|
313840
|
-
}
|
|
313841
|
-
throw new WithdrawRoutingError(`Invalid account selector "${selector2}"`);
|
|
313842
|
-
}
|
|
313843
|
-
async function transferBinanceSubAccountToMaster(source, code, amount) {
|
|
313870
|
+
async function transferBinanceInternal(source, dest, code, amount) {
|
|
313844
313871
|
const exchange = source.exchange;
|
|
313845
|
-
if (typeof exchange.sapiPostSubAccountTransferSubToMaster !== "function") {
|
|
313846
|
-
throw new WithdrawRoutingUnavailableError("Binance sub-account to master transfer is unavailable in this CCXT build");
|
|
313847
|
-
}
|
|
313848
313872
|
await source.exchange.loadMarkets();
|
|
313849
313873
|
const currency = source.exchange.currency(code);
|
|
313850
|
-
|
|
313851
|
-
|
|
313852
|
-
|
|
313853
|
-
|
|
313854
|
-
|
|
313855
|
-
|
|
313856
|
-
|
|
313857
|
-
|
|
313858
|
-
|
|
313859
|
-
|
|
313860
|
-
|
|
313861
|
-
|
|
313862
|
-
|
|
313863
|
-
|
|
313864
|
-
network,
|
|
313865
|
-
params,
|
|
313866
|
-
routeViaMaster,
|
|
313867
|
-
sourceAccount,
|
|
313868
|
-
masterAccount
|
|
313869
|
-
} = args;
|
|
313870
|
-
const withdrawParams = {
|
|
313871
|
-
...params ?? {},
|
|
313872
|
-
network
|
|
313873
|
-
};
|
|
313874
|
-
if (!routeViaMaster) {
|
|
313875
|
-
return await selectedBroker.withdraw(code, amount, recipientAddress, undefined, withdrawParams);
|
|
313876
|
-
}
|
|
313877
|
-
const sourceSelector = normalizeAccountSelector(sourceAccount, metadata, "current");
|
|
313878
|
-
const masterSelector = normalizeAccountSelector(masterAccount, metadata, "primary");
|
|
313879
|
-
if (!brokers) {
|
|
313880
|
-
throw new WithdrawRoutingUnavailableError("Routed withdraw requires configured broker accounts");
|
|
313881
|
-
}
|
|
313882
|
-
const source = resolveBrokerAccount(brokers, sourceSelector);
|
|
313883
|
-
if (!source) {
|
|
313884
|
-
throw new WithdrawRoutingError(`Source account ${sourceSelector} is not configured`);
|
|
313885
|
-
}
|
|
313886
|
-
const master = resolveBrokerAccount(brokers, masterSelector);
|
|
313887
|
-
if (!master) {
|
|
313888
|
-
throw new WithdrawRoutingError(`Master account ${masterSelector} is not configured`);
|
|
313889
|
-
}
|
|
313890
|
-
if (!isMasterBrokerAccount(master)) {
|
|
313891
|
-
throw new WithdrawRoutingError(`Master account ${masterSelector} must resolve to the primary/master account`);
|
|
313892
|
-
}
|
|
313893
|
-
if (source.label === master.label) {
|
|
313894
|
-
return await master.exchange.withdraw(code, amount, recipientAddress, undefined, withdrawParams);
|
|
313874
|
+
const asset = currency.id;
|
|
313875
|
+
const amountStr = source.exchange.currencyToPrecision(code, amount);
|
|
313876
|
+
const isSourceSecondary = source.label.startsWith("secondary:");
|
|
313877
|
+
const isDestPrimary = dest.label === "primary";
|
|
313878
|
+
const isDestSecondary = dest.label.startsWith("secondary:");
|
|
313879
|
+
const isSourcePrimary = source.label === "primary";
|
|
313880
|
+
if (isSourceSecondary && isDestPrimary) {
|
|
313881
|
+
if (typeof exchange.sapiPostSubAccountTransferSubToMaster !== "function") {
|
|
313882
|
+
throw new Error("Binance sub→master transfer is unavailable in this CCXT build");
|
|
313883
|
+
}
|
|
313884
|
+
return await exchange.sapiPostSubAccountTransferSubToMaster({
|
|
313885
|
+
asset,
|
|
313886
|
+
amount: amountStr
|
|
313887
|
+
});
|
|
313895
313888
|
}
|
|
313896
|
-
if (
|
|
313897
|
-
|
|
313889
|
+
if (isSourceSecondary && isDestSecondary) {
|
|
313890
|
+
if (typeof exchange.sapiPostSubAccountTransferSubToSub !== "function") {
|
|
313891
|
+
throw new Error("Binance sub→sub transfer is unavailable in this CCXT build");
|
|
313892
|
+
}
|
|
313893
|
+
const destEmail = requireDestinationEmail(dest, "sub-to-sub");
|
|
313894
|
+
return await exchange.sapiPostSubAccountTransferSubToSub({
|
|
313895
|
+
toEmail: destEmail,
|
|
313896
|
+
asset,
|
|
313897
|
+
amount: amountStr
|
|
313898
|
+
});
|
|
313898
313899
|
}
|
|
313899
|
-
if (
|
|
313900
|
-
|
|
313900
|
+
if (isSourcePrimary && isDestSecondary) {
|
|
313901
|
+
if (typeof exchange.sapiPostSubAccountUniversalTransfer !== "function") {
|
|
313902
|
+
throw new Error("Binance universal transfer is unavailable in this CCXT build");
|
|
313903
|
+
}
|
|
313904
|
+
const destEmail = requireDestinationEmail(dest, "primary-to-sub");
|
|
313905
|
+
return await exchange.sapiPostSubAccountUniversalTransfer({
|
|
313906
|
+
fromAccountType: "SPOT",
|
|
313907
|
+
toAccountType: "SPOT",
|
|
313908
|
+
toEmail: destEmail,
|
|
313909
|
+
asset,
|
|
313910
|
+
amount: amountStr
|
|
313911
|
+
});
|
|
313901
313912
|
}
|
|
313902
|
-
|
|
313903
|
-
return await master.exchange.withdraw(code, amount, recipientAddress, undefined, withdrawParams);
|
|
313913
|
+
throw new Error(`Unsupported transfer direction: ${source.label} → ${dest.label}`);
|
|
313904
313914
|
}
|
|
313905
313915
|
function isMarketPatternMatch(pattern, broker, fromToken, toToken) {
|
|
313906
313916
|
const normalizedPattern = pattern.toUpperCase().trim();
|
|
@@ -314368,160 +314378,8 @@ function createOtelLogsFromEnv() {
|
|
|
314368
314378
|
// src/server.ts
|
|
314369
314379
|
var grpc = __toESM(require_src3(), 1);
|
|
314370
314380
|
var protoLoader = __toESM(require_src2(), 1);
|
|
314371
|
-
|
|
314372
|
-
|
|
314373
|
-
var Action = {
|
|
314374
|
-
NoAction: 0,
|
|
314375
|
-
Deposit: 1,
|
|
314376
|
-
Withdraw: 2,
|
|
314377
|
-
CreateOrder: 3,
|
|
314378
|
-
GetOrderDetails: 4,
|
|
314379
|
-
CancelOrder: 5,
|
|
314380
|
-
FetchBalances: 6,
|
|
314381
|
-
FetchDepositAddresses: 7,
|
|
314382
|
-
FetchTicker: 8,
|
|
314383
|
-
FetchCurrency: 9,
|
|
314384
|
-
Call: 10,
|
|
314385
|
-
FetchAccountId: 11,
|
|
314386
|
-
FetchFees: 12
|
|
314387
|
-
};
|
|
314388
|
-
|
|
314389
|
-
// src/proto/cex_broker/SubscriptionType.ts
|
|
314390
|
-
var SubscriptionType = {
|
|
314391
|
-
NO_ACTION: 0,
|
|
314392
|
-
ORDERBOOK: 1,
|
|
314393
|
-
TRADES: 2,
|
|
314394
|
-
TICKER: 3,
|
|
314395
|
-
OHLCV: 4,
|
|
314396
|
-
BALANCE: 5,
|
|
314397
|
-
ORDERS: 6
|
|
314398
|
-
};
|
|
314399
|
-
|
|
314400
|
-
// src/proto/node.descriptor.ts
|
|
314401
|
-
var descriptor = {
|
|
314402
|
-
nested: {
|
|
314403
|
-
cex_broker: {
|
|
314404
|
-
nested: {
|
|
314405
|
-
ActionRequest: {
|
|
314406
|
-
fields: {
|
|
314407
|
-
action: {
|
|
314408
|
-
type: "Action",
|
|
314409
|
-
id: 1
|
|
314410
|
-
},
|
|
314411
|
-
payload: {
|
|
314412
|
-
keyType: "string",
|
|
314413
|
-
type: "string",
|
|
314414
|
-
id: 2
|
|
314415
|
-
},
|
|
314416
|
-
cex: {
|
|
314417
|
-
type: "string",
|
|
314418
|
-
id: 3
|
|
314419
|
-
},
|
|
314420
|
-
symbol: {
|
|
314421
|
-
type: "string",
|
|
314422
|
-
id: 4
|
|
314423
|
-
}
|
|
314424
|
-
}
|
|
314425
|
-
},
|
|
314426
|
-
ActionResponse: {
|
|
314427
|
-
fields: {
|
|
314428
|
-
result: {
|
|
314429
|
-
type: "string",
|
|
314430
|
-
id: 1
|
|
314431
|
-
},
|
|
314432
|
-
proof: {
|
|
314433
|
-
type: "string",
|
|
314434
|
-
id: 2
|
|
314435
|
-
}
|
|
314436
|
-
}
|
|
314437
|
-
},
|
|
314438
|
-
SubscribeRequest: {
|
|
314439
|
-
fields: {
|
|
314440
|
-
cex: {
|
|
314441
|
-
type: "string",
|
|
314442
|
-
id: 1
|
|
314443
|
-
},
|
|
314444
|
-
symbol: {
|
|
314445
|
-
type: "string",
|
|
314446
|
-
id: 2
|
|
314447
|
-
},
|
|
314448
|
-
type: {
|
|
314449
|
-
type: "SubscriptionType",
|
|
314450
|
-
id: 3
|
|
314451
|
-
},
|
|
314452
|
-
options: {
|
|
314453
|
-
keyType: "string",
|
|
314454
|
-
type: "string",
|
|
314455
|
-
id: 4
|
|
314456
|
-
}
|
|
314457
|
-
}
|
|
314458
|
-
},
|
|
314459
|
-
SubscribeResponse: {
|
|
314460
|
-
fields: {
|
|
314461
|
-
data: {
|
|
314462
|
-
type: "string",
|
|
314463
|
-
id: 1
|
|
314464
|
-
},
|
|
314465
|
-
timestamp: {
|
|
314466
|
-
type: "int64",
|
|
314467
|
-
id: 2
|
|
314468
|
-
},
|
|
314469
|
-
symbol: {
|
|
314470
|
-
type: "string",
|
|
314471
|
-
id: 3
|
|
314472
|
-
},
|
|
314473
|
-
type: {
|
|
314474
|
-
type: "SubscriptionType",
|
|
314475
|
-
id: 4
|
|
314476
|
-
}
|
|
314477
|
-
}
|
|
314478
|
-
},
|
|
314479
|
-
SubscriptionType: {
|
|
314480
|
-
values: {
|
|
314481
|
-
NO_ACTION: 0,
|
|
314482
|
-
ORDERBOOK: 1,
|
|
314483
|
-
TRADES: 2,
|
|
314484
|
-
TICKER: 3,
|
|
314485
|
-
OHLCV: 4,
|
|
314486
|
-
BALANCE: 5,
|
|
314487
|
-
ORDERS: 6
|
|
314488
|
-
}
|
|
314489
|
-
},
|
|
314490
|
-
cex_service: {
|
|
314491
|
-
methods: {
|
|
314492
|
-
ExecuteAction: {
|
|
314493
|
-
requestType: "ActionRequest",
|
|
314494
|
-
responseType: "ActionResponse"
|
|
314495
|
-
},
|
|
314496
|
-
Subscribe: {
|
|
314497
|
-
requestType: "SubscribeRequest",
|
|
314498
|
-
responseType: "SubscribeResponse",
|
|
314499
|
-
responseStream: true
|
|
314500
|
-
}
|
|
314501
|
-
}
|
|
314502
|
-
},
|
|
314503
|
-
Action: {
|
|
314504
|
-
values: {
|
|
314505
|
-
NoAction: 0,
|
|
314506
|
-
Deposit: 1,
|
|
314507
|
-
Withdraw: 2,
|
|
314508
|
-
CreateOrder: 3,
|
|
314509
|
-
GetOrderDetails: 4,
|
|
314510
|
-
CancelOrder: 5,
|
|
314511
|
-
FetchBalances: 6,
|
|
314512
|
-
FetchDepositAddresses: 7,
|
|
314513
|
-
FetchTicker: 8,
|
|
314514
|
-
FetchCurrency: 9,
|
|
314515
|
-
Call: 10,
|
|
314516
|
-
FetchAccountId: 11,
|
|
314517
|
-
FetchFees: 12
|
|
314518
|
-
}
|
|
314519
|
-
}
|
|
314520
|
-
}
|
|
314521
|
-
}
|
|
314522
|
-
}
|
|
314523
|
-
};
|
|
314524
|
-
var node_descriptor_default = descriptor;
|
|
314381
|
+
import path from "path";
|
|
314382
|
+
import { fileURLToPath } from "url";
|
|
314525
314383
|
|
|
314526
314384
|
// node_modules/zod/v4/classic/external.js
|
|
314527
314385
|
var exports_external = {};
|
|
@@ -315464,9 +315322,9 @@ function createTransparentProxy(getter) {
|
|
|
315464
315322
|
target ?? (target = getter());
|
|
315465
315323
|
return Reflect.getOwnPropertyDescriptor(target, prop3);
|
|
315466
315324
|
},
|
|
315467
|
-
defineProperty(_, prop3,
|
|
315325
|
+
defineProperty(_, prop3, descriptor) {
|
|
315468
315326
|
target ?? (target = getter());
|
|
315469
|
-
return Reflect.defineProperty(target, prop3,
|
|
315327
|
+
return Reflect.defineProperty(target, prop3, descriptor);
|
|
315470
315328
|
}
|
|
315471
315329
|
});
|
|
315472
315330
|
}
|
|
@@ -328100,11 +327958,13 @@ var WithdrawPayloadSchema = exports_external.object({
|
|
|
328100
327958
|
recipientAddress: exports_external.string().min(1),
|
|
328101
327959
|
amount: exports_external.coerce.number().positive(),
|
|
328102
327960
|
chain: exports_external.string().min(1),
|
|
328103
|
-
routeViaMaster: booleanLikeSchema.optional().default(false),
|
|
328104
|
-
sourceAccount: exports_external.string().min(1).optional(),
|
|
328105
|
-
masterAccount: exports_external.string().min(1).optional(),
|
|
328106
327961
|
params: exports_external.preprocess(parseJsonString, stringNumberRecordSchema).default({})
|
|
328107
327962
|
});
|
|
327963
|
+
var InternalTransferPayloadSchema = exports_external.object({
|
|
327964
|
+
amount: exports_external.coerce.number().positive(),
|
|
327965
|
+
fromAccount: exports_external.string().min(1).optional(),
|
|
327966
|
+
toAccount: exports_external.string().min(1).optional()
|
|
327967
|
+
});
|
|
328108
327968
|
var CreateOrderPayloadSchema = exports_external.object({
|
|
328109
327969
|
orderType: exports_external.enum(["market", "limit"]).default("limit"),
|
|
328110
327970
|
amount: exports_external.coerce.number().positive(),
|
|
@@ -328127,7 +327987,15 @@ var FetchFeesPayloadSchema = exports_external.object({
|
|
|
328127
327987
|
});
|
|
328128
327988
|
|
|
328129
327989
|
// src/server.ts
|
|
328130
|
-
var
|
|
327990
|
+
var __filename2 = fileURLToPath(import.meta.url);
|
|
327991
|
+
var __dirname2 = path.dirname(__filename2);
|
|
327992
|
+
var protoPath = path.join(__dirname2, "proto", "node.proto");
|
|
327993
|
+
var packageDef = protoLoader.loadSync(protoPath, {
|
|
327994
|
+
keepCase: true,
|
|
327995
|
+
longs: String,
|
|
327996
|
+
defaults: true,
|
|
327997
|
+
oneofs: true
|
|
327998
|
+
});
|
|
328131
327999
|
var grpcObj = grpc.loadPackageDefinition(packageDef);
|
|
328132
328000
|
var cexNode = grpcObj.cex_broker;
|
|
328133
328001
|
function parsePayload(schema, rawPayload) {
|
|
@@ -328136,10 +328004,10 @@ function parsePayload(schema, rawPayload) {
|
|
|
328136
328004
|
return { success: true, data: parsed.data };
|
|
328137
328005
|
}
|
|
328138
328006
|
const firstIssue = parsed.error.issues[0];
|
|
328139
|
-
const
|
|
328007
|
+
const path2 = firstIssue && firstIssue.path.length > 0 ? `${firstIssue.path.join(".")}: ` : "";
|
|
328140
328008
|
return {
|
|
328141
328009
|
success: false,
|
|
328142
|
-
message: `ValidationError: ${
|
|
328010
|
+
message: `ValidationError: ${path2}${firstIssue?.message ?? "Invalid payload"}`
|
|
328143
328011
|
};
|
|
328144
328012
|
}
|
|
328145
328013
|
function getErrorMessage(error48) {
|
|
@@ -328152,6 +328020,31 @@ function safeLogError(context2, error48) {
|
|
|
328152
328020
|
console.error(context2, error48);
|
|
328153
328021
|
}
|
|
328154
328022
|
}
|
|
328023
|
+
function mapCcxtErrorToGrpcStatus(error48) {
|
|
328024
|
+
if (error48 instanceof ccxt_default.AuthenticationError)
|
|
328025
|
+
return grpc.status.UNAUTHENTICATED;
|
|
328026
|
+
if (error48 instanceof ccxt_default.PermissionDenied)
|
|
328027
|
+
return grpc.status.PERMISSION_DENIED;
|
|
328028
|
+
if (error48 instanceof ccxt_default.InsufficientFunds)
|
|
328029
|
+
return grpc.status.FAILED_PRECONDITION;
|
|
328030
|
+
if (error48 instanceof ccxt_default.InvalidAddress)
|
|
328031
|
+
return grpc.status.INVALID_ARGUMENT;
|
|
328032
|
+
if (error48 instanceof ccxt_default.BadSymbol)
|
|
328033
|
+
return grpc.status.NOT_FOUND;
|
|
328034
|
+
if (error48 instanceof ccxt_default.BadRequest)
|
|
328035
|
+
return grpc.status.INVALID_ARGUMENT;
|
|
328036
|
+
if (error48 instanceof ccxt_default.NotSupported)
|
|
328037
|
+
return grpc.status.UNIMPLEMENTED;
|
|
328038
|
+
if (error48 instanceof ccxt_default.RateLimitExceeded)
|
|
328039
|
+
return grpc.status.RESOURCE_EXHAUSTED;
|
|
328040
|
+
if (error48 instanceof ccxt_default.OnMaintenance)
|
|
328041
|
+
return grpc.status.UNAVAILABLE;
|
|
328042
|
+
if (error48 instanceof ccxt_default.ExchangeNotAvailable)
|
|
328043
|
+
return grpc.status.UNAVAILABLE;
|
|
328044
|
+
if (error48 instanceof ccxt_default.NetworkError)
|
|
328045
|
+
return grpc.status.UNAVAILABLE;
|
|
328046
|
+
return;
|
|
328047
|
+
}
|
|
328155
328048
|
function getServer(policy, brokers, whitelistIps, useVerity, verityProverUrl, otelMetrics) {
|
|
328156
328049
|
const server = new grpc.Server;
|
|
328157
328050
|
server.addService(cexNode.cex_service.service, {
|
|
@@ -328163,7 +328056,7 @@ function getServer(policy, brokers, whitelistIps, useVerity, verityProverUrl, ot
|
|
|
328163
328056
|
if (!actionCompleted) {
|
|
328164
328057
|
actionCompleted = true;
|
|
328165
328058
|
const latency = Date.now() - startTime;
|
|
328166
|
-
const actionName = action
|
|
328059
|
+
const actionName = getActionName(action);
|
|
328167
328060
|
otelMetrics?.recordHistogram("execute_action_duration_ms", latency, {
|
|
328168
328061
|
action: actionName,
|
|
328169
328062
|
cex: cex3 || "unknown"
|
|
@@ -328189,7 +328082,7 @@ function getServer(policy, brokers, whitelistIps, useVerity, verityProverUrl, ot
|
|
|
328189
328082
|
cex: cex3,
|
|
328190
328083
|
symbol: symbol2
|
|
328191
328084
|
});
|
|
328192
|
-
const actionName = action
|
|
328085
|
+
const actionName = getActionName(action);
|
|
328193
328086
|
otelMetrics?.recordCounter("execute_action_requests_total", 1, {
|
|
328194
328087
|
action: actionName,
|
|
328195
328088
|
cex: cex3 || "unknown"
|
|
@@ -328207,7 +328100,8 @@ function getServer(policy, brokers, whitelistIps, useVerity, verityProverUrl, ot
|
|
|
328207
328100
|
message: "`action` AND `cex` fields are required"
|
|
328208
328101
|
}, null);
|
|
328209
328102
|
}
|
|
328210
|
-
const
|
|
328103
|
+
const normalizedCex = cex3.trim().toLowerCase();
|
|
328104
|
+
const broker = selectBroker(brokers[normalizedCex], metadata) ?? createBroker(normalizedCex, metadata);
|
|
328211
328105
|
if (!broker) {
|
|
328212
328106
|
return wrappedCallback({
|
|
328213
328107
|
code: grpc.status.UNAUTHENTICATED,
|
|
@@ -328545,39 +328439,10 @@ function getServer(policy, brokers, whitelistIps, useVerity, verityProverUrl, ot
|
|
|
328545
328439
|
}, null);
|
|
328546
328440
|
}
|
|
328547
328441
|
try {
|
|
328548
|
-
|
|
328549
|
-
|
|
328550
|
-
|
|
328551
|
-
|
|
328552
|
-
brokers: brokers[cex3],
|
|
328553
|
-
metadata,
|
|
328554
|
-
selectedBroker: broker,
|
|
328555
|
-
code: symbol2,
|
|
328556
|
-
amount: transferValue.amount,
|
|
328557
|
-
recipientAddress: transferValue.recipientAddress,
|
|
328558
|
-
network: transferValue.chain,
|
|
328559
|
-
params: transferValue.params,
|
|
328560
|
-
routeViaMaster: transferValue.routeViaMaster,
|
|
328561
|
-
sourceAccount: transferValue.sourceAccount,
|
|
328562
|
-
masterAccount: transferValue.masterAccount
|
|
328563
|
-
});
|
|
328564
|
-
} catch (error48) {
|
|
328565
|
-
if (error48 instanceof WithdrawRoutingUnavailableError) {
|
|
328566
|
-
log.warn("Withdraw routing unavailable, falling back", {
|
|
328567
|
-
cex: cex3,
|
|
328568
|
-
error: error48.message
|
|
328569
|
-
});
|
|
328570
|
-
if (transferValue.routeViaMaster) {
|
|
328571
|
-
throw error48;
|
|
328572
|
-
}
|
|
328573
|
-
transaction = await broker.withdraw(symbol2, transferValue.amount, transferValue.recipientAddress, undefined, {
|
|
328574
|
-
...transferValue.params ?? {},
|
|
328575
|
-
network: transferValue.chain
|
|
328576
|
-
});
|
|
328577
|
-
} else {
|
|
328578
|
-
throw error48;
|
|
328579
|
-
}
|
|
328580
|
-
}
|
|
328442
|
+
const transaction = await broker.withdraw(symbol2, transferValue.amount, transferValue.recipientAddress, undefined, {
|
|
328443
|
+
...transferValue.params ?? {},
|
|
328444
|
+
network: transferValue.chain
|
|
328445
|
+
});
|
|
328581
328446
|
log.info(`Withdraw Result: ${JSON.stringify(transaction)}`);
|
|
328582
328447
|
wrappedCallback(null, {
|
|
328583
328448
|
proof: verityProof,
|
|
@@ -328585,10 +328450,10 @@ function getServer(policy, brokers, whitelistIps, useVerity, verityProverUrl, ot
|
|
|
328585
328450
|
});
|
|
328586
328451
|
} catch (error48) {
|
|
328587
328452
|
safeLogError("Withdraw failed", error48);
|
|
328588
|
-
const
|
|
328453
|
+
const code = mapCcxtErrorToGrpcStatus(error48) ?? grpc.status.INTERNAL;
|
|
328589
328454
|
wrappedCallback({
|
|
328590
|
-
code
|
|
328591
|
-
message: `Withdraw failed: ${
|
|
328455
|
+
code,
|
|
328456
|
+
message: `Withdraw failed: ${getErrorMessage(error48)}`
|
|
328592
328457
|
}, null);
|
|
328593
328458
|
}
|
|
328594
328459
|
break;
|
|
@@ -328761,6 +328626,86 @@ function getServer(policy, brokers, whitelistIps, useVerity, verityProverUrl, ot
|
|
|
328761
328626
|
}, null);
|
|
328762
328627
|
}
|
|
328763
328628
|
break;
|
|
328629
|
+
case Action.InternalTransfer: {
|
|
328630
|
+
if (!symbol2) {
|
|
328631
|
+
return wrappedCallback({
|
|
328632
|
+
code: grpc.status.INVALID_ARGUMENT,
|
|
328633
|
+
message: `ValidationError: Symbol required`
|
|
328634
|
+
}, null);
|
|
328635
|
+
}
|
|
328636
|
+
const parsedPayload = parsePayload(InternalTransferPayloadSchema, call.request.payload);
|
|
328637
|
+
if (!parsedPayload.success) {
|
|
328638
|
+
return wrappedCallback({
|
|
328639
|
+
code: grpc.status.INVALID_ARGUMENT,
|
|
328640
|
+
message: parsedPayload.message
|
|
328641
|
+
}, null);
|
|
328642
|
+
}
|
|
328643
|
+
const transferPayload = parsedPayload.data;
|
|
328644
|
+
if (normalizedCex !== "binance") {
|
|
328645
|
+
return wrappedCallback({
|
|
328646
|
+
code: grpc.status.UNIMPLEMENTED,
|
|
328647
|
+
message: `InternalTransfer is only supported for Binance`
|
|
328648
|
+
}, null);
|
|
328649
|
+
}
|
|
328650
|
+
const pool = brokers[normalizedCex];
|
|
328651
|
+
if (!pool) {
|
|
328652
|
+
return wrappedCallback({
|
|
328653
|
+
code: grpc.status.FAILED_PRECONDITION,
|
|
328654
|
+
message: `No broker accounts configured for ${normalizedCex}`
|
|
328655
|
+
}, null);
|
|
328656
|
+
}
|
|
328657
|
+
const fromSelector = transferPayload.fromAccount ?? getCurrentBrokerSelector(metadata);
|
|
328658
|
+
const toSelector = transferPayload.toAccount ?? "primary";
|
|
328659
|
+
const sourceAccount = resolveBrokerAccount(pool, fromSelector);
|
|
328660
|
+
if (!sourceAccount) {
|
|
328661
|
+
return wrappedCallback({
|
|
328662
|
+
code: grpc.status.INVALID_ARGUMENT,
|
|
328663
|
+
message: `Source account "${fromSelector}" is not configured`
|
|
328664
|
+
}, null);
|
|
328665
|
+
}
|
|
328666
|
+
const destAccount = resolveBrokerAccount(pool, toSelector);
|
|
328667
|
+
if (!destAccount) {
|
|
328668
|
+
return wrappedCallback({
|
|
328669
|
+
code: grpc.status.INVALID_ARGUMENT,
|
|
328670
|
+
message: `Destination account "${toSelector}" is not configured`
|
|
328671
|
+
}, null);
|
|
328672
|
+
}
|
|
328673
|
+
try {
|
|
328674
|
+
if (useVerity) {
|
|
328675
|
+
sourceAccount.exchange.setHttpClientOverride(buildHttpClientOverrideFromMetadata(metadata, verityProverUrl, (proof, notaryPubKey) => {
|
|
328676
|
+
verityProof = proof;
|
|
328677
|
+
log.debug(`Verity proof:`, { proof, notaryPubKey });
|
|
328678
|
+
}), verityHttpClientOverridePredicate);
|
|
328679
|
+
}
|
|
328680
|
+
const result = await transferBinanceInternal(sourceAccount, destAccount, symbol2, transferPayload.amount);
|
|
328681
|
+
wrappedCallback(null, {
|
|
328682
|
+
proof: verityProof,
|
|
328683
|
+
result: JSON.stringify(result)
|
|
328684
|
+
});
|
|
328685
|
+
} catch (error48) {
|
|
328686
|
+
safeLogError("InternalTransfer failed", error48);
|
|
328687
|
+
if (error48 instanceof BrokerAccountPreconditionError) {
|
|
328688
|
+
return wrappedCallback({
|
|
328689
|
+
code: grpc.status.FAILED_PRECONDITION,
|
|
328690
|
+
message: getErrorMessage(error48)
|
|
328691
|
+
}, null);
|
|
328692
|
+
}
|
|
328693
|
+
const msg = getErrorMessage(error48);
|
|
328694
|
+
let code;
|
|
328695
|
+
if (msg.includes("Unsupported transfer direction")) {
|
|
328696
|
+
code = grpc.status.INVALID_ARGUMENT;
|
|
328697
|
+
} else if (msg.includes("unavailable in this CCXT build")) {
|
|
328698
|
+
code = grpc.status.UNIMPLEMENTED;
|
|
328699
|
+
} else {
|
|
328700
|
+
code = mapCcxtErrorToGrpcStatus(error48) ?? grpc.status.INTERNAL;
|
|
328701
|
+
}
|
|
328702
|
+
wrappedCallback({
|
|
328703
|
+
code,
|
|
328704
|
+
message: `InternalTransfer failed: ${msg}`
|
|
328705
|
+
}, null);
|
|
328706
|
+
}
|
|
328707
|
+
break;
|
|
328708
|
+
}
|
|
328764
328709
|
default:
|
|
328765
328710
|
return wrappedCallback({
|
|
328766
328711
|
code: grpc.status.INVALID_ARGUMENT,
|
|
@@ -328793,20 +328738,13 @@ function getServer(policy, brokers, whitelistIps, useVerity, verityProverUrl, ot
|
|
|
328793
328738
|
try {
|
|
328794
328739
|
const request = call.request;
|
|
328795
328740
|
const { cex: cex3, symbol: symbol2, type: type2, options } = request;
|
|
328796
|
-
const subscriptionType = type2
|
|
328741
|
+
const subscriptionType = resolveSubscriptionType(type2);
|
|
328797
328742
|
log.info(`Request - Subscribe:`, {
|
|
328798
328743
|
cex: request.cex,
|
|
328799
328744
|
symbol: request.symbol,
|
|
328800
328745
|
type: subscriptionType
|
|
328801
328746
|
});
|
|
328802
|
-
const subscriptionTypeName = (
|
|
328803
|
-
for (const [key, value] of Object.entries(SubscriptionType)) {
|
|
328804
|
-
if (value === subscriptionType && Number.isNaN(Number(key))) {
|
|
328805
|
-
return key;
|
|
328806
|
-
}
|
|
328807
|
-
}
|
|
328808
|
-
return `unknown_${subscriptionType}`;
|
|
328809
|
-
})();
|
|
328747
|
+
const subscriptionTypeName = getSubscriptionTypeName(subscriptionType);
|
|
328810
328748
|
otelMetrics?.recordCounter("subscribe_requests_total", 1, {
|
|
328811
328749
|
cex: cex3 || "unknown",
|
|
328812
328750
|
symbol: symbol2 || "unknown",
|
|
@@ -328894,7 +328832,7 @@ function getServer(policy, brokers, whitelistIps, useVerity, verityProverUrl, ot
|
|
|
328894
328832
|
data: JSON.stringify(ticker),
|
|
328895
328833
|
timestamp: Date.now(),
|
|
328896
328834
|
symbol: symbol2,
|
|
328897
|
-
type:
|
|
328835
|
+
type: subscriptionType
|
|
328898
328836
|
});
|
|
328899
328837
|
}
|
|
328900
328838
|
} catch (error48) {
|
|
@@ -328919,7 +328857,7 @@ function getServer(policy, brokers, whitelistIps, useVerity, verityProverUrl, ot
|
|
|
328919
328857
|
data: JSON.stringify(ohlcv),
|
|
328920
328858
|
timestamp: Date.now(),
|
|
328921
328859
|
symbol: symbol2,
|
|
328922
|
-
type:
|
|
328860
|
+
type: subscriptionType
|
|
328923
328861
|
});
|
|
328924
328862
|
}
|
|
328925
328863
|
} catch (error48) {
|
|
@@ -328943,7 +328881,7 @@ function getServer(policy, brokers, whitelistIps, useVerity, verityProverUrl, ot
|
|
|
328943
328881
|
data: JSON.stringify(balance),
|
|
328944
328882
|
timestamp: Date.now(),
|
|
328945
328883
|
symbol: symbol2,
|
|
328946
|
-
type:
|
|
328884
|
+
type: subscriptionType
|
|
328947
328885
|
});
|
|
328948
328886
|
}
|
|
328949
328887
|
} catch (error48) {
|
|
@@ -328967,7 +328905,7 @@ function getServer(policy, brokers, whitelistIps, useVerity, verityProverUrl, ot
|
|
|
328967
328905
|
data: JSON.stringify(orders),
|
|
328968
328906
|
timestamp: Date.now(),
|
|
328969
328907
|
symbol: symbol2,
|
|
328970
|
-
type:
|
|
328908
|
+
type: subscriptionType
|
|
328971
328909
|
});
|
|
328972
328910
|
}
|
|
328973
328911
|
} catch (error48) {
|
|
@@ -328988,7 +328926,7 @@ function getServer(policy, brokers, whitelistIps, useVerity, verityProverUrl, ot
|
|
|
328988
328926
|
data: JSON.stringify({ error: "Invalid subscription type" }),
|
|
328989
328927
|
timestamp: Date.now(),
|
|
328990
328928
|
symbol: symbol2,
|
|
328991
|
-
type:
|
|
328929
|
+
type: subscriptionType
|
|
328992
328930
|
});
|
|
328993
328931
|
}
|
|
328994
328932
|
} catch (error48) {
|