@gbozee/ultimate 0.0.2-105 → 0.0.2-107
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/frontend-index.d.ts +40 -0
- package/dist/frontend-index.js +42 -0
- package/dist/index.cjs +87 -13
- package/dist/index.d.ts +27 -8
- package/dist/index.js +87 -13
- package/dist/mcp-server.cjs +87 -13
- package/dist/mcp-server.js +87 -13
- package/package.json +1 -1
package/dist/frontend-index.d.ts
CHANGED
|
@@ -78,6 +78,46 @@ export declare function computeSellZones(payload: {
|
|
|
78
78
|
exit: number;
|
|
79
79
|
zones?: number;
|
|
80
80
|
}): number[];
|
|
81
|
+
export type RawPosition = {
|
|
82
|
+
entry: number;
|
|
83
|
+
quantity: number;
|
|
84
|
+
price_places: string;
|
|
85
|
+
decimal_places: string;
|
|
86
|
+
};
|
|
87
|
+
export type ConfigOptionType = {
|
|
88
|
+
reduce_ratio: number | string;
|
|
89
|
+
profit_percent: number | string;
|
|
90
|
+
};
|
|
91
|
+
/**
|
|
92
|
+
* This function determines the take profit price for a given position based of the profit percent and the reduce ratio
|
|
93
|
+
* @param payload
|
|
94
|
+
* @returns {
|
|
95
|
+
* tp_price: number;
|
|
96
|
+
* pnl: number;
|
|
97
|
+
* quantity: number;
|
|
98
|
+
* reduce_quantity: number;
|
|
99
|
+
* expected_loss: number;
|
|
100
|
+
* }
|
|
101
|
+
*/
|
|
102
|
+
export declare function determineTPSl(payload: {
|
|
103
|
+
sell_ratio?: number;
|
|
104
|
+
positions: {
|
|
105
|
+
long: RawPosition;
|
|
106
|
+
short: RawPosition;
|
|
107
|
+
};
|
|
108
|
+
configs: {
|
|
109
|
+
long: ConfigOptionType;
|
|
110
|
+
short: ConfigOptionType;
|
|
111
|
+
};
|
|
112
|
+
kind: "long" | "short";
|
|
113
|
+
decimal_places?: string;
|
|
114
|
+
}): {
|
|
115
|
+
tp_price: number;
|
|
116
|
+
pnl: number;
|
|
117
|
+
quantity: number;
|
|
118
|
+
reduce_quantity: number;
|
|
119
|
+
expected_loss: number;
|
|
120
|
+
};
|
|
81
121
|
export type SignalConfigType = {
|
|
82
122
|
focus: number;
|
|
83
123
|
budget: number;
|
package/dist/frontend-index.js
CHANGED
|
@@ -1153,6 +1153,47 @@ function computeSellZones(payload) {
|
|
|
1153
1153
|
const spread = factor - 1;
|
|
1154
1154
|
return Array.from({ length: zones }, (_, i) => entry * Math.pow(1 + spread, i));
|
|
1155
1155
|
}
|
|
1156
|
+
function determineTPSl(payload) {
|
|
1157
|
+
const { sell_ratio = 1, kind, positions, configs, decimal_places } = payload;
|
|
1158
|
+
const long_settings = configs.long;
|
|
1159
|
+
const short_settings = configs.short;
|
|
1160
|
+
const settings = kind === "long" ? long_settings : short_settings;
|
|
1161
|
+
const reverse_kind = kind === "long" ? "short" : "long";
|
|
1162
|
+
const _position = positions[kind];
|
|
1163
|
+
const reverse_position = positions[reverse_kind];
|
|
1164
|
+
const reduce_ratio = settings.reduce_ratio;
|
|
1165
|
+
const notion = _position.entry * _position.quantity;
|
|
1166
|
+
const profit_percent = settings.profit_percent;
|
|
1167
|
+
const places = decimal_places || reverse_position.decimal_places;
|
|
1168
|
+
if (profit_percent) {
|
|
1169
|
+
let quantity = to_f(_position.quantity * sell_ratio, places);
|
|
1170
|
+
const as_float = parseFloat(profit_percent) * sell_ratio;
|
|
1171
|
+
const pnl = to_f(as_float * notion / 100, "%.2f");
|
|
1172
|
+
const diff = pnl / quantity;
|
|
1173
|
+
const tp_price = to_f(kind === "long" ? _position.entry + diff : _position.entry - diff, _position.price_places);
|
|
1174
|
+
const expected_loss = to_f(parseFloat(reduce_ratio) * pnl, "%.2f");
|
|
1175
|
+
let reduce_quantity = 0;
|
|
1176
|
+
if (reverse_position.quantity > 0) {
|
|
1177
|
+
const total_loss = Math.abs(tp_price - reverse_position.entry) * reverse_position.quantity;
|
|
1178
|
+
const ratio = expected_loss / total_loss;
|
|
1179
|
+
reduce_quantity = to_f(reverse_position.quantity * ratio, places);
|
|
1180
|
+
}
|
|
1181
|
+
return {
|
|
1182
|
+
tp_price,
|
|
1183
|
+
pnl,
|
|
1184
|
+
quantity,
|
|
1185
|
+
reduce_quantity,
|
|
1186
|
+
expected_loss
|
|
1187
|
+
};
|
|
1188
|
+
}
|
|
1189
|
+
return {
|
|
1190
|
+
tp_price: 0,
|
|
1191
|
+
pnl: 0,
|
|
1192
|
+
quantity: 0,
|
|
1193
|
+
reduce_quantity: 0,
|
|
1194
|
+
expected_loss: 0
|
|
1195
|
+
};
|
|
1196
|
+
}
|
|
1156
1197
|
// src/helpers/shared.ts
|
|
1157
1198
|
function buildConfig(app_config, {
|
|
1158
1199
|
take_profit,
|
|
@@ -2441,6 +2482,7 @@ export {
|
|
|
2441
2482
|
determine_average_entry_and_size,
|
|
2442
2483
|
determine_amount_to_sell2 as determine_amount_to_sell,
|
|
2443
2484
|
determine_amount_to_buy,
|
|
2485
|
+
determineTPSl,
|
|
2444
2486
|
determineRewardFactor,
|
|
2445
2487
|
determineOptimumReward,
|
|
2446
2488
|
createGapPairs,
|
package/dist/index.cjs
CHANGED
|
@@ -51468,8 +51468,12 @@ async function initPocketBaseClient(proxy_credentials) {
|
|
|
51468
51468
|
|
|
51469
51469
|
class AppDatabase {
|
|
51470
51470
|
pb;
|
|
51471
|
-
|
|
51471
|
+
email;
|
|
51472
|
+
salt;
|
|
51473
|
+
constructor(pb, payload) {
|
|
51472
51474
|
this.pb = pb;
|
|
51475
|
+
this.email = payload.email;
|
|
51476
|
+
this.salt = payload.salt;
|
|
51473
51477
|
const customInspectSymbol = Symbol.for("nodejs.util.inspect.custom");
|
|
51474
51478
|
this[customInspectSymbol] = function() {
|
|
51475
51479
|
return `AppDatabase { pb: [PocketBase Instance - Sensitive Data Masked] }`;
|
|
@@ -51481,21 +51485,79 @@ class AppDatabase {
|
|
|
51481
51485
|
};
|
|
51482
51486
|
};
|
|
51483
51487
|
}
|
|
51484
|
-
|
|
51488
|
+
async getUserByEmail() {
|
|
51489
|
+
if (!this.email) {
|
|
51490
|
+
throw new Error("Email is not set");
|
|
51491
|
+
}
|
|
51492
|
+
const user = await this.pb.collection("users").getFullList({
|
|
51493
|
+
filter: `email="${this.email}"`
|
|
51494
|
+
});
|
|
51495
|
+
return user[0];
|
|
51496
|
+
}
|
|
51497
|
+
async generateUserPassword() {
|
|
51498
|
+
const user = await this.getUserByEmail();
|
|
51499
|
+
if (user) {
|
|
51500
|
+
const userPassword = Math.random().toString(36).substring(2, 15);
|
|
51501
|
+
const encrypted = encryptObject(userPassword, this.salt);
|
|
51502
|
+
await this.pb.collection("users").update(user.id, {
|
|
51503
|
+
settings: {
|
|
51504
|
+
...user.settings || {},
|
|
51505
|
+
password: encrypted
|
|
51506
|
+
}
|
|
51507
|
+
});
|
|
51508
|
+
}
|
|
51509
|
+
}
|
|
51510
|
+
async getUserCredentials() {
|
|
51511
|
+
const record = await this.getUserByEmail();
|
|
51512
|
+
if (record && record?.settings) {
|
|
51513
|
+
const password = decryptObject(record.settings.password, this.salt);
|
|
51514
|
+
if (password) {
|
|
51515
|
+
if (!record.settings.credentials) {
|
|
51516
|
+
return [];
|
|
51517
|
+
}
|
|
51518
|
+
return decryptObject(record.settings.credentials, password);
|
|
51519
|
+
}
|
|
51520
|
+
}
|
|
51521
|
+
return null;
|
|
51522
|
+
}
|
|
51523
|
+
async getCredentials(payload) {
|
|
51524
|
+
const { password } = payload;
|
|
51525
|
+
if (this.salt && this.email) {
|
|
51526
|
+
return this.getUserCredentials();
|
|
51527
|
+
}
|
|
51485
51528
|
const credentials = this.pb.authStore.record.credentials;
|
|
51486
51529
|
if (credentials) {
|
|
51487
51530
|
return decryptObject(credentials, password);
|
|
51488
51531
|
}
|
|
51489
51532
|
return null;
|
|
51490
51533
|
}
|
|
51491
|
-
async saveCredentials(
|
|
51492
|
-
const
|
|
51493
|
-
|
|
51494
|
-
|
|
51495
|
-
|
|
51534
|
+
async saveCredentials(params) {
|
|
51535
|
+
const { password, credentials } = params;
|
|
51536
|
+
if (this.salt && this.email) {
|
|
51537
|
+
const user = await this.getUserByEmail();
|
|
51538
|
+
if (user) {
|
|
51539
|
+
const userPassword = decryptObject(user.settings.password, this.salt);
|
|
51540
|
+
if (userPassword) {
|
|
51541
|
+
const encrypted = encryptObject(credentials, userPassword);
|
|
51542
|
+
return await this.pb.collection("users").update(user.id, {
|
|
51543
|
+
settings: {
|
|
51544
|
+
...user.settings,
|
|
51545
|
+
credentials: encrypted
|
|
51546
|
+
}
|
|
51547
|
+
});
|
|
51548
|
+
}
|
|
51549
|
+
}
|
|
51550
|
+
}
|
|
51551
|
+
if (password) {
|
|
51552
|
+
const encrypted = encryptObject(credentials, password);
|
|
51553
|
+
await this.pb.collection("_superusers").update(this.pb.authStore.record.id, {
|
|
51554
|
+
credentials: encrypted
|
|
51555
|
+
});
|
|
51556
|
+
}
|
|
51496
51557
|
}
|
|
51497
|
-
async addNewCredential(
|
|
51498
|
-
|
|
51558
|
+
async addNewCredential(params) {
|
|
51559
|
+
const { password, payload } = params;
|
|
51560
|
+
let credentials = await this.getCredentials({ password });
|
|
51499
51561
|
if (credentials) {
|
|
51500
51562
|
let found = false;
|
|
51501
51563
|
for (const credential of credentials) {
|
|
@@ -51509,7 +51571,7 @@ class AppDatabase {
|
|
|
51509
51571
|
if (!found) {
|
|
51510
51572
|
credentials.push(payload);
|
|
51511
51573
|
}
|
|
51512
|
-
await this.saveCredentials(password, credentials);
|
|
51574
|
+
await this.saveCredentials({ password, credentials });
|
|
51513
51575
|
}
|
|
51514
51576
|
}
|
|
51515
51577
|
async getAccountWithActivePositions() {
|
|
@@ -51595,7 +51657,14 @@ class AppDatabase {
|
|
|
51595
51657
|
});
|
|
51596
51658
|
}
|
|
51597
51659
|
async get_exchange_db_instance(account) {
|
|
51598
|
-
|
|
51660
|
+
let filter = `owner="${account.owner}" && exchange="${account.exchange}"`;
|
|
51661
|
+
if (this.email) {
|
|
51662
|
+
const user = await this.getUserByEmail();
|
|
51663
|
+
if (user) {
|
|
51664
|
+
filter = `${filter} && user = "${user.id}"`;
|
|
51665
|
+
}
|
|
51666
|
+
}
|
|
51667
|
+
const result = await this.pb.collection("exchange_accounts").getFirstListItem(filter, {
|
|
51599
51668
|
expand: "proxy"
|
|
51600
51669
|
});
|
|
51601
51670
|
return result;
|
|
@@ -59910,11 +59979,16 @@ class App {
|
|
|
59910
59979
|
}
|
|
59911
59980
|
async function initApp(payload) {
|
|
59912
59981
|
const pb = await initPocketBaseClient(payload.db);
|
|
59913
|
-
const app_db = new AppDatabase(pb
|
|
59982
|
+
const app_db = new AppDatabase(pb, {
|
|
59983
|
+
email: payload.email,
|
|
59984
|
+
salt: payload.salt
|
|
59985
|
+
});
|
|
59914
59986
|
let _getCredentials = payload.getCredentials;
|
|
59915
59987
|
if (payload.password) {
|
|
59916
59988
|
try {
|
|
59917
|
-
const credentials = app_db.getCredentials(
|
|
59989
|
+
const credentials = await app_db.getCredentials({
|
|
59990
|
+
password: payload.password
|
|
59991
|
+
});
|
|
59918
59992
|
if (credentials) {
|
|
59919
59993
|
_getCredentials = (account, exchange) => {
|
|
59920
59994
|
const credential = credentials.find((c) => c.name === account && c.exchange === exchange);
|
package/dist/index.d.ts
CHANGED
|
@@ -437,14 +437,31 @@ export type ExchangeType = {
|
|
|
437
437
|
};
|
|
438
438
|
export declare class AppDatabase {
|
|
439
439
|
pb: PocketBase;
|
|
440
|
-
|
|
441
|
-
|
|
442
|
-
|
|
443
|
-
|
|
444
|
-
|
|
445
|
-
|
|
446
|
-
|
|
447
|
-
|
|
440
|
+
email?: string;
|
|
441
|
+
salt?: string;
|
|
442
|
+
constructor(pb: PocketBase, payload: {
|
|
443
|
+
email?: string;
|
|
444
|
+
salt?: string;
|
|
445
|
+
});
|
|
446
|
+
getUserByEmail(): Promise<import("pocketbase").RecordModel>;
|
|
447
|
+
generateUserPassword(): Promise<void>;
|
|
448
|
+
getUserCredentials(): Promise<any>;
|
|
449
|
+
getCredentials(payload: {
|
|
450
|
+
password?: string;
|
|
451
|
+
}): Promise<any>;
|
|
452
|
+
saveCredentials(params: {
|
|
453
|
+
password?: string;
|
|
454
|
+
credentials: any;
|
|
455
|
+
}): Promise<import("pocketbase").RecordModel>;
|
|
456
|
+
addNewCredential(params: {
|
|
457
|
+
password?: string;
|
|
458
|
+
payload: {
|
|
459
|
+
name: string;
|
|
460
|
+
email: string;
|
|
461
|
+
exchange: string;
|
|
462
|
+
api_key: string;
|
|
463
|
+
api_secret: string;
|
|
464
|
+
};
|
|
448
465
|
}): Promise<void>;
|
|
449
466
|
getAccountWithActivePositions(): Promise<import("pocketbase").RecordModel[]>;
|
|
450
467
|
getAllSymbolsFromPositions(options?: {
|
|
@@ -2387,6 +2404,8 @@ export declare function initApp(payload: {
|
|
|
2387
2404
|
password: string;
|
|
2388
2405
|
};
|
|
2389
2406
|
password?: string;
|
|
2407
|
+
salt?: string;
|
|
2408
|
+
email?: string;
|
|
2390
2409
|
getCredentials: (account: string, exchange: string) => {
|
|
2391
2410
|
api_key: string;
|
|
2392
2411
|
api_secret: string;
|
package/dist/index.js
CHANGED
|
@@ -51420,8 +51420,12 @@ async function initPocketBaseClient(proxy_credentials) {
|
|
|
51420
51420
|
|
|
51421
51421
|
class AppDatabase {
|
|
51422
51422
|
pb;
|
|
51423
|
-
|
|
51423
|
+
email;
|
|
51424
|
+
salt;
|
|
51425
|
+
constructor(pb, payload) {
|
|
51424
51426
|
this.pb = pb;
|
|
51427
|
+
this.email = payload.email;
|
|
51428
|
+
this.salt = payload.salt;
|
|
51425
51429
|
const customInspectSymbol = Symbol.for("nodejs.util.inspect.custom");
|
|
51426
51430
|
this[customInspectSymbol] = function() {
|
|
51427
51431
|
return `AppDatabase { pb: [PocketBase Instance - Sensitive Data Masked] }`;
|
|
@@ -51433,21 +51437,79 @@ class AppDatabase {
|
|
|
51433
51437
|
};
|
|
51434
51438
|
};
|
|
51435
51439
|
}
|
|
51436
|
-
|
|
51440
|
+
async getUserByEmail() {
|
|
51441
|
+
if (!this.email) {
|
|
51442
|
+
throw new Error("Email is not set");
|
|
51443
|
+
}
|
|
51444
|
+
const user = await this.pb.collection("users").getFullList({
|
|
51445
|
+
filter: `email="${this.email}"`
|
|
51446
|
+
});
|
|
51447
|
+
return user[0];
|
|
51448
|
+
}
|
|
51449
|
+
async generateUserPassword() {
|
|
51450
|
+
const user = await this.getUserByEmail();
|
|
51451
|
+
if (user) {
|
|
51452
|
+
const userPassword = Math.random().toString(36).substring(2, 15);
|
|
51453
|
+
const encrypted = encryptObject(userPassword, this.salt);
|
|
51454
|
+
await this.pb.collection("users").update(user.id, {
|
|
51455
|
+
settings: {
|
|
51456
|
+
...user.settings || {},
|
|
51457
|
+
password: encrypted
|
|
51458
|
+
}
|
|
51459
|
+
});
|
|
51460
|
+
}
|
|
51461
|
+
}
|
|
51462
|
+
async getUserCredentials() {
|
|
51463
|
+
const record = await this.getUserByEmail();
|
|
51464
|
+
if (record && record?.settings) {
|
|
51465
|
+
const password = decryptObject(record.settings.password, this.salt);
|
|
51466
|
+
if (password) {
|
|
51467
|
+
if (!record.settings.credentials) {
|
|
51468
|
+
return [];
|
|
51469
|
+
}
|
|
51470
|
+
return decryptObject(record.settings.credentials, password);
|
|
51471
|
+
}
|
|
51472
|
+
}
|
|
51473
|
+
return null;
|
|
51474
|
+
}
|
|
51475
|
+
async getCredentials(payload) {
|
|
51476
|
+
const { password } = payload;
|
|
51477
|
+
if (this.salt && this.email) {
|
|
51478
|
+
return this.getUserCredentials();
|
|
51479
|
+
}
|
|
51437
51480
|
const credentials = this.pb.authStore.record.credentials;
|
|
51438
51481
|
if (credentials) {
|
|
51439
51482
|
return decryptObject(credentials, password);
|
|
51440
51483
|
}
|
|
51441
51484
|
return null;
|
|
51442
51485
|
}
|
|
51443
|
-
async saveCredentials(
|
|
51444
|
-
const
|
|
51445
|
-
|
|
51446
|
-
|
|
51447
|
-
|
|
51486
|
+
async saveCredentials(params) {
|
|
51487
|
+
const { password, credentials } = params;
|
|
51488
|
+
if (this.salt && this.email) {
|
|
51489
|
+
const user = await this.getUserByEmail();
|
|
51490
|
+
if (user) {
|
|
51491
|
+
const userPassword = decryptObject(user.settings.password, this.salt);
|
|
51492
|
+
if (userPassword) {
|
|
51493
|
+
const encrypted = encryptObject(credentials, userPassword);
|
|
51494
|
+
return await this.pb.collection("users").update(user.id, {
|
|
51495
|
+
settings: {
|
|
51496
|
+
...user.settings,
|
|
51497
|
+
credentials: encrypted
|
|
51498
|
+
}
|
|
51499
|
+
});
|
|
51500
|
+
}
|
|
51501
|
+
}
|
|
51502
|
+
}
|
|
51503
|
+
if (password) {
|
|
51504
|
+
const encrypted = encryptObject(credentials, password);
|
|
51505
|
+
await this.pb.collection("_superusers").update(this.pb.authStore.record.id, {
|
|
51506
|
+
credentials: encrypted
|
|
51507
|
+
});
|
|
51508
|
+
}
|
|
51448
51509
|
}
|
|
51449
|
-
async addNewCredential(
|
|
51450
|
-
|
|
51510
|
+
async addNewCredential(params) {
|
|
51511
|
+
const { password, payload } = params;
|
|
51512
|
+
let credentials = await this.getCredentials({ password });
|
|
51451
51513
|
if (credentials) {
|
|
51452
51514
|
let found = false;
|
|
51453
51515
|
for (const credential of credentials) {
|
|
@@ -51461,7 +51523,7 @@ class AppDatabase {
|
|
|
51461
51523
|
if (!found) {
|
|
51462
51524
|
credentials.push(payload);
|
|
51463
51525
|
}
|
|
51464
|
-
await this.saveCredentials(password, credentials);
|
|
51526
|
+
await this.saveCredentials({ password, credentials });
|
|
51465
51527
|
}
|
|
51466
51528
|
}
|
|
51467
51529
|
async getAccountWithActivePositions() {
|
|
@@ -51547,7 +51609,14 @@ class AppDatabase {
|
|
|
51547
51609
|
});
|
|
51548
51610
|
}
|
|
51549
51611
|
async get_exchange_db_instance(account) {
|
|
51550
|
-
|
|
51612
|
+
let filter = `owner="${account.owner}" && exchange="${account.exchange}"`;
|
|
51613
|
+
if (this.email) {
|
|
51614
|
+
const user = await this.getUserByEmail();
|
|
51615
|
+
if (user) {
|
|
51616
|
+
filter = `${filter} && user = "${user.id}"`;
|
|
51617
|
+
}
|
|
51618
|
+
}
|
|
51619
|
+
const result = await this.pb.collection("exchange_accounts").getFirstListItem(filter, {
|
|
51551
51620
|
expand: "proxy"
|
|
51552
51621
|
});
|
|
51553
51622
|
return result;
|
|
@@ -59862,11 +59931,16 @@ class App {
|
|
|
59862
59931
|
}
|
|
59863
59932
|
async function initApp(payload) {
|
|
59864
59933
|
const pb = await initPocketBaseClient(payload.db);
|
|
59865
|
-
const app_db = new AppDatabase(pb
|
|
59934
|
+
const app_db = new AppDatabase(pb, {
|
|
59935
|
+
email: payload.email,
|
|
59936
|
+
salt: payload.salt
|
|
59937
|
+
});
|
|
59866
59938
|
let _getCredentials = payload.getCredentials;
|
|
59867
59939
|
if (payload.password) {
|
|
59868
59940
|
try {
|
|
59869
|
-
const credentials = app_db.getCredentials(
|
|
59941
|
+
const credentials = await app_db.getCredentials({
|
|
59942
|
+
password: payload.password
|
|
59943
|
+
});
|
|
59870
59944
|
if (credentials) {
|
|
59871
59945
|
_getCredentials = (account, exchange) => {
|
|
59872
59946
|
const credential = credentials.find((c) => c.name === account && c.exchange === exchange);
|
package/dist/mcp-server.cjs
CHANGED
|
@@ -58176,8 +58176,12 @@ async function initPocketBaseClient(proxy_credentials) {
|
|
|
58176
58176
|
|
|
58177
58177
|
class AppDatabase {
|
|
58178
58178
|
pb;
|
|
58179
|
-
|
|
58179
|
+
email;
|
|
58180
|
+
salt;
|
|
58181
|
+
constructor(pb, payload) {
|
|
58180
58182
|
this.pb = pb;
|
|
58183
|
+
this.email = payload.email;
|
|
58184
|
+
this.salt = payload.salt;
|
|
58181
58185
|
const customInspectSymbol = Symbol.for("nodejs.util.inspect.custom");
|
|
58182
58186
|
this[customInspectSymbol] = function() {
|
|
58183
58187
|
return `AppDatabase { pb: [PocketBase Instance - Sensitive Data Masked] }`;
|
|
@@ -58189,21 +58193,79 @@ class AppDatabase {
|
|
|
58189
58193
|
};
|
|
58190
58194
|
};
|
|
58191
58195
|
}
|
|
58192
|
-
|
|
58196
|
+
async getUserByEmail() {
|
|
58197
|
+
if (!this.email) {
|
|
58198
|
+
throw new Error("Email is not set");
|
|
58199
|
+
}
|
|
58200
|
+
const user = await this.pb.collection("users").getFullList({
|
|
58201
|
+
filter: `email="${this.email}"`
|
|
58202
|
+
});
|
|
58203
|
+
return user[0];
|
|
58204
|
+
}
|
|
58205
|
+
async generateUserPassword() {
|
|
58206
|
+
const user = await this.getUserByEmail();
|
|
58207
|
+
if (user) {
|
|
58208
|
+
const userPassword = Math.random().toString(36).substring(2, 15);
|
|
58209
|
+
const encrypted = encryptObject(userPassword, this.salt);
|
|
58210
|
+
await this.pb.collection("users").update(user.id, {
|
|
58211
|
+
settings: {
|
|
58212
|
+
...user.settings || {},
|
|
58213
|
+
password: encrypted
|
|
58214
|
+
}
|
|
58215
|
+
});
|
|
58216
|
+
}
|
|
58217
|
+
}
|
|
58218
|
+
async getUserCredentials() {
|
|
58219
|
+
const record2 = await this.getUserByEmail();
|
|
58220
|
+
if (record2 && record2?.settings) {
|
|
58221
|
+
const password = decryptObject(record2.settings.password, this.salt);
|
|
58222
|
+
if (password) {
|
|
58223
|
+
if (!record2.settings.credentials) {
|
|
58224
|
+
return [];
|
|
58225
|
+
}
|
|
58226
|
+
return decryptObject(record2.settings.credentials, password);
|
|
58227
|
+
}
|
|
58228
|
+
}
|
|
58229
|
+
return null;
|
|
58230
|
+
}
|
|
58231
|
+
async getCredentials(payload) {
|
|
58232
|
+
const { password } = payload;
|
|
58233
|
+
if (this.salt && this.email) {
|
|
58234
|
+
return this.getUserCredentials();
|
|
58235
|
+
}
|
|
58193
58236
|
const credentials = this.pb.authStore.record.credentials;
|
|
58194
58237
|
if (credentials) {
|
|
58195
58238
|
return decryptObject(credentials, password);
|
|
58196
58239
|
}
|
|
58197
58240
|
return null;
|
|
58198
58241
|
}
|
|
58199
|
-
async saveCredentials(
|
|
58200
|
-
const
|
|
58201
|
-
|
|
58202
|
-
|
|
58203
|
-
|
|
58242
|
+
async saveCredentials(params) {
|
|
58243
|
+
const { password, credentials } = params;
|
|
58244
|
+
if (this.salt && this.email) {
|
|
58245
|
+
const user = await this.getUserByEmail();
|
|
58246
|
+
if (user) {
|
|
58247
|
+
const userPassword = decryptObject(user.settings.password, this.salt);
|
|
58248
|
+
if (userPassword) {
|
|
58249
|
+
const encrypted = encryptObject(credentials, userPassword);
|
|
58250
|
+
return await this.pb.collection("users").update(user.id, {
|
|
58251
|
+
settings: {
|
|
58252
|
+
...user.settings,
|
|
58253
|
+
credentials: encrypted
|
|
58254
|
+
}
|
|
58255
|
+
});
|
|
58256
|
+
}
|
|
58257
|
+
}
|
|
58258
|
+
}
|
|
58259
|
+
if (password) {
|
|
58260
|
+
const encrypted = encryptObject(credentials, password);
|
|
58261
|
+
await this.pb.collection("_superusers").update(this.pb.authStore.record.id, {
|
|
58262
|
+
credentials: encrypted
|
|
58263
|
+
});
|
|
58264
|
+
}
|
|
58204
58265
|
}
|
|
58205
|
-
async addNewCredential(
|
|
58206
|
-
|
|
58266
|
+
async addNewCredential(params) {
|
|
58267
|
+
const { password, payload } = params;
|
|
58268
|
+
let credentials = await this.getCredentials({ password });
|
|
58207
58269
|
if (credentials) {
|
|
58208
58270
|
let found = false;
|
|
58209
58271
|
for (const credential of credentials) {
|
|
@@ -58217,7 +58279,7 @@ class AppDatabase {
|
|
|
58217
58279
|
if (!found) {
|
|
58218
58280
|
credentials.push(payload);
|
|
58219
58281
|
}
|
|
58220
|
-
await this.saveCredentials(password, credentials);
|
|
58282
|
+
await this.saveCredentials({ password, credentials });
|
|
58221
58283
|
}
|
|
58222
58284
|
}
|
|
58223
58285
|
async getAccountWithActivePositions() {
|
|
@@ -58303,7 +58365,14 @@ class AppDatabase {
|
|
|
58303
58365
|
});
|
|
58304
58366
|
}
|
|
58305
58367
|
async get_exchange_db_instance(account) {
|
|
58306
|
-
|
|
58368
|
+
let filter = `owner="${account.owner}" && exchange="${account.exchange}"`;
|
|
58369
|
+
if (this.email) {
|
|
58370
|
+
const user = await this.getUserByEmail();
|
|
58371
|
+
if (user) {
|
|
58372
|
+
filter = `${filter} && user = "${user.id}"`;
|
|
58373
|
+
}
|
|
58374
|
+
}
|
|
58375
|
+
const result = await this.pb.collection("exchange_accounts").getFirstListItem(filter, {
|
|
58307
58376
|
expand: "proxy"
|
|
58308
58377
|
});
|
|
58309
58378
|
return result;
|
|
@@ -66592,11 +66661,16 @@ class App {
|
|
|
66592
66661
|
}
|
|
66593
66662
|
async function initApp(payload) {
|
|
66594
66663
|
const pb = await initPocketBaseClient(payload.db);
|
|
66595
|
-
const app_db = new AppDatabase(pb
|
|
66664
|
+
const app_db = new AppDatabase(pb, {
|
|
66665
|
+
email: payload.email,
|
|
66666
|
+
salt: payload.salt
|
|
66667
|
+
});
|
|
66596
66668
|
let _getCredentials = payload.getCredentials;
|
|
66597
66669
|
if (payload.password) {
|
|
66598
66670
|
try {
|
|
66599
|
-
const credentials = app_db.getCredentials(
|
|
66671
|
+
const credentials = await app_db.getCredentials({
|
|
66672
|
+
password: payload.password
|
|
66673
|
+
});
|
|
66600
66674
|
if (credentials) {
|
|
66601
66675
|
_getCredentials = (account, exchange) => {
|
|
66602
66676
|
const credential = credentials.find((c) => c.name === account && c.exchange === exchange);
|
package/dist/mcp-server.js
CHANGED
|
@@ -58153,8 +58153,12 @@ async function initPocketBaseClient(proxy_credentials) {
|
|
|
58153
58153
|
|
|
58154
58154
|
class AppDatabase {
|
|
58155
58155
|
pb;
|
|
58156
|
-
|
|
58156
|
+
email;
|
|
58157
|
+
salt;
|
|
58158
|
+
constructor(pb, payload) {
|
|
58157
58159
|
this.pb = pb;
|
|
58160
|
+
this.email = payload.email;
|
|
58161
|
+
this.salt = payload.salt;
|
|
58158
58162
|
const customInspectSymbol = Symbol.for("nodejs.util.inspect.custom");
|
|
58159
58163
|
this[customInspectSymbol] = function() {
|
|
58160
58164
|
return `AppDatabase { pb: [PocketBase Instance - Sensitive Data Masked] }`;
|
|
@@ -58166,21 +58170,79 @@ class AppDatabase {
|
|
|
58166
58170
|
};
|
|
58167
58171
|
};
|
|
58168
58172
|
}
|
|
58169
|
-
|
|
58173
|
+
async getUserByEmail() {
|
|
58174
|
+
if (!this.email) {
|
|
58175
|
+
throw new Error("Email is not set");
|
|
58176
|
+
}
|
|
58177
|
+
const user = await this.pb.collection("users").getFullList({
|
|
58178
|
+
filter: `email="${this.email}"`
|
|
58179
|
+
});
|
|
58180
|
+
return user[0];
|
|
58181
|
+
}
|
|
58182
|
+
async generateUserPassword() {
|
|
58183
|
+
const user = await this.getUserByEmail();
|
|
58184
|
+
if (user) {
|
|
58185
|
+
const userPassword = Math.random().toString(36).substring(2, 15);
|
|
58186
|
+
const encrypted = encryptObject(userPassword, this.salt);
|
|
58187
|
+
await this.pb.collection("users").update(user.id, {
|
|
58188
|
+
settings: {
|
|
58189
|
+
...user.settings || {},
|
|
58190
|
+
password: encrypted
|
|
58191
|
+
}
|
|
58192
|
+
});
|
|
58193
|
+
}
|
|
58194
|
+
}
|
|
58195
|
+
async getUserCredentials() {
|
|
58196
|
+
const record2 = await this.getUserByEmail();
|
|
58197
|
+
if (record2 && record2?.settings) {
|
|
58198
|
+
const password = decryptObject(record2.settings.password, this.salt);
|
|
58199
|
+
if (password) {
|
|
58200
|
+
if (!record2.settings.credentials) {
|
|
58201
|
+
return [];
|
|
58202
|
+
}
|
|
58203
|
+
return decryptObject(record2.settings.credentials, password);
|
|
58204
|
+
}
|
|
58205
|
+
}
|
|
58206
|
+
return null;
|
|
58207
|
+
}
|
|
58208
|
+
async getCredentials(payload) {
|
|
58209
|
+
const { password } = payload;
|
|
58210
|
+
if (this.salt && this.email) {
|
|
58211
|
+
return this.getUserCredentials();
|
|
58212
|
+
}
|
|
58170
58213
|
const credentials = this.pb.authStore.record.credentials;
|
|
58171
58214
|
if (credentials) {
|
|
58172
58215
|
return decryptObject(credentials, password);
|
|
58173
58216
|
}
|
|
58174
58217
|
return null;
|
|
58175
58218
|
}
|
|
58176
|
-
async saveCredentials(
|
|
58177
|
-
const
|
|
58178
|
-
|
|
58179
|
-
|
|
58180
|
-
|
|
58219
|
+
async saveCredentials(params) {
|
|
58220
|
+
const { password, credentials } = params;
|
|
58221
|
+
if (this.salt && this.email) {
|
|
58222
|
+
const user = await this.getUserByEmail();
|
|
58223
|
+
if (user) {
|
|
58224
|
+
const userPassword = decryptObject(user.settings.password, this.salt);
|
|
58225
|
+
if (userPassword) {
|
|
58226
|
+
const encrypted = encryptObject(credentials, userPassword);
|
|
58227
|
+
return await this.pb.collection("users").update(user.id, {
|
|
58228
|
+
settings: {
|
|
58229
|
+
...user.settings,
|
|
58230
|
+
credentials: encrypted
|
|
58231
|
+
}
|
|
58232
|
+
});
|
|
58233
|
+
}
|
|
58234
|
+
}
|
|
58235
|
+
}
|
|
58236
|
+
if (password) {
|
|
58237
|
+
const encrypted = encryptObject(credentials, password);
|
|
58238
|
+
await this.pb.collection("_superusers").update(this.pb.authStore.record.id, {
|
|
58239
|
+
credentials: encrypted
|
|
58240
|
+
});
|
|
58241
|
+
}
|
|
58181
58242
|
}
|
|
58182
|
-
async addNewCredential(
|
|
58183
|
-
|
|
58243
|
+
async addNewCredential(params) {
|
|
58244
|
+
const { password, payload } = params;
|
|
58245
|
+
let credentials = await this.getCredentials({ password });
|
|
58184
58246
|
if (credentials) {
|
|
58185
58247
|
let found = false;
|
|
58186
58248
|
for (const credential of credentials) {
|
|
@@ -58194,7 +58256,7 @@ class AppDatabase {
|
|
|
58194
58256
|
if (!found) {
|
|
58195
58257
|
credentials.push(payload);
|
|
58196
58258
|
}
|
|
58197
|
-
await this.saveCredentials(password, credentials);
|
|
58259
|
+
await this.saveCredentials({ password, credentials });
|
|
58198
58260
|
}
|
|
58199
58261
|
}
|
|
58200
58262
|
async getAccountWithActivePositions() {
|
|
@@ -58280,7 +58342,14 @@ class AppDatabase {
|
|
|
58280
58342
|
});
|
|
58281
58343
|
}
|
|
58282
58344
|
async get_exchange_db_instance(account) {
|
|
58283
|
-
|
|
58345
|
+
let filter = `owner="${account.owner}" && exchange="${account.exchange}"`;
|
|
58346
|
+
if (this.email) {
|
|
58347
|
+
const user = await this.getUserByEmail();
|
|
58348
|
+
if (user) {
|
|
58349
|
+
filter = `${filter} && user = "${user.id}"`;
|
|
58350
|
+
}
|
|
58351
|
+
}
|
|
58352
|
+
const result = await this.pb.collection("exchange_accounts").getFirstListItem(filter, {
|
|
58284
58353
|
expand: "proxy"
|
|
58285
58354
|
});
|
|
58286
58355
|
return result;
|
|
@@ -66569,11 +66638,16 @@ class App {
|
|
|
66569
66638
|
}
|
|
66570
66639
|
async function initApp(payload) {
|
|
66571
66640
|
const pb = await initPocketBaseClient(payload.db);
|
|
66572
|
-
const app_db = new AppDatabase(pb
|
|
66641
|
+
const app_db = new AppDatabase(pb, {
|
|
66642
|
+
email: payload.email,
|
|
66643
|
+
salt: payload.salt
|
|
66644
|
+
});
|
|
66573
66645
|
let _getCredentials = payload.getCredentials;
|
|
66574
66646
|
if (payload.password) {
|
|
66575
66647
|
try {
|
|
66576
|
-
const credentials = app_db.getCredentials(
|
|
66648
|
+
const credentials = await app_db.getCredentials({
|
|
66649
|
+
password: payload.password
|
|
66650
|
+
});
|
|
66577
66651
|
if (credentials) {
|
|
66578
66652
|
_getCredentials = (account, exchange) => {
|
|
66579
66653
|
const credential = credentials.find((c) => c.name === account && c.exchange === exchange);
|