v0.1.0-pre.061

This commit is contained in:
2026-07-28 18:41:30 +02:00
parent c7bad46f50
commit f40fb78817
527 changed files with 4598 additions and 4114 deletions

View File

@@ -1,5 +1,5 @@
// file: kb-app-demo-desktop/frontend/ts/demo_execution_spl.ts
// version: 3
// version: 4
import * as bootstrap from "bootstrap";
import "simplebar";
@@ -25,9 +25,9 @@ import type { DemoSplAtaDerivationPayload } from "./bindings/kb_app_demo_desktop
import type { DemoSplAtaDerivationRequest } from "./bindings/kb_app_demo_desktop/demo_spl_ata/DemoSplAtaDerivationRequest.ts";
import type { DemoSplAtaJournalRequest } from "./bindings/kb_app_demo_desktop/demo_spl_ata/DemoSplAtaJournalRequest.ts";
import type { DemoSplAtaJournalRow } from "./bindings/kb_app_demo_desktop/demo_spl_ata/DemoSplAtaJournalRow.ts";
import type { DemoExecutionSplToken2022Request } from "./bindings/kb_app_demo_desktop/demo_spl_token2022/DemoExecutionSplToken2022Request.ts";
import type { DemoExecutionSplToken2022SummaryPayload } from "./bindings/kb_app_demo_desktop/demo_spl_token2022/DemoExecutionSplToken2022SummaryPayload.ts";
import type { DemoSplToken2022FixturePayload } from "./bindings/kb_app_demo_desktop/demo_spl_token2022/DemoSplToken2022FixturePayload.ts";
import type { DemoExecutionSplToken2022Request } from "./bindings/kb_app_demo_desktop/demo_spl_token_2022/DemoExecutionSplToken2022Request.ts";
import type { DemoExecutionSplToken2022SummaryPayload } from "./bindings/kb_app_demo_desktop/demo_spl_token_2022/DemoExecutionSplToken2022SummaryPayload.ts";
import type { DemoSplToken2022FixturePayload } from "./bindings/kb_app_demo_desktop/demo_spl_token_2022/DemoSplToken2022FixturePayload.ts";
(window as Window & typeof globalThis & { bootstrap?: typeof bootstrap }).bootstrap = bootstrap;
@@ -37,7 +37,7 @@ const logLines: string[] = [];
const maximumLogLines = 1200;
let running = false;
let profileOptions: DemoExecutionSolanaCoreProfileOption[] = [];
let token2022Fixture: DemoSplToken2022FixturePayload | null = null;
let token_2022Fixture: DemoSplToken2022FixturePayload | null = null;
function element<T extends HTMLElement>(selector: string): T {
const value = document.querySelector<T>(selector);
@@ -297,10 +297,18 @@ async function executeAta(submit: boolean): Promise<void> {
if (running) {
return;
}
if (submit && !element<HTMLInputElement>("#executionOperatorConfirmedInput").checked) {
const message = "La confirmation opérateur est obligatoire avant signature ATA.";
appendLog({
timestamp: new Date().toISOString(),
level: "error",
stage: "ata_validation",
message,
});
frontendError("kb-app-demo-desktop.frontend.execution_spl", message);
return;
}
try {
if (submit && !element<HTMLInputElement>("#executionOperatorConfirmedInput").checked) {
throw new Error("La confirmation opérateur est obligatoire avant signature ATA.");
}
const derivation = await deriveAta();
const request: DemoExecutionSplAtaRequest = {
profileName: element<HTMLSelectElement>("#executionProfileSelect").value,
@@ -558,86 +566,86 @@ function renderTokenJournal(rows: DemoSplTokenJournalRow[]): void {
function token2022ScenarioAmount(fixture: DemoSplToken2022FixturePayload, scenarioId: string): string {
if (scenarioId === "token2022_mint_to_checked") {
function token_2022ScenarioAmount(fixture: DemoSplToken2022FixturePayload, scenarioId: string): string {
if (scenarioId === "token_2022_mint_to_checked") {
return "1";
}
if (scenarioId === "token2022_approve_checked") {
if (scenarioId === "token_2022_approve_checked") {
return "2";
}
if (scenarioId === "token2022_burn_checked") {
if (scenarioId === "token_2022_burn_checked") {
return "1";
}
return fixture.defaultAmountRaw;
}
function applyToken2022Fixture(): void {
if (!token2022Fixture) {
if (!token_2022Fixture) {
return;
}
const scenarioId = element<HTMLSelectElement>("#token2022ScenarioSelect").value;
element<HTMLInputElement>("#token2022SourceInput").value = scenarioId === "token2022_close_destination"
? token2022Fixture.closeAccount
: token2022Fixture.source;
element<HTMLInputElement>("#token2022MintInput").value = token2022Fixture.mint;
element<HTMLInputElement>("#token2022DestinationInput").value = scenarioId === "token2022_close_destination"
? token2022Fixture.authority
: token2022Fixture.destination;
element<HTMLInputElement>("#token2022DelegateInput").value = token2022Fixture.delegate;
element<HTMLInputElement>("#token2022AuthorityInput").value = token2022Fixture.authority;
element<HTMLInputElement>("#token2022FreezeAuthorityInput").value = token2022Fixture.freezeAuthority;
element<HTMLInputElement>("#token2022AmountInput").value = token2022ScenarioAmount(token2022Fixture, scenarioId);
element<HTMLInputElement>("#token2022DecimalsInput").value = String(token2022Fixture.decimals);
const scenarioId = element<HTMLSelectElement>("#token_2022ScenarioSelect").value;
element<HTMLInputElement>("#token_2022SourceInput").value = scenarioId === "token_2022_close_destination"
? token_2022Fixture.closeAccount
: token_2022Fixture.source;
element<HTMLInputElement>("#token_2022MintInput").value = token_2022Fixture.mint;
element<HTMLInputElement>("#token_2022DestinationInput").value = scenarioId === "token_2022_close_destination"
? token_2022Fixture.authority
: token_2022Fixture.destination;
element<HTMLInputElement>("#token_2022DelegateInput").value = token_2022Fixture.delegate;
element<HTMLInputElement>("#token_2022AuthorityInput").value = token_2022Fixture.authority;
element<HTMLInputElement>("#token_2022FreezeAuthorityInput").value = token_2022Fixture.freezeAuthority;
element<HTMLInputElement>("#token_2022AmountInput").value = token_2022ScenarioAmount(token_2022Fixture, scenarioId);
element<HTMLInputElement>("#token_2022DecimalsInput").value = String(token_2022Fixture.decimals);
}
async function loadToken2022Fixture(): Promise<void> {
try {
token2022Fixture = await invoke<DemoSplToken2022FixturePayload>("demo_spl_token2022_fixture", {
token_2022Fixture = await invoke<DemoSplToken2022FixturePayload>("demo_spl_token_2022_fixture", {
profileName: element<HTMLSelectElement>("#executionProfileSelect").value,
});
applyToken2022Fixture();
element<HTMLElement>("#token2022FixtureHelp").textContent = `Fixture: ${token2022Fixture.fixturePath} — program=${token2022Fixture.programId}`;
element<HTMLElement>("#token_2022FixtureHelp").textContent = `Fixture: ${token_2022Fixture.fixturePath} — program=${token_2022Fixture.programId}`;
appendLog({
timestamp: new Date().toISOString(),
level: "info",
stage: "token2022_fixture",
message: `fixture chargée: mint=${token2022Fixture.mint}, source=${token2022Fixture.source}, destination=${token2022Fixture.destination}`,
stage: "token_2022_fixture",
message: `fixture chargée: mint=${token_2022Fixture.mint}, source=${token_2022Fixture.source}, destination=${token_2022Fixture.destination}`,
});
} catch (caughtError) {
const message = caughtError instanceof Error ? caughtError.message : String(caughtError);
token2022Fixture = null;
element<HTMLElement>("#token2022FixtureHelp").textContent = message;
appendLog({ timestamp: new Date().toISOString(), level: "error", stage: "token2022_fixture", message });
token_2022Fixture = null;
element<HTMLElement>("#token_2022FixtureHelp").textContent = message;
appendLog({ timestamp: new Date().toISOString(), level: "error", stage: "token_2022_fixture", message });
}
}
function buildToken2022Request(submit: boolean): DemoExecutionSplToken2022Request {
const scenarioId = element<HTMLSelectElement>("#token2022ScenarioSelect").value;
const source = element<HTMLInputElement>("#token2022SourceInput").value.trim();
const mint = element<HTMLInputElement>("#token2022MintInput").value.trim();
const destination = element<HTMLInputElement>("#token2022DestinationInput").value.trim();
const delegate = element<HTMLInputElement>("#token2022DelegateInput").value.trim();
const authority = element<HTMLInputElement>("#token2022AuthorityInput").value.trim();
const freezeAuthority = element<HTMLInputElement>("#token2022FreezeAuthorityInput").value.trim();
const scenarioId = element<HTMLSelectElement>("#token_2022ScenarioSelect").value;
const source = element<HTMLInputElement>("#token_2022SourceInput").value.trim();
const mint = element<HTMLInputElement>("#token_2022MintInput").value.trim();
const destination = element<HTMLInputElement>("#token_2022DestinationInput").value.trim();
const delegate = element<HTMLInputElement>("#token_2022DelegateInput").value.trim();
const authority = element<HTMLInputElement>("#token_2022AuthorityInput").value.trim();
const freezeAuthority = element<HTMLInputElement>("#token_2022FreezeAuthorityInput").value.trim();
if (source.length === 0) {
throw new Error("Le compte source ou cible Token-2022 est obligatoire.");
}
if (scenarioId !== "token2022_revoke" && scenarioId !== "token2022_close_destination" && mint.length === 0) {
if (scenarioId !== "token_2022_revoke" && scenarioId !== "token_2022_close_destination" && mint.length === 0) {
throw new Error("Le mint Token-2022 est obligatoire pour ce scénario.");
}
if (scenarioId === "token2022_transfer_checked" && destination.length === 0) {
if (scenarioId === "token_2022_transfer_checked" && destination.length === 0) {
throw new Error("Le compte destination Token-2022 est obligatoire.");
}
if (scenarioId === "token2022_close_destination" && destination.length === 0) {
if (scenarioId === "token_2022_close_destination" && destination.length === 0) {
throw new Error("La destination lamports est obligatoire pour CloseAccount.");
}
if (scenarioId === "token2022_approve_checked" && delegate.length === 0) {
if (scenarioId === "token_2022_approve_checked" && delegate.length === 0) {
throw new Error("Le delegate est obligatoire pour ApproveChecked.");
}
if (["token2022_freeze_account", "token2022_thaw_account"].includes(scenarioId) && freezeAuthority.length === 0) {
if (["token_2022_freeze_account", "token_2022_thaw_account"].includes(scenarioId) && freezeAuthority.length === 0) {
throw new Error("La freeze authority est obligatoire pour FreezeAccount et ThawAccount.");
}
if (!["token2022_freeze_account", "token2022_thaw_account"].includes(scenarioId) && authority.length === 0) {
if (!["token_2022_freeze_account", "token_2022_thaw_account"].includes(scenarioId) && authority.length === 0) {
throw new Error("Lautorité Token-2022 est obligatoire.");
}
return {
@@ -649,8 +657,8 @@ function buildToken2022Request(submit: boolean): DemoExecutionSplToken2022Reques
delegate,
authority,
freezeAuthority,
amountRaw: element<HTMLInputElement>("#token2022AmountInput").value.trim(),
decimals: integerValue("#token2022DecimalsInput"),
amountRaw: element<HTMLInputElement>("#token_2022AmountInput").value.trim(),
decimals: integerValue("#token_2022DecimalsInput"),
submit,
operatorConfirmed: element<HTMLInputElement>("#executionOperatorConfirmedInput").checked,
forcePostValidationReplay: element<HTMLInputElement>("#executionForceReplayInput").checked,
@@ -692,12 +700,12 @@ async function executeToken2022(submit: boolean): Promise<void> {
if (submit && !request.operatorConfirmed) {
const message = "La confirmation opérateur est obligatoire avant signature Token-2022.";
element<HTMLTextAreaElement>("#executionSummaryOutput").value = JSON.stringify({ warning: message }, null, 2);
appendLog({ timestamp: new Date().toISOString(), level: "error", stage: "token2022_failed", message });
appendLog({ timestamp: new Date().toISOString(), level: "error", stage: "token_2022_failed", message });
return;
}
} catch (caughtError) {
const message = caughtError instanceof Error ? caughtError.message : String(caughtError);
appendLog({ timestamp: new Date().toISOString(), level: "error", stage: "token2022_failed", message });
appendLog({ timestamp: new Date().toISOString(), level: "error", stage: "token_2022_failed", message });
return;
}
setRunning(true);
@@ -705,23 +713,23 @@ async function executeToken2022(submit: boolean): Promise<void> {
appendLog({
timestamp: new Date().toISOString(),
level: "info",
stage: submit ? "token2022_submit" : "token2022_simulation",
stage: submit ? "token_2022_submit" : "token_2022_simulation",
message: `${request.scenarioId}, source=${request.source}`,
});
try {
const summary = await invoke<DemoExecutionSplToken2022SummaryPayload>("demo_execution_spl_token2022_execute", { request });
const summary = await invoke<DemoExecutionSplToken2022SummaryPayload>("demo_execution_spl_token_2022_execute", { request });
displayToken2022Summary(summary);
appendLog({
timestamp: new Date().toISOString(),
level: summary.simulationSuccess ? "info" : "error",
stage: "token2022_completed",
stage: "token_2022_completed",
message: `scenario=${summary.scenarioId}, simulation=${summary.simulationSuccess}, confirmation=${summary.confirmationStatus ?? "none"}, materializations=${summary.materializationCount}, idempotence=${summary.idempotenceValidated}`,
signature: summary.transactionSignature,
});
} catch (caughtError) {
const message = caughtError instanceof Error ? caughtError.message : String(caughtError);
element<HTMLTextAreaElement>("#executionSummaryOutput").value = JSON.stringify({ error: message }, null, 2);
appendLog({ timestamp: new Date().toISOString(), level: "error", stage: "token2022_failed", message });
appendLog({ timestamp: new Date().toISOString(), level: "error", stage: "token_2022_failed", message });
frontendError("kb-app-demo-desktop.frontend.demo_execution_spl", `Token-2022 execution failed: ${message}`);
} finally {
setRunning(false);
@@ -841,7 +849,7 @@ document.addEventListener("DOMContentLoaded", () => {
element<HTMLButtonElement>("#loadToken2022FixtureButton").addEventListener("click", () => {
void loadToken2022Fixture();
});
element<HTMLSelectElement>("#token2022ScenarioSelect").addEventListener("change", applyToken2022Fixture);
element<HTMLSelectElement>("#token_2022ScenarioSelect").addEventListener("change", applyToken2022Fixture);
element<HTMLButtonElement>("#simulateToken2022Button").addEventListener("click", () => {
void executeToken2022(false);
});