v0.1.0-pre.054
This commit is contained in:
20
.env.example
Normal file
20
.env.example
Normal file
@@ -0,0 +1,20 @@
|
||||
# file: .env.example
|
||||
# Copy to .env at the workspace root. Never commit the real file.
|
||||
|
||||
# Helius HTTP and WebSocket endpoint interpolation used by config/example.config.json.
|
||||
HELIUS_API_KEY=replace-with-your-helius-api-key
|
||||
|
||||
# Optional configuration override.
|
||||
# KB_CONFIG_PATH=config/example.config.json
|
||||
|
||||
# Optional Token-2022 Devnet validation fixtures.
|
||||
TOKEN_2022_PROGRAM=TokenzQdBNbLqP5VEhdkAS6EPFLC1PHnBqCXEpPxuEb
|
||||
TOKEN_2022_MINT=
|
||||
TOKEN_2022_SOURCE=
|
||||
TOKEN_2022_DESTINATION=
|
||||
TOKEN_2022_CLOSE_ACCOUNT=
|
||||
TOKEN_2022_DELEGATE=
|
||||
TOKEN_2022_AUTHORITY=
|
||||
TOKEN_2022_FREEZE_AUTHORITY=
|
||||
TOKEN_2022_DECIMALS=9
|
||||
TOKEN_2022_TRANSFER_AMOUNT_RAW=1
|
||||
3
.gitignore
vendored
3
.gitignore
vendored
@@ -39,7 +39,10 @@ dist
|
||||
var/
|
||||
# env
|
||||
.env
|
||||
.env.*
|
||||
!.env.dev
|
||||
!.env.example
|
||||
|
||||
config.json
|
||||
|
||||
# bindings TS-rs
|
||||
|
||||
10
CHANGELOG.md
10
CHANGELOG.md
@@ -1,3 +1,13 @@
|
||||
|
||||
## 0.1.0-pre.054
|
||||
|
||||
- stabilise le desktop après le portage complet des fenêtres Bot2 ;
|
||||
- charge `.env` avant la configuration et fournit `.env.example` pour Helius ;
|
||||
- corrige l'inventaire Metaplex Token Metadata ;
|
||||
- normalise les exports TS-RS Token-2022 sous `kb_lib` ;
|
||||
- retire les routes de logs héritées de crates supprimées ;
|
||||
- restaure les tables SQL pleine largeur et les afficheurs JSON/logs bornés ;
|
||||
- initialise le schéma PostgreSQL dans le splash et ferme la session WS à la fermeture globale.
|
||||
## 0.1.0-pre.031
|
||||
|
||||
## 0.1.0-pre.037
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
# file: Cargo.toml
|
||||
# version: 5
|
||||
# version: 6
|
||||
|
||||
[workspace]
|
||||
resolver = "3"
|
||||
@@ -26,6 +26,7 @@ authors = ["SinuS von SifriduS <sinus@sasedev.net>"]
|
||||
publish = false
|
||||
|
||||
[workspace.dependencies]
|
||||
dotenvy = {version = "^0.15", features = ["clap", "cli"]}
|
||||
argon2 = { version = "^0.5", features = ["std", "zeroize"] }
|
||||
async-trait = { version = "^0.1", features = [] }
|
||||
base64 = { version = "^0.23", features = [] }
|
||||
|
||||
11
README.md
11
README.md
@@ -110,3 +110,14 @@ La migration de `kb-pipeline` couvre désormais le backfill, l'extraction core,
|
||||
### Migration `0.1.0-pre.037`
|
||||
|
||||
`kb-pipeline` inclut désormais les contrôles stateful bornés des opérations Solana natives.
|
||||
|
||||
## Recherche ciblée des exports TS-RS
|
||||
|
||||
Pour éviter `node_modules`, limiter la recherche aux sources Rust :
|
||||
|
||||
```bash
|
||||
find kb-config kb-lib kb-app-demo-desktop -type f -name '*.rs' -print0 \
|
||||
| xargs -0 grep -n 'export_to'
|
||||
```
|
||||
|
||||
Le fichier `.env` optionnel est chargé depuis la racine du workspace, puis depuis `kb-app-demo-desktop/.env`. Les valeurs existantes de l'environnement ne sont pas remplacées.
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
13
idls/metaplex_token_metadata.SOURCE.md
Normal file
13
idls/metaplex_token_metadata.SOURCE.md
Normal file
@@ -0,0 +1,13 @@
|
||||
# Metaplex Token Metadata IDL source
|
||||
|
||||
- Repository: `metaplex-foundation/mpl-token-metadata`
|
||||
- Path: `idls/token_metadata.json`
|
||||
- Branch used for this snapshot: `main`
|
||||
- Program ID: `metaqbxxUerdq28cj1RbAWkYQm3ybzjb6a8bt518x1s`
|
||||
- Git blob SHA observed during retrieval: `5df4a24f62c2743125be096cc174680790c92c18`
|
||||
|
||||
Refresh with:
|
||||
|
||||
```bash
|
||||
scripts/fetch_metaplex_token_metadata_idl.sh
|
||||
```
|
||||
File diff suppressed because it is too large
Load Diff
@@ -1,5 +1,5 @@
|
||||
# file: kb-app-demo-desktop/Cargo.toml
|
||||
# version: 4
|
||||
# version: 5
|
||||
|
||||
[package]
|
||||
name = "kb-app-demo-desktop"
|
||||
@@ -21,6 +21,7 @@ path = "src/main.rs"
|
||||
tauri-build.workspace = true
|
||||
|
||||
[dependencies]
|
||||
dotenvy.workspace = true
|
||||
chrono.workspace = true
|
||||
fs2.workspace = true
|
||||
kb-config = { path = "../kb-config" }
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
<!-- file: kb-app-demo-desktop/frontend/demo_backfill.html -->
|
||||
<!-- version: 2 -->
|
||||
<!-- version: 3 -->
|
||||
<!DOCTYPE html>
|
||||
<html lang="fr">
|
||||
|
||||
@@ -155,20 +155,23 @@
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="accordion-item">
|
||||
<h2 class="accordion-header" id="backfillLogHeading">
|
||||
<button class="accordion-button collapsed" type="button" data-bs-toggle="collapse" data-bs-target="#backfillLogCollapse" aria-expanded="false" aria-controls="backfillLogCollapse">Journal et résultat</button>
|
||||
</h2>
|
||||
<div id="backfillLogCollapse" class="accordion-collapse collapse" aria-labelledby="backfillLogHeading" data-bs-parent="#backfillAccordion">
|
||||
<div class="accordion-body">
|
||||
</div>
|
||||
|
||||
<div class="card shadow-sm border-0 mt-4">
|
||||
<div class="card-body">
|
||||
<div class="d-flex justify-content-between align-items-center mb-2">
|
||||
<h3 class="h6 mb-0">Journal</h3><button id="clearBackfillLogButton" class="btn btn-sm btn-outline-secondary" type="button">Effacer</button>
|
||||
</div>
|
||||
<textarea id="backfillLogOutput" class="form-control font-monospace mb-3" rows="15" readonly>Aucune campagne exécutée.</textarea>
|
||||
<h3 class="h6">Résumé JSON</h3>
|
||||
<textarea id="backfillSummaryOutput" class="form-control font-monospace" rows="16" readonly>Aucun résultat.</textarea>
|
||||
<h2 class="h5 mb-0">Journal</h2>
|
||||
<div class="btn-group btn-group-sm">
|
||||
<button id="copyBackfillLogButton" class="btn btn-outline-primary" type="button">Copier</button>
|
||||
<button id="clearBackfillLogButton" class="btn btn-outline-secondary" type="button">Effacer</button>
|
||||
</div>
|
||||
</div>
|
||||
<textarea id="backfillLogOutput" class="form-control font-monospace app-log-output mb-4" readonly>Aucune campagne exécutée.</textarea>
|
||||
<div class="d-flex justify-content-between align-items-center mb-2">
|
||||
<h2 class="h5 mb-0">Résumé JSON</h2>
|
||||
<button id="copyBackfillSummaryButton" class="btn btn-sm btn-outline-primary" type="button">Copier</button>
|
||||
</div>
|
||||
<div id="backfillSummaryOutput" class="app-json-viewer"></div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
<!-- file: kb-app-demo-desktop/frontend/demo_config.html -->
|
||||
<!-- version: 2 -->
|
||||
<!-- version: 3 -->
|
||||
<!DOCTYPE html>
|
||||
<html lang="fr">
|
||||
|
||||
@@ -50,7 +50,7 @@
|
||||
<div class="card shadow-sm border-0 h-100">
|
||||
<div class="card-body">
|
||||
<h2 class="h5 card-title mb-3">Configuration active</h2>
|
||||
<div id="activeProfileJson" class="app-config-box app-json-viewer mb-0">Chargement...</div>
|
||||
<div id="activeProfileJson" class="app-json-viewer" class="app-config-box app-json-viewer mb-0">Chargement...</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
@@ -59,7 +59,7 @@
|
||||
<div class="card shadow-sm border-0 h-100">
|
||||
<div class="card-body">
|
||||
<h2 class="h5 card-title mb-3">Configuration complète</h2>
|
||||
<div id="fullConfigJson" class="app-config-box app-json-viewer mb-0">Chargement...</div>
|
||||
<div id="fullConfigJson" class="app-json-viewer" class="app-config-box app-json-viewer mb-0">Chargement...</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
@@ -68,7 +68,7 @@
|
||||
<div class="card shadow-sm border-0">
|
||||
<div class="card-body">
|
||||
<h2 class="h5 card-title mb-3">Schéma JSON embarqué</h2>
|
||||
<div id="schemaJson" class="app-config-box app-json-viewer mb-0">Chargement...</div>
|
||||
<div id="schemaJson" class="app-json-viewer" class="app-config-box app-json-viewer mb-0">Chargement...</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
@@ -138,7 +138,7 @@
|
||||
</div>
|
||||
<textarea id="coreExtractionLogOutput" class="form-control font-monospace mb-3" rows="15" readonly>Aucune campagne exécutée.</textarea>
|
||||
<h3 class="h6">Résumé JSON</h3>
|
||||
<textarea id="coreExtractionSummaryOutput" class="form-control font-monospace" rows="16" readonly>Aucun résultat.</textarea>
|
||||
<textarea id="coreExtractionSummaryOutput" class="form-control font-monospace" rows="16" readonly data-json-viewer="true">Aucun résultat.</textarea>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
@@ -112,9 +112,9 @@
|
||||
<h2 class="h5">Journal</h2>
|
||||
<textarea id="decodeReplayLogOutput" class="form-control font-monospace mb-3" rows="14" readonly>Aucune campagne exécutée.</textarea>
|
||||
<h2 class="h5">Résumé</h2>
|
||||
<textarea id="decodeReplaySummaryOutput" class="form-control font-monospace mb-3" rows="15" readonly>Aucun résultat.</textarea>
|
||||
<textarea id="decodeReplaySummaryOutput" class="form-control font-monospace mb-3" rows="15" readonly data-json-viewer="true">Aucun résultat.</textarea>
|
||||
<h2 class="h5">Diagnostics</h2>
|
||||
<textarea id="decodeReplayDiagnosticsOutput" class="form-control font-monospace" rows="18" readonly>Diagnostics non chargés.</textarea>
|
||||
<textarea id="decodeReplayDiagnosticsOutput" class="form-control font-monospace" rows="18" readonly data-json-viewer="true">Diagnostics non chargés.</textarea>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
<!-- file: kb-app-demo-desktop/frontend/demo_execution_solana_core.html -->
|
||||
<!-- version: 6 -->
|
||||
<!-- version: 7 -->
|
||||
<!DOCTYPE html>
|
||||
|
||||
<html lang="fr">
|
||||
@@ -12,8 +12,9 @@
|
||||
<body class="app-body">
|
||||
<header class="app-header bg-dark text-light">
|
||||
<nav class="container-fluid h-100 d-flex align-items-center justify-content-between px-4">
|
||||
<div>
|
||||
<h1 class="h4 mb-0">Exécution Solana Core Devnet</h1><small class="text-light-emphasis">System Program uniquement — simulation-first et replay post-exécution</small>
|
||||
<div class="navbar-brand d-flex align-items-center mb-0">
|
||||
<img alt="Logo Khadhroony" src="imgs/logo.png" class="app-logo"/>
|
||||
<span class="ps-2 fs-4 fw-bold text-primary font-logo">Bot3</span>
|
||||
</div>
|
||||
<div class="d-flex align-items-center gap-2"><span class="badge text-bg-success" id="executionStatusBadge">Prêt</span><button class="btn btn-sm btn-outline-warning" disabled="" id="cancelExecutionButton" type="button">Annuler</button></div>
|
||||
</nav>
|
||||
@@ -21,6 +22,10 @@
|
||||
<main class="app-main">
|
||||
<div class="osb-scrollable pt-1 pb-4" data-simplebar="">
|
||||
<div class="container-fluid py-4 px-4">
|
||||
<div class="card shadow-sm border-0 mb-4"><div class="card-body">
|
||||
<h1 class="h3 card-title mb-2">Exécution Solana Core Devnet</h1>
|
||||
<p class="text-body-secondary mb-0">System Program uniquement — simulation-first et replay post-exécution.</p>
|
||||
</div></div>
|
||||
<div class="alert alert-warning">Cette fenêtre est strictement réservée aux opérations Solana Core. Les opérations SPL sont disponibles dans « Exécution SPL Devnet ».</div>
|
||||
<div class="row g-4">
|
||||
<div class="col-12 col-xl-5">
|
||||
@@ -53,14 +58,14 @@
|
||||
<div class="col-12 col-xl-7">
|
||||
<div class="card shadow-sm border-0">
|
||||
<div class="card-body">
|
||||
<h2 class="h5 mb-3">Résumé</h2><textarea class="form-control font-monospace" id="executionSummaryOutput" readonly="" rows="14">Aucun résultat.</textarea>
|
||||
<h2 class="h5 mb-3">Résumé</h2><textarea class="form-control font-monospace" id="executionSummaryOutput" readonly="" rows="14" data-json-viewer="true">Aucun résultat.</textarea>
|
||||
</div>
|
||||
</div>
|
||||
<div class="card shadow-sm border-0 mt-4">
|
||||
<div class="card-body">
|
||||
<h2 class="h5">Plan exact</h2><textarea class="form-control font-monospace" id="executionPlanOutput" readonly="" rows="12">Aucun plan.</textarea>
|
||||
<h2 class="h5 mt-3">Simulation exacte</h2><textarea class="form-control font-monospace" id="executionSimulationOutput" readonly="" rows="12">Aucune simulation.</textarea>
|
||||
<h2 class="h5 mt-3">Confirmation et replay</h2><textarea class="form-control font-monospace" id="executionDiagnosticsOutput" readonly="" rows="12">Aucun diagnostic.</textarea>
|
||||
<h2 class="h5">Plan exact</h2><textarea class="form-control font-monospace" id="executionPlanOutput" readonly="" rows="12" data-json-viewer="true">Aucun plan.</textarea>
|
||||
<h2 class="h5 mt-3">Simulation exacte</h2><textarea class="form-control font-monospace" id="executionSimulationOutput" readonly="" rows="12" data-json-viewer="true">Aucune simulation.</textarea>
|
||||
<h2 class="h5 mt-3">Confirmation et replay</h2><textarea class="form-control font-monospace" id="executionDiagnosticsOutput" readonly="" rows="12" data-json-viewer="true">Aucun diagnostic.</textarea>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
<!-- file: kb-app-demo-desktop/frontend/demo_execution_spl.html -->
|
||||
<!-- version: 8 -->
|
||||
<!-- version: 9 -->
|
||||
<!DOCTYPE html>
|
||||
<html lang="fr">
|
||||
<head>
|
||||
@@ -12,16 +12,10 @@
|
||||
<body class="app-body">
|
||||
<header class="app-header bg-dark text-light">
|
||||
<nav class="container-fluid h-100 d-flex align-items-center justify-content-between px-4">
|
||||
<div class="d-flex align-items-center gap-3">
|
||||
<div class="navbar-brand d-flex align-items-center mb-0">
|
||||
<img alt="Logo" src="imgs/logo.png" class="app-logo" />
|
||||
<img alt="Logo Khadhroony" src="imgs/logo.png" class="app-logo" />
|
||||
<span class="ps-2 fs-4 fw-bold text-primary font-logo">Bot3</span>
|
||||
</div>
|
||||
<div>
|
||||
<h1 class="h4 mb-0">Exécution SPL Devnet</h1>
|
||||
<small class="text-light-emphasis">Memo, SPL Token classique, Token-2022 et ATA — simulation-first et replay post-exécution</small>
|
||||
</div>
|
||||
</div>
|
||||
<div class="d-flex align-items-center gap-2">
|
||||
<span class="badge text-bg-success" id="executionStatusBadge">Prêt</span>
|
||||
<button class="btn btn-sm btn-outline-warning" disabled="" id="cancelExecutionButton" type="button">Annuler</button>
|
||||
@@ -31,6 +25,10 @@
|
||||
<main class="app-main">
|
||||
<div class="osb-scrollable pt-1 pb-4" data-simplebar="">
|
||||
<div class="container-fluid py-4 px-4">
|
||||
<div class="card shadow-sm border-0 mb-4"><div class="card-body">
|
||||
<h1 class="h3 card-title mb-2">Exécution SPL Devnet</h1>
|
||||
<p class="text-body-secondary mb-0">Memo, SPL Token classique, Token-2022 et ATA — simulation-first et replay post-exécution.</p>
|
||||
</div></div>
|
||||
<div class="alert alert-warning" role="alert">
|
||||
Cette fenêtre est limitée à Devnet. La clé privée du wallet source reste dans le backend Rust et n’est jamais transmise à la WebView.
|
||||
</div>
|
||||
@@ -162,7 +160,7 @@
|
||||
<label class="form-label" for="ataTokenProgramSelect">Token Program cible</label>
|
||||
<select class="form-select" id="ataTokenProgramSelect">
|
||||
<option value="classic">SPL Token classique</option>
|
||||
<option value="token_2022">Token-2022</option>
|
||||
<option value="token2022">Token-2022</option>
|
||||
</select>
|
||||
</div>
|
||||
<div class="col-12 col-md-6">
|
||||
@@ -199,21 +197,21 @@
|
||||
</div>
|
||||
</div>
|
||||
<div class="accordion-item">
|
||||
<h2 class="accordion-header" id="splToken2022DecoderHeading"><button aria-controls="splToken2022DecoderCollapse" aria-expanded="false" class="accordion-button collapsed" data-bs-target="#splToken2022DecoderCollapse" data-bs-toggle="collapse" type="button"><span class="d-flex flex-wrap align-items-center justify-content-between gap-2 w-100 me-2"><span>Exécution spl_token_2022 — scénarios publics</span><span class="badge text-bg-success">Exécutable</span></span></button></h2>
|
||||
<h2 class="accordion-header" id="splToken2022DecoderHeading"><button aria-controls="splToken2022DecoderCollapse" aria-expanded="false" class="accordion-button collapsed" data-bs-target="#splToken2022DecoderCollapse" data-bs-toggle="collapse" type="button"><span class="d-flex flex-wrap align-items-center justify-content-between gap-2 w-100 me-2"><span>Exécution spl_token2022 — scénarios publics</span><span class="badge text-bg-success">Exécutable</span></span></button></h2>
|
||||
<div aria-labelledby="splToken2022DecoderHeading" class="accordion-collapse collapse" data-bs-parent="#decoderExecutionAccordion" id="splToken2022DecoderCollapse">
|
||||
<div class="accordion-body">
|
||||
<div class="alert alert-info">Chaque opération est simulée sur le message exact avant toute signature. Les scénarios sont indépendants et réutilisent la fixture chargée dans les deux terminaux.</div>
|
||||
<div class="d-grid mb-3"><button class="btn btn-outline-secondary" id="loadToken2022FixtureButton" type="button">Charger la fixture Token-2022</button></div>
|
||||
<div class="form-text mb-3" id="token2022FixtureHelp">Aucune fixture chargée.</div>
|
||||
<div class="mb-3"><label class="form-label" for="token2022ScenarioSelect">Scénario</label><select class="form-select" id="token2022ScenarioSelect">
|
||||
<option value="token_2022_mint_to_checked">MintToChecked</option>
|
||||
<option value="token_2022_transfer_checked">TransferChecked</option>
|
||||
<option value="token_2022_approve_checked">ApproveChecked</option>
|
||||
<option value="token_2022_revoke">Revoke</option>
|
||||
<option value="token_2022_burn_checked">BurnChecked</option>
|
||||
<option value="token_2022_freeze_account">FreezeAccount</option>
|
||||
<option value="token_2022_thaw_account">ThawAccount</option>
|
||||
<option value="token_2022_close_destination">CloseAccount</option>
|
||||
<option value="token2022_mint_to_checked">MintToChecked</option>
|
||||
<option value="token2022_transfer_checked">TransferChecked</option>
|
||||
<option value="token2022_approve_checked">ApproveChecked</option>
|
||||
<option value="token2022_revoke">Revoke</option>
|
||||
<option value="token2022_burn_checked">BurnChecked</option>
|
||||
<option value="token2022_freeze_account">FreezeAccount</option>
|
||||
<option value="token2022_thaw_account">ThawAccount</option>
|
||||
<option value="token2022_close_destination">CloseAccount</option>
|
||||
</select></div>
|
||||
<div class="mb-3"><label class="form-label" for="token2022SourceInput">Compte source / compte cible</label><input class="form-control font-monospace" id="token2022SourceInput" type="text" /></div>
|
||||
<div class="mb-3"><label class="form-label" for="token2022MintInput">Mint Token-2022</label><input class="form-control font-monospace" id="token2022MintInput" type="text" /></div>
|
||||
@@ -263,7 +261,7 @@
|
||||
</h2>
|
||||
<div class="accordion-collapse collapse" data-bs-parent="#executionDetailsAccordion" id="executionPlanCollapse">
|
||||
<div class="accordion-body">
|
||||
<textarea class="form-control font-monospace" id="executionPlanOutput" readonly="" rows="16">Aucun plan.</textarea>
|
||||
<textarea class="form-control font-monospace" id="executionPlanOutput" readonly="" rows="16" data-json-viewer="true">Aucun plan.</textarea>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
@@ -273,7 +271,7 @@
|
||||
</h2>
|
||||
<div class="accordion-collapse collapse" data-bs-parent="#executionDetailsAccordion" id="executionSimulationCollapse">
|
||||
<div class="accordion-body">
|
||||
<textarea class="form-control font-monospace" id="executionSimulationOutput" readonly="" rows="16">Aucune simulation.</textarea>
|
||||
<textarea class="form-control font-monospace" id="executionSimulationOutput" readonly="" rows="16" data-json-viewer="true">Aucune simulation.</textarea>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
@@ -283,7 +281,7 @@
|
||||
</h2>
|
||||
<div class="accordion-collapse collapse" data-bs-parent="#executionDetailsAccordion" id="executionDiagnosticsCollapse">
|
||||
<div class="accordion-body">
|
||||
<textarea class="form-control font-monospace" id="executionDiagnosticsOutput" readonly="" rows="16">Aucun diagnostic.</textarea>
|
||||
<textarea class="form-control font-monospace" id="executionDiagnosticsOutput" readonly="" rows="16" data-json-viewer="true">Aucun diagnostic.</textarea>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
@@ -405,7 +403,7 @@
|
||||
<div class="card shadow-sm border-0 mt-4">
|
||||
<div class="card-body">
|
||||
<h2 class="h5 mb-3">Résumé</h2>
|
||||
<textarea class="form-control font-monospace" id="executionSummaryOutput" readonly="" rows="14">Aucun résultat.</textarea>
|
||||
<textarea class="form-control font-monospace" id="executionSummaryOutput" readonly="" rows="14" data-json-viewer="true">Aucun résultat.</textarea>
|
||||
</div>
|
||||
</div>
|
||||
<div class="card shadow-sm border-0 mt-4">
|
||||
|
||||
@@ -73,7 +73,7 @@
|
||||
<h2 class="h5 card-title mb-0">Résultat</h2>
|
||||
<button id="copyHttpResultButton" class="btn btn-sm btn-outline-secondary">Copier</button>
|
||||
</div>
|
||||
<textarea id="httpResultOutput" class="form-control font-monospace" rows="18" readonly>Aucune requête exécutée.</textarea>
|
||||
<textarea id="httpResultOutput" class="form-control font-monospace" rows="18" readonly data-json-viewer="true">Aucune requête exécutée.</textarea>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
@@ -27,9 +27,9 @@
|
||||
|
||||
<main class="app-main">
|
||||
<div class="osb-scrollable pt-1 pb-4" data-simplebar>
|
||||
<div class="container py-4">
|
||||
<div class="container-fluid py-4 px-4">
|
||||
<div class="row g-4">
|
||||
<div class="col-12 col-xl-6">
|
||||
<div class="col-12">
|
||||
<div class="card shadow-sm border-0">
|
||||
<div class="card-body">
|
||||
<div class="d-flex flex-wrap gap-2 justify-content-between align-items-center mb-3">
|
||||
@@ -61,11 +61,11 @@
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="col-12 col-xl-6">
|
||||
<div class="col-12">
|
||||
<div class="card shadow-sm border-0">
|
||||
<div class="card-body">
|
||||
<h2 class="h5 card-title mb-3">Tables raw/core connues</h2>
|
||||
<div class="table-responsive">
|
||||
<div class="table-responsive app-table-full-width">
|
||||
<table class="table table-sm align-middle mb-0">
|
||||
<thead>
|
||||
<tr>
|
||||
|
||||
@@ -27,9 +27,9 @@
|
||||
|
||||
<main class="app-main">
|
||||
<div class="osb-scrollable pt-1 pb-4" data-simplebar>
|
||||
<div class="container py-4">
|
||||
<div class="container-fluid py-4 px-4">
|
||||
<div class="row g-4">
|
||||
<div class="col-12 col-xl-6">
|
||||
<div class="col-12">
|
||||
<div class="card shadow-sm border-0">
|
||||
<div class="card-body">
|
||||
<div class="d-flex flex-wrap gap-2 justify-content-between align-items-center mb-3">
|
||||
@@ -48,11 +48,11 @@
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="col-12 col-xl-6">
|
||||
<div class="col-12">
|
||||
<div class="card shadow-sm border-0">
|
||||
<div class="card-body">
|
||||
<h2 class="h5 card-title mb-3">Tables core</h2>
|
||||
<div class="table-responsive">
|
||||
<div class="table-responsive app-table-full-width">
|
||||
<table class="table table-sm align-middle mb-0">
|
||||
<thead>
|
||||
<tr>
|
||||
|
||||
@@ -27,9 +27,9 @@
|
||||
|
||||
<main class="app-main">
|
||||
<div class="osb-scrollable pt-1 pb-4" data-simplebar>
|
||||
<div class="container py-4">
|
||||
<div class="container-fluid py-4 px-4">
|
||||
<div class="row g-4">
|
||||
<div class="col-12 col-xl-6">
|
||||
<div class="col-12">
|
||||
<div class="card shadow-sm border-0">
|
||||
<div class="card-body">
|
||||
<div class="d-flex flex-wrap gap-2 justify-content-between align-items-center mb-3">
|
||||
@@ -48,11 +48,11 @@
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="col-12 col-xl-6">
|
||||
<div class="col-12">
|
||||
<div class="card shadow-sm border-0">
|
||||
<div class="card-body">
|
||||
<h2 class="h5 card-title mb-3">Transactions canoniques et observations</h2>
|
||||
<div class="table-responsive">
|
||||
<div class="table-responsive app-table-full-width">
|
||||
<table class="table table-sm align-middle mb-0">
|
||||
<thead>
|
||||
<tr>
|
||||
|
||||
@@ -90,7 +90,7 @@
|
||||
<h2 class="h5 card-title mb-0">Messages</h2>
|
||||
<button id="copyWsResultButton" class="btn btn-sm btn-outline-secondary">Copier</button>
|
||||
</div>
|
||||
<textarea id="wsResultOutput" class="form-control font-monospace" rows="16" readonly>Aucune connexion active.</textarea>
|
||||
<textarea id="wsResultOutput" class="form-control font-monospace" rows="16" readonly data-json-viewer="true">Aucune connexion active.</textarea>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
<!-- file: kb-app-demo-desktop/frontend/main.html -->
|
||||
<!-- version: 6 -->
|
||||
<!-- version: 7 -->
|
||||
<!DOCTYPE html>
|
||||
<html lang="fr">
|
||||
<head>
|
||||
@@ -24,19 +24,24 @@
|
||||
<ul class="dropdown-menu dropdown-menu-end">
|
||||
<li><a id="openDemoConfigLink" class="dropdown-item" href="#">Configuration</a></li>
|
||||
<li><hr class="dropdown-divider"></li>
|
||||
<li><a id="openDemoWsLink" class="dropdown-item" href="#">WebSocket standard</a></li>
|
||||
<li><h6 class="dropdown-header">Transport et collecte</h6></li>
|
||||
<li><a id="openDemoHttpLink" class="dropdown-item" href="#">HTTP JSON-RPC</a></li>
|
||||
<li><a id="openDemoWsLink" class="dropdown-item" href="#">WebSocket standard</a></li>
|
||||
<li><a id="openDemoBackfillLink" class="dropdown-item" href="#">Backfill HTTP</a></li>
|
||||
<li><hr class="dropdown-divider"></li>
|
||||
<li><h6 class="dropdown-header">Pipeline</h6></li>
|
||||
<li><a id="openDemoCoreExtractionLink" class="dropdown-item" href="#">Extraction core</a></li>
|
||||
<li><a id="openDemoDecodeReplayLink" class="dropdown-item" href="#">Décodage contextualisé</a></li>
|
||||
<li><a id="openDemoExecutionSolanaCoreLink" class="dropdown-item" href="#">Exécution Solana Core</a></li>
|
||||
<li><a id="openDemoExecutionSplLink" class="dropdown-item" href="#">Exécution SPL</a></li>
|
||||
<li><hr class="dropdown-divider"></li>
|
||||
<li><h6 class="dropdown-header">Stockage</h6></li>
|
||||
<li><a id="openDemoSqlDiagLink" class="dropdown-item" href="#">SQL diagnostics</a></li>
|
||||
<li><a id="openDemoSqlPgRawLink" class="dropdown-item" href="#">SQL PostgreSQL raw</a></li>
|
||||
<li><a id="openDemoSqlPgCoreLink" class="dropdown-item" href="#">SQL PostgreSQL core</a></li>
|
||||
<li><a id="openDemoSqlReplayCandidatesLink" class="dropdown-item" href="#">SQL replay candidates</a></li>
|
||||
<li><hr class="dropdown-divider"></li>
|
||||
<li><h6 class="dropdown-header">Exécution Devnet</h6></li>
|
||||
<li><a id="openDemoExecutionSolanaCoreLink" class="dropdown-item" href="#">Solana Core</a></li>
|
||||
<li><a id="openDemoExecutionSplLink" class="dropdown-item" href="#">SPL</a></li>
|
||||
</ul>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
@@ -383,3 +383,38 @@ video#vbackground:not([playsinline]) {
|
||||
background-color: rgba(0, 0, 0, 0.04);
|
||||
white-space: pre-wrap;
|
||||
}
|
||||
.app-json-viewer {
|
||||
display: block;
|
||||
height: 24rem;
|
||||
max-height: 24rem;
|
||||
overflow: auto;
|
||||
overscroll-behavior: contain;
|
||||
border: 1px solid var(--bs-border-color);
|
||||
border-radius: var(--bs-border-radius);
|
||||
background: var(--bs-body-bg);
|
||||
}
|
||||
|
||||
.app-json-viewer > andypf-json-viewer {
|
||||
display: block;
|
||||
min-width: 0;
|
||||
}
|
||||
|
||||
.app-log-output {
|
||||
display: block;
|
||||
width: 100%;
|
||||
height: 18rem;
|
||||
max-height: 18rem;
|
||||
overflow: auto;
|
||||
resize: vertical;
|
||||
white-space: pre;
|
||||
}
|
||||
|
||||
.app-table-full-width {
|
||||
width: 100%;
|
||||
overflow-x: auto;
|
||||
}
|
||||
|
||||
.app-table-full-width table {
|
||||
width: 100%;
|
||||
min-width: 0;
|
||||
}
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
// file: kb_demo_app/frontend/sass/main.scss
|
||||
// file: kb-app-demo-desktop/frontend/sass/main.scss
|
||||
// version: 1
|
||||
|
||||
@import "bootstrap/scss/functions";
|
||||
|
||||
@@ -1,8 +1,9 @@
|
||||
// file: kb-app-demo-desktop/frontend/ts/demo_backfill.ts
|
||||
// version: 5
|
||||
// version: 6
|
||||
|
||||
import * as bootstrap from "bootstrap";
|
||||
import "simplebar";
|
||||
import "@andypf/json-viewer";
|
||||
import ResizeObserver from "resize-observer-polyfill";
|
||||
import { invoke } from "@tauri-apps/api/core";
|
||||
import { listen } from "@tauri-apps/api/event";
|
||||
@@ -146,7 +147,7 @@ function validationMessage(request: DemoBackfillRequest): string | null {
|
||||
}
|
||||
|
||||
function reportValidationWarning(message: string): void {
|
||||
element<HTMLTextAreaElement>("#backfillSummaryOutput").value = JSON.stringify({ validation: message }, null, 2);
|
||||
renderBackfillSummary({ validation: message });
|
||||
appendLog({ timestamp: new Date().toISOString(), level: "warn", message });
|
||||
frontendDebug("kb-app-demo-desktop.frontend.backfill", `Backfill request rejected locally: ${message}`);
|
||||
}
|
||||
@@ -174,10 +175,10 @@ async function executeBackfill(mode: string): Promise<void> {
|
||||
return;
|
||||
}
|
||||
setRunning(true);
|
||||
element<HTMLTextAreaElement>("#backfillSummaryOutput").value = "Exécution en cours...";
|
||||
renderBackfillSummary({ status: "Exécution en cours" });
|
||||
appendLog({ timestamp: new Date().toISOString(), level: "info", message: `Démarrage du mode ${mode}` });
|
||||
const summary = await invoke<DemoBackfillSummaryPayload>("demo_backfill_execute", { request });
|
||||
element<HTMLTextAreaElement>("#backfillSummaryOutput").value = JSON.stringify(summary, null, 2);
|
||||
renderBackfillSummary(summary);
|
||||
appendLog({
|
||||
timestamp: new Date().toISOString(),
|
||||
level: summary.cancelled ? "warn" : "info",
|
||||
@@ -185,7 +186,7 @@ async function executeBackfill(mode: string): Promise<void> {
|
||||
});
|
||||
} catch (caughtError) {
|
||||
const message = caughtError instanceof Error ? caughtError.message : String(caughtError);
|
||||
element<HTMLTextAreaElement>("#backfillSummaryOutput").value = JSON.stringify({ error: message }, null, 2);
|
||||
renderBackfillSummary({ error: message });
|
||||
appendLog({ timestamp: new Date().toISOString(), level: "error", message });
|
||||
frontendError("kb-app-demo-desktop.frontend.backfill", `Backfill failed: ${message}`);
|
||||
} finally {
|
||||
@@ -232,6 +233,28 @@ async function loadOptions(): Promise<void> {
|
||||
setRunning(options.running);
|
||||
}
|
||||
|
||||
|
||||
function renderBackfillSummary(value: unknown): void {
|
||||
const container = document.querySelector<HTMLElement>("#backfillSummaryOutput");
|
||||
if (!container) {
|
||||
return;
|
||||
}
|
||||
container.textContent = "";
|
||||
const viewer = document.createElement("andypf-json-viewer");
|
||||
viewer.setAttribute("indent", "2");
|
||||
viewer.setAttribute("expanded", "1");
|
||||
viewer.setAttribute("theme", "default-light");
|
||||
viewer.setAttribute("show-data-types", "true");
|
||||
viewer.setAttribute("show-toolbar", "false");
|
||||
viewer.setAttribute("show-copy", "true");
|
||||
viewer.setAttribute("data", JSON.stringify(value ?? { status: "Aucun résultat" }, null, 2));
|
||||
container.appendChild(viewer);
|
||||
}
|
||||
|
||||
async function copyText(value: string): Promise<void> {
|
||||
await navigator.clipboard.writeText(value);
|
||||
}
|
||||
|
||||
document.addEventListener("DOMContentLoaded", () => {
|
||||
installFrontendConsoleBridge("kb-app-demo-desktop.frontend.backfill");
|
||||
frontendDebug("kb-app-demo-desktop.frontend.backfill", "backfill demo window loaded");
|
||||
@@ -264,4 +287,14 @@ document.addEventListener("DOMContentLoaded", () => {
|
||||
appendLog({ timestamp: new Date().toISOString(), level: "error", message });
|
||||
frontendError("kb-app-demo-desktop.frontend.backfill", `Options loading failed: ${message}`);
|
||||
});
|
||||
|
||||
document.querySelector<HTMLButtonElement>("#copyBackfillLogButton")?.addEventListener("click", async () => {
|
||||
const value = document.querySelector<HTMLTextAreaElement>("#backfillLogOutput")?.value ?? "";
|
||||
await copyText(value);
|
||||
});
|
||||
document.querySelector<HTMLButtonElement>("#copyBackfillSummaryButton")?.addEventListener("click", async () => {
|
||||
const value = document.querySelector("#backfillSummaryOutput andypf-json-viewer")?.getAttribute("data") ?? "";
|
||||
await copyText(value);
|
||||
});
|
||||
renderBackfillSummary(null);
|
||||
});
|
||||
|
||||
@@ -1,8 +1,9 @@
|
||||
// file: kb-app-demo-desktop/frontend/ts/frontend_log.ts
|
||||
// version: 1
|
||||
// version: 2
|
||||
|
||||
//! Frontend logging helpers that preserve explicit tracing targets.
|
||||
|
||||
import "@andypf/json-viewer";
|
||||
import { invoke } from "@tauri-apps/api/core";
|
||||
import type { FrontendLogPayload } from "./bindings/kb_app_demo_desktop/frontend_log/FrontendLogPayload.ts";
|
||||
|
||||
@@ -87,7 +88,80 @@ function buildConsoleBridge(level: FrontendLogLevel, target: string, original: C
|
||||
};
|
||||
}
|
||||
|
||||
|
||||
function upgradeJsonTextareas(): void {
|
||||
document.querySelectorAll<HTMLTextAreaElement>("textarea[data-json-viewer]").forEach(textarea => {
|
||||
if (textarea.dataset.jsonViewerInstalled === "true") {
|
||||
return;
|
||||
}
|
||||
textarea.dataset.jsonViewerInstalled = "true";
|
||||
const container = document.createElement("div");
|
||||
container.className = "app-json-viewer";
|
||||
const viewer = document.createElement("andypf-json-viewer");
|
||||
viewer.setAttribute("indent", "2");
|
||||
viewer.setAttribute("expanded", "1");
|
||||
viewer.setAttribute("theme", "default-light");
|
||||
viewer.setAttribute("show-data-types", "true");
|
||||
viewer.setAttribute("show-toolbar", "false");
|
||||
viewer.setAttribute("show-copy", "true");
|
||||
const descriptor = Object.getOwnPropertyDescriptor(HTMLTextAreaElement.prototype, "value");
|
||||
let currentValue = textarea.value;
|
||||
const render = (value: string): void => {
|
||||
currentValue = value;
|
||||
let parsed: unknown = value;
|
||||
try {
|
||||
parsed = JSON.parse(value) as unknown;
|
||||
} catch {
|
||||
parsed = { message: value };
|
||||
}
|
||||
viewer.setAttribute("data", JSON.stringify(parsed, null, 2));
|
||||
};
|
||||
Object.defineProperty(textarea, "value", {
|
||||
configurable: true,
|
||||
get: () => currentValue,
|
||||
set: (value: string) => {
|
||||
descriptor?.set?.call(textarea, value);
|
||||
render(value);
|
||||
},
|
||||
});
|
||||
textarea.classList.add("d-none");
|
||||
textarea.insertAdjacentElement("afterend", container);
|
||||
container.appendChild(viewer);
|
||||
render(currentValue);
|
||||
});
|
||||
}
|
||||
|
||||
function upgradeLogOutputs(): void {
|
||||
document.querySelectorAll<HTMLTextAreaElement>("textarea[id$='LogOutput'], textarea[data-log-output]").forEach(textarea => {
|
||||
if (textarea.dataset.logOutputInstalled === "true") {
|
||||
return;
|
||||
}
|
||||
textarea.dataset.logOutputInstalled = "true";
|
||||
textarea.classList.add("app-log-output");
|
||||
const toolbar = document.createElement("div");
|
||||
toolbar.className = "d-flex justify-content-end gap-2 mb-2";
|
||||
const copyButton = document.createElement("button");
|
||||
copyButton.type = "button";
|
||||
copyButton.className = "btn btn-sm btn-outline-secondary";
|
||||
copyButton.textContent = "Copier";
|
||||
copyButton.addEventListener("click", () => {
|
||||
void navigator.clipboard.writeText(textarea.value);
|
||||
});
|
||||
const clearButton = document.createElement("button");
|
||||
clearButton.type = "button";
|
||||
clearButton.className = "btn btn-sm btn-outline-secondary";
|
||||
clearButton.textContent = "Effacer";
|
||||
clearButton.addEventListener("click", () => {
|
||||
textarea.value = "";
|
||||
});
|
||||
toolbar.append(copyButton, clearButton);
|
||||
textarea.insertAdjacentElement("beforebegin", toolbar);
|
||||
});
|
||||
}
|
||||
|
||||
export function installFrontendConsoleBridge(target: string): void {
|
||||
upgradeJsonTextareas();
|
||||
upgradeLogOutputs();
|
||||
console.trace = buildConsoleBridge("trace", target, originalConsole.trace);
|
||||
console.debug = buildConsoleBridge("debug", target, originalConsole.debug);
|
||||
console.log = buildConsoleBridge("info", target, originalConsole.log);
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
// file: kb-app-demo-desktop/src/app_state.rs
|
||||
// version: 6
|
||||
// version: 8
|
||||
|
||||
//! Shared Tauri application state and startup initialization.
|
||||
|
||||
@@ -28,6 +28,7 @@ pub(crate) struct AppState {
|
||||
impl crate::AppState {
|
||||
/// Initializes configuration, logging and shared runtime state.
|
||||
pub(crate) fn initialize() -> kb_core::Result<crate::AppState> {
|
||||
load_workspace_dotenv();
|
||||
let config_path = resolve_config_path();
|
||||
let app_config = match kb_config::read_config_json_file(&config_path) {
|
||||
std::result::Result::Ok(config) => config,
|
||||
@@ -179,6 +180,23 @@ impl crate::AppState {
|
||||
}
|
||||
}
|
||||
|
||||
fn load_workspace_dotenv() {
|
||||
let workspace_path = crate::workspace_root_dir().join(".env");
|
||||
load_dotenv_path(&workspace_path);
|
||||
let desktop_path = crate::workspace_root_dir().join("kb-app-demo-desktop/.env");
|
||||
load_dotenv_path(&desktop_path);
|
||||
}
|
||||
|
||||
fn load_dotenv_path(path: &std::path::Path) {
|
||||
let result = dotenvy::from_path(path);
|
||||
if let std::result::Result::Err(error) = result {
|
||||
if matches!(error, dotenvy::Error::Io(ref io_error) if io_error.kind() == std::io::ErrorKind::NotFound) {
|
||||
return;
|
||||
}
|
||||
eprintln!("cannot load {}: {error}", path.display());
|
||||
}
|
||||
}
|
||||
|
||||
fn convert_logging_config(config: &kb_config::LoggingConfig) -> kb_logging::LoggingConfig {
|
||||
let mut targets = std::vec::Vec::<kb_logging::LogTargetConfig>::new();
|
||||
for target in &config.targets {
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
// file: kb-app-demo-desktop/src/demo_decode_replay.rs
|
||||
// version: 25
|
||||
// version: 27
|
||||
|
||||
//! Tauri commands and UI payloads for contextual instruction decode replay.
|
||||
|
||||
@@ -299,7 +299,7 @@ pub(crate) struct DemoDecodeReplayObserver<'a> {
|
||||
|
||||
impl kb_pipeline::DecodeReplayObserver for crate::DemoDecodeReplayObserver<'_> {
|
||||
fn on_progress(&self, event: &kb_pipeline::DecodeReplayProgressEvent) {
|
||||
let payload = DemoDecodeReplayProgressPayload {
|
||||
let payload = crate::DemoDecodeReplayProgressPayload {
|
||||
campaign_id: self.campaign_id.clone(),
|
||||
timestamp: event.timestamp.clone(),
|
||||
level: event.level.code().to_string(),
|
||||
@@ -727,7 +727,7 @@ mod tests {
|
||||
assert_eq!(
|
||||
names,
|
||||
std::vec![
|
||||
"kb_decoder_metadata_metaplex_token_metadata".to_string(),
|
||||
"metadata_metaplex_token_metadata".to_string(),
|
||||
"solana_native_classifier".to_string(),
|
||||
"spl_associated_token_account".to_string(),
|
||||
"spl_elgamal_registry".to_string(),
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
// file: kb-app-demo-desktop/src/tauri.rs
|
||||
// version: 9
|
||||
// version: 10
|
||||
|
||||
//! Tauri runtime assembly and private command wrappers.
|
||||
|
||||
@@ -92,6 +92,16 @@ pub fn run() -> kb_core::Result<()> {
|
||||
open_demo_config_window,
|
||||
load_demo_config,
|
||||
]);
|
||||
builder = builder.on_window_event(|window, event| {
|
||||
if window.label() != "main" || !matches!(event, tauri::WindowEvent::Destroyed) {
|
||||
return;
|
||||
}
|
||||
let app_handle = window.app_handle().clone();
|
||||
tauri::async_runtime::spawn(async move {
|
||||
let state = app_handle.state::<crate::AppState>();
|
||||
crate::disconnect_demo_ws_app_state(&state, false).await;
|
||||
});
|
||||
});
|
||||
builder = builder.plugin(tracing_builder.build::<tauri::Wry>());
|
||||
builder = builder.setup(|app| {
|
||||
let splash_window = match app.get_webview_window("splash") {
|
||||
@@ -112,6 +122,7 @@ pub fn run() -> kb_core::Result<()> {
|
||||
)));
|
||||
},
|
||||
};
|
||||
let app_handle = app.handle().clone();
|
||||
tauri::async_runtime::spawn(async move {
|
||||
let started_at = tokio::time::Instant::now();
|
||||
crate::emit_splash_order(
|
||||
@@ -135,6 +146,8 @@ pub fn run() -> kb_core::Result<()> {
|
||||
std::option::Option::None,
|
||||
std::option::Option::None,
|
||||
);
|
||||
let state = app_handle.state::<crate::AppState>();
|
||||
crate::initialize_postgres_schema_for_startup(&state, &splash_window).await;
|
||||
crate::emit_splash_order(
|
||||
&splash_window,
|
||||
"fadein",
|
||||
@@ -230,7 +243,7 @@ fn open_demo_core_extraction_window(
|
||||
"demo_core_extraction",
|
||||
tauri::WebviewUrl::App("demo_core_extraction.html".into()),
|
||||
)
|
||||
.title("Khadhroony Bot2 - Extraction canonical vers core")
|
||||
.title("Khadhroony Bot3 - Extraction canonical vers core")
|
||||
.inner_size(1280.0, 860.0)
|
||||
.min_inner_size(960.0, 620.0)
|
||||
.resizable(true)
|
||||
@@ -341,7 +354,7 @@ fn open_demo_decode_replay_window(
|
||||
"demo_decode_replay",
|
||||
tauri::WebviewUrl::App("demo_decode_replay.html".into()),
|
||||
)
|
||||
.title("Khadhroony Bot2 - Décodage et matérialisation")
|
||||
.title("Khadhroony Bot3 - Décodage et matérialisation")
|
||||
.inner_size(1320.0, 900.0)
|
||||
.min_inner_size(980.0, 660.0)
|
||||
.resizable(true)
|
||||
|
||||
@@ -88,7 +88,7 @@ pub const EX_SPL_TOKEN_SUPPORTED_OPERATION_CODES: &[&str] = &[
|
||||
#[derive(Clone, Debug, Eq, PartialEq, serde::Deserialize, serde::Serialize, TS)]
|
||||
#[ts(
|
||||
export,
|
||||
export_to = "../frontend/ts/bindings/kb_lib_executor_spl_token/intent/ExSplClassicTokenAmount.ts"
|
||||
export_to = "../frontend/ts/bindings/kb_lib/executor/spl/token/intent/ExSplClassicTokenAmount.ts"
|
||||
)]
|
||||
pub struct ExSplClassicTokenAmount(
|
||||
/// Canonical unsigned decimal representation.
|
||||
@@ -99,7 +99,7 @@ pub struct ExSplClassicTokenAmount(
|
||||
#[derive(Clone, Debug, Eq, PartialEq, serde::Deserialize, serde::Serialize, TS)]
|
||||
#[ts(
|
||||
export,
|
||||
export_to = "../frontend/ts/bindings/kb_lib_executor_spl_token/intent/ExSplClassicTokenAuthority.ts"
|
||||
export_to = "../frontend/ts/bindings/kb_lib/executor/spl/token/intent/ExSplClassicTokenAuthority.ts"
|
||||
)]
|
||||
pub struct ExSplClassicTokenAuthority {
|
||||
/// Authority account. It signs only when `multisig_signers` is empty.
|
||||
@@ -113,7 +113,7 @@ pub struct ExSplClassicTokenAuthority {
|
||||
#[serde(rename_all = "snake_case")]
|
||||
#[ts(
|
||||
export,
|
||||
export_to = "../frontend/ts/bindings/kb_lib_executor_spl_token/intent/ExSplClassicTokenAuthorityType.ts"
|
||||
export_to = "../frontend/ts/bindings/kb_lib/executor/spl/token/intent/ExSplClassicTokenAuthorityType.ts"
|
||||
)]
|
||||
pub enum ExSplClassicTokenAuthorityType {
|
||||
/// Mint authority.
|
||||
@@ -131,7 +131,7 @@ pub enum ExSplClassicTokenAuthorityType {
|
||||
#[serde(tag = "instruction", rename_all = "snake_case")]
|
||||
#[ts(
|
||||
export,
|
||||
export_to = "../frontend/ts/bindings/kb_lib_executor_spl_token/intent/ExSplClassicTokenSingleOperation.ts"
|
||||
export_to = "../frontend/ts/bindings/kb_lib/executor/spl/token/intent/ExSplClassicTokenSingleOperation.ts"
|
||||
)]
|
||||
pub enum ExSplClassicTokenSingleOperation {
|
||||
/// Initialize a mint with the current no-Rent builder.
|
||||
@@ -411,7 +411,7 @@ impl crate::ExSplClassicTokenSingleOperation {
|
||||
#[serde(tag = "operation", rename_all = "snake_case")]
|
||||
#[ts(
|
||||
export,
|
||||
export_to = "../frontend/ts/bindings/kb_lib_executor_spl_token/intent/ExSplClassicTokenOperation.ts"
|
||||
export_to = "../frontend/ts/bindings/kb_lib/executor/spl/token/intent/ExSplClassicTokenOperation.ts"
|
||||
)]
|
||||
pub enum ExSplClassicTokenOperation {
|
||||
/// Build one non-batch instruction.
|
||||
@@ -449,7 +449,7 @@ impl crate::ExSplClassicTokenOperation {
|
||||
#[derive(Clone, Debug, Eq, PartialEq, serde::Deserialize, serde::Serialize, TS)]
|
||||
#[ts(
|
||||
export,
|
||||
export_to = "../frontend/ts/bindings/kb_lib_executor_spl_token/intent/ExSplClassicTokenExecutionIntent.ts"
|
||||
export_to = "../frontend/ts/bindings/kb_lib/executor/spl/token/intent/ExSplClassicTokenExecutionIntent.ts"
|
||||
)]
|
||||
pub struct ExSplClassicTokenExecutionIntent {
|
||||
/// Stable caller-provided identifier used for logs and replay correlation.
|
||||
|
||||
@@ -30,7 +30,7 @@ pub const EX_SPL_TOKEN2022_CONFIDENTIAL_TRANSFER_WITH_FEE_INSTRUCTION_DATA_BYTES
|
||||
#[derive(Clone, Debug, Eq, PartialEq, serde::Deserialize, serde::Serialize, TS)]
|
||||
#[ts(
|
||||
export,
|
||||
export_to = "../frontend/ts/bindings/kb_executor_spl_token_2022/confidential/ExSplTokenElGamalPubkey.ts"
|
||||
export_to = "../frontend/ts/bindings/kb_lib/executor/spl/token2022/confidential/ExSplTokenElGamalPubkey.ts"
|
||||
)]
|
||||
pub struct ExSplTokenElGamalPubkey(pub std::string::String);
|
||||
|
||||
@@ -59,7 +59,7 @@ impl ExSplTokenElGamalPubkey {
|
||||
#[derive(Clone, Debug, Eq, PartialEq, serde::Deserialize, serde::Serialize, TS)]
|
||||
#[ts(
|
||||
export,
|
||||
export_to = "../frontend/ts/bindings/kb_executor_spl_token_2022/confidential/ExSplTokenDecryptableBalance.ts"
|
||||
export_to = "../frontend/ts/bindings/kb_lib/executor/spl/token2022/confidential/ExSplTokenDecryptableBalance.ts"
|
||||
)]
|
||||
pub struct ExSplTokenDecryptableBalance(pub std::string::String);
|
||||
|
||||
@@ -89,7 +89,7 @@ impl ExSplTokenDecryptableBalance {
|
||||
#[derive(Clone, Debug, Eq, PartialEq, serde::Deserialize, serde::Serialize, TS)]
|
||||
#[ts(
|
||||
export,
|
||||
export_to = "../frontend/ts/bindings/kb_executor_spl_token_2022/confidential/ExSplTokenElGamalCiphertext.ts"
|
||||
export_to = "../frontend/ts/bindings/kb_lib/executor/spl/token2022/confidential/ExSplTokenElGamalCiphertext.ts"
|
||||
)]
|
||||
pub struct ExSplTokenElGamalCiphertext(pub std::string::String);
|
||||
|
||||
@@ -157,7 +157,7 @@ fn decode_hex_nibble(value: u8) -> Option<u8> {
|
||||
#[serde(rename_all = "snake_case")]
|
||||
#[ts(
|
||||
export,
|
||||
export_to = "../frontend/ts/bindings/kb_executor_spl_token_2022/confidential/ExSplTokenConfidentialProofKind.ts"
|
||||
export_to = "../frontend/ts/bindings/kb_lib/executor/spl/token2022/confidential/ExSplTokenConfidentialProofKind.ts"
|
||||
)]
|
||||
pub enum ExSplTokenConfidentialProofKind {
|
||||
/// ElGamal public-key validity.
|
||||
@@ -187,7 +187,7 @@ pub enum ExSplTokenConfidentialProofKind {
|
||||
#[serde(rename_all = "snake_case", tag = "mode")]
|
||||
#[ts(
|
||||
export,
|
||||
export_to = "../frontend/ts/bindings/kb_executor_spl_token_2022/confidential/ExSplTokenConfidentialProofLocation.ts"
|
||||
export_to = "../frontend/ts/bindings/kb_lib/executor/spl/token2022/confidential/ExSplTokenConfidentialProofLocation.ts"
|
||||
)]
|
||||
pub enum ExSplTokenConfidentialProofLocation {
|
||||
/// Relative transaction offset of a separate ZK proof-program instruction.
|
||||
@@ -220,7 +220,7 @@ impl ExSplTokenConfidentialProofLocation {
|
||||
#[serde(rename_all = "camelCase")]
|
||||
#[ts(
|
||||
export,
|
||||
export_to = "../frontend/ts/bindings/kb_executor_spl_token_2022/confidential/ExSplTokenConfidentialProofReference.ts"
|
||||
export_to = "../frontend/ts/bindings/kb_lib/executor/spl/token2022/confidential/ExSplTokenConfidentialProofReference.ts"
|
||||
)]
|
||||
pub struct ExSplTokenConfidentialProofReference {
|
||||
/// Exact proof statement required by the Token-2022 builder.
|
||||
@@ -234,7 +234,7 @@ pub struct ExSplTokenConfidentialProofReference {
|
||||
#[serde(rename_all = "snake_case")]
|
||||
#[ts(
|
||||
export,
|
||||
export_to = "../frontend/ts/bindings/kb_executor_spl_token_2022/confidential/ExSplTokenConfidentialOperation.ts"
|
||||
export_to = "../frontend/ts/bindings/kb_lib/executor/spl/token2022/confidential/ExSplTokenConfidentialOperation.ts"
|
||||
)]
|
||||
pub enum ExSplTokenConfidentialOperation {
|
||||
/// Initialize confidential-transfer mint configuration.
|
||||
@@ -336,7 +336,7 @@ impl ExSplTokenConfidentialOperation {
|
||||
#[serde(rename_all = "snake_case")]
|
||||
#[ts(
|
||||
export,
|
||||
export_to = "../frontend/ts/bindings/kb_executor_spl_token_2022/confidential/ExSplTokenConfidentialMintBurnOperation.ts"
|
||||
export_to = "../frontend/ts/bindings/kb_lib/executor/spl/token2022/confidential/ExSplTokenConfidentialMintBurnOperation.ts"
|
||||
)]
|
||||
pub enum ExSplTokenConfidentialMintBurnOperation {
|
||||
/// Initialize the mint extension with supply encryption material.
|
||||
@@ -399,7 +399,7 @@ impl ExSplTokenConfidentialMintBurnOperation {
|
||||
#[serde(rename_all = "snake_case")]
|
||||
#[ts(
|
||||
export,
|
||||
export_to = "../frontend/ts/bindings/kb_executor_spl_token_2022/confidential/ExSplTokenConfidentialExecutorSupport.ts"
|
||||
export_to = "../frontend/ts/bindings/kb_lib/executor/spl/token2022/confidential/ExSplTokenConfidentialExecutorSupport.ts"
|
||||
)]
|
||||
pub enum ExSplTokenConfidentialExecutorSupport {
|
||||
/// The builder needs only public fields and ordinary authorities.
|
||||
|
||||
@@ -351,7 +351,7 @@ pub const EX_SPL_TOKEN2022_SUPPORTED_OPERATION_CODES: &[&str] = &[
|
||||
#[derive(Clone, Debug, Eq, PartialEq, serde::Deserialize, serde::Serialize, TS)]
|
||||
#[ts(
|
||||
export,
|
||||
export_to = "../frontend/ts/bindings/kb_executor_spl_token_2022/intent/ExSplTokenAmount.ts"
|
||||
export_to = "../frontend/ts/bindings/kb_lib/executor/spl/token2022/intent/ExSplTokenAmount.ts"
|
||||
)]
|
||||
pub struct ExSplTokenAmount(
|
||||
/// Canonical unsigned decimal representation.
|
||||
@@ -362,7 +362,7 @@ pub struct ExSplTokenAmount(
|
||||
#[derive(Clone, Debug, Eq, PartialEq, serde::Deserialize, serde::Serialize, TS)]
|
||||
#[ts(
|
||||
export,
|
||||
export_to = "../frontend/ts/bindings/kb_executor_spl_token_2022/intent/ExSplTokenMultiplier.ts"
|
||||
export_to = "../frontend/ts/bindings/kb_lib/executor/spl/token2022/intent/ExSplTokenMultiplier.ts"
|
||||
)]
|
||||
pub struct ExSplTokenMultiplier(
|
||||
/// Decimal representation parsed to the official `f64` wire contract.
|
||||
@@ -373,7 +373,7 @@ pub struct ExSplTokenMultiplier(
|
||||
#[derive(Clone, Debug, Eq, PartialEq, serde::Deserialize, serde::Serialize, TS)]
|
||||
#[ts(
|
||||
export,
|
||||
export_to = "../frontend/ts/bindings/kb_executor_spl_token_2022/intent/ExSplTokenAuthority.ts"
|
||||
export_to = "../frontend/ts/bindings/kb_lib/executor/spl/token2022/intent/ExSplTokenAuthority.ts"
|
||||
)]
|
||||
pub struct ExSplTokenAuthority {
|
||||
/// Authority account. It signs only when `multisig_signers` is empty.
|
||||
@@ -387,7 +387,7 @@ pub struct ExSplTokenAuthority {
|
||||
#[serde(rename_all = "snake_case")]
|
||||
#[ts(
|
||||
export,
|
||||
export_to = "../frontend/ts/bindings/kb_executor_spl_token_2022/intent/ExSplTokenAuthorityType.ts"
|
||||
export_to = "../frontend/ts/bindings/kb_lib/executor/spl/token2022/intent/ExSplTokenAuthorityType.ts"
|
||||
)]
|
||||
pub enum ExSplTokenAuthorityType {
|
||||
/// Mint authority.
|
||||
@@ -405,7 +405,7 @@ pub enum ExSplTokenAuthorityType {
|
||||
#[serde(rename_all = "snake_case")]
|
||||
#[ts(
|
||||
export,
|
||||
export_to = "../frontend/ts/bindings/kb_executor_spl_token_2022/intent/ExSplTokenDefaultAccountState.ts"
|
||||
export_to = "../frontend/ts/bindings/kb_lib/executor/spl/token2022/intent/ExSplTokenDefaultAccountState.ts"
|
||||
)]
|
||||
pub enum ExSplTokenDefaultAccountState {
|
||||
/// Newly initialized accounts remain usable.
|
||||
@@ -419,7 +419,7 @@ pub enum ExSplTokenDefaultAccountState {
|
||||
#[serde(rename_all = "snake_case", tag = "kind", content = "key")]
|
||||
#[ts(
|
||||
export,
|
||||
export_to = "../frontend/ts/bindings/kb_executor_spl_token_2022/intent/ExSplTokenMetadataField.ts"
|
||||
export_to = "../frontend/ts/bindings/kb_lib/executor/spl/token2022/intent/ExSplTokenMetadataField.ts"
|
||||
)]
|
||||
pub enum ExSplTokenMetadataField {
|
||||
/// Update the required name field.
|
||||
@@ -437,7 +437,7 @@ pub enum ExSplTokenMetadataField {
|
||||
#[serde(tag = "instruction", rename_all = "snake_case")]
|
||||
#[ts(
|
||||
export,
|
||||
export_to = "../frontend/ts/bindings/kb_executor_spl_token_2022/intent/ExSplTokenSingleOperation.ts"
|
||||
export_to = "../frontend/ts/bindings/kb_lib/executor/spl/token2022/intent/ExSplTokenSingleOperation.ts"
|
||||
)]
|
||||
pub enum ExSplTokenSingleOperation {
|
||||
/// Initialize a mint with the current no-Rent builder.
|
||||
@@ -1577,7 +1577,7 @@ impl crate::ExSplTokenSingleOperation {
|
||||
#[serde(tag = "operation", rename_all = "snake_case")]
|
||||
#[ts(
|
||||
export,
|
||||
export_to = "../frontend/ts/bindings/kb_executor_spl_token_2022/intent/ExSplToken2022Operation.ts"
|
||||
export_to = "../frontend/ts/bindings/kb_lib/executor/spl/token2022/intent/ExSplToken2022Operation.ts"
|
||||
)]
|
||||
pub enum ExSplToken2022Operation {
|
||||
/// Build one non-batch instruction.
|
||||
@@ -1615,7 +1615,7 @@ impl crate::ExSplToken2022Operation {
|
||||
#[derive(Clone, Debug, Eq, PartialEq, serde::Deserialize, serde::Serialize, TS)]
|
||||
#[ts(
|
||||
export,
|
||||
export_to = "../frontend/ts/bindings/kb_executor_spl_token_2022/intent/ExSplToken2022ExecutionIntent.ts"
|
||||
export_to = "../frontend/ts/bindings/kb_lib/executor/spl/token2022/intent/ExSplToken2022ExecutionIntent.ts"
|
||||
)]
|
||||
pub struct ExSplToken2022ExecutionIntent {
|
||||
/// Stable caller-provided identifier used for logs and replay correlation.
|
||||
|
||||
7
scripts/fetch_metaplex_token_metadata_idl.sh
Executable file
7
scripts/fetch_metaplex_token_metadata_idl.sh
Executable file
@@ -0,0 +1,7 @@
|
||||
#!/usr/bin/env bash
|
||||
set -euo pipefail
|
||||
readonly URL="https://raw.githubusercontent.com/metaplex-foundation/mpl-token-metadata/main/idls/token_metadata.json"
|
||||
readonly OUTPUT="idls/metaplex_token_metadata.metaqbxxUerdq28cj1RbAWkYQm3ybzjb6a8bt518x1s.json"
|
||||
curl --fail --location --silent --show-error "$URL" --output "$OUTPUT"
|
||||
python3 -m json.tool "$OUTPUT" >/dev/null
|
||||
printf 'Fetched %s\n' "$OUTPUT"
|
||||
Reference in New Issue
Block a user