@usherlabs/cex-broker 0.2.51 → 0.2.52

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.
@@ -317211,6 +317211,16 @@ function withTimeout(promise, timeoutMs, label) {
317211
317211
  return Promise.race([promise, expiry]).finally(() => clearTimeout(timer));
317212
317212
  }
317213
317213
  var ALL_CURRENCIES_CODE = "*";
317214
+ var BINANCE_UNLOCK_PROGRESS_SOURCE = {
317215
+ venue: "binance",
317216
+ endpoint: "GET /sapi/v1/capital/deposit/hisrec",
317217
+ fields: {
317218
+ status: "info.status",
317219
+ confirmTimes: "info.confirmTimes",
317220
+ unlockConfirm: "info.unlockConfirm",
317221
+ completeTime: "info.completeTime"
317222
+ }
317223
+ };
317214
317224
  function depositTimestamp(record) {
317215
317225
  const observedAt = depositField(record, [
317216
317226
  "timestamp",
@@ -317223,12 +317233,185 @@ function depositTimestamp(record) {
317223
317233
  const timestamp = typeof observedAt === "number" ? observedAt : typeof observedAt === "string" ? Date.parse(observedAt) : Number.NaN;
317224
317234
  return Number.isFinite(timestamp) ? timestamp : undefined;
317225
317235
  }
317226
- function archivedDepositStatus(exchangeId, record) {
317227
- const rawStatus = asRecord(record.info)?.status;
317228
- if (exchangeId?.toLowerCase() === "binance" && String(rawStatus ?? "").trim() === "6") {
317229
- return "credited_not_withdrawable";
317236
+ function parseNonNegativeInteger(value) {
317237
+ if (typeof value === "number") {
317238
+ return Number.isSafeInteger(value) && value >= 0 ? value : undefined;
317239
+ }
317240
+ if (typeof value !== "string") {
317241
+ return;
317242
+ }
317243
+ const trimmed = value.trim();
317244
+ if (!/^\d+$/.test(trimmed)) {
317245
+ return;
317246
+ }
317247
+ const parsed = Number(trimmed);
317248
+ return Number.isSafeInteger(parsed) && parsed >= 0 ? parsed : undefined;
317249
+ }
317250
+ function parseConfirmTimes(value) {
317251
+ if (value === undefined || value === null) {
317252
+ return { reason: "missing_confirmTimes" };
317253
+ }
317254
+ let currentValue;
317255
+ let creditRequiredValue;
317256
+ if (typeof value === "string") {
317257
+ const match = /^(\d+)\s*\/\s*(\d+)$/.exec(value.trim());
317258
+ if (!match) {
317259
+ return { reason: "invalid_confirmTimes" };
317260
+ }
317261
+ currentValue = match[1];
317262
+ creditRequiredValue = match[2];
317263
+ } else {
317264
+ const record = asRecord(value);
317265
+ if (!record) {
317266
+ return { reason: "invalid_confirmTimes" };
317267
+ }
317268
+ currentValue = record.current;
317269
+ creditRequiredValue = record.credit_required;
317270
+ }
317271
+ const current = parseNonNegativeInteger(currentValue);
317272
+ const creditRequired = parseNonNegativeInteger(creditRequiredValue);
317273
+ if (current === undefined || creditRequired === undefined) {
317274
+ return { reason: "invalid_confirmTimes" };
317230
317275
  }
317231
- return normalizeCcxtTransactionForArchive(record).status;
317276
+ return { current, creditRequired, reason: null };
317277
+ }
317278
+ function parseOptionalNonNegativeInteger(value, fieldName) {
317279
+ if (value === undefined || value === null) {
317280
+ return { value: undefined, reason: null };
317281
+ }
317282
+ const parsed = parseNonNegativeInteger(value);
317283
+ return parsed === undefined ? { value: undefined, reason: `invalid_${fieldName}` } : { value: parsed, reason: null };
317284
+ }
317285
+ function parseBinanceUnlockProgress(record) {
317286
+ const info = asRecord(record.info);
317287
+ const nativeStatus = parseNonNegativeInteger(info?.status);
317288
+ const confirmations = parseConfirmTimes(info?.confirmTimes);
317289
+ const unlockRequired = parseOptionalNonNegativeInteger(info?.unlockConfirm, "unlockConfirm");
317290
+ const completeTime = parseOptionalNonNegativeInteger(info?.completeTime, "completeTime");
317291
+ let quality = "valid";
317292
+ let reason = null;
317293
+ if (nativeStatus === undefined) {
317294
+ quality = "unknown";
317295
+ reason = "missing_or_invalid_status";
317296
+ } else if (confirmations.reason !== null) {
317297
+ quality = "unknown";
317298
+ reason = confirmations.reason;
317299
+ } else if (unlockRequired.reason !== null) {
317300
+ quality = "unknown";
317301
+ reason = unlockRequired.reason;
317302
+ } else if (completeTime.reason !== null) {
317303
+ quality = "unknown";
317304
+ reason = completeTime.reason;
317305
+ }
317306
+ let state = "unknown";
317307
+ switch (nativeStatus) {
317308
+ case 0:
317309
+ state = "pending";
317310
+ break;
317311
+ case 1:
317312
+ if (quality === "valid" && confirmations.current !== undefined && unlockRequired.value !== undefined && confirmations.current >= unlockRequired.value) {
317313
+ state = "ok";
317314
+ } else if (quality === "valid") {
317315
+ state = "credited_not_withdrawable";
317316
+ }
317317
+ break;
317318
+ case 2:
317319
+ case 7:
317320
+ state = "failed";
317321
+ break;
317322
+ case 6:
317323
+ state = "credited_not_withdrawable";
317324
+ break;
317325
+ case 8:
317326
+ state = "pending";
317327
+ break;
317328
+ default:
317329
+ quality = "unknown";
317330
+ reason = "unsupported_status";
317331
+ break;
317332
+ }
317333
+ return {
317334
+ version: 1,
317335
+ state,
317336
+ progress_state: quality,
317337
+ reason,
317338
+ native_status: nativeStatus ?? null,
317339
+ current: confirmations.current ?? null,
317340
+ credit_required: confirmations.creditRequired ?? null,
317341
+ unlock_required: unlockRequired.value ?? null,
317342
+ complete_time: completeTime.value ?? null,
317343
+ observed_at: new Date().toISOString(),
317344
+ source: BINANCE_UNLOCK_PROGRESS_SOURCE
317345
+ };
317346
+ }
317347
+ function unlockProgressKey(progress) {
317348
+ return JSON.stringify({
317349
+ version: progress.version,
317350
+ state: progress.state,
317351
+ progress_state: progress.progress_state,
317352
+ reason: progress.reason,
317353
+ native_status: progress.native_status,
317354
+ current: progress.current,
317355
+ credit_required: progress.credit_required,
317356
+ unlock_required: progress.unlock_required,
317357
+ complete_time: progress.complete_time
317358
+ });
317359
+ }
317360
+ function progressWatermark(progress, previous) {
317361
+ if (progress.progress_state !== "valid" || progress.current === null || progress.credit_required === null || progress.unlock_required === null) {
317362
+ return previous;
317363
+ }
317364
+ return {
317365
+ current: Math.max(previous?.current ?? 0, progress.current),
317366
+ credit_required: progress.credit_required,
317367
+ unlock_required: progress.unlock_required
317368
+ };
317369
+ }
317370
+ function classifyBinanceDeposit(record, previous) {
317371
+ let progress = parseBinanceUnlockProgress(record);
317372
+ let highWatermark = previous?.highWatermark;
317373
+ if (progress.progress_state === "valid" && progress.current !== null && progress.credit_required !== null && progress.unlock_required !== null && previous?.highWatermark !== undefined && (progress.current < previous.highWatermark.current || progress.credit_required !== previous.highWatermark.credit_required || progress.unlock_required !== previous.highWatermark.unlock_required)) {
317374
+ progress = {
317375
+ ...progress,
317376
+ state: "unknown",
317377
+ progress_state: "contradictory",
317378
+ reason: "confirmation_progress_regressed_or_requirement_changed"
317379
+ };
317380
+ } else {
317381
+ highWatermark = progressWatermark(progress, previous?.highWatermark);
317382
+ }
317383
+ return {
317384
+ archiveStatus: progress.state,
317385
+ holdCursor: progress.state === "pending" || progress.state === "credited_not_withdrawable" || progress.state === "unknown",
317386
+ unlockProgress: progress,
317387
+ progressKey: unlockProgressKey(progress),
317388
+ highWatermark
317389
+ };
317390
+ }
317391
+ function classifyDeposit(exchangeId, record, previous) {
317392
+ if (exchangeId?.toLowerCase() === "binance") {
317393
+ return classifyBinanceDeposit(record, previous);
317394
+ }
317395
+ const archiveStatus = normalizeCcxtTransactionForArchive(record).status ?? "";
317396
+ const status = normalizeDepositStatus(depositField(record, ["status", "state"]));
317397
+ return {
317398
+ archiveStatus,
317399
+ holdCursor: archiveStatus === "credited_not_withdrawable" || status === "pending",
317400
+ progressKey: JSON.stringify({ status: archiveStatus })
317401
+ };
317402
+ }
317403
+ function depositIdentity(input) {
317404
+ if (input.externalId === undefined && input.txid === undefined) {
317405
+ return;
317406
+ }
317407
+ return JSON.stringify({
317408
+ exchange: input.exchangeId,
317409
+ account: input.accountSelector,
317410
+ coin: input.coin === undefined ? "" : String(input.coin),
317411
+ network: input.network === undefined ? "" : String(input.network),
317412
+ external_id: input.externalId ?? "",
317413
+ txid: input.txid ?? ""
317414
+ });
317232
317415
  }
317233
317416
  function nextDepositCursor(deposits, currentSince, depositsLimit, exchangeId) {
317234
317417
  if (deposits.length >= depositsLimit) {
@@ -317242,9 +317425,8 @@ function nextDepositCursor(deposits, currentSince, depositsLimit, exchangeId) {
317242
317425
  return currentSince;
317243
317426
  }
317244
317427
  const timestamp = depositTimestamp(record);
317245
- const archiveStatus = archivedDepositStatus(exchangeId, record);
317246
- const status = normalizeDepositStatus(depositField(record, ["status", "state"]));
317247
- const isPending = archiveStatus === "credited_not_withdrawable" || status === "pending";
317428
+ const classification = classifyDeposit(exchangeId, record);
317429
+ const isPending = classification.holdCursor;
317248
317430
  if (timestamp === undefined) {
317249
317431
  if (isPending) {
317250
317432
  return currentSince;
@@ -317364,7 +317546,8 @@ class DepositArchivePoller {
317364
317546
  if (!record) {
317365
317547
  continue;
317366
317548
  }
317367
- const assetSymbol = depositField(record, ["currency", "code", "asset"]);
317549
+ const info = asRecord(record.info);
317550
+ const assetSymbol = depositField(record, ["currency", "code", "asset"]) ?? info?.coin;
317368
317551
  const amount = depositField(record, ["amount"]);
317369
317552
  const address = depositField(record, [
317370
317553
  "address",
@@ -317373,8 +317556,21 @@ class DepositArchivePoller {
317373
317556
  "destination"
317374
317557
  ]);
317375
317558
  const txid = depositField(record, ["txid", "txId", "tx_hash", "txHash"]);
317376
- const network = depositField(record, ["network", "chain"]);
317377
- const archiveStatus = archivedDepositStatus(target.exchangeId, record);
317559
+ const network = depositField(record, ["network", "chain"]) ?? info?.network;
317560
+ const depositTxid = txid === undefined ? undefined : String(txid);
317561
+ const identity = depositIdentity({
317562
+ exchangeId: target.exchangeId,
317563
+ accountSelector: target.account.label,
317564
+ coin: assetSymbol,
317565
+ network,
317566
+ externalId: depositTxid,
317567
+ txid: depositTxid
317568
+ });
317569
+ const lastArchived = identity === undefined ? undefined : this.#lastArchivedByTarget.get(key)?.get(identity);
317570
+ const classification = classifyDeposit(target.exchangeId, record, lastArchived);
317571
+ if (lastArchived && lastArchived.status === classification.archiveStatus && lastArchived.progressKey === classification.progressKey) {
317572
+ continue;
317573
+ }
317378
317574
  const creditedAt = depositField(record, [
317379
317575
  "creditedAt",
317380
317576
  "credited_at",
@@ -317383,11 +317579,7 @@ class DepositArchivePoller {
317383
317579
  "timestamp",
317384
317580
  "datetime"
317385
317581
  ]);
317386
- const depositTxid = txid === undefined ? undefined : String(txid);
317387
- const lastArchived = depositTxid === undefined ? undefined : this.#lastArchivedByTarget.get(key)?.get(depositTxid);
317388
- if (lastArchived && lastArchived.status === archiveStatus) {
317389
- continue;
317390
- }
317582
+ const payload = classification.unlockProgress === undefined ? record : { ...record, unlock_progress: classification.unlockProgress };
317391
317583
  this.params.archiver.enqueue(buildTransferEventArchiveRow({
317392
317584
  tags: buildCommonArchiveTags({
317393
317585
  deploymentId: this.params.archiver.getDeploymentId(),
@@ -317398,25 +317590,27 @@ class DepositArchivePoller {
317398
317590
  transfer: {
317399
317591
  eventKind: "deposit",
317400
317592
  lifecycleAction: "observe_deposit",
317401
- status: archiveStatus,
317593
+ status: classification.archiveStatus,
317402
317594
  amount: amount === undefined ? undefined : String(amount),
317403
317595
  address: address === undefined ? undefined : String(address),
317404
317596
  network: network === undefined ? undefined : String(network),
317405
317597
  externalId: depositTxid,
317406
317598
  txid: depositTxid,
317407
317599
  exchangeTimestamp: normalizeTimestamp(creditedAt),
317408
- payload: record
317600
+ payload
317409
317601
  }
317410
317602
  }));
317411
- if (depositTxid !== undefined) {
317603
+ if (identity !== undefined) {
317412
317604
  let targetDeposits2 = this.#lastArchivedByTarget.get(key);
317413
317605
  if (!targetDeposits2) {
317414
317606
  targetDeposits2 = new Map;
317415
317607
  this.#lastArchivedByTarget.set(key, targetDeposits2);
317416
317608
  }
317417
- targetDeposits2.set(depositTxid, {
317418
- status: archiveStatus,
317419
- timestamp: depositTimestamp(record)
317609
+ targetDeposits2.set(identity, {
317610
+ status: classification.archiveStatus,
317611
+ timestamp: depositTimestamp(record),
317612
+ progressKey: classification.progressKey,
317613
+ highWatermark: classification.highWatermark
317420
317614
  });
317421
317615
  }
317422
317616
  archived += 1;
@@ -34692,8 +34692,8 @@ function validateReleaseIdentity(release) {
34692
34692
  return release;
34693
34693
  }
34694
34694
  function bakedReleaseIdentity() {
34695
- const packageVersion = "0.2.51";
34696
- const gitHead = "4ce5bc9326b07e2e58db53901d2160e6d91911a3";
34695
+ const packageVersion = "0.2.52";
34696
+ const gitHead = "6679e281b8d29c2474780a2bfb778871975da83b";
34697
34697
  return validateReleaseIdentity({ packageVersion, gitHead });
34698
34698
  }
34699
34699
  function readOptionalEnvironment(environment, name) {
@@ -34927,4 +34927,4 @@ export {
34927
34927
  createBackfillDependenciesFromEnv
34928
34928
  };
34929
34929
 
34930
- //# debugId=3982C5640CE7A75D64756E2164756E21
34930
+ //# debugId=E14D7155C57C5E5E64756E2164756E21