@gbozee/ultimate 0.0.2-104 → 0.0.2-106
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.js +1 -0
- package/dist/index.cjs +107 -13
- package/dist/index.d.ts +27 -8
- package/dist/index.js +107 -13
- package/dist/mcp-server.cjs +107 -13
- package/dist/mcp-server.js +107 -13
- package/package.json +1 -1
package/dist/frontend-index.js
CHANGED
|
@@ -1794,6 +1794,7 @@ function computeProfitDetail(payload) {
|
|
|
1794
1794
|
loss = Math.abs(reduce_position.entry - sell_price) * reduce_position.quantity;
|
|
1795
1795
|
const ratio = pnl / loss;
|
|
1796
1796
|
quantity = to_f(reduce_position.quantity * ratio, decimal_places);
|
|
1797
|
+
expected_loss = to_f(Math.abs(reduce_position.entry - sell_price) * quantity, "%.2f");
|
|
1797
1798
|
}
|
|
1798
1799
|
if (reverse_position) {
|
|
1799
1800
|
expected_loss = Math.abs(reverse_position.avg_price - sell_price) * reverse_position.avg_qty;
|
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;
|
|
@@ -52017,6 +52086,17 @@ class AppDatabase {
|
|
|
52017
52086
|
secondary_long_strategy,
|
|
52018
52087
|
secondary_short_strategy
|
|
52019
52088
|
} = instance.expand;
|
|
52089
|
+
const update_boolean = (value) => {
|
|
52090
|
+
if (!value) {
|
|
52091
|
+
return value;
|
|
52092
|
+
}
|
|
52093
|
+
return {
|
|
52094
|
+
...value,
|
|
52095
|
+
follow: Boolean(value.follow),
|
|
52096
|
+
place_tp: Boolean(value.place_tp),
|
|
52097
|
+
pause_tp: Boolean(value.pause_tp)
|
|
52098
|
+
};
|
|
52099
|
+
};
|
|
52020
52100
|
return {
|
|
52021
52101
|
...instance,
|
|
52022
52102
|
main: {
|
|
@@ -52029,6 +52109,10 @@ class AppDatabase {
|
|
|
52029
52109
|
position: {
|
|
52030
52110
|
long: instance.main_long_position,
|
|
52031
52111
|
short: instance.main_short_position
|
|
52112
|
+
},
|
|
52113
|
+
config: {
|
|
52114
|
+
long: update_boolean(instance.main_long_config),
|
|
52115
|
+
short: update_boolean(instance.main_short_config)
|
|
52032
52116
|
}
|
|
52033
52117
|
},
|
|
52034
52118
|
secondary: {
|
|
@@ -52041,6 +52125,10 @@ class AppDatabase {
|
|
|
52041
52125
|
position: {
|
|
52042
52126
|
long: instance.secondary_long_position,
|
|
52043
52127
|
short: instance.secondary_short_position
|
|
52128
|
+
},
|
|
52129
|
+
config: {
|
|
52130
|
+
long: update_boolean(instance.secondary_long_config),
|
|
52131
|
+
short: update_boolean(instance.secondary_short_config)
|
|
52044
52132
|
}
|
|
52045
52133
|
}
|
|
52046
52134
|
};
|
|
@@ -53967,6 +54055,7 @@ function computeProfitDetail(payload) {
|
|
|
53967
54055
|
loss = Math.abs(reduce_position.entry - sell_price) * reduce_position.quantity;
|
|
53968
54056
|
const ratio = pnl / loss;
|
|
53969
54057
|
quantity = to_f2(reduce_position.quantity * ratio, decimal_places);
|
|
54058
|
+
expected_loss = to_f2(Math.abs(reduce_position.entry - sell_price) * quantity, "%.2f");
|
|
53970
54059
|
}
|
|
53971
54060
|
if (reverse_position) {
|
|
53972
54061
|
expected_loss = Math.abs(reverse_position.avg_price - sell_price) * reverse_position.avg_qty;
|
|
@@ -59890,11 +59979,16 @@ class App {
|
|
|
59890
59979
|
}
|
|
59891
59980
|
async function initApp(payload) {
|
|
59892
59981
|
const pb = await initPocketBaseClient(payload.db);
|
|
59893
|
-
const app_db = new AppDatabase(pb
|
|
59982
|
+
const app_db = new AppDatabase(pb, {
|
|
59983
|
+
email: payload.email,
|
|
59984
|
+
salt: payload.salt
|
|
59985
|
+
});
|
|
59894
59986
|
let _getCredentials = payload.getCredentials;
|
|
59895
59987
|
if (payload.password) {
|
|
59896
59988
|
try {
|
|
59897
|
-
const credentials = app_db.getCredentials(
|
|
59989
|
+
const credentials = await app_db.getCredentials({
|
|
59990
|
+
password: payload.password
|
|
59991
|
+
});
|
|
59898
59992
|
if (credentials) {
|
|
59899
59993
|
_getCredentials = (account, exchange) => {
|
|
59900
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;
|
|
@@ -51969,6 +52038,17 @@ class AppDatabase {
|
|
|
51969
52038
|
secondary_long_strategy,
|
|
51970
52039
|
secondary_short_strategy
|
|
51971
52040
|
} = instance.expand;
|
|
52041
|
+
const update_boolean = (value) => {
|
|
52042
|
+
if (!value) {
|
|
52043
|
+
return value;
|
|
52044
|
+
}
|
|
52045
|
+
return {
|
|
52046
|
+
...value,
|
|
52047
|
+
follow: Boolean(value.follow),
|
|
52048
|
+
place_tp: Boolean(value.place_tp),
|
|
52049
|
+
pause_tp: Boolean(value.pause_tp)
|
|
52050
|
+
};
|
|
52051
|
+
};
|
|
51972
52052
|
return {
|
|
51973
52053
|
...instance,
|
|
51974
52054
|
main: {
|
|
@@ -51981,6 +52061,10 @@ class AppDatabase {
|
|
|
51981
52061
|
position: {
|
|
51982
52062
|
long: instance.main_long_position,
|
|
51983
52063
|
short: instance.main_short_position
|
|
52064
|
+
},
|
|
52065
|
+
config: {
|
|
52066
|
+
long: update_boolean(instance.main_long_config),
|
|
52067
|
+
short: update_boolean(instance.main_short_config)
|
|
51984
52068
|
}
|
|
51985
52069
|
},
|
|
51986
52070
|
secondary: {
|
|
@@ -51993,6 +52077,10 @@ class AppDatabase {
|
|
|
51993
52077
|
position: {
|
|
51994
52078
|
long: instance.secondary_long_position,
|
|
51995
52079
|
short: instance.secondary_short_position
|
|
52080
|
+
},
|
|
52081
|
+
config: {
|
|
52082
|
+
long: update_boolean(instance.secondary_long_config),
|
|
52083
|
+
short: update_boolean(instance.secondary_short_config)
|
|
51996
52084
|
}
|
|
51997
52085
|
}
|
|
51998
52086
|
};
|
|
@@ -53919,6 +54007,7 @@ function computeProfitDetail(payload) {
|
|
|
53919
54007
|
loss = Math.abs(reduce_position.entry - sell_price) * reduce_position.quantity;
|
|
53920
54008
|
const ratio = pnl / loss;
|
|
53921
54009
|
quantity = to_f2(reduce_position.quantity * ratio, decimal_places);
|
|
54010
|
+
expected_loss = to_f2(Math.abs(reduce_position.entry - sell_price) * quantity, "%.2f");
|
|
53922
54011
|
}
|
|
53923
54012
|
if (reverse_position) {
|
|
53924
54013
|
expected_loss = Math.abs(reverse_position.avg_price - sell_price) * reverse_position.avg_qty;
|
|
@@ -59842,11 +59931,16 @@ class App {
|
|
|
59842
59931
|
}
|
|
59843
59932
|
async function initApp(payload) {
|
|
59844
59933
|
const pb = await initPocketBaseClient(payload.db);
|
|
59845
|
-
const app_db = new AppDatabase(pb
|
|
59934
|
+
const app_db = new AppDatabase(pb, {
|
|
59935
|
+
email: payload.email,
|
|
59936
|
+
salt: payload.salt
|
|
59937
|
+
});
|
|
59846
59938
|
let _getCredentials = payload.getCredentials;
|
|
59847
59939
|
if (payload.password) {
|
|
59848
59940
|
try {
|
|
59849
|
-
const credentials = app_db.getCredentials(
|
|
59941
|
+
const credentials = await app_db.getCredentials({
|
|
59942
|
+
password: payload.password
|
|
59943
|
+
});
|
|
59850
59944
|
if (credentials) {
|
|
59851
59945
|
_getCredentials = (account, exchange) => {
|
|
59852
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;
|
|
@@ -58725,6 +58794,17 @@ class AppDatabase {
|
|
|
58725
58794
|
secondary_long_strategy,
|
|
58726
58795
|
secondary_short_strategy
|
|
58727
58796
|
} = instance.expand;
|
|
58797
|
+
const update_boolean = (value) => {
|
|
58798
|
+
if (!value) {
|
|
58799
|
+
return value;
|
|
58800
|
+
}
|
|
58801
|
+
return {
|
|
58802
|
+
...value,
|
|
58803
|
+
follow: Boolean(value.follow),
|
|
58804
|
+
place_tp: Boolean(value.place_tp),
|
|
58805
|
+
pause_tp: Boolean(value.pause_tp)
|
|
58806
|
+
};
|
|
58807
|
+
};
|
|
58728
58808
|
return {
|
|
58729
58809
|
...instance,
|
|
58730
58810
|
main: {
|
|
@@ -58737,6 +58817,10 @@ class AppDatabase {
|
|
|
58737
58817
|
position: {
|
|
58738
58818
|
long: instance.main_long_position,
|
|
58739
58819
|
short: instance.main_short_position
|
|
58820
|
+
},
|
|
58821
|
+
config: {
|
|
58822
|
+
long: update_boolean(instance.main_long_config),
|
|
58823
|
+
short: update_boolean(instance.main_short_config)
|
|
58740
58824
|
}
|
|
58741
58825
|
},
|
|
58742
58826
|
secondary: {
|
|
@@ -58749,6 +58833,10 @@ class AppDatabase {
|
|
|
58749
58833
|
position: {
|
|
58750
58834
|
long: instance.secondary_long_position,
|
|
58751
58835
|
short: instance.secondary_short_position
|
|
58836
|
+
},
|
|
58837
|
+
config: {
|
|
58838
|
+
long: update_boolean(instance.secondary_long_config),
|
|
58839
|
+
short: update_boolean(instance.secondary_short_config)
|
|
58752
58840
|
}
|
|
58753
58841
|
}
|
|
58754
58842
|
};
|
|
@@ -60655,6 +60743,7 @@ function computeProfitDetail(payload) {
|
|
|
60655
60743
|
loss = Math.abs(reduce_position.entry - sell_price) * reduce_position.quantity;
|
|
60656
60744
|
const ratio = pnl / loss;
|
|
60657
60745
|
quantity = to_f2(reduce_position.quantity * ratio, decimal_places);
|
|
60746
|
+
expected_loss = to_f2(Math.abs(reduce_position.entry - sell_price) * quantity, "%.2f");
|
|
60658
60747
|
}
|
|
60659
60748
|
if (reverse_position) {
|
|
60660
60749
|
expected_loss = Math.abs(reverse_position.avg_price - sell_price) * reverse_position.avg_qty;
|
|
@@ -66572,11 +66661,16 @@ class App {
|
|
|
66572
66661
|
}
|
|
66573
66662
|
async function initApp(payload) {
|
|
66574
66663
|
const pb = await initPocketBaseClient(payload.db);
|
|
66575
|
-
const app_db = new AppDatabase(pb
|
|
66664
|
+
const app_db = new AppDatabase(pb, {
|
|
66665
|
+
email: payload.email,
|
|
66666
|
+
salt: payload.salt
|
|
66667
|
+
});
|
|
66576
66668
|
let _getCredentials = payload.getCredentials;
|
|
66577
66669
|
if (payload.password) {
|
|
66578
66670
|
try {
|
|
66579
|
-
const credentials = app_db.getCredentials(
|
|
66671
|
+
const credentials = await app_db.getCredentials({
|
|
66672
|
+
password: payload.password
|
|
66673
|
+
});
|
|
66580
66674
|
if (credentials) {
|
|
66581
66675
|
_getCredentials = (account, exchange) => {
|
|
66582
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;
|
|
@@ -58702,6 +58771,17 @@ class AppDatabase {
|
|
|
58702
58771
|
secondary_long_strategy,
|
|
58703
58772
|
secondary_short_strategy
|
|
58704
58773
|
} = instance.expand;
|
|
58774
|
+
const update_boolean = (value) => {
|
|
58775
|
+
if (!value) {
|
|
58776
|
+
return value;
|
|
58777
|
+
}
|
|
58778
|
+
return {
|
|
58779
|
+
...value,
|
|
58780
|
+
follow: Boolean(value.follow),
|
|
58781
|
+
place_tp: Boolean(value.place_tp),
|
|
58782
|
+
pause_tp: Boolean(value.pause_tp)
|
|
58783
|
+
};
|
|
58784
|
+
};
|
|
58705
58785
|
return {
|
|
58706
58786
|
...instance,
|
|
58707
58787
|
main: {
|
|
@@ -58714,6 +58794,10 @@ class AppDatabase {
|
|
|
58714
58794
|
position: {
|
|
58715
58795
|
long: instance.main_long_position,
|
|
58716
58796
|
short: instance.main_short_position
|
|
58797
|
+
},
|
|
58798
|
+
config: {
|
|
58799
|
+
long: update_boolean(instance.main_long_config),
|
|
58800
|
+
short: update_boolean(instance.main_short_config)
|
|
58717
58801
|
}
|
|
58718
58802
|
},
|
|
58719
58803
|
secondary: {
|
|
@@ -58726,6 +58810,10 @@ class AppDatabase {
|
|
|
58726
58810
|
position: {
|
|
58727
58811
|
long: instance.secondary_long_position,
|
|
58728
58812
|
short: instance.secondary_short_position
|
|
58813
|
+
},
|
|
58814
|
+
config: {
|
|
58815
|
+
long: update_boolean(instance.secondary_long_config),
|
|
58816
|
+
short: update_boolean(instance.secondary_short_config)
|
|
58729
58817
|
}
|
|
58730
58818
|
}
|
|
58731
58819
|
};
|
|
@@ -60632,6 +60720,7 @@ function computeProfitDetail(payload) {
|
|
|
60632
60720
|
loss = Math.abs(reduce_position.entry - sell_price) * reduce_position.quantity;
|
|
60633
60721
|
const ratio = pnl / loss;
|
|
60634
60722
|
quantity = to_f2(reduce_position.quantity * ratio, decimal_places);
|
|
60723
|
+
expected_loss = to_f2(Math.abs(reduce_position.entry - sell_price) * quantity, "%.2f");
|
|
60635
60724
|
}
|
|
60636
60725
|
if (reverse_position) {
|
|
60637
60726
|
expected_loss = Math.abs(reverse_position.avg_price - sell_price) * reverse_position.avg_qty;
|
|
@@ -66549,11 +66638,16 @@ class App {
|
|
|
66549
66638
|
}
|
|
66550
66639
|
async function initApp(payload) {
|
|
66551
66640
|
const pb = await initPocketBaseClient(payload.db);
|
|
66552
|
-
const app_db = new AppDatabase(pb
|
|
66641
|
+
const app_db = new AppDatabase(pb, {
|
|
66642
|
+
email: payload.email,
|
|
66643
|
+
salt: payload.salt
|
|
66644
|
+
});
|
|
66553
66645
|
let _getCredentials = payload.getCredentials;
|
|
66554
66646
|
if (payload.password) {
|
|
66555
66647
|
try {
|
|
66556
|
-
const credentials = app_db.getCredentials(
|
|
66648
|
+
const credentials = await app_db.getCredentials({
|
|
66649
|
+
password: payload.password
|
|
66650
|
+
});
|
|
66557
66651
|
if (credentials) {
|
|
66558
66652
|
_getCredentials = (account, exchange) => {
|
|
66559
66653
|
const credential = credentials.find((c) => c.name === account && c.exchange === exchange);
|