@ercworldio/blockchain-shared 1.0.1-dev.2 → 1.0.1-dev.4

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.
@@ -210,7 +210,7 @@ class WalletManager extends errors_1.default {
210
210
  });
211
211
  this.updateWebhookAddress = (subscription, blockchain, old_wallet, new_wallet, limiter) => __awaiter(this, void 0, void 0, function* () {
212
212
  const alchemy_service = AlchemyService_1.default.getInstance(this.config);
213
- const qn_service = QnWebhookAddressManager_1.default.getInstance(this.config);
213
+ const qn_service = QnWebhookAddressManager_1.default.getInstance(this.config, this.dbPool, { maxConcurrent: 1, minDelayMs: 1000 });
214
214
  // Add new address and remove expired address (quicknode and alchemy webhooks)
215
215
  const alchemy_res = yield limiter.execute(() => (0, AsyncRateLimiter_1.withRetry)(() => __awaiter(this, void 0, void 0, function* () { return yield alchemy_service.add_remove_addresses_all_webhooks(subscription, blockchain, [new_wallet.address], [old_wallet.address]); }), 2, 500));
216
216
  const quicknode_res_add = yield limiter.execute(() => (0, AsyncRateLimiter_1.withRetry)(() => __awaiter(this, void 0, void 0, function* () { return yield qn_service.add_address(blockchain, new_wallet.address); }), 3, 500));
@@ -1,13 +1,15 @@
1
1
  import { BlockchainType, ChainId } from "../../interfaces";
2
2
  import { IConfig } from "../../interfaces/config";
3
+ import { IDatabasePool } from "../../interfaces/database";
3
4
  import { RateLimiterOptions } from "../../utils/AsyncRateLimiter";
4
5
  declare class QnWebhookAddressManager {
5
6
  private static instance;
6
7
  private api;
7
8
  private config;
8
9
  private cache;
10
+ private db;
9
11
  private constructor();
10
- static getInstance(config: IConfig, rlc?: RateLimiterOptions): QnWebhookAddressManager;
12
+ static getInstance(config: IConfig, db: IDatabasePool, rlc?: RateLimiterOptions): QnWebhookAddressManager;
11
13
  private get_blockchain_for_chain;
12
14
  /** Returns the { name, network } pairs for the notification configs of a given chain. */
13
15
  private get_webhook_keys_for_chain;
@@ -42,6 +44,7 @@ declare class QnWebhookAddressManager {
42
44
  * Call this fire-and-forget after responding to the caller.
43
45
  */
44
46
  sync_remove_from_remaining(blockchain: BlockchainType, address: string, exclude_chain_id: ChainId): Promise<void>;
47
+ private fetch_all_db_addresses;
45
48
  }
46
49
  export default QnWebhookAddressManager;
47
50
  //# sourceMappingURL=QnWebhookAddressManager.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"QnWebhookAddressManager.d.ts","sourceRoot":"","sources":["../../../src/services/quicknode-notifications/QnWebhookAddressManager.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,cAAc,EAAE,OAAO,EAAiB,MAAM,kBAAkB,CAAC;AAC1E,OAAO,EAAE,OAAO,EAAE,MAAM,yBAAyB,CAAC;AAClD,OAAO,EAAE,kBAAkB,EAAE,MAAM,8BAA8B,CAAC;AA0BlE,cAAM,uBAAuB;IACzB,OAAO,CAAC,MAAM,CAAC,QAAQ,CAA0B;IACjD,OAAO,CAAC,GAAG,CAAqB;IAChC,OAAO,CAAC,MAAM,CAAU;IACxB,OAAO,CAAC,KAAK,CAAmD;IAEhE,OAAO;IAKP,MAAM,CAAC,WAAW,CAAC,MAAM,EAAE,OAAO,EAAE,GAAG,CAAC,EAAE,kBAAkB,GAAG,uBAAuB;IAOtF,OAAO,CAAC,wBAAwB;IAKhC,yFAAyF;IACzF,OAAO,CAAC,0BAA0B;IAQlC,OAAO,CAAC,iBAAiB;IAkBzB,OAAO,CAAC,QAAQ;YAMF,IAAI;YAuCJ,aAAa;IAO3B,OAAO,CAAC,WAAW;IAIN,WAAW,CAAC,UAAU,EAAE,cAAc,EAAE,OAAO,EAAE,MAAM,GAAG,OAAO,CAAC,OAAO,CAAC;IAiB1E,cAAc,CAAC,UAAU,EAAE,cAAc,EAAE,OAAO,EAAE,MAAM,GAAG,OAAO,CAAC,OAAO,CAAC;IAiB1F;;;;OAIG;IACU,oBAAoB,CAAC,QAAQ,EAAE,OAAO,EAAE,OAAO,EAAE,MAAM,GAAG,OAAO,CAAC,OAAO,CAAC;IAuBvF;;;;OAIG;IACU,yBAAyB,CAAC,QAAQ,EAAE,OAAO,EAAE,OAAO,EAAE,MAAM,GAAG,OAAO,CAAC,OAAO,CAAC;IAuB5F;;;;OAIG;IACU,qBAAqB,CAAC,UAAU,EAAE,cAAc,EAAE,OAAO,EAAE,MAAM,EAAE,gBAAgB,EAAE,OAAO,GAAG,OAAO,CAAC,IAAI,CAAC;IAkBzH;;;;OAIG;IACU,0BAA0B,CAAC,UAAU,EAAE,cAAc,EAAE,OAAO,EAAE,MAAM,EAAE,gBAAgB,EAAE,OAAO,GAAG,OAAO,CAAC,IAAI,CAAC;CAkBjI;AAED,eAAe,uBAAuB,CAAC"}
1
+ {"version":3,"file":"QnWebhookAddressManager.d.ts","sourceRoot":"","sources":["../../../src/services/quicknode-notifications/QnWebhookAddressManager.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,cAAc,EAAE,OAAO,EAAiB,MAAM,kBAAkB,CAAC;AAC1E,OAAO,EAAE,OAAO,EAAE,MAAM,yBAAyB,CAAC;AAClD,OAAO,EAAE,aAAa,EAAE,MAAM,2BAA2B,CAAC;AAC1D,OAAO,EAAE,kBAAkB,EAAE,MAAM,8BAA8B,CAAC;AA8BlE,cAAM,uBAAuB;IACzB,OAAO,CAAC,MAAM,CAAC,QAAQ,CAA0B;IACjD,OAAO,CAAC,GAAG,CAAqB;IAChC,OAAO,CAAC,MAAM,CAAU;IACxB,OAAO,CAAC,KAAK,CAAmD;IAEhE,OAAO,CAAC,EAAE,CAAgB;IAC1B,OAAO;IAMP,MAAM,CAAC,WAAW,CAAC,MAAM,EAAE,OAAO,EAAE,EAAE,EAAE,aAAa,EAAE,GAAG,CAAC,EAAE,kBAAkB,GAAG,uBAAuB;IAOzG,OAAO,CAAC,wBAAwB;IAKhC,yFAAyF;IACzF,OAAO,CAAC,0BAA0B;IAQlC,OAAO,CAAC,iBAAiB;IAkBzB,OAAO,CAAC,QAAQ;YAMF,IAAI;YAwCJ,aAAa;IAO3B,OAAO,CAAC,WAAW;IAIN,WAAW,CAAC,UAAU,EAAE,cAAc,EAAE,OAAO,EAAE,MAAM,GAAG,OAAO,CAAC,OAAO,CAAC;IAkB1E,cAAc,CAAC,UAAU,EAAE,cAAc,EAAE,OAAO,EAAE,MAAM,GAAG,OAAO,CAAC,OAAO,CAAC;IAiB1F;;;;OAIG;IACU,oBAAoB,CAAC,QAAQ,EAAE,OAAO,EAAE,OAAO,EAAE,MAAM,GAAG,OAAO,CAAC,OAAO,CAAC;IAuBvF;;;;OAIG;IACU,yBAAyB,CAAC,QAAQ,EAAE,OAAO,EAAE,OAAO,EAAE,MAAM,GAAG,OAAO,CAAC,OAAO,CAAC;IAuB5F;;;;OAIG;IACU,qBAAqB,CAAC,UAAU,EAAE,cAAc,EAAE,OAAO,EAAE,MAAM,EAAE,gBAAgB,EAAE,OAAO,GAAG,OAAO,CAAC,IAAI,CAAC;IAkBzH;;;;OAIG;IACU,0BAA0B,CAAC,UAAU,EAAE,cAAc,EAAE,OAAO,EAAE,MAAM,EAAE,gBAAgB,EAAE,OAAO,GAAG,OAAO,CAAC,IAAI,CAAC;YAqBhH,sBAAsB;CAuBvC;AAED,eAAe,uBAAuB,CAAC"}
@@ -13,17 +13,21 @@ var __importDefault = (this && this.__importDefault) || function (mod) {
13
13
  };
14
14
  Object.defineProperty(exports, "__esModule", { value: true });
15
15
  const ChainManager_1 = __importDefault(require("../ChainManager"));
16
+ const DepositAddressService_1 = __importDefault(require("../DepositAddressService"));
16
17
  const QnNotificationsApi_1 = __importDefault(require("./QnNotificationsApi"));
17
18
  const CACHE_TTL_MS = 10 * 60 * 1000; // 10 minutes
19
+ const ADDRESS_SYNC_BATCH_SIZE = 500;
20
+ const ADDRESS_LOG_THRESHOLD = 1000;
18
21
  class QnWebhookAddressManager {
19
- constructor(config, rlc) {
22
+ constructor(config, db, rlc) {
20
23
  this.cache = new Map();
21
24
  this.config = config;
22
25
  this.api = QnNotificationsApi_1.default.getInstance(config, rlc);
26
+ this.db = db;
23
27
  }
24
- static getInstance(config, rlc) {
28
+ static getInstance(config, db, rlc) {
25
29
  if (!this.instance) {
26
- this.instance = new QnWebhookAddressManager(config, rlc);
30
+ this.instance = new QnWebhookAddressManager(config, db, rlc);
27
31
  }
28
32
  return this.instance;
29
33
  }
@@ -62,7 +66,6 @@ class QnWebhookAddressManager {
62
66
  }
63
67
  load(blockchain) {
64
68
  return __awaiter(this, void 0, void 0, function* () {
65
- var _a;
66
69
  const notif_configs = this.get_notif_configs(blockchain);
67
70
  if (notif_configs.length === 0)
68
71
  return;
@@ -75,6 +78,8 @@ class QnWebhookAddressManager {
75
78
  console.error(`QnWebhookAddressManager: Failed to fetch webhooks for blockchain=${blockchain}`, error);
76
79
  return;
77
80
  }
81
+ // Get all addresses to add to webhook
82
+ const addresses = yield this.fetch_all_db_addresses(blockchain);
78
83
  const entries = [];
79
84
  for (const notif_config of notif_configs) {
80
85
  const existing = all_webhooks.find(w => {
@@ -86,8 +91,6 @@ class QnWebhookAddressManager {
86
91
  console.warn(`QnWebhookAddressManager: No webhook found for config=${notif_config.name} network=${notif_config.network}`);
87
92
  continue;
88
93
  }
89
- const arg_key = notif_config.template === 'solanaWalletFilter' ? 'accounts' : 'wallets';
90
- const addresses = ((_a = existing.templateArgs) === null || _a === void 0 ? void 0 : _a[arg_key]) || [];
91
94
  entries.push({
92
95
  webhook_id: existing.id,
93
96
  name: notif_config.name.toLowerCase(),
@@ -119,6 +122,7 @@ class QnWebhookAddressManager {
119
122
  continue;
120
123
  entry.address_set.add(address);
121
124
  try {
125
+ console.log(`Adding addresses: `, entry.address_set);
122
126
  yield this.api.update_webhook_addresses(entry.webhook_id, entry.template, Array.from(entry.address_set));
123
127
  console.log(`QnWebhookAddressManager: Added ${address} to ${entry.name} webhook`);
124
128
  }
@@ -261,5 +265,27 @@ class QnWebhookAddressManager {
261
265
  }
262
266
  });
263
267
  }
268
+ // Get all custodial addresses for monitoring
269
+ fetch_all_db_addresses(blockchain) {
270
+ return __awaiter(this, void 0, void 0, function* () {
271
+ const service = new DepositAddressService_1.default(this.db);
272
+ const addresses = [];
273
+ let page = 1;
274
+ const page_size = ADDRESS_SYNC_BATCH_SIZE;
275
+ while (true) {
276
+ const result = yield service.getDepositAddressesPaginated(page, page_size, { blockchain });
277
+ for (const item of result.items) {
278
+ addresses.push(item.address);
279
+ }
280
+ if (!result.has_next)
281
+ break;
282
+ page++;
283
+ }
284
+ if (addresses.length > ADDRESS_LOG_THRESHOLD) {
285
+ console.warn(`QnWebhookAddressManager: ${addresses.length} addresses fetched for blockchain=${blockchain} — ensure QN webhook limit is sufficient`);
286
+ }
287
+ return addresses;
288
+ });
289
+ }
264
290
  }
265
291
  exports.default = QnWebhookAddressManager;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@ercworldio/blockchain-shared",
3
- "version": "1.0.1-dev.2",
3
+ "version": "1.0.1-dev.4",
4
4
  "description": "Shared library for blockchain projects",
5
5
  "main": "build/index.js",
6
6
  "types": "build/index.d.ts",