"use strict";Object.defineProperty(exports,"__esModule",{value:!0});exports.walletDataService=exports.WalletDataService=void 0;const db_1=require("@b/db"),encrypt_1=require("@b/utils/encrypt"),console_1=require("@b/utils/console"),errors_1=require("./errors"),precision_1=require("./utils/precision");class WalletDataService{constructor(){}static getInstance(){WalletDataService.instance||(WalletDataService.instance=new WalletDataService);return WalletDataService.instance}async create(e){const{walletId:a,currency:t,chain:r,address:l,index:n=0,encryptedData:c,transaction:i}=e;if(await db_1.models.walletData.findOne({where:{walletId:a,currency:t,chain:r},...i&&{transaction:i}})){await db_1.models.walletData.update({balance:0,index:n,data:c},{where:{walletId:a,currency:t,chain:r},...i&&{transaction:i}});const e=await db_1.models.walletData.findOne({where:{walletId:a,currency:t,chain:r},...i&&{transaction:i}});return this.toAttributes(e)}const o=await db_1.models.walletData.create({walletId:a,currency:t,chain:r,balance:0,index:n,data:c},i?{transaction:i}:void 0);console_1.logger.debug("WALLET_DATA",`Created wallet data for ${a}/${r}`);return this.toAttributes(o)}async getByWalletAndChain(e,a,t){const r=await db_1.models.walletData.findOne({where:{walletId:e,chain:a},...t&&{transaction:t}});return r?this.toAttributes(r):null}async getByWalletAndChainOrThrow(e,a,t){const r=await this.getByWalletAndChain(e,a,t);if(!r)throw new errors_1.WalletDataNotFoundError(e,a);return r}async getAllForWallet(e){return(await db_1.models.walletData.findAll({where:{walletId:e}})).map(e=>this.toAttributes(e))}async getDecryptedData(e,a){const t=await this.getByWalletAndChain(e,a);if(!t||!t.data)return null;try{return JSON.parse((0,encrypt_1.decrypt)(t.data))}catch(e){console_1.logger.error("WALLET_DATA",`Failed to decrypt wallet data: ${e.message}`);throw new errors_1.EncryptionError("decrypt")}}async getDecryptedDataOrThrow(e,a){const t=await this.getDecryptedData(e,a);if(!t)throw new errors_1.WalletDataNotFoundError(e,a);return t}async updateBalance(e,a,t,r,l){var n;const c=await db_1.models.walletData.findOne({where:{walletId:e,chain:a},...l&&{transaction:l}});if(!c)throw new errors_1.WalletDataNotFoundError(e,a);const i=parseFloat((null===(n=c.balance)||void 0===n?void 0:n.toString())||"0");let o;if("add"===r)o=(0,precision_1.safeAdd)(i,t,c.currency);else{o=(0,precision_1.safeSubtract)(i,t,c.currency);if(o<0)throw new errors_1.WalletError(`Insufficient balance in wallet data: ${i} < ${t}`,"INSUFFICIENT_WALLET_DATA_BALANCE",400)}await db_1.models.walletData.update({balance:o},{where:{walletId:e,chain:a},...l&&{transaction:l}});console_1.logger.debug("WALLET_DATA",`Updated balance for ${e}/${a}: ${i} -> ${o}`)}async syncBalance(e,a,t,r){await db_1.models.walletData.update({balance:t},{where:{walletId:e,chain:a},...r&&{transaction:r}})}async getTotalBalance(e){return await db_1.models.walletData.sum("balance",{where:{walletId:e}})||0}async exists(e,a){return await db_1.models.walletData.count({where:{walletId:e,chain:a}})>0}async delete(e,a,t){await db_1.models.walletData.destroy({where:{walletId:e,chain:a},...t&&{transaction:t}})}toAttributes(e){var a;const t=e.get?e.get({plain:!0}):e;return{...t,balance:parseFloat((null===(a=t.balance)||void 0===a?void 0:a.toString())||"0")}}}exports.WalletDataService=WalletDataService;exports.walletDataService=WalletDataService.getInstance();