0.7.43-E5C
This commit is contained in:
@@ -24,7 +24,7 @@
|
||||
|
||||
<main class="app-main">
|
||||
<div class="osb-scrollable pt-1 pb-4" data-simplebar>
|
||||
<div class="container-fluid py-4">
|
||||
<div class="container-fluid py-4">
|
||||
<div class="row g-4">
|
||||
<div class="col-12 col-xxl-4">
|
||||
<div class="card shadow-sm border-0 mb-4">
|
||||
@@ -37,24 +37,59 @@
|
||||
Recherche directement sur Solana via <code>getSignaturesForAddress</code> + <code>getTransaction</code>.
|
||||
Le résultat sert à trouver une signature, un pool ou un mint à backfiller ensuite dans Demo Pipeline 2.
|
||||
</p>
|
||||
|
||||
|
||||
<div class="mb-3">
|
||||
<label for="demo3PresetSelect" class="form-label">Preset DEX</label>
|
||||
<select id="demo3PresetSelect" class="form-select"></select>
|
||||
<div id="demo3PresetHelp" class="form-text">Choisis un DEX ou saisis un program id manuellement.</div>
|
||||
</div>
|
||||
|
||||
|
||||
<div class="mb-3">
|
||||
<label for="demo3DexCodeInput" class="form-label">DEX code</label>
|
||||
<input id="demo3DexCodeInput" type="text" class="form-control font-monospace" spellcheck="false" />
|
||||
</div>
|
||||
|
||||
|
||||
<div class="mb-3">
|
||||
<label for="demo3ProgramIdInput" class="form-label">Program id</label>
|
||||
<label for="demo3ProgramIdInput" class="form-label">Program id filter</label>
|
||||
<input id="demo3ProgramIdInput" type="text" class="form-control font-monospace" spellcheck="false" />
|
||||
<div class="form-text">Used to filter matched instructions. With address source, signatures are fetched from Source address instead.</div>
|
||||
</div>
|
||||
|
||||
|
||||
<div class="row g-2 mb-3">
|
||||
<div class="col-6">
|
||||
<label for="demo3SignatureSourceSelect" class="form-label">Signature source</label>
|
||||
<select id="demo3SignatureSourceSelect" class="form-select">
|
||||
<option value="program_id">program_id</option>
|
||||
<option value="address">address / pool / vault / position</option>
|
||||
</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" />
|
||||
</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>
|
||||
|
||||
<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>
|
||||
<div class="form-text">Use this to find corpus signatures for non-swap decoders without promoting unverified events.</div>
|
||||
</div>
|
||||
<div class="col-6">
|
||||
<label for="demo3HttpRoleInput" class="form-label">HTTP role</label>
|
||||
<input id="demo3HttpRoleInput" type="text" class="form-control" value="history_backfill" />
|
||||
@@ -71,8 +106,20 @@
|
||||
<label for="demo3CandidateLimitInput" class="form-label">Candidate limit</label>
|
||||
<input id="demo3CandidateLimitInput" type="number" min="1" max="100" class="form-control" value="25" />
|
||||
</div>
|
||||
<div class="col-6">
|
||||
<div class="form-check mt-2">
|
||||
<input id="demo3ExcludeSwapsInput" class="form-check-input" type="checkbox" />
|
||||
<label for="demo3ExcludeSwapsInput" class="form-check-label">Exclude tx with swap logs</label>
|
||||
</div>
|
||||
</div>
|
||||
<div class="col-6">
|
||||
<div class="form-check mt-2">
|
||||
<input id="demo3IncludeFailedInput" class="form-check-input" type="checkbox" checked />
|
||||
<label for="demo3IncludeFailedInput" class="form-check-label">Include failed tx</label>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
|
||||
<div class="d-flex flex-wrap gap-2 mt-3">
|
||||
<button id="demo3DiscoverButton" type="button" class="btn btn-primary">Discover on-chain</button>
|
||||
<button id="demo3LocalSearchButton" type="button" class="btn btn-outline-primary">Search local DB</button>
|
||||
@@ -81,7 +128,7 @@
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
|
||||
<div class="card shadow-sm border-0 mb-4">
|
||||
<div class="card-body">
|
||||
<h2 class="h5 mb-3">Filtres locaux optionnels</h2>
|
||||
@@ -103,15 +150,20 @@
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
|
||||
<div class="card shadow-sm border-0 mb-4">
|
||||
<div class="card-body">
|
||||
<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 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>
|
||||
<div class="col-6"><strong>Failed tx:</strong> <span id="demo3SummaryFailedTxCount">0</span></div>
|
||||
<div class="col-6"><strong>Skipped failed:</strong> <span id="demo3SummarySkippedFailedTxCount">0</span></div>
|
||||
<div class="col-6"><strong>Skipped swap tx:</strong> <span id="demo3SummarySkippedSwapTxCount">0</span></div>
|
||||
<div class="col-6"><strong>Extracted:</strong> <span id="demo3SummaryExtractedCandidateCount">0</span></div>
|
||||
<div class="col-6"><strong>Rejected by target:</strong> <span id="demo3SummaryRejectedCandidateCount">0</span></div>
|
||||
<div class="col-6"><strong>Candidates:</strong> <span id="demo3SummaryCandidateCount">0</span></div>
|
||||
<div class="col-6"><strong>Local pairs:</strong> <span id="demo3SummaryLocalPairCount">0</span></div>
|
||||
</div>
|
||||
@@ -120,9 +172,13 @@
|
||||
<strong>Target:</strong>
|
||||
<span id="demo3TargetText" class="font-monospace">-</span>
|
||||
</div>
|
||||
<div class="small text-body-secondary mt-2">
|
||||
<strong>Backfill signatures:</strong>
|
||||
<span id="demo3UniqueSignatureText" class="font-monospace">-</span>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
|
||||
<div class="card shadow-sm border-0">
|
||||
<div class="card-body">
|
||||
<h2 class="h5 mb-3">Logs</h2>
|
||||
@@ -131,7 +187,7 @@
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
|
||||
<div class="col-12 col-xxl-8">
|
||||
<div class="card shadow-sm border-0 mb-4">
|
||||
<div class="card-body">
|
||||
@@ -144,6 +200,7 @@
|
||||
<th>Slot</th>
|
||||
<th>Kind</th>
|
||||
<th>Confidence</th>
|
||||
<th>Data prefix</th>
|
||||
<th>Verified pool</th>
|
||||
<th>Token A</th>
|
||||
<th>Token B</th>
|
||||
@@ -154,13 +211,39 @@
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody id="demo3OnchainCandidateTableBody">
|
||||
<tr><td colspan="11" class="text-body-secondary">No on-chain candidate.</td></tr>
|
||||
<tr>
|
||||
<td colspan="12" class="text-body-secondary">No on-chain candidate.</td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
|
||||
<div class="card shadow-sm border-0 mb-4">
|
||||
<div class="card-body">
|
||||
<h2 class="h5 mb-3">Rejected candidate summary</h2>
|
||||
<div class="table-responsive">
|
||||
<table class="table table-sm align-middle mb-0">
|
||||
<thead>
|
||||
<tr>
|
||||
<th>Kind</th>
|
||||
<th>Prefix</th>
|
||||
<th>Instruction</th>
|
||||
<th>Reason</th>
|
||||
<th>Count</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody id="demo3RejectedSummaryTableBody">
|
||||
<tr>
|
||||
<td colspan="5" class="text-body-secondary">No rejected candidate summary.</td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="card shadow-sm border-0 mb-4">
|
||||
<div class="card-body">
|
||||
<h2 class="h5 mb-3">Recherche locale DB</h2>
|
||||
@@ -179,13 +262,15 @@
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody id="demo3LocalPoolPairTableBody">
|
||||
<tr><td colspan="8" class="text-body-secondary">No local pool/pair sample.</td></tr>
|
||||
<tr>
|
||||
<td colspan="8" class="text-body-secondary">No local pool/pair sample.</td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
|
||||
<div class="card shadow-sm border-0">
|
||||
<div class="card-body">
|
||||
<h2 class="h5 mb-3">Raw result JSON</h2>
|
||||
@@ -211,4 +296,4 @@
|
||||
<script type="module" src="ts/demo3.ts" defer></script>
|
||||
</body>
|
||||
|
||||
</html>
|
||||
</html>
|
||||
@@ -179,7 +179,8 @@
|
||||
<div class="mb-3">
|
||||
<label for="demoPipeline2ValidationProfileSelect" class="form-label">Validation profile</label>
|
||||
<select id="demoPipeline2ValidationProfileSelect" class="form-select">
|
||||
<option value="0.7.42_raydium_family_event_coverage" selected>0.7.42 — Raydium family event coverage</option>
|
||||
<option value="0.7.43_meteora_effective_surfaces" selected>0.7.43 — Meteora family event coverage</option>
|
||||
<option value="0.7.42_raydium_family_event_coverage">0.7.42 — Raydium family event coverage</option>
|
||||
<option value="0.7.41_raydium_amm_v4_swap_decoder">0.7.41 — Raydium AMM v4 swap decoder</option>
|
||||
<option value="0.7.40_raydium_effective_surfaces">0.7.40 — Raydium effective surfaces</option>
|
||||
<option value="0.7.39_dex_first_effective_swap_surfaces">0.7.39 — DEX-first effective swap surfaces</option>
|
||||
|
||||
@@ -12,6 +12,26 @@ dexCode: string | null,
|
||||
* Optional Solana program id. When absent, dex_code must resolve to a verified program id.
|
||||
*/
|
||||
programId: string | null,
|
||||
/**
|
||||
* Optional signature source: `program_id` or `address`.
|
||||
*/
|
||||
signatureSource: string | null,
|
||||
/**
|
||||
* Optional source address used when signature_source is `address`.
|
||||
*/
|
||||
sourceAddress: string | null,
|
||||
/**
|
||||
* Optional target event family used to find non-swap signatures.
|
||||
*/
|
||||
targetEvent: string | null,
|
||||
/**
|
||||
* Whether transactions containing swap-like logs should be skipped.
|
||||
*/
|
||||
excludeSwaps: boolean,
|
||||
/**
|
||||
* Whether failed transactions should be returned as candidates.
|
||||
*/
|
||||
includeFailed: boolean,
|
||||
/**
|
||||
* HTTP role used to query Solana RPC.
|
||||
*/
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
// 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 { Demo3OnchainDexPairCandidate } from "./Demo3OnchainDexPairCandidate";
|
||||
import type { Demo3OnchainDexRejectedCandidateSummary } from "./Demo3OnchainDexRejectedCandidateSummary";
|
||||
|
||||
/**
|
||||
* Structured on-chain DEX discovery result.
|
||||
@@ -15,9 +16,29 @@ request: Demo3OnchainDexDiscoveryRequest,
|
||||
*/
|
||||
resolvedDexCode: string | null,
|
||||
/**
|
||||
* Program id scanned with getSignaturesForAddress.
|
||||
* Program id used to filter matched instructions.
|
||||
*/
|
||||
resolvedProgramId: string,
|
||||
/**
|
||||
* Signature source actually used by getSignaturesForAddress.
|
||||
*/
|
||||
resolvedSignatureSource: string,
|
||||
/**
|
||||
* Address scanned with getSignaturesForAddress.
|
||||
*/
|
||||
resolvedSignatureAddress: string,
|
||||
/**
|
||||
* Number of unique candidate signatures.
|
||||
*/
|
||||
uniqueSignatureCount: number,
|
||||
/**
|
||||
* Unique signatures ready for signature backfill.
|
||||
*/
|
||||
uniqueBackfillSignatures: Array<string>,
|
||||
/**
|
||||
* Rejected candidate summary.
|
||||
*/
|
||||
rejectedCandidateSummary: Array<Demo3OnchainDexRejectedCandidateSummary>,
|
||||
/**
|
||||
* Number of signatures returned by Solana RPC.
|
||||
*/
|
||||
@@ -34,6 +55,22 @@ missingTransactionCount: number,
|
||||
* Number of failed transactions encountered.
|
||||
*/
|
||||
failedTransactionCount: number,
|
||||
/**
|
||||
* Number of failed transactions skipped because include_failed is false.
|
||||
*/
|
||||
skippedFailedTransactionCount: number,
|
||||
/**
|
||||
* Number of swap-log transactions skipped by the transaction-level swap guard.
|
||||
*/
|
||||
skippedSwapLogTransactionCount: number,
|
||||
/**
|
||||
* Number of candidate rows extracted before target-event filtering.
|
||||
*/
|
||||
extractedCandidateCount: number,
|
||||
/**
|
||||
* Number of candidate rows rejected by target-event filtering.
|
||||
*/
|
||||
targetRejectedCandidateCount: number,
|
||||
/**
|
||||
* Number of candidate rows returned.
|
||||
*/
|
||||
|
||||
@@ -50,6 +50,10 @@ innerInstructionIndex: number | null,
|
||||
* Instruction name inferred from data/logs.
|
||||
*/
|
||||
instructionName: string | null,
|
||||
/**
|
||||
* Prefix of the raw base58 instruction data, useful for audit grouping.
|
||||
*/
|
||||
instructionDataPrefix: string | null,
|
||||
/**
|
||||
* Candidate pool address.
|
||||
*/
|
||||
|
||||
@@ -0,0 +1,26 @@
|
||||
// This file was generated by [ts-rs](https://github.com/Aleph-Alpha/ts-rs). Do not edit this file manually.
|
||||
|
||||
/**
|
||||
* Rejected on-chain discovery candidate summary.
|
||||
*/
|
||||
export type Demo3OnchainDexRejectedCandidateSummary = {
|
||||
/**
|
||||
* Candidate kind rejected by target filtering.
|
||||
*/
|
||||
candidateKind: string,
|
||||
/**
|
||||
* Optional instruction data prefix.
|
||||
*/
|
||||
instructionDataPrefix: string | null,
|
||||
/**
|
||||
* Optional instruction name.
|
||||
*/
|
||||
instructionName: string | null,
|
||||
/**
|
||||
* Rejection reason.
|
||||
*/
|
||||
rejectionReason: string,
|
||||
/**
|
||||
* Count of matching rejected candidates.
|
||||
*/
|
||||
count: number, };
|
||||
@@ -7,11 +7,11 @@ import { invoke } from "@tauri-apps/api/core";
|
||||
import { debug, takeoverConsole } from "@fltsci/tauri-plugin-tracing";
|
||||
import type { Demo3LocalDexCorpusSearchRequest } from "./bindings/Demo3LocalDexCorpusSearchRequest.ts";
|
||||
import type { Demo3LocalDexCorpusSearchPayload } from "./bindings/Demo3LocalDexCorpusSearchPayload.ts";
|
||||
import type { Demo3OnchainDexDiscoveryRequest } from "./bindings/Demo3OnchainDexDiscoveryRequest.ts";
|
||||
import type { Demo3OnchainDexDiscoveryResult } from "./bindings/Demo3OnchainDexDiscoveryResult.ts";
|
||||
import type { Demo3OnchainDexPairCandidate } from "./bindings/Demo3OnchainDexPairCandidate.ts";
|
||||
import type { Demo3LocalDexCorpusSearchResult } from "./bindings/Demo3LocalDexCorpusSearchResult.ts";
|
||||
import type { Demo3OnchainDexDiscoveryPayload } from "./bindings/Demo3OnchainDexDiscoveryPayload.ts";
|
||||
import type { Demo3OnchainDexDiscoveryRequest } from "./bindings/Demo3OnchainDexDiscoveryRequest.ts";
|
||||
import type { Demo3OnchainDexDiscoveryResult } from "./bindings/Demo3OnchainDexDiscoveryResult.ts";
|
||||
import type { Demo3OnchainDexPairCandidate } from "./bindings/Demo3OnchainDexPairCandidate.ts";
|
||||
import type { Demo3LocalDexCorpusSearchResult } from "./bindings/Demo3LocalDexCorpusSearchResult.ts";
|
||||
import type { Demo3OnchainDexDiscoveryPayload } from "./bindings/Demo3OnchainDexDiscoveryPayload.ts";
|
||||
|
||||
(window as Window & typeof globalThis & { bootstrap?: typeof bootstrap }).bootstrap = bootstrap;
|
||||
(window as Window & typeof globalThis & { ResizeObserver?: typeof ResizeObserver }).ResizeObserver = ResizeObserver;
|
||||
@@ -37,6 +37,59 @@ const presets: Demo3Preset[] = [
|
||||
{ label: "Orca Whirlpools", dexCode: "orca_whirlpools", programId: "whirLbMiicVdio4qvUfM5KAg6Ct8VwpYzGff3uctyCc", description: "Orca Whirlpools CLMM." },
|
||||
{ label: "FluxBeam", dexCode: "fluxbeam", programId: "FLUXubRmkEi2q6K3Y9kBPg9248ggaZVsoSFhtJHSrm1X", description: "FluxBeam." },
|
||||
{ label: "DexLab", dexCode: "dexlab", programId: "DSwpgjMvXhtGn6BsbqmacdBZyfLj6jSWf3HJpdJtmg6N", description: "DexLab Swap/Pool." },
|
||||
{ label: "Aldrin (historical)", dexCode: "aldrin", programId: "AMM55ShdkoGRB5jVYPjWziwk8m5MpwyDgsMWHaMSQWH6", description: "Program id historique importé depuis entities.py; à vérifier par corpus." },
|
||||
{ label: "Aldrin V2 (historical)", dexCode: "aldrin_v2", programId: "CURVGoZn8zycx6FXwwevgBTB2gVvdbGTEpvMJDbgs2t4", description: "Program id historique importé depuis entities.py; à vérifier par corpus." },
|
||||
{ label: "Crema (historical)", dexCode: "crema", programId: "CLMM9tUoggJu2wagPkkqs9eFG4BWhVBZWkP1qv3Sp7tR", description: "Program id historique importé depuis entities.py; à vérifier par corpus." },
|
||||
{ label: "Cropper (historical)", dexCode: "cropper", programId: "H8W3ctz92svYg6mkn1UtGfu2aQr2fnUFHM1RhScEtQDt", description: "Program id historique importé depuis entities.py; à vérifier par corpus." },
|
||||
{ label: "Lifinity V1 (historical)", dexCode: "lifinity_v1", programId: "EewxydAPCCVuNEyrVN68PuSYdQ7wKn27V9Gjeoi8dy3S", description: "Program id historique importé depuis entities.py; à vérifier par corpus." },
|
||||
{ label: "Lifinity V2 (historical)", dexCode: "lifinity_v2", programId: "2wT8Yq49kHgDzXuPxZSaeLaH1qbmGXtEyPy64bL7aD3c", description: "Program id historique importé depuis entities.py; à vérifier par corpus." },
|
||||
{ label: "Mercurial (historical)", dexCode: "mercurial", programId: "MERLuDFBMmsHnsBPZw2sDQZHvXFMwp8EdjudcU2HKky", description: "Program id historique importé depuis entities.py; à vérifier par corpus." },
|
||||
{ label: "Orca V1 (historical)", dexCode: "orca_v1", programId: "DjVE6JNiYqPL2QXyCUUh8rNjHrbz9hXHNYt99MQ59qw1", description: "Program id historique importé depuis entities.py; à vérifier par corpus." },
|
||||
{ label: "Orca V2 (historical)", dexCode: "orca_v2", programId: "9W959DqEETiGZocYWCQPaJ6sBmUzgfxXfqGeTEdp3aQP", description: "Program id historique importé depuis entities.py; à vérifier par corpus." },
|
||||
{ label: "Phoenix (historical)", dexCode: "phoenix", programId: "PhoeNiXZ8ByJGLkxNfZRnkUfjvmuYqLR89jjFHGqdXY", description: "Program id historique importé depuis entities.py; à vérifier par corpus." },
|
||||
{ label: "Saber (historical)", dexCode: "saber", programId: "SSwpkEEcbUqx4vtoEByFjSkhKdCT862DNVb52nZg1UZ", description: "Program id historique importé depuis entities.py; à vérifier par corpus." },
|
||||
{ label: "OpenBook V2 (historical)", dexCode: "openbook_v2", programId: "opnb2LAfJYbRMAHHvqjCwQxanZn7ReEHp1k81EohpZb", description: "Program id historique importé depuis entities.py; à vérifier par corpus." },
|
||||
{ label: "OpenBook (historical)", dexCode: "openbook", programId: "srmqPvymJeFKQ4zGQed1GFppgkRHL9kaELCbyksJtPX", description: "Program id historique importé depuis entities.py; à vérifier par corpus." },
|
||||
{ label: "Fox (historical)", dexCode: "fox", programId: "HyhpEq587ANShDdbx1mP4dTmDZC44CXWft29oYQXDb53", description: "Program id historique importé depuis entities.py; à vérifier par corpus." },
|
||||
{ label: "Sanctum Infinity (historical)", dexCode: "sanctum_infinity", programId: "5ocnV1qiCgaQR8Jb8xWnVbApfaygJ8tNoZfgPwsgx9kx", description: "Program id historique importé depuis entities.py; à vérifier par corpus." },
|
||||
{ label: "Saros (historical)", dexCode: "saros", programId: "SSwapUtytfBdBn1b9NUGG6foMVPtcWgpRU32HToDUZr", description: "Program id historique importé depuis entities.py; à vérifier par corpus." },
|
||||
{ label: "Perps (historical)", dexCode: "perps", programId: "PERPHjGBqRHArX4DySjwM6UJHiR3sWAatqfdBS2qQJu", description: "Program id historique importé depuis entities.py; à vérifier par corpus." },
|
||||
{ label: "StepN (historical)", dexCode: "stepn", programId: "Dooar9JkhdZ7J3LHN3A7YCuoGRUggXhQaG4kijfLGU2j", description: "Program id historique importé depuis entities.py; à vérifier par corpus." },
|
||||
{ label: "Solayer (historical)", dexCode: "solayer", programId: "endoLNCKTqDn8gSVnN2hDdpgACUPWHZTwoYnnMybpAT", description: "Program id historique importé depuis entities.py; à vérifier par corpus." },
|
||||
{ label: "Penguin (historical)", dexCode: "penguin", programId: "PSwapMdSai8tjrEXcxFeQth87xC4rRsa4VA5mhGhXkP", description: "Program id historique importé depuis entities.py; à vérifier par corpus." },
|
||||
{ label: "Sanctum (historical)", dexCode: "sanctum", programId: "stkitrT1Uoy18Dk1fTrgPw8W6MVzoCfYoAFT4MLsmhq", description: "Program id historique importé depuis entities.py; à vérifier par corpus." },
|
||||
{ label: "Guacswap (historical)", dexCode: "guacswap", programId: "Gswppe6ERWKpUTXvRPfXdzHhiCyJvLadVvXGfdpBqcE1", description: "Program id historique importé depuis entities.py; à vérifier par corpus." },
|
||||
{ label: "Oasis (historical)", dexCode: "oasis", programId: "9tKE7Mbmj4mxDjWatikzGAtkoWosiiZX9y6J4Hfm2R8H", description: "Program id historique importé depuis entities.py; à vérifier par corpus." },
|
||||
{ label: "Saber Decimals (historical)", dexCode: "saber_decimals", programId: "DecZY86MU5Gj7kppfUCEmd4LbXXuyZH1yHaP2NTqdiZB", description: "Program id historique importé depuis entities.py; à vérifier par corpus." },
|
||||
{ label: "Stabble Stable Swap (historical)", dexCode: "stabble_stable_swap", programId: "swapNyd8XiQwJ6ianp9snpu4brUqFxadzvHebnAXjJZ", description: "Program id historique importé depuis entities.py; à vérifier par corpus." },
|
||||
{ label: "Stabble Weighted Swap (historical)", dexCode: "stabble_weighted_swap", programId: "swapFpHZwjELNnjvThjajtiVmkz3yPQEHjLtka2fwHW", description: "Program id historique importé depuis entities.py; à vérifier par corpus." },
|
||||
{ label: "1DEX (historical)", dexCode: "one_dex", programId: "DEXYosS6oEGvk8uCDayvwEZz4qEyDJRf9nFgYCaqPMTm", description: "Program id historique importé depuis entities.py; à vérifier par corpus." },
|
||||
{ label: "SolFi (historical)", dexCode: "solfi", programId: "SoLFiHG9TfgtdUXUjWAxi3LtvYuFyDLVhBWxdMZxyCe", description: "Program id historique importé depuis entities.py; à vérifier par corpus." },
|
||||
{ label: "Moonshot (historical)", dexCode: "moonshot", programId: "MoonCVVNZFSYkqNXP6bxHLPL6QQJiMagDL3qcqUQTrG", description: "Program id historique importé depuis entities.py; à vérifier par corpus." },
|
||||
{ label: "Bonkswap (historical)", dexCode: "bonkswap", programId: "BSwp6bEBihVLdqJRKGgzjcGLHkcTuzmSo1TQkHepzH8p", description: "Program id historique importé depuis entities.py; à vérifier par corpus." },
|
||||
{ label: "Invariant (historical)", dexCode: "invariant", programId: "HyaB3W9q6XdA5xwpU4XnSZV94htfmbmqJXZcEbRaJutt", description: "Program id historique importé depuis entities.py; à vérifier par corpus." },
|
||||
{ label: "Token Swap (historical)", dexCode: "token_swap", programId: "SwaPpA9LAaLfeLi3a68M4DjnLqgtticKg6CnyNwgAC8", description: "Program id historique importé depuis entities.py; à vérifier par corpus." },
|
||||
{ label: "Helium Network (historical)", dexCode: "helium_network", programId: "treaf4wWBBty3fHdyBpo35Mz84M8k3heKXmjmi9vFt5", description: "Program id historique importé depuis entities.py; à vérifier par corpus." },
|
||||
{ label: "Raydium Legacy V2 (historical)", dexCode: "raydium_legacy_v2", programId: "27haf8L6oxUeXrHrgEgsexjSY5hbVUWEmvv9Nyxg8vQv", description: "Program id historique importé depuis entities.py; à vérifier par corpus." },
|
||||
{ label: "Raydium Legacy V3 (historical)", dexCode: "raydium_legacy_v3", programId: "7quYqsZdpWSZ3qgDextersDqoKjZy7aCgwHBBfRb7KPt", description: "Program id historique importé depuis entities.py; à vérifier par corpus." },
|
||||
{ label: "Serum V3 (historical)", dexCode: "serum_v3", programId: "9xQeWvG816bUx9EPjHmaT23yvVM2ZWbrrpZb9PusVFin", description: "Program id historique importé depuis entities.py; à vérifier par corpus." },
|
||||
{ label: "Mango Private Pools (historical)", dexCode: "mango_private_pools", programId: "AtdP2iyfh6xBGwVZzHvY73E7uKKkZBTH2siHh3ZuEf1P", description: "Program id historique importé depuis entities.py; à vérifier par corpus." },
|
||||
{ label: "Marinade Liquid Staking (historical)", dexCode: "marinade_liquid_staking", programId: "MarBmsSgKXdrN1egZf5sqe1TMai9K1rChYNDJgjq7aD", description: "Program id historique importé depuis entities.py; à vérifier par corpus." },
|
||||
{ label: "Step Finance Pools (historical)", dexCode: "step_finance_pools", programId: "StepAscQoEioFxxWGnh2sLBDFp9d8rvKz2Yp39iDpyT", description: "Program id historique importé depuis entities.py; à vérifier par corpus." },
|
||||
{ label: "Francium Yield Pools (historical)", dexCode: "francium_yield_pools", programId: "FC81tbGt6JWRXidaWYFXxGnTk4VgobhJHATvTRVMqgWj", description: "Program id historique importé depuis entities.py; à vérifier par corpus." },
|
||||
{ label: "Cropper Legacy (historical)", dexCode: "cropper_legacy", programId: "CyZuD7RPDcrqCGbNvzrNVs1zpCQehqp7SuXB7rdFKSzo", description: "Program id historique importé depuis entities.py; à vérifier par corpus." },
|
||||
{ label: "Dexlab Beta (historical)", dexCode: "dexlab_beta", programId: "9qvG1zP8ZzY1sTnExx7mkyxhW1063YHVYZxMYz2HkM4m", description: "Program id historique importé depuis entities.py; à vérifier par corpus." },
|
||||
{ label: "Marinade Governance (historical)", dexCode: "marinade_governance", programId: "GovER5Lthms3bLBqWub97yVrMmEogzX7xNjdXpPPCVZw", description: "Program id historique importé depuis entities.py; à vérifier par corpus." },
|
||||
{ label: "Serum DAO (historical)", dexCode: "serum_dao", programId: "SPoo1Ku8WFXoNDMHPsrGSTSG1Y47rzgn41SLUNakuHy", description: "Program id historique importé depuis entities.py; à vérifier par corpus." },
|
||||
{ label: "Port Finance (historical)", dexCode: "port_finance", programId: "Port7uDYB3wk6GJAw4KT1WpTeMtSu9bTcChBHkX2LfR", description: "Program id historique importé depuis entities.py; à vérifier par corpus." },
|
||||
{ label: "Solend Classic (historical)", dexCode: "solend_classic", programId: "So1endDq2YkqhipRh3WViPa8hdiSpxWy6z3Z6tMCpAo", description: "Program id historique importé depuis entities.py; à vérifier par corpus." },
|
||||
{ label: "Hyperspace NFT AMM (historical)", dexCode: "hyperspace_nft_amm", programId: "HYPERfwdTjyJ2SCaKHmpF2MtrXqWxrsotYDsTrshHWq8", description: "Program id historique importé depuis entities.py; à vérifier par corpus." },
|
||||
{ label: "Magic Eden NFT AMM (historical)", dexCode: "magic_eden_nft_amm", programId: "MEisE1HzehtrDpAAT8PnLHjpSSkRYakotTuJRPjTpo8", description: "Program id historique importé depuis entities.py; à vérifier par corpus." },
|
||||
{ label: "Raydium Staking Early (historical)", dexCode: "raydium_staking_early", programId: "EhhTKczWMGQt46ynNeRX1WfeagwwJd7ufHvCDjRxjo5Q", description: "Program id historique importé depuis entities.py; à vérifier par corpus." },
|
||||
{ label: "Orca Aquafarm V1 (historical)", dexCode: "orca_aquafarm_v1", programId: "82yxjeMsvaURa4MbZZ7WZZHfobirZYkH1zF8fmeGtyaQ", description: "Program id historique importé depuis entities.py; à vérifier par corpus." },
|
||||
{ label: "Quarry Merge Mining (historical)", dexCode: "quarry_merge_mining", programId: "QMNeHCGYnLVDn1icRAfQZpjPLBNkfGbSKRB83G5d8KB", description: "Program id historique importé depuis entities.py; à vérifier par corpus." },
|
||||
{ label: "SWAB Finance Beta (historical)", dexCode: "swab_finance_beta", programId: "SWABxNGyxEBVoNRGn6RvYBt5UqercSE5PBHuJeYXYHq", description: "Program id historique importé depuis entities.py; à vérifier par corpus." },
|
||||
{ label: "CRAFT Early (historical)", dexCode: "craft_early", programId: "CrAFTUv7zKXBaS5471aBiARBu6x7nP4rDzr8xwBewbr1", description: "Program id historique importé depuis entities.py; à vérifier par corpus." },
|
||||
{ label: "metaDAO", dexCode: "metadao", programId: "", description: "DEX à vérifier. Aucun program id n'est inventé." },
|
||||
{ label: "Printr", dexCode: "printr", programId: "", description: "DEX à vérifier. Aucun program id n'est inventé." },
|
||||
];
|
||||
@@ -56,6 +109,26 @@ function valueOrNull(value: string): string | null {
|
||||
return trimmed === "" ? null : trimmed;
|
||||
}
|
||||
|
||||
function isSolanaAddressLike(value: string): boolean {
|
||||
const trimmed = value.trim();
|
||||
if (trimmed.length < 32 || trimmed.length > 44) {
|
||||
return false;
|
||||
}
|
||||
return /^[1-9A-HJ-NP-Za-km-z]+$/.test(trimmed);
|
||||
}
|
||||
|
||||
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'.");
|
||||
}
|
||||
}
|
||||
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.");
|
||||
}
|
||||
}
|
||||
|
||||
function numberValueOrNull(value: string): number | null {
|
||||
const trimmed = value.trim();
|
||||
if (trimmed === "") {
|
||||
@@ -157,6 +230,11 @@ function readOnchainRequest(): Demo3OnchainDexDiscoveryRequest {
|
||||
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),
|
||||
excludeSwaps: byId<HTMLInputElement>("demo3ExcludeSwapsInput").checked,
|
||||
includeFailed: byId<HTMLInputElement>("demo3IncludeFailedInput").checked,
|
||||
httpRole: byId<HTMLInputElement>("demo3HttpRoleInput").value.trim() || "history_backfill",
|
||||
signatureLimit: intValue("demo3SignatureLimitInput", 50),
|
||||
transactionLimit: intValue("demo3TransactionLimitInput", 25),
|
||||
@@ -179,28 +257,57 @@ function readLocalRequest(): Demo3LocalDexCorpusSearchRequest {
|
||||
function clearFilters(): void {
|
||||
byId<HTMLInputElement>("demo3DexCodeInput").value = "";
|
||||
byId<HTMLInputElement>("demo3ProgramIdInput").value = "";
|
||||
byId<HTMLSelectElement>("demo3SignatureSourceSelect").value = "program_id";
|
||||
byId<HTMLInputElement>("demo3SourceAddressInput").value = "";
|
||||
byId<HTMLInputElement>("demo3PairIdInput").value = "";
|
||||
byId<HTMLInputElement>("demo3PoolAddressInput").value = "";
|
||||
byId<HTMLInputElement>("demo3TokenMintInput").value = "";
|
||||
byId<HTMLInputElement>("demo3SignatureInput").value = "";
|
||||
byId<HTMLSelectElement>("demo3TargetEventSelect").value = "";
|
||||
byId<HTMLInputElement>("demo3ExcludeSwapsInput").checked = false;
|
||||
byId<HTMLInputElement>("demo3IncludeFailedInput").checked = true;
|
||||
byId<HTMLSelectElement>("demo3PresetSelect").value = "";
|
||||
byId<HTMLElement>("demo3PresetHelp").textContent = "Choisis un DEX ou saisis un program id manuellement.";
|
||||
}
|
||||
|
||||
function renderOnchainResult(result: Demo3OnchainDexDiscoveryResult): void {
|
||||
byId<HTMLElement>("demo3SummarySignatureCount").textContent = String(result.fetchedSignatureCount);
|
||||
byId<HTMLElement>("demo3SummaryUniqueSignatureCount").textContent = String(result.uniqueSignatureCount);
|
||||
byId<HTMLElement>("demo3SummaryFetchedTxCount").textContent = String(result.fetchedTransactionCount);
|
||||
byId<HTMLElement>("demo3SummaryMissingTxCount").textContent = String(result.missingTransactionCount);
|
||||
byId<HTMLElement>("demo3SummaryFailedTxCount").textContent = String(result.failedTransactionCount);
|
||||
byId<HTMLElement>("demo3SummarySkippedFailedTxCount").textContent = String(result.skippedFailedTransactionCount);
|
||||
byId<HTMLElement>("demo3SummarySkippedSwapTxCount").textContent = String(result.skippedSwapLogTransactionCount);
|
||||
byId<HTMLElement>("demo3SummaryExtractedCandidateCount").textContent = String(result.extractedCandidateCount);
|
||||
byId<HTMLElement>("demo3SummaryRejectedCandidateCount").textContent = String(result.targetRejectedCandidateCount);
|
||||
byId<HTMLElement>("demo3SummaryCandidateCount").textContent = String(result.candidateCount);
|
||||
byId<HTMLElement>("demo3TargetText").textContent = `${result.resolvedDexCode ?? "custom"} / ${result.resolvedProgramId}`;
|
||||
const targetEvent = result.request.targetEvent ?? "any";
|
||||
byId<HTMLElement>("demo3TargetText").textContent = `${result.resolvedDexCode ?? "custom"} / program=${result.resolvedProgramId} / source=${result.resolvedSignatureSource}:${result.resolvedSignatureAddress} / target=${targetEvent}`;
|
||||
byId<HTMLElement>("demo3UniqueSignatureText").textContent = result.uniqueBackfillSignatures.length === 0 ? "-" : result.uniqueBackfillSignatures.join(", ");
|
||||
renderRejectedSummary(result);
|
||||
renderOnchainCandidates(result.candidates);
|
||||
}
|
||||
|
||||
function renderRejectedSummary(result: Demo3OnchainDexDiscoveryResult): void {
|
||||
const body = byId<HTMLTableSectionElement>("demo3RejectedSummaryTableBody");
|
||||
if (result.rejectedCandidateSummary.length === 0) {
|
||||
body.innerHTML = '<tr><td colspan="5" class="text-body-secondary">No rejected candidate summary.</td></tr>';
|
||||
return;
|
||||
}
|
||||
body.innerHTML = result.rejectedCandidateSummary.map((summary) => `
|
||||
<tr>
|
||||
<td>${escapeHtml(summary.candidateKind)}</td>
|
||||
<td class="font-monospace" title="${escapeHtml(summary.instructionDataPrefix ?? "")}">${escapeHtml(shortText(summary.instructionDataPrefix, 16))}</td>
|
||||
<td>${escapeHtml(summary.instructionName ?? "-")}</td>
|
||||
<td>${escapeHtml(summary.rejectionReason)}</td>
|
||||
<td>${summary.count}</td>
|
||||
</tr>`).join("");
|
||||
}
|
||||
|
||||
function renderOnchainCandidates(candidates: Demo3OnchainDexPairCandidate[]): void {
|
||||
const body = byId<HTMLTableSectionElement>("demo3OnchainCandidateTableBody");
|
||||
if (candidates.length === 0) {
|
||||
body.innerHTML = '<tr><td colspan="11" class="text-body-secondary">No on-chain candidate.</td></tr>';
|
||||
body.innerHTML = '<tr><td colspan="12" class="text-body-secondary">No on-chain candidate.</td></tr>';
|
||||
return;
|
||||
}
|
||||
body.innerHTML = candidates.map((candidate) => {
|
||||
@@ -225,6 +332,7 @@ function renderOnchainCandidates(candidates: Demo3OnchainDexPairCandidate[]): vo
|
||||
<td>${candidate.slot ?? "-"}</td>
|
||||
<td><span class="badge text-bg-info">${escapeHtml(candidate.candidateKind)}</span></td>
|
||||
<td><span class="badge text-bg-${candidate.confidence === "high" ? "success" : candidate.confidence === "medium" ? "warning" : "secondary"}">${escapeHtml(candidate.confidence)}</span></td>
|
||||
<td class="font-monospace" title="${escapeHtml(candidate.instructionDataPrefix ?? "")}">${escapeHtml(shortText(candidate.instructionDataPrefix, 14))}</td>
|
||||
<td class="font-monospace" title="${escapeHtml(verifiedPool ?? "")}">${escapeHtml(shortText(verifiedPool, 14))}</td>
|
||||
<td class="font-monospace" title="${escapeHtml(candidate.tokenAMint ?? "")}">${escapeHtml(shortText(candidate.tokenAMint, 14))}</td>
|
||||
<td class="font-monospace" title="${escapeHtml(candidate.tokenBMint ?? "")}">${escapeHtml(shortText(candidate.tokenBMint, 14))}</td>
|
||||
@@ -258,15 +366,22 @@ function renderLocalResult(result: Demo3LocalDexCorpusSearchResult): void {
|
||||
|
||||
async function discoverOnchain(): Promise<void> {
|
||||
const request = readOnchainRequest();
|
||||
try {
|
||||
validateOnchainRequest(request);
|
||||
} catch (error) {
|
||||
setStatus("error", "text-bg-danger");
|
||||
appendLogLine(`on-chain discovery rejected locally: ${String(error)}`);
|
||||
return;
|
||||
}
|
||||
setStatus("running", "text-bg-warning");
|
||||
appendLogLine(`on-chain discovery dex='${request.dexCode ?? ""}' program='${request.programId ?? ""}' role='${request.httpRole}'`);
|
||||
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}'`);
|
||||
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}' signatures='${payload.result.fetchedSignatureCount}'`);
|
||||
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}'`);
|
||||
} catch (error) {
|
||||
setStatus("error", "text-bg-danger");
|
||||
appendLogLine(`on-chain discovery failed: ${String(error)}`);
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
{
|
||||
"name": "kb-demo-app",
|
||||
"private": true,
|
||||
"version": "0.7.42",
|
||||
"version": "0.7.43",
|
||||
"type": "module",
|
||||
"scripts": {
|
||||
"dev": "vite",
|
||||
|
||||
@@ -431,6 +431,16 @@ pub(crate) struct Demo3OnchainDexDiscoveryRequest {
|
||||
pub dex_code: std::option::Option<std::string::String>,
|
||||
/// Optional Solana program id. When absent, dex_code must resolve to a verified program id.
|
||||
pub program_id: std::option::Option<std::string::String>,
|
||||
/// Optional signature source: `program_id` or `address`.
|
||||
pub signature_source: std::option::Option<std::string::String>,
|
||||
/// Optional source address used when signature_source is `address`.
|
||||
pub source_address: std::option::Option<std::string::String>,
|
||||
/// Optional target event family used to find non-swap signatures.
|
||||
pub target_event: std::option::Option<std::string::String>,
|
||||
/// Whether transactions containing swap-like logs should be skipped.
|
||||
pub exclude_swaps: bool,
|
||||
/// Whether failed transactions should be returned as candidates.
|
||||
pub include_failed: bool,
|
||||
/// HTTP role used to query Solana RPC.
|
||||
pub http_role: std::string::String,
|
||||
/// Maximum number of signatures to inspect.
|
||||
@@ -463,8 +473,19 @@ pub(crate) struct Demo3OnchainDexDiscoveryResult {
|
||||
pub request: Demo3OnchainDexDiscoveryRequest,
|
||||
/// DEX code resolved from the support matrix when available.
|
||||
pub resolved_dex_code: std::option::Option<std::string::String>,
|
||||
/// Program id scanned with getSignaturesForAddress.
|
||||
/// Program id used to filter matched instructions.
|
||||
pub resolved_program_id: std::string::String,
|
||||
/// Signature source actually used by getSignaturesForAddress.
|
||||
pub resolved_signature_source: std::string::String,
|
||||
/// Address scanned with getSignaturesForAddress.
|
||||
pub resolved_signature_address: std::string::String,
|
||||
/// Number of unique candidate signatures.
|
||||
#[ts(type = "number")]
|
||||
pub unique_signature_count: usize,
|
||||
/// Unique signatures ready for signature backfill.
|
||||
pub unique_backfill_signatures: std::vec::Vec<std::string::String>,
|
||||
/// Rejected candidate summary.
|
||||
pub rejected_candidate_summary: std::vec::Vec<Demo3OnchainDexRejectedCandidateSummary>,
|
||||
/// Number of signatures returned by Solana RPC.
|
||||
#[ts(type = "number")]
|
||||
pub fetched_signature_count: usize,
|
||||
@@ -477,6 +498,18 @@ pub(crate) struct Demo3OnchainDexDiscoveryResult {
|
||||
/// Number of failed transactions encountered.
|
||||
#[ts(type = "number")]
|
||||
pub failed_transaction_count: usize,
|
||||
/// Number of failed transactions skipped because include_failed is false.
|
||||
#[ts(type = "number")]
|
||||
pub skipped_failed_transaction_count: usize,
|
||||
/// Number of swap-log transactions skipped by the transaction-level swap guard.
|
||||
#[ts(type = "number")]
|
||||
pub skipped_swap_log_transaction_count: usize,
|
||||
/// Number of candidate rows extracted before target-event filtering.
|
||||
#[ts(type = "number")]
|
||||
pub extracted_candidate_count: usize,
|
||||
/// Number of candidate rows rejected by target-event filtering.
|
||||
#[ts(type = "number")]
|
||||
pub target_rejected_candidate_count: usize,
|
||||
/// Number of candidate rows returned.
|
||||
#[ts(type = "number")]
|
||||
pub candidate_count: usize,
|
||||
@@ -484,6 +517,27 @@ pub(crate) struct Demo3OnchainDexDiscoveryResult {
|
||||
pub candidates: std::vec::Vec<Demo3OnchainDexPairCandidate>,
|
||||
}
|
||||
|
||||
/// Rejected on-chain discovery candidate summary.
|
||||
#[derive(Clone, Debug, serde::Serialize, TS)]
|
||||
#[ts(
|
||||
export,
|
||||
export_to = "../frontend/ts/bindings/Demo3OnchainDexRejectedCandidateSummary.ts"
|
||||
)]
|
||||
#[serde(rename_all = "camelCase")]
|
||||
pub(crate) struct Demo3OnchainDexRejectedCandidateSummary {
|
||||
/// Candidate kind rejected by target filtering.
|
||||
pub candidate_kind: std::string::String,
|
||||
/// Optional instruction data prefix.
|
||||
pub instruction_data_prefix: std::option::Option<std::string::String>,
|
||||
/// Optional instruction name.
|
||||
pub instruction_name: std::option::Option<std::string::String>,
|
||||
/// Rejection reason.
|
||||
pub rejection_reason: std::string::String,
|
||||
/// Count of matching rejected candidates.
|
||||
#[ts(type = "number")]
|
||||
pub count: usize,
|
||||
}
|
||||
|
||||
/// Candidate on-chain transaction/instruction for a DEX program id.
|
||||
#[derive(Clone, Debug, serde::Serialize, TS)]
|
||||
#[ts(export, export_to = "../frontend/ts/bindings/Demo3OnchainDexPairCandidate.ts")]
|
||||
@@ -515,6 +569,8 @@ pub(crate) struct Demo3OnchainDexPairCandidate {
|
||||
pub inner_instruction_index: std::option::Option<i64>,
|
||||
/// Instruction name inferred from data/logs.
|
||||
pub instruction_name: std::option::Option<std::string::String>,
|
||||
/// Prefix of the raw base58 instruction data, useful for audit grouping.
|
||||
pub instruction_data_prefix: std::option::Option<std::string::String>,
|
||||
/// Candidate pool address.
|
||||
pub pool_address: std::option::Option<std::string::String>,
|
||||
/// Candidate token A mint.
|
||||
@@ -627,6 +683,11 @@ fn to_lib_onchain_request(
|
||||
return kb_lib::OnchainDexPairDiscoveryRequestDto {
|
||||
dex_code: normalize_optional_text(request.dex_code.clone()),
|
||||
program_id: normalize_optional_text(request.program_id.clone()),
|
||||
signature_source: normalize_optional_text(request.signature_source.clone()),
|
||||
source_address: normalize_optional_text(request.source_address.clone()),
|
||||
target_event: normalize_optional_text(request.target_event.clone()),
|
||||
exclude_swaps: request.exclude_swaps,
|
||||
include_failed: request.include_failed,
|
||||
http_role: request.http_role.trim().to_string(),
|
||||
signature_limit: request.signature_limit,
|
||||
transaction_limit: request.transaction_limit,
|
||||
@@ -645,6 +706,11 @@ fn from_lib_onchain_result(
|
||||
request: Demo3OnchainDexDiscoveryRequest {
|
||||
dex_code: result.request.dex_code,
|
||||
program_id: result.request.program_id,
|
||||
signature_source: result.request.signature_source,
|
||||
source_address: result.request.source_address,
|
||||
target_event: result.request.target_event,
|
||||
exclude_swaps: result.request.exclude_swaps,
|
||||
include_failed: result.request.include_failed,
|
||||
http_role: result.request.http_role,
|
||||
signature_limit: result.request.signature_limit,
|
||||
transaction_limit: result.request.transaction_limit,
|
||||
@@ -652,15 +718,42 @@ fn from_lib_onchain_result(
|
||||
},
|
||||
resolved_dex_code: result.resolved_dex_code,
|
||||
resolved_program_id: result.resolved_program_id,
|
||||
resolved_signature_source: result.resolved_signature_source,
|
||||
resolved_signature_address: result.resolved_signature_address,
|
||||
unique_signature_count: result.unique_signature_count,
|
||||
unique_backfill_signatures: result.unique_backfill_signatures,
|
||||
rejected_candidate_summary: from_lib_rejected_candidate_summary(
|
||||
result.rejected_candidate_summary,
|
||||
),
|
||||
fetched_signature_count: result.fetched_signature_count,
|
||||
fetched_transaction_count: result.fetched_transaction_count,
|
||||
missing_transaction_count: result.missing_transaction_count,
|
||||
failed_transaction_count: result.failed_transaction_count,
|
||||
skipped_failed_transaction_count: result.skipped_failed_transaction_count,
|
||||
skipped_swap_log_transaction_count: result.skipped_swap_log_transaction_count,
|
||||
extracted_candidate_count: result.extracted_candidate_count,
|
||||
target_rejected_candidate_count: result.target_rejected_candidate_count,
|
||||
candidate_count: result.candidate_count,
|
||||
candidates,
|
||||
};
|
||||
}
|
||||
|
||||
fn from_lib_rejected_candidate_summary(
|
||||
values: std::vec::Vec<kb_lib::OnchainDexRejectedCandidateSummaryDto>,
|
||||
) -> std::vec::Vec<Demo3OnchainDexRejectedCandidateSummary> {
|
||||
let mut mapped = std::vec::Vec::new();
|
||||
for value in values {
|
||||
mapped.push(Demo3OnchainDexRejectedCandidateSummary {
|
||||
candidate_kind: value.candidate_kind,
|
||||
instruction_data_prefix: value.instruction_data_prefix,
|
||||
instruction_name: value.instruction_name,
|
||||
rejection_reason: value.rejection_reason,
|
||||
count: value.count,
|
||||
});
|
||||
}
|
||||
return mapped;
|
||||
}
|
||||
|
||||
fn from_lib_onchain_candidate(
|
||||
candidate: kb_lib::OnchainDexPairCandidateDto,
|
||||
) -> Demo3OnchainDexPairCandidate {
|
||||
@@ -676,6 +769,7 @@ fn from_lib_onchain_candidate(
|
||||
instruction_index: candidate.instruction_index,
|
||||
inner_instruction_index: candidate.inner_instruction_index,
|
||||
instruction_name: candidate.instruction_name,
|
||||
instruction_data_prefix: candidate.instruction_data_prefix,
|
||||
pool_address: candidate.pool_address,
|
||||
token_a_mint: candidate.token_a_mint,
|
||||
token_b_mint: candidate.token_b_mint,
|
||||
|
||||
@@ -1279,7 +1279,7 @@ pub(crate) async fn demo_pipeline2_validate_local_pipeline(
|
||||
let service = kb_lib::LocalPipelineValidationService::new(database.clone());
|
||||
let profile_code = match request {
|
||||
Some(request) => request.profile_code,
|
||||
None => "0.7.42_raydium_family_event_coverage".to_string(),
|
||||
None => "0.7.43_meteora_effective_surfaces".to_string(),
|
||||
};
|
||||
let run_result = match profile_code.as_str() {
|
||||
"0.7.27" | "0.7.27_dexes_non_regression" => {
|
||||
@@ -1332,6 +1332,9 @@ pub(crate) async fn demo_pipeline2_validate_local_pipeline(
|
||||
"0.7.42" | "0.7.42_raydium_family_event_coverage" => {
|
||||
service.validate_v0_7_42_current_database().await
|
||||
},
|
||||
"0.7.43" | "0.7.43_meteora_effective_surfaces" => {
|
||||
service.validate_v0_7_43_current_database().await
|
||||
},
|
||||
other => Err(kb_lib::Error::InvalidState(format!(
|
||||
"unsupported local pipeline validation profile: {other}"
|
||||
))),
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
{
|
||||
"$schema": "https://schema.tauri.app/config/2",
|
||||
"productName": "kb-demo-app",
|
||||
"version": "0.7.42",
|
||||
"version": "0.7.43",
|
||||
"identifier": "com.sasedev.kb-demo-app",
|
||||
"build": {
|
||||
"beforeDevCommand": "npm run dev",
|
||||
|
||||
Reference in New Issue
Block a user