0.7.46
This commit is contained in:
@@ -64,30 +64,86 @@
|
||||
</select>
|
||||
</div>
|
||||
<div class="col-6">
|
||||
<label for="demo3SourceAddressInput" class="form-label">Source address</label>
|
||||
<input id="demo3SourceAddressInput" type="text" class="form-control font-monospace" spellcheck="false" placeholder="pool / vault / position / config / mint address" />
|
||||
<label for="demo3SourceAddressInput" class="form-label">Source addresses</label>
|
||||
<textarea id="demo3SourceAddressInput" class="form-control font-monospace" rows="3" spellcheck="false" placeholder="pool / vault / position / config / mint addresses, one per line"></textarea>
|
||||
</div>
|
||||
<div class="col-12 form-text">Use address source to discover signatures around a pool, vault, position, config or mint while keeping the program id filter.</div>
|
||||
<div class="col-12 form-text">Use address source to discover signatures around one or several pools, vaults, positions, configs or mints while keeping the program id filter.</div>
|
||||
<div class="col-6">
|
||||
<label for="demo3BeforeSignatureInput" class="form-label">Before signature</label>
|
||||
<input id="demo3BeforeSignatureInput" type="text" class="form-control font-monospace" spellcheck="false" placeholder="optional pagination cursor" />
|
||||
</div>
|
||||
<div class="col-6">
|
||||
<label for="demo3UntilSignatureInput" class="form-label">Until signature</label>
|
||||
<input id="demo3UntilSignatureInput" type="text" class="form-control font-monospace" spellcheck="false" placeholder="optional stop cursor" />
|
||||
</div>
|
||||
<div class="col-6">
|
||||
<label for="demo3MaxPagesInput" class="form-label">Max pages / address</label>
|
||||
<input id="demo3MaxPagesInput" type="number" min="1" max="25" class="form-control" value="1" />
|
||||
</div>
|
||||
<div class="col-6">
|
||||
<label for="demo3ScanOrderSelect" class="form-label">Scan order</label>
|
||||
<select id="demo3ScanOrderSelect" class="form-select">
|
||||
<option value="newest_first">newest_first</option>
|
||||
<option value="oldest_first">oldest_first</option>
|
||||
</select>
|
||||
</div>
|
||||
<div class="col-12 form-text">For pool creation analysis, scan a pool address with enough pages and use oldest_first to process the oldest fetched signatures first.</div>
|
||||
</div>
|
||||
|
||||
<div class="row g-2">
|
||||
<div class="col-12">
|
||||
<label for="demo3TargetEventSelect" class="form-label">Target event</label>
|
||||
<select id="demo3TargetEventSelect" class="form-select">
|
||||
<option value="">Any / generic pair-pool discovery</option>
|
||||
<option value="swap">swap</option>
|
||||
<option value="add_liquidity">add_liquidity</option>
|
||||
<option value="remove_liquidity">remove_liquidity</option>
|
||||
<option value="claim_fee">claim_fee / collect_fee</option>
|
||||
<option value="claim_reward">claim_reward</option>
|
||||
<option value="position_open">position_open</option>
|
||||
<option value="position_close">position_close</option>
|
||||
<option value="pool_create">pool_create / initialize_pool</option>
|
||||
<option value="pool_admin">pool_admin / config / authority</option>
|
||||
<option value="unknown_non_swap">unknown_non_swap</option>
|
||||
<option value="audit_non_swap_like">audit_non_swap_like</option>
|
||||
<option value="unclassified_instruction">unclassified_instruction</option>
|
||||
</select>
|
||||
<label class="form-label">Target events</label>
|
||||
<div id="demo3TargetEventCheckboxGroup" class="border rounded p-2 bg-body" style="max-height: 220px; overflow-y: auto;">
|
||||
<div class="form-check form-check-inline">
|
||||
<input id="demo3TargetSwapInput" class="form-check-input" type="checkbox" name="demo3TargetEventInput" value="swap" />
|
||||
<label for="demo3TargetSwapInput" class="form-check-label">swap</label>
|
||||
</div>
|
||||
<div class="form-check form-check-inline">
|
||||
<input id="demo3TargetAddLiquidityInput" class="form-check-input" type="checkbox" name="demo3TargetEventInput" value="add_liquidity" />
|
||||
<label for="demo3TargetAddLiquidityInput" class="form-check-label">add_liquidity</label>
|
||||
</div>
|
||||
<div class="form-check form-check-inline">
|
||||
<input id="demo3TargetRemoveLiquidityInput" class="form-check-input" type="checkbox" name="demo3TargetEventInput" value="remove_liquidity" />
|
||||
<label for="demo3TargetRemoveLiquidityInput" class="form-check-label">remove_liquidity</label>
|
||||
</div>
|
||||
<div class="form-check form-check-inline">
|
||||
<input id="demo3TargetClaimFeeInput" class="form-check-input" type="checkbox" name="demo3TargetEventInput" value="claim_fee" />
|
||||
<label for="demo3TargetClaimFeeInput" class="form-check-label">claim_fee</label>
|
||||
</div>
|
||||
<div class="form-check form-check-inline">
|
||||
<input id="demo3TargetClaimRewardInput" class="form-check-input" type="checkbox" name="demo3TargetEventInput" value="claim_reward" />
|
||||
<label for="demo3TargetClaimRewardInput" class="form-check-label">claim_reward</label>
|
||||
</div>
|
||||
<div class="form-check form-check-inline">
|
||||
<input id="demo3TargetCreateLockEscrowInput" class="form-check-input" type="checkbox" name="demo3TargetEventInput" value="create_lock_escrow" />
|
||||
<label for="demo3TargetCreateLockEscrowInput" class="form-check-label">create_lock_escrow</label>
|
||||
</div>
|
||||
<div class="form-check form-check-inline">
|
||||
<input id="demo3TargetLockLiquidityInput" class="form-check-input" type="checkbox" name="demo3TargetEventInput" value="lock_liquidity" />
|
||||
<label for="demo3TargetLockLiquidityInput" class="form-check-label">lock_liquidity</label>
|
||||
</div>
|
||||
<div class="form-check form-check-inline">
|
||||
<input id="demo3TargetPositionOpenInput" class="form-check-input" type="checkbox" name="demo3TargetEventInput" value="position_open" />
|
||||
<label for="demo3TargetPositionOpenInput" class="form-check-label">position_open</label>
|
||||
</div>
|
||||
<div class="form-check form-check-inline">
|
||||
<input id="demo3TargetPositionCloseInput" class="form-check-input" type="checkbox" name="demo3TargetEventInput" value="position_close" />
|
||||
<label for="demo3TargetPositionCloseInput" class="form-check-label">position_close</label>
|
||||
</div>
|
||||
<div class="form-check form-check-inline">
|
||||
<input id="demo3TargetPoolCreateInput" class="form-check-input" type="checkbox" name="demo3TargetEventInput" value="pool_create" />
|
||||
<label for="demo3TargetPoolCreateInput" class="form-check-label">pool_create</label>
|
||||
</div>
|
||||
<div class="form-check form-check-inline">
|
||||
<input id="demo3TargetPoolAdminInput" class="form-check-input" type="checkbox" name="demo3TargetEventInput" value="pool_admin" />
|
||||
<label for="demo3TargetPoolAdminInput" class="form-check-label">pool_admin</label>
|
||||
</div>
|
||||
<div class="form-check form-check-inline">
|
||||
<input id="demo3TargetUnknownNonSwapInput" class="form-check-input" type="checkbox" name="demo3TargetEventInput" value="unknown_non_swap" />
|
||||
<label for="demo3TargetUnknownNonSwapInput" class="form-check-label">unknown_non_swap</label>
|
||||
</div>
|
||||
</div>
|
||||
<div class="form-text">Leave all unchecked for generic discovery. Check several surfaces to scan once and keep candidates matching any selected target.</div>
|
||||
<div class="form-text">Use this to find corpus signatures for non-swap decoders without promoting unverified events.</div>
|
||||
</div>
|
||||
<div class="col-6">
|
||||
@@ -156,6 +212,8 @@
|
||||
<h2 class="h5 mb-3">Résumé</h2>
|
||||
<div class="row g-2 small">
|
||||
<div class="col-6"><strong>Signatures:</strong> <span id="demo3SummarySignatureCount">0</span></div>
|
||||
<div class="col-6"><strong>Unique fetched:</strong> <span id="demo3SummaryUniqueFetchedSignatureCount">0</span></div>
|
||||
<div class="col-6"><strong>Pages:</strong> <span id="demo3SummaryFetchedPageCount">0</span></div>
|
||||
<div class="col-6"><strong>Unique candidates:</strong> <span id="demo3SummaryUniqueSignatureCount">0</span></div>
|
||||
<div class="col-6"><strong>Tx fetched:</strong> <span id="demo3SummaryFetchedTxCount">0</span></div>
|
||||
<div class="col-6"><strong>Missing tx:</strong> <span id="demo3SummaryMissingTxCount">0</span></div>
|
||||
@@ -176,6 +234,10 @@
|
||||
<strong>Backfill signatures:</strong>
|
||||
<span id="demo3UniqueSignatureText" class="font-monospace">-</span>
|
||||
</div>
|
||||
<div class="small text-body-secondary mt-2">
|
||||
<strong>Next before cursors:</strong>
|
||||
<span id="demo3NextBeforeText" class="font-monospace">-</span>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
|
||||
@@ -20,6 +20,26 @@ signatureSource: string | null,
|
||||
* Optional source address used when signature_source is `address`.
|
||||
*/
|
||||
sourceAddress: string | null,
|
||||
/**
|
||||
* Optional extra source addresses used for multi-pool discovery.
|
||||
*/
|
||||
sourceAddresses: Array<string>,
|
||||
/**
|
||||
* Optional `before` cursor passed to Solana getSignaturesForAddress.
|
||||
*/
|
||||
beforeSignature: string | null,
|
||||
/**
|
||||
* Optional `until` cursor passed to Solana getSignaturesForAddress.
|
||||
*/
|
||||
untilSignature: string | null,
|
||||
/**
|
||||
* Maximum number of signature pages to fetch per source address.
|
||||
*/
|
||||
maxPages: number,
|
||||
/**
|
||||
* Signature processing order: newest_first or oldest_first.
|
||||
*/
|
||||
scanOrder: string | null,
|
||||
/**
|
||||
* Optional target event family used to find non-swap signatures.
|
||||
*/
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
// This file was generated by [ts-rs](https://github.com/Aleph-Alpha/ts-rs). Do not edit this file manually.
|
||||
import type { Demo3OnchainDexDiscoveryRequest } from "./Demo3OnchainDexDiscoveryRequest";
|
||||
import type { Demo3OnchainDexPaginationCursor } from "./Demo3OnchainDexPaginationCursor";
|
||||
import type { Demo3OnchainDexPairCandidate } from "./Demo3OnchainDexPairCandidate";
|
||||
import type { Demo3OnchainDexRejectedCandidateSummary } from "./Demo3OnchainDexRejectedCandidateSummary";
|
||||
|
||||
@@ -27,6 +28,22 @@ resolvedSignatureSource: string,
|
||||
* Address scanned with getSignaturesForAddress.
|
||||
*/
|
||||
resolvedSignatureAddress: string,
|
||||
/**
|
||||
* All addresses scanned with getSignaturesForAddress.
|
||||
*/
|
||||
resolvedSignatureAddresses: Array<string>,
|
||||
/**
|
||||
* Cursor hints by scanned address.
|
||||
*/
|
||||
nextBeforeByAddress: Array<Demo3OnchainDexPaginationCursor>,
|
||||
/**
|
||||
* Number of signature pages fetched.
|
||||
*/
|
||||
fetchedSignaturePageCount: number,
|
||||
/**
|
||||
* Number of unique fetched signatures after de-duplication.
|
||||
*/
|
||||
uniqueFetchedSignatureCount: number,
|
||||
/**
|
||||
* Number of unique candidate signatures.
|
||||
*/
|
||||
|
||||
@@ -0,0 +1,22 @@
|
||||
// This file was generated by [ts-rs](https://github.com/Aleph-Alpha/ts-rs). Do not edit this file manually.
|
||||
|
||||
/**
|
||||
* Pagination cursor hint for one scanned source address.
|
||||
*/
|
||||
export type Demo3OnchainDexPaginationCursor = {
|
||||
/**
|
||||
* Scanned source address.
|
||||
*/
|
||||
address: string,
|
||||
/**
|
||||
* Signature usable as beforeSignature for the next page window.
|
||||
*/
|
||||
nextBeforeSignature: string | null,
|
||||
/**
|
||||
* Raw signature count fetched for this address.
|
||||
*/
|
||||
fetchedSignatureCount: number,
|
||||
/**
|
||||
* Page count fetched for this address.
|
||||
*/
|
||||
fetchedPageCount: number, };
|
||||
@@ -117,13 +117,49 @@ function isSolanaAddressLike(value: string): boolean {
|
||||
return /^[1-9A-HJ-NP-Za-km-z]+$/.test(trimmed);
|
||||
}
|
||||
|
||||
function splitSourceAddresses(value: string): string[] {
|
||||
const seen = new Set<string>();
|
||||
const addresses: string[] = [];
|
||||
for (const token of value.split(/[\s,;]+/g)) {
|
||||
const trimmed = token.trim();
|
||||
if (trimmed === "" || seen.has(trimmed)) {
|
||||
continue;
|
||||
}
|
||||
seen.add(trimmed);
|
||||
addresses.push(trimmed);
|
||||
}
|
||||
return addresses;
|
||||
}
|
||||
|
||||
function isSolanaSignatureLike(value: string): boolean {
|
||||
const trimmed = value.trim();
|
||||
if (trimmed.length < 64 || trimmed.length > 128) {
|
||||
return false;
|
||||
}
|
||||
return /^[1-9A-HJ-NP-Za-km-z]+$/.test(trimmed);
|
||||
}
|
||||
|
||||
function validateOptionalSignature(value: string | null, label: string): void {
|
||||
if (value === null || value.trim() === "") {
|
||||
return;
|
||||
}
|
||||
if (!isSolanaSignatureLike(value)) {
|
||||
throw new Error(`${label} must be a valid Solana transaction signature.`);
|
||||
}
|
||||
}
|
||||
|
||||
function validateOnchainRequest(request: Demo3OnchainDexDiscoveryRequest): void {
|
||||
if (request.signatureSource === "address") {
|
||||
const sourceAddress = request.sourceAddress ?? "";
|
||||
if (!isSolanaAddressLike(sourceAddress)) {
|
||||
throw new Error("Signature source is 'address': Source address must be a real Solana account address, pool, vault, position, config or mint. It cannot be empty or the literal value 'address'.");
|
||||
const addresses = request.sourceAddresses ?? [];
|
||||
if (request.signatureSource === "address" && addresses.length === 0) {
|
||||
throw new Error("Signature source is 'address': provide at least one Solana account, pool, vault, position, config or mint address.");
|
||||
}
|
||||
for (const address of addresses) {
|
||||
if (!isSolanaAddressLike(address)) {
|
||||
throw new Error(`Invalid source address '${address}'. Provide Solana account addresses separated by commas, spaces or new lines.`);
|
||||
}
|
||||
}
|
||||
validateOptionalSignature(request.beforeSignature, "Before signature");
|
||||
validateOptionalSignature(request.untilSignature, "Until signature");
|
||||
if (request.programId !== null && !isSolanaAddressLike(request.programId)) {
|
||||
throw new Error("Program id filter must be a valid Solana program id, or empty when using a preset that resolves it.");
|
||||
}
|
||||
@@ -143,6 +179,27 @@ function intValue(id: string, fallback: number): number {
|
||||
return Number.isFinite(parsed) && parsed > 0 ? parsed : fallback;
|
||||
}
|
||||
|
||||
function selectedTargetEvents(): string[] {
|
||||
return Array.from(document.querySelectorAll<HTMLInputElement>('input[name="demo3TargetEventInput"]:checked'))
|
||||
.map((input) => input.value.trim())
|
||||
.filter((value) => value !== "");
|
||||
}
|
||||
|
||||
function readTargetEventFilter(): string | null {
|
||||
const selected = selectedTargetEvents();
|
||||
return selected.length === 0 ? null : selected.join(",");
|
||||
}
|
||||
|
||||
function targetEventLabel(targetEvent: string | null): string {
|
||||
return targetEvent === null || targetEvent.trim() === "" ? "any" : targetEvent;
|
||||
}
|
||||
|
||||
function clearTargetEventFilters(): void {
|
||||
document.querySelectorAll<HTMLInputElement>('input[name="demo3TargetEventInput"]').forEach((input) => {
|
||||
input.checked = false;
|
||||
});
|
||||
}
|
||||
|
||||
function escapeHtml(value: string): string {
|
||||
return value
|
||||
.replace(/&/g, "&")
|
||||
@@ -227,12 +284,18 @@ function applyPreset(indexText: string): void {
|
||||
}
|
||||
|
||||
function readOnchainRequest(): Demo3OnchainDexDiscoveryRequest {
|
||||
const sourceAddresses = splitSourceAddresses(byId<HTMLTextAreaElement>("demo3SourceAddressInput").value);
|
||||
return {
|
||||
dexCode: valueOrNull(byId<HTMLInputElement>("demo3DexCodeInput").value),
|
||||
programId: valueOrNull(byId<HTMLInputElement>("demo3ProgramIdInput").value),
|
||||
signatureSource: valueOrNull(byId<HTMLSelectElement>("demo3SignatureSourceSelect").value),
|
||||
sourceAddress: valueOrNull(byId<HTMLInputElement>("demo3SourceAddressInput").value),
|
||||
targetEvent: valueOrNull(byId<HTMLSelectElement>("demo3TargetEventSelect").value),
|
||||
sourceAddress: sourceAddresses.length === 1 ? sourceAddresses[0] : null,
|
||||
sourceAddresses,
|
||||
beforeSignature: valueOrNull(byId<HTMLInputElement>("demo3BeforeSignatureInput").value),
|
||||
untilSignature: valueOrNull(byId<HTMLInputElement>("demo3UntilSignatureInput").value),
|
||||
maxPages: intValue("demo3MaxPagesInput", 1),
|
||||
scanOrder: valueOrNull(byId<HTMLSelectElement>("demo3ScanOrderSelect").value),
|
||||
targetEvent: readTargetEventFilter(),
|
||||
excludeSwaps: byId<HTMLInputElement>("demo3ExcludeSwapsInput").checked,
|
||||
includeFailed: byId<HTMLInputElement>("demo3IncludeFailedInput").checked,
|
||||
httpRole: byId<HTMLInputElement>("demo3HttpRoleInput").value.trim() || "history_backfill",
|
||||
@@ -258,12 +321,16 @@ function clearFilters(): void {
|
||||
byId<HTMLInputElement>("demo3DexCodeInput").value = "";
|
||||
byId<HTMLInputElement>("demo3ProgramIdInput").value = "";
|
||||
byId<HTMLSelectElement>("demo3SignatureSourceSelect").value = "program_id";
|
||||
byId<HTMLInputElement>("demo3SourceAddressInput").value = "";
|
||||
byId<HTMLTextAreaElement>("demo3SourceAddressInput").value = "";
|
||||
byId<HTMLInputElement>("demo3BeforeSignatureInput").value = "";
|
||||
byId<HTMLInputElement>("demo3UntilSignatureInput").value = "";
|
||||
byId<HTMLInputElement>("demo3MaxPagesInput").value = "1";
|
||||
byId<HTMLSelectElement>("demo3ScanOrderSelect").value = "newest_first";
|
||||
byId<HTMLInputElement>("demo3PairIdInput").value = "";
|
||||
byId<HTMLInputElement>("demo3PoolAddressInput").value = "";
|
||||
byId<HTMLInputElement>("demo3TokenMintInput").value = "";
|
||||
byId<HTMLInputElement>("demo3SignatureInput").value = "";
|
||||
byId<HTMLSelectElement>("demo3TargetEventSelect").value = "";
|
||||
clearTargetEventFilters();
|
||||
byId<HTMLInputElement>("demo3ExcludeSwapsInput").checked = false;
|
||||
byId<HTMLInputElement>("demo3IncludeFailedInput").checked = true;
|
||||
byId<HTMLSelectElement>("demo3PresetSelect").value = "";
|
||||
@@ -272,6 +339,8 @@ function clearFilters(): void {
|
||||
|
||||
function renderOnchainResult(result: Demo3OnchainDexDiscoveryResult): void {
|
||||
byId<HTMLElement>("demo3SummarySignatureCount").textContent = String(result.fetchedSignatureCount);
|
||||
byId<HTMLElement>("demo3SummaryUniqueFetchedSignatureCount").textContent = String(result.uniqueFetchedSignatureCount);
|
||||
byId<HTMLElement>("demo3SummaryFetchedPageCount").textContent = String(result.fetchedSignaturePageCount);
|
||||
byId<HTMLElement>("demo3SummaryUniqueSignatureCount").textContent = String(result.uniqueSignatureCount);
|
||||
byId<HTMLElement>("demo3SummaryFetchedTxCount").textContent = String(result.fetchedTransactionCount);
|
||||
byId<HTMLElement>("demo3SummaryMissingTxCount").textContent = String(result.missingTransactionCount);
|
||||
@@ -281,9 +350,11 @@ function renderOnchainResult(result: Demo3OnchainDexDiscoveryResult): void {
|
||||
byId<HTMLElement>("demo3SummaryExtractedCandidateCount").textContent = String(result.extractedCandidateCount);
|
||||
byId<HTMLElement>("demo3SummaryRejectedCandidateCount").textContent = String(result.targetRejectedCandidateCount);
|
||||
byId<HTMLElement>("demo3SummaryCandidateCount").textContent = String(result.candidateCount);
|
||||
const targetEvent = result.request.targetEvent ?? "any";
|
||||
byId<HTMLElement>("demo3TargetText").textContent = `${result.resolvedDexCode ?? "custom"} / program=${result.resolvedProgramId} / source=${result.resolvedSignatureSource}:${result.resolvedSignatureAddress} / target=${targetEvent}`;
|
||||
const targetEvent = targetEventLabel(result.request.targetEvent);
|
||||
const sourceText = result.resolvedSignatureAddresses.length === 0 ? result.resolvedSignatureAddress : result.resolvedSignatureAddresses.join(",");
|
||||
byId<HTMLElement>("demo3TargetText").textContent = `${result.resolvedDexCode ?? "custom"} / program=${result.resolvedProgramId} / source=${result.resolvedSignatureSource}:${sourceText} / target=${targetEvent} / order=${result.request.scanOrder ?? "newest_first"}`;
|
||||
byId<HTMLElement>("demo3UniqueSignatureText").textContent = result.uniqueBackfillSignatures.length === 0 ? "-" : result.uniqueBackfillSignatures.join(", ");
|
||||
byId<HTMLElement>("demo3NextBeforeText").textContent = result.nextBeforeByAddress.length === 0 ? "-" : result.nextBeforeByAddress.map((cursor) => `${cursor.address}:${cursor.nextBeforeSignature ?? "-"}`).join(" | ");
|
||||
renderRejectedSummary(result);
|
||||
renderOnchainCandidates(result.candidates);
|
||||
}
|
||||
@@ -374,14 +445,14 @@ async function discoverOnchain(): Promise<void> {
|
||||
return;
|
||||
}
|
||||
setStatus("running", "text-bg-warning");
|
||||
appendLogLine(`on-chain discovery dex='${request.dexCode ?? ""}' program='${request.programId ?? ""}' source='${request.signatureSource ?? "program_id"}:${request.sourceAddress ?? ""}' target='${request.targetEvent ?? "any"}' excludeSwaps='${request.excludeSwaps}' role='${request.httpRole}'`);
|
||||
appendLogLine(`on-chain discovery dex='${request.dexCode ?? ""}' program='${request.programId ?? ""}' source='${request.signatureSource ?? "program_id"}:${request.sourceAddresses.join(",")}' target='${targetEventLabel(request.targetEvent)}' pages='${request.maxPages}' order='${request.scanOrder ?? "newest_first"}' before='${request.beforeSignature ?? ""}' until='${request.untilSignature ?? ""}' excludeSwaps='${request.excludeSwaps}' role='${request.httpRole}'`);
|
||||
try {
|
||||
const payload = await invoke<Demo3OnchainDexDiscoveryPayload>("demo3_discover_onchain_dex_pairs", { request });
|
||||
lastResultJson = payload.resultJson;
|
||||
byId<HTMLTextAreaElement>("demo3JsonTextarea").value = payload.resultJson;
|
||||
renderOnchainResult(payload.result);
|
||||
setStatus("ok", "text-bg-success");
|
||||
appendLogLine(`on-chain discovery completed: candidates='${payload.result.candidateCount}' unique='${payload.result.uniqueSignatureCount}' signatures='${payload.result.fetchedSignatureCount}' extracted='${payload.result.extractedCandidateCount}' rejected='${payload.result.targetRejectedCandidateCount}' skippedSwapTx='${payload.result.skippedSwapLogTransactionCount}'`);
|
||||
appendLogLine(`on-chain discovery completed: candidates='${payload.result.candidateCount}' unique='${payload.result.uniqueSignatureCount}' signatures='${payload.result.fetchedSignatureCount}' uniqueFetched='${payload.result.uniqueFetchedSignatureCount}' pages='${payload.result.fetchedSignaturePageCount}' extracted='${payload.result.extractedCandidateCount}' rejected='${payload.result.targetRejectedCandidateCount}' skippedSwapTx='${payload.result.skippedSwapLogTransactionCount}'`);
|
||||
} catch (error) {
|
||||
setStatus("error", "text-bg-danger");
|
||||
appendLogLine(`on-chain discovery failed: ${String(error)}`);
|
||||
|
||||
Reference in New Issue
Block a user