@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;
|
|
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,
|
|
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
|
|
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;
|