@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.
- package/dist/commands/cex-canonical-orderbook-export.js +3 -3
- package/dist/commands/cex-canonical-orderbook-export.js.map +1 -1
- package/dist/commands/cli.js +216 -22
- package/dist/commands/market-data-vendor-backfill.js +3 -3
- package/dist/commands/market-data-vendor-backfill.js.map +1 -1
- package/dist/helpers/deposit-archive-poller.d.ts +33 -0
- package/dist/index.js +217 -23
- package/dist/index.js.map +3 -3
- package/package.json +1 -1
package/dist/commands/cli.js
CHANGED
|
@@ -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
|
|
317227
|
-
|
|
317228
|
-
|
|
317229
|
-
|
|
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
|
|
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
|
|
317246
|
-
const
|
|
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
|
|
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
|
|
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
|
|
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
|
|
317600
|
+
payload
|
|
317409
317601
|
}
|
|
317410
317602
|
}));
|
|
317411
|
-
if (
|
|
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(
|
|
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.
|
|
34696
|
-
const gitHead = "
|
|
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=
|
|
34930
|
+
//# debugId=E14D7155C57C5E5E64756E2164756E21
|