@ercworldio/blockchain-shared 1.0.1-dev.5 → 1.0.1-dev.6

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.
@@ -1,5 +1,6 @@
1
1
  import { DepositWalletBalance } from "../entities/DepositWalletBalance";
2
2
  import { BlockchainType, ChainId, SweepResult, TransferResult } from "../interfaces";
3
+ import { IWallet } from "./types/wallet_manager";
3
4
  import { IDatabasePool } from "../interfaces/database";
4
5
  import { IConfig } from "../interfaces/config";
5
6
  import { DepositEvent } from "./types";
@@ -25,6 +26,14 @@ declare class BalanceService extends BaseErrors {
25
26
  removeWalletBalances(walletId: number, blockchain: string): Promise<boolean>;
26
27
  initializeWalletBalances(walletId: number, blockchain: string): Promise<boolean>;
27
28
  createBalanceBatch(walletId: number, blockchain: string): Promise<boolean>;
29
+ /**
30
+ * Atomically in a single DB round-trip:
31
+ * 1. Archive the old deposit address (ON CONFLICT DO NOTHING — idempotent)
32
+ * 2. Update deposit_addresses with new child index, address, expiry
33
+ * 3. Delete old balance rows
34
+ * 4. Insert fresh balance rows for all payment tokens on the blockchain
35
+ */
36
+ renewWalletTransaction(userId: number, blockchain: string, newChildIndex: number, newAddress: string, newExpiresAt: Date): Promise<IWallet>;
28
37
  private createBalance;
29
38
  batchUpdateBalances(events: DepositEvent[]): Promise<void>;
30
39
  updateBalance(userId: number, blockchain: BlockchainType, address: string, chainId: ChainId, paymentToken: string, amountInWei: bigint, operationType: OperationType): Promise<{
@@ -1 +1 @@
1
- {"version":3,"file":"BalanceService.d.ts","sourceRoot":"","sources":["../../src/services/BalanceService.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,oBAAoB,EAAE,MAAM,kCAAkC,CAAC;AACxE,OAAO,EAAE,cAAc,EAAgB,OAAO,EAAgB,WAAW,EAAE,cAAc,EAAE,MAAM,eAAe,CAAC;AAOjH,OAAO,EAAE,aAAa,EAAE,MAAM,wBAAwB,CAAC;AACvD,OAAO,EAAE,OAAO,EAAE,MAAM,sBAAsB,CAAC;AAC/C,OAAO,EAAE,YAAY,EAAE,MAAM,SAAS,CAAC;AACvC,OAAO,UAAU,MAAM,kBAAkB,CAAC;AAI1C,KAAK,aAAa,GAAG,KAAK,GAAG,QAAQ,CAAC;AAEtC,UAAU,sBAAsB;IAC5B,KAAK,EAAE,MAAM,CAAC;IACd,MAAM,EAAE,MAAM,CAAC;IACf,QAAQ,EAAE,MAAM,CAAC;CACpB;AAED,cAAM,cAAe,SAAQ,UAAU;IACnC,OAAO,CAAC,MAAM,CAAgB;IAC9B,OAAO,CAAC,MAAM,CAAU;IACxB,OAAO,CAAC,MAAM,CAAS;gBACX,MAAM,EAAE,aAAa,EAAE,MAAM,EAAE,OAAO;IASlD;;;OAGG;YACW,iBAAiB;IA6CzB,UAAU,CAAC,MAAM,EAAE,MAAM,EAAE,UAAU,EAAE,MAAM,EAAE,OAAO,EAAE,OAAO,EAAE,YAAY,EAAE,MAAM,GAAG,OAAO,CAAC,sBAAsB,CAAC;IAgCvH,2BAA2B,CAAC,UAAU,EAAE,cAAc,EAAE,OAAO,EAAE,OAAO,EAAE,YAAY,EAAE,MAAM;IAsB9F,oBAAoB,CAAC,QAAQ,EAAE,MAAM,EAAE,UAAU,EAAE,MAAM;IA2BzD,wBAAwB,CAAC,QAAQ,EAAE,MAAM,EAAE,UAAU,EAAE,MAAM;IAI7D,kBAAkB,CAAC,QAAQ,EAAE,MAAM,EAAE,UAAU,EAAE,MAAM;YAmD/C,aAAa;IAwBd,mBAAmB,CAAC,MAAM,EAAE,YAAY,EAAE;IA0EjD,aAAa,CAAC,MAAM,EAAE,MAAM,EAAE,UAAU,EAAE,cAAc,EAAE,OAAO,EAAE,MAAM,EAAE,OAAO,EAAE,OAAO,EAAE,YAAY,EAAE,MAAM,EAAE,WAAW,EAAE,MAAM,EAAE,aAAa,EAAE,aAAa;;;;IA2FpK,qBAAqB,CAAC,SAAS,EAAE,MAAM,EAAE,UAAU,EAAE,cAAc,EAAE,cAAc,EAAE,MAAM,EAAE,aAAa,GAAE,OAAe;IAmE3H,cAAc,CAAC,MAAM,EAAE,MAAM,EAAE,UAAU,EAAE,cAAc;IAUlD,uBAAuB;IAuBvB,kBAAkB,CAAC,KAAK,GAAE,MAAY;YAOrC,gBAAgB;IAoBxB,yBAAyB,CAAC,mBAAmB,EAAE,WAAW,EAAE;IAY5D,6BAA6B,CAAC,mBAAmB,EAAE,cAAc,EAAE;CA8D5E;AAED,eAAe,cAAc,CAAC"}
1
+ {"version":3,"file":"BalanceService.d.ts","sourceRoot":"","sources":["../../src/services/BalanceService.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,oBAAoB,EAAE,MAAM,kCAAkC,CAAC;AACxE,OAAO,EAAE,cAAc,EAAgB,OAAO,EAAgB,WAAW,EAAE,cAAc,EAAE,MAAM,eAAe,CAAC;AACjH,OAAO,EAAE,OAAO,EAAE,MAAM,wBAAwB,CAAC;AAOjD,OAAO,EAAE,aAAa,EAAE,MAAM,wBAAwB,CAAC;AACvD,OAAO,EAAE,OAAO,EAAE,MAAM,sBAAsB,CAAC;AAC/C,OAAO,EAAE,YAAY,EAAE,MAAM,SAAS,CAAC;AACvC,OAAO,UAAU,MAAM,kBAAkB,CAAC;AAI1C,KAAK,aAAa,GAAG,KAAK,GAAG,QAAQ,CAAC;AAEtC,UAAU,sBAAsB;IAC5B,KAAK,EAAE,MAAM,CAAC;IACd,MAAM,EAAE,MAAM,CAAC;IACf,QAAQ,EAAE,MAAM,CAAC;CACpB;AAED,cAAM,cAAe,SAAQ,UAAU;IACnC,OAAO,CAAC,MAAM,CAAgB;IAC9B,OAAO,CAAC,MAAM,CAAU;IACxB,OAAO,CAAC,MAAM,CAAS;gBACX,MAAM,EAAE,aAAa,EAAE,MAAM,EAAE,OAAO;IASlD;;;OAGG;YACW,iBAAiB;IA6CzB,UAAU,CAAC,MAAM,EAAE,MAAM,EAAE,UAAU,EAAE,MAAM,EAAE,OAAO,EAAE,OAAO,EAAE,YAAY,EAAE,MAAM,GAAG,OAAO,CAAC,sBAAsB,CAAC;IAgCvH,2BAA2B,CAAC,UAAU,EAAE,cAAc,EAAE,OAAO,EAAE,OAAO,EAAE,YAAY,EAAE,MAAM;IAsB9F,oBAAoB,CAAC,QAAQ,EAAE,MAAM,EAAE,UAAU,EAAE,MAAM;IA2BzD,wBAAwB,CAAC,QAAQ,EAAE,MAAM,EAAE,UAAU,EAAE,MAAM;IAI7D,kBAAkB,CAAC,QAAQ,EAAE,MAAM,EAAE,UAAU,EAAE,MAAM;IAiD7D;;;;;;OAMG;IACG,sBAAsB,CACxB,MAAM,EAAE,MAAM,EACd,UAAU,EAAE,MAAM,EAClB,aAAa,EAAE,MAAM,EACrB,UAAU,EAAE,MAAM,EAClB,YAAY,EAAE,IAAI,GACnB,OAAO,CAAC,OAAO,CAAC;YAwFL,aAAa;IAwBd,mBAAmB,CAAC,MAAM,EAAE,YAAY,EAAE;IA0EjD,aAAa,CAAC,MAAM,EAAE,MAAM,EAAE,UAAU,EAAE,cAAc,EAAE,OAAO,EAAE,MAAM,EAAE,OAAO,EAAE,OAAO,EAAE,YAAY,EAAE,MAAM,EAAE,WAAW,EAAE,MAAM,EAAE,aAAa,EAAE,aAAa;;;;IA2FpK,qBAAqB,CAAC,SAAS,EAAE,MAAM,EAAE,UAAU,EAAE,cAAc,EAAE,cAAc,EAAE,MAAM,EAAE,aAAa,GAAE,OAAe;IAmE3H,cAAc,CAAC,MAAM,EAAE,MAAM,EAAE,UAAU,EAAE,cAAc;IAUlD,uBAAuB;IAuBvB,kBAAkB,CAAC,KAAK,GAAE,MAAY;YAOrC,gBAAgB;IAoBxB,yBAAyB,CAAC,mBAAmB,EAAE,WAAW,EAAE;IAY5D,6BAA6B,CAAC,mBAAmB,EAAE,cAAc,EAAE;CA8D5E;AAED,eAAe,cAAc,CAAC"}
@@ -185,6 +185,99 @@ class BalanceService extends errors_1.default {
185
185
  return true;
186
186
  });
187
187
  }
188
+ /**
189
+ * Atomically in a single DB round-trip:
190
+ * 1. Archive the old deposit address (ON CONFLICT DO NOTHING — idempotent)
191
+ * 2. Update deposit_addresses with new child index, address, expiry
192
+ * 3. Delete old balance rows
193
+ * 4. Insert fresh balance rows for all payment tokens on the blockchain
194
+ */
195
+ renewWalletTransaction(userId, blockchain, newChildIndex, newAddress, newExpiresAt) {
196
+ return __awaiter(this, void 0, void 0, function* () {
197
+ const dataSource = this.dbPool.getDataSource();
198
+ if (!dataSource)
199
+ throw new Error('Database connection is not initialized.');
200
+ const chainManager = ChainManager_1.default.getInstance(this.config);
201
+ if (!chainManager.paymentTokenMap)
202
+ throw new Error('Payment token map not defined in ChainManager.');
203
+ const chainIds = [];
204
+ const tokens = [];
205
+ const decimals = [];
206
+ for (const [_, config] of Object.entries(chainManager.paymentTokenMap)) {
207
+ if (config.blockchainType.toLowerCase() !== blockchain.toLowerCase())
208
+ continue;
209
+ if (config.status === false)
210
+ continue;
211
+ for (const token of config.paymentTokens) {
212
+ chainIds.push(config.chainId.toString());
213
+ tokens.push(token.address);
214
+ decimals.push(token.decimals);
215
+ }
216
+ }
217
+ if (tokens.length === 0)
218
+ throw new Error(`No payment tokens found for blockchain ${blockchain}`);
219
+ const rows = yield dataSource.query(`
220
+ WITH old_address AS (
221
+ SELECT id, user_id, blockchain, parent_index, child_index, address, transaction_count, expires_at
222
+ FROM usersmanagement.deposit_addresses
223
+ WHERE user_id = $1 AND blockchain = $2
224
+ ),
225
+ archive_step AS (
226
+ INSERT INTO usersmanagement.deposit_addresses_archive
227
+ (original_id, user_id, blockchain, parent_index, child_index, address, transaction_count, expires_at, archived_at, archived_reason)
228
+ SELECT id, user_id, blockchain, parent_index, child_index, address, transaction_count, expires_at, now(), 'renewed'
229
+ FROM old_address
230
+ ON CONFLICT (original_id) DO NOTHING
231
+ ),
232
+ updated_address AS (
233
+ UPDATE usersmanagement.deposit_addresses
234
+ SET child_index = $3,
235
+ address = $4,
236
+ expires_at = $5,
237
+ updated_at = now()
238
+ WHERE user_id = $1 AND blockchain = $2
239
+ RETURNING id, user_id, blockchain, parent_index, child_index, address, transaction_count, expires_at, created_at, updated_at
240
+ ),
241
+ deleted_balances AS (
242
+ DELETE FROM usersmanagement.deposit_wallet_balance
243
+ WHERE wallet_id = (SELECT id FROM updated_address)
244
+ AND blockchain = $2
245
+ ),
246
+ inserted_balances AS (
247
+ INSERT INTO usersmanagement.deposit_wallet_balance
248
+ (wallet_id, blockchain, chain_id, token, decimals, balance, transaction_count, created_at, updated_at)
249
+ SELECT
250
+ (SELECT id FROM updated_address),
251
+ $2,
252
+ v.chain_id,
253
+ v.token,
254
+ v.decimals,
255
+ 0, 0, now(), now()
256
+ FROM (
257
+ SELECT unnest($6::text[]) AS chain_id,
258
+ unnest($7::text[]) AS token,
259
+ unnest($8::int[]) AS decimals
260
+ ) AS v
261
+ )
262
+ SELECT * FROM updated_address;
263
+ `, [userId, blockchain, newChildIndex, newAddress, newExpiresAt.toISOString(), chainIds, tokens, decimals]);
264
+ if (!rows[0])
265
+ throw new Error(`Deposit address not found for user ${userId} on ${blockchain}`);
266
+ const r = rows[0];
267
+ return {
268
+ id: Number(r.id),
269
+ userId: Number(r.user_id),
270
+ blockchain: r.blockchain,
271
+ parentIndex: r.parent_index,
272
+ childIndex: r.child_index,
273
+ address: r.address,
274
+ transactionCount: r.transaction_count,
275
+ expiresAt: r.expires_at,
276
+ createdAt: r.created_at,
277
+ updatedAt: r.updated_at,
278
+ };
279
+ });
280
+ }
188
281
  // Create a balance entity for a given wallet on a given chain for a given payment token
189
282
  // Used when creating new deposit wallets for users
190
283
  createBalance(walletId, blockchain, config, paymentToken, decimals) {
@@ -1 +1 @@
1
- {"version":3,"file":"WalletManager.d.ts","sourceRoot":"","sources":["../../src/services/WalletManager.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,MAAM,EAAoC,MAAM,QAAQ,CAAC;AAClE,OAAO,EAAE,OAAO,EAAE,MAAM,iBAAiB,CAAC;AAM1C,OAAO,EAAE,cAAc,EAAE,OAAO,EAAE,MAAM,eAAe,CAAC;AAIxD,OAAO,EAAe,eAAe,EAAE,MAAM,oBAAoB,CAAC;AAClE,OAAO,EAAE,OAAO,EAAE,MAAM,sBAAsB,CAAC;AAC/C,OAAO,EAAE,aAAa,EAAE,MAAM,wBAAwB,CAAC;AACvD,OAAO,EAAE,SAAS,EAAe,OAAO,EAAgB,cAAc,EAAc,MAAM,wBAAwB,CAAC;AACnH,OAAO,EAAE,yBAAyB,EAAE,MAAM,iBAAiB,CAAC;AAO5D,OAAO,UAAU,MAAM,kBAAkB,CAAC;AAG1C,OAAO,gBAA+B,MAAM,2BAA2B,CAAC;AAGxE,cAAM,aAAc,SAAQ,UAAU;IAClC,MAAM,CAAC,QAAQ,EAAE,aAAa,CAAC;IAC/B,OAAO,CAAC,MAAM,CAAU;IACxB,OAAO,CAAC,MAAM,CAAgB;IACvB,wBAAwB,EAAE,MAAM,CAAC;IACjC,8BAA8B,EAAE,MAAM,CAAC;IACvC,0BAA0B,EAAE,MAAM,CAAC;IAC1C,OAAO,CAAC,MAAM,CAAS;gBACX,MAAM,EAAE,OAAO,EAAE,MAAM,EAAE,aAAa;IAelD,MAAM,CAAC,WAAW,CAAC,MAAM,EAAE,OAAO,EAAE,MAAM,EAAE,aAAa;IAOlD,SAAS,GAAU,QAAQ,MAAM,EAAE,YAAY,cAAc,KAAG,OAAO,CAAC,OAAO,GAAG,IAAI,CAAC,CAsB7F;IAEM,2BAA2B,GAAI,YAAY,cAAc,8CAoC/D;IAGM,gBAAgB,GAAU,SAAS,OAAO,EAAE,SAAS,MAAM,EAAE,EAAE,iBAAiB,eAAe,qBAiBrG;IAED,OAAO,CAAC,2BAA2B;IAa5B,YAAY,GAAU,QAAQ,MAAM,EAAE,YAAY,cAAc,EAAE,mBAAmB,MAAM,KAAG,OAAO,CAAC,OAAO,CAAC,CA4BpH;IAEY,gBAAgB,CAAC,UAAU,EAAE,cAAc,EAAE,OAAO,EAAE,MAAM;IAsBlE,gBAAgB,CAAC,MAAM,EAAE,OAAO;;;;;;;IAoBhC,YAAY,GAAU,QAAQ,MAAM,EAAE,YAAY,cAAc;;;OAGtE;IAGM,WAAW,GAAU,cAAc,yBAAyB,EAAE,QAAQ,MAAM,EAAE,YAAY,cAAc,EAAE,iBAAiB,MAAM,EAAE,mBAAmB,MAAM,KAAG,OAAO,CAAC,OAAO,CAAC,CAuCrL;IAEM,oBAAoB,GAAU,cAAc,yBAAyB,EAAE,YAAY,cAAc,EAAE,YAAY,OAAO,EAAE,YAAY,OAAO,EAAE,SAAS,gBAAgB,sBA8B5K;IAGM,iBAAiB,GAAU,YAAY,OAAO,EAAE,YAAY,OAAO,sBAezE;IAIM,YAAY,GAAI,aAAa,MAAM,EAAE,YAAY,MAAM,EAAE,YAAY,cAAc,EAAE,YAAY,MAAM,eA4E7G;CAIJ;AAED,eAAe,aAAa,CAAC"}
1
+ {"version":3,"file":"WalletManager.d.ts","sourceRoot":"","sources":["../../src/services/WalletManager.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,MAAM,EAAoC,MAAM,QAAQ,CAAC;AAClE,OAAO,EAAE,OAAO,EAAE,MAAM,iBAAiB,CAAC;AAM1C,OAAO,EAAE,cAAc,EAAE,OAAO,EAAE,MAAM,eAAe,CAAC;AAIxD,OAAO,EAAe,eAAe,EAAE,MAAM,oBAAoB,CAAC;AAClE,OAAO,EAAE,OAAO,EAAE,MAAM,sBAAsB,CAAC;AAC/C,OAAO,EAAE,aAAa,EAAE,MAAM,wBAAwB,CAAC;AACvD,OAAO,EAAE,SAAS,EAAe,OAAO,EAAgB,cAAc,EAAc,MAAM,wBAAwB,CAAC;AACnH,OAAO,EAAE,yBAAyB,EAAE,MAAM,iBAAiB,CAAC;AAO5D,OAAO,UAAU,MAAM,kBAAkB,CAAC;AAG1C,OAAO,gBAA+B,MAAM,2BAA2B,CAAC;AAGxE,cAAM,aAAc,SAAQ,UAAU;IAClC,MAAM,CAAC,QAAQ,EAAE,aAAa,CAAC;IAC/B,OAAO,CAAC,MAAM,CAAU;IACxB,OAAO,CAAC,MAAM,CAAgB;IACvB,wBAAwB,EAAE,MAAM,CAAC;IACjC,8BAA8B,EAAE,MAAM,CAAC;IACvC,0BAA0B,EAAE,MAAM,CAAC;IAC1C,OAAO,CAAC,MAAM,CAAS;gBACX,MAAM,EAAE,OAAO,EAAE,MAAM,EAAE,aAAa;IAelD,MAAM,CAAC,WAAW,CAAC,MAAM,EAAE,OAAO,EAAE,MAAM,EAAE,aAAa;IAOlD,SAAS,GAAU,QAAQ,MAAM,EAAE,YAAY,cAAc,KAAG,OAAO,CAAC,OAAO,GAAG,IAAI,CAAC,CAsB7F;IAEM,2BAA2B,GAAI,YAAY,cAAc,8CAoC/D;IAGM,gBAAgB,GAAU,SAAS,OAAO,EAAE,SAAS,MAAM,EAAE,EAAE,iBAAiB,eAAe,qBAiBrG;IAED,OAAO,CAAC,2BAA2B;IAa5B,YAAY,GAAU,QAAQ,MAAM,EAAE,YAAY,cAAc,EAAE,mBAAmB,MAAM,KAAG,OAAO,CAAC,OAAO,CAAC,CA4BpH;IAEY,gBAAgB,CAAC,UAAU,EAAE,cAAc,EAAE,OAAO,EAAE,MAAM;IAsBlE,gBAAgB,CAAC,MAAM,EAAE,OAAO;;;;;;;IAoBhC,YAAY,GAAU,QAAQ,MAAM,EAAE,YAAY,cAAc;;;OAGtE;IAGM,WAAW,GAAU,cAAc,yBAAyB,EAAE,QAAQ,MAAM,EAAE,YAAY,cAAc,EAAE,iBAAiB,MAAM,EAAE,mBAAmB,MAAM,KAAG,OAAO,CAAC,OAAO,CAAC,CA8BrL;IAEM,oBAAoB,GAAU,cAAc,yBAAyB,EAAE,YAAY,cAAc,EAAE,YAAY,OAAO,EAAE,YAAY,OAAO,EAAE,SAAS,gBAAgB,sBA8B5K;IAGM,iBAAiB,GAAU,YAAY,OAAO,EAAE,YAAY,OAAO,sBAezE;IAIM,YAAY,GAAI,aAAa,MAAM,EAAE,YAAY,MAAM,EAAE,YAAY,cAAc,EAAE,YAAY,MAAM,eA4E7G;CAIJ;AAED,eAAe,aAAa,CAAC"}
@@ -191,21 +191,8 @@ class WalletManager extends errors_1.default {
191
191
  if (!newWallet) {
192
192
  throw new Error("Failed to derive new wallet.");
193
193
  }
194
- const depositAddressService = new DepositAddressService_1.default(this.dbPool);
195
- const updatedWallet = yield depositAddressService.updateDepositAddress(userId, {
196
- parentIndex: wallet.parentIndex,
197
- childIndex: newChildIndex,
198
- blockchain,
199
- address: newWallet.address,
200
- expiresAt: new Date(new Date().getTime() + expiry_duration_s * 1000)
201
- });
202
194
  const balanceService = new BalanceService_1.default(this.dbPool, this.config);
203
- const deleteBalancesAndDispatchSweep = yield balanceService.removeWalletBalances(updatedWallet.id, blockchain);
204
- if (!deleteBalancesAndDispatchSweep)
205
- throw new Error(`Failed to remove wallet balances for expired address ${wallet.address}`);
206
- const updatedBalance = yield balanceService.initializeWalletBalances(updatedWallet.id, blockchain);
207
- if (!updatedBalance)
208
- throw new Error(`Failed to initialize wallet balances for address ${updatedWallet.address}`);
195
+ const updatedWallet = yield balanceService.renewWalletTransaction(userId, blockchain, newChildIndex, newWallet.address, new Date(Date.now() + expiry_duration_s * 1000));
209
196
  const timerManager = TimerManager_1.default.getInstance(this.config, this.dbPool);
210
197
  yield timerManager.delete_timer(userId, blockchain);
211
198
  return updatedWallet;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@ercworldio/blockchain-shared",
3
- "version": "1.0.1-dev.5",
3
+ "version": "1.0.1-dev.6",
4
4
  "description": "Shared library for blockchain projects",
5
5
  "main": "build/index.js",
6
6
  "types": "build/index.d.ts",