@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.
@@ -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
- constructor(pb) {
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
- getCredentials(password) {
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(password, credentials) {
51492
- const encrypted = encryptObject(credentials, password);
51493
- await this.pb.collection("_superusers").update(this.pb.authStore.record.id, {
51494
- credentials: encrypted
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(password, payload) {
51498
- let credentials = this.getCredentials(password);
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
- const result = await this.pb.collection("exchange_accounts").getFirstListItem(`owner="${account.owner}" && exchange="${account.exchange}"`, {
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(payload.password);
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
- constructor(pb: PocketBase);
441
- getCredentials(password: string): any;
442
- saveCredentials(password: string, credentials: any): Promise<void>;
443
- addNewCredential(password: string, payload: {
444
- name: string;
445
- exchange: string;
446
- api_key: string;
447
- api_secret: string;
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
- constructor(pb) {
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
- getCredentials(password) {
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(password, credentials) {
51444
- const encrypted = encryptObject(credentials, password);
51445
- await this.pb.collection("_superusers").update(this.pb.authStore.record.id, {
51446
- credentials: encrypted
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(password, payload) {
51450
- let credentials = this.getCredentials(password);
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
- const result = await this.pb.collection("exchange_accounts").getFirstListItem(`owner="${account.owner}" && exchange="${account.exchange}"`, {
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(payload.password);
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);
@@ -58176,8 +58176,12 @@ async function initPocketBaseClient(proxy_credentials) {
58176
58176
 
58177
58177
  class AppDatabase {
58178
58178
  pb;
58179
- constructor(pb) {
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
- getCredentials(password) {
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(password, credentials) {
58200
- const encrypted = encryptObject(credentials, password);
58201
- await this.pb.collection("_superusers").update(this.pb.authStore.record.id, {
58202
- credentials: encrypted
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(password, payload) {
58206
- let credentials = this.getCredentials(password);
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
- const result = await this.pb.collection("exchange_accounts").getFirstListItem(`owner="${account.owner}" && exchange="${account.exchange}"`, {
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(payload.password);
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);
@@ -58153,8 +58153,12 @@ async function initPocketBaseClient(proxy_credentials) {
58153
58153
 
58154
58154
  class AppDatabase {
58155
58155
  pb;
58156
- constructor(pb) {
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
- getCredentials(password) {
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(password, credentials) {
58177
- const encrypted = encryptObject(credentials, password);
58178
- await this.pb.collection("_superusers").update(this.pb.authStore.record.id, {
58179
- credentials: encrypted
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(password, payload) {
58183
- let credentials = this.getCredentials(password);
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
- const result = await this.pb.collection("exchange_accounts").getFirstListItem(`owner="${account.owner}" && exchange="${account.exchange}"`, {
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(payload.password);
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);
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "@gbozee/ultimate",
3
3
  "type": "module",
4
- "version": "0.0.2-104",
4
+ "version": "0.0.2-106",
5
5
  "main": "./dist/index.cjs",
6
6
  "module": "./dist/index.js",
7
7
  "types": "./dist/index.d.ts",