v0.4.8-pre.013
This commit is contained in:
@@ -1,5 +1,5 @@
|
||||
// file: kb-app-demo-desktop/src/demo_execution_metadata_metaplex_token_metadata.rs
|
||||
// version: 1
|
||||
// version: 4
|
||||
|
||||
//! Desktop adapters for Metaplex Token Metadata execution demo scenarios.
|
||||
|
||||
@@ -190,6 +190,13 @@ pub(crate) async fn demo_execution_metadata_metaplex_token_metadata_execute(
|
||||
std::result::Result::Ok(value) => value,
|
||||
std::result::Result::Err(error) => return std::result::Result::Err(error.to_string()),
|
||||
};
|
||||
let store = match crate::connect_postgres_store(&profile).await {
|
||||
std::result::Result::Ok(value) => value,
|
||||
std::result::Result::Err(error) => return std::result::Result::Err(error.to_string()),
|
||||
};
|
||||
if let std::result::Result::Err(error) = store.initialize_store_schema().await {
|
||||
return std::result::Result::Err(error.to_string());
|
||||
}
|
||||
let mut execution_request = match kb_pipeline_demo_scenarios::DevnetMetaplexTokenMetadataExecutionRequest::from_operation_json(
|
||||
request.intent_id,
|
||||
request.operation_json.as_str(),
|
||||
@@ -210,9 +217,20 @@ pub(crate) async fn demo_execution_metadata_metaplex_token_metadata_execute(
|
||||
execution_request.submit = request.submit;
|
||||
execution_request.operator_confirmed = request.operator_confirmed;
|
||||
execution_request.materialize_after_confirmation = request.materialize_after_confirmation;
|
||||
execution_request.post_validation_max_retries = 20;
|
||||
execution_request.force_post_validation_replay = false;
|
||||
if let std::result::Result::Err(error) = execution_request.validate() {
|
||||
return std::result::Result::Err(error.to_string());
|
||||
}
|
||||
let decoders: std::vec::Vec<std::sync::Arc<dyn kb_lib::DcApiInstructionDecoder>> =
|
||||
std::vec![std::sync::Arc::new(kb_lib::DcMetadataMetaplexTokenMetadataDecoder)];
|
||||
let materializers: std::vec::Vec<std::sync::Arc<dyn kb_lib::MtApiEventMaterializer>> = std::vec![
|
||||
std::sync::Arc::new(kb_lib::MtAdminMaterializer),
|
||||
std::sync::Arc::new(kb_lib::MtComplianceAuditMaterializer),
|
||||
std::sync::Arc::new(kb_lib::MtLifecycleMaterializer),
|
||||
std::sync::Arc::new(kb_lib::MtMetadataMetaplexTokenMetadataMaterializer),
|
||||
std::sync::Arc::new(kb_lib::MtRiskMaterializer),
|
||||
];
|
||||
let observer = crate::DemoExecutionMetadataObserver {
|
||||
app_handle,
|
||||
cancel_requested: state.demo_execution_solana_core_cancel_requested(),
|
||||
@@ -220,9 +238,12 @@ pub(crate) async fn demo_execution_metadata_metaplex_token_metadata_execute(
|
||||
let workspace_root = crate::workspace_root_dir();
|
||||
let summary = match kb_pipeline_demo_scenarios::execute_devnet_metaplex_token_metadata(
|
||||
&http_pool,
|
||||
&store,
|
||||
&profile,
|
||||
workspace_root.as_path(),
|
||||
&execution_request,
|
||||
decoders.as_slice(),
|
||||
materializers.as_slice(),
|
||||
&observer,
|
||||
)
|
||||
.await
|
||||
@@ -241,7 +262,13 @@ pub(crate) async fn demo_execution_metadata_metaplex_token_metadata_execute(
|
||||
"confirmation": &summary.confirmation,
|
||||
"after": &summary.after,
|
||||
"materializationRequested": summary.materialization_requested,
|
||||
"materializedSnapshots": &summary.materialized_snapshots
|
||||
"materializedSnapshots": &summary.materialized_snapshots,
|
||||
"backfill": summary.backfill.as_ref().map(backfill_summary_json),
|
||||
"coreExtraction": summary.core_extraction.as_ref().map(core_extraction_summary_json),
|
||||
"decodeReplay": summary.decode_replay.as_ref().map(decode_replay_summary_json),
|
||||
"idempotenceReplay": summary.idempotence_replay.as_ref().map(decode_replay_summary_json),
|
||||
"instructionMaterializations": &summary.materializations,
|
||||
"postExecution": &summary.post_execution
|
||||
}));
|
||||
return std::result::Result::Ok(
|
||||
crate::DemoExecutionMetadataMetaplexTokenMetadataSummaryPayload {
|
||||
@@ -263,6 +290,88 @@ pub(crate) async fn demo_execution_metadata_metaplex_token_metadata_execute(
|
||||
);
|
||||
}
|
||||
|
||||
fn backfill_summary_json(summary: &kb_pipeline::BackfillSummary) -> serde_json::Value {
|
||||
return serde_json::json!({
|
||||
"captureSessionId": summary.capture_session_id,
|
||||
"filterCode": summary.filter_code,
|
||||
"role": summary.role,
|
||||
"provider": summary.provider,
|
||||
"endpointCode": summary.endpoint_code,
|
||||
"pagesFetched": summary.pages_fetched,
|
||||
"candidatesSelected": summary.candidates_selected,
|
||||
"candidatesStarted": summary.candidates_started,
|
||||
"candidatesCompleted": summary.candidates_completed,
|
||||
"candidatesCancelled": summary.candidates_cancelled,
|
||||
"candidatesNotStarted": summary.candidates_not_started,
|
||||
"transactionsReceived": summary.transactions_received,
|
||||
"canonicalInserted": summary.canonical_inserted,
|
||||
"canonicalSkipped": summary.canonical_skipped,
|
||||
"existingSkipped": summary.existing_skipped,
|
||||
"missing": summary.missing,
|
||||
"failed": summary.failed,
|
||||
"observationsInserted": summary.observations_inserted,
|
||||
"attempts": summary.attempts,
|
||||
"cancelled": summary.cancelled,
|
||||
"resumeBeforeSignature": summary.resume_before_signature,
|
||||
"startedAt": summary.started_at,
|
||||
"finishedAt": summary.finished_at
|
||||
});
|
||||
}
|
||||
|
||||
fn core_extraction_summary_json(summary: &kb_pipeline::CoreExtractionSummary) -> serde_json::Value {
|
||||
return serde_json::json!({
|
||||
"processorVersion": summary.processor_version,
|
||||
"selected": summary.selected,
|
||||
"started": summary.started,
|
||||
"completed": summary.completed,
|
||||
"skipped": summary.skipped,
|
||||
"extracted": summary.extracted,
|
||||
"failed": summary.failed,
|
||||
"cancelledCandidates": summary.cancelled_candidates,
|
||||
"notStarted": summary.not_started,
|
||||
"cancelled": summary.cancelled,
|
||||
"startedAt": summary.started_at,
|
||||
"finishedAt": summary.finished_at
|
||||
});
|
||||
}
|
||||
|
||||
fn decode_replay_summary_json(summary: &kb_pipeline::DecodeReplaySummary) -> serde_json::Value {
|
||||
let processors = summary
|
||||
.processors
|
||||
.iter()
|
||||
.map(|processor| {
|
||||
return serde_json::json!({
|
||||
"name": processor.processor_name,
|
||||
"version": processor.processor_version,
|
||||
"dispatched": processor.dispatched,
|
||||
"skipped": processor.skipped,
|
||||
"decoded": processor.decoded,
|
||||
"ignored": processor.ignored,
|
||||
"unsupported": processor.unsupported,
|
||||
"failed": processor.failed,
|
||||
"processingErrors": processor.processing_errors,
|
||||
"materializedOutputs": processor.materialized_outputs,
|
||||
"materializationRefused": processor.materialization_refused
|
||||
});
|
||||
})
|
||||
.collect::<std::vec::Vec<serde_json::Value>>();
|
||||
return serde_json::json!({
|
||||
"campaignId": summary.campaign_id,
|
||||
"pipelineVersion": summary.pipeline_version,
|
||||
"selected": summary.selected,
|
||||
"started": summary.started,
|
||||
"completed": summary.completed,
|
||||
"unmatched": summary.unmatched,
|
||||
"notStarted": summary.not_started,
|
||||
"failedInputs": summary.failed_inputs,
|
||||
"processingErrorInputs": summary.processing_error_inputs,
|
||||
"cancelled": summary.cancelled,
|
||||
"processors": processors,
|
||||
"startedAt": summary.started_at,
|
||||
"finishedAt": summary.finished_at
|
||||
});
|
||||
}
|
||||
|
||||
fn parse_stateful_reads(
|
||||
value: &str,
|
||||
) -> std::result::Result<
|
||||
@@ -280,13 +389,29 @@ fn parse_stateful_reads(
|
||||
};
|
||||
}
|
||||
|
||||
/// Creates or reuses the Devnet mint fixture used by the named Create scenario.
|
||||
/// Creates or reuses the Devnet NFT mint fixture used by the standalone Create action.
|
||||
pub(crate) async fn demo_execution_metadata_metaplex_token_metadata_prepare_create_fixture(
|
||||
state: tauri::State<'_, crate::AppState>,
|
||||
profile_name: std::string::String,
|
||||
) -> std::result::Result<
|
||||
crate::DemoExecutionMetadataMetaplexTokenMetadataCreateFixturePayload,
|
||||
std::string::String,
|
||||
> {
|
||||
return prepare_create_fixture_for_family(
|
||||
state,
|
||||
profile_name,
|
||||
kb_pipeline_demo_scenarios::MetaplexTokenMetadataAssetFamily::Nft,
|
||||
)
|
||||
.await;
|
||||
}
|
||||
|
||||
async fn prepare_create_fixture_for_family(
|
||||
state: tauri::State<'_, crate::AppState>,
|
||||
profile_name: std::string::String,
|
||||
asset_family: kb_pipeline_demo_scenarios::MetaplexTokenMetadataAssetFamily,
|
||||
) -> std::result::Result<
|
||||
crate::DemoExecutionMetadataMetaplexTokenMetadataCreateFixturePayload,
|
||||
std::string::String,
|
||||
> {
|
||||
let profile = match crate::select_devnet_profile(state.app_config(), profile_name.as_str()) {
|
||||
std::result::Result::Ok(value) => value,
|
||||
@@ -303,11 +428,14 @@ pub(crate) async fn demo_execution_metadata_metaplex_token_metadata_prepare_crea
|
||||
std::result::Result::Err(error) => return std::result::Result::Err(error.to_string()),
|
||||
};
|
||||
let workspace_root = crate::workspace_root_dir();
|
||||
let options =
|
||||
kb_pipeline_demo_scenarios::MetaplexCreateFixturePreparationOptions::new(wallet_dir)
|
||||
.with_asset_family(asset_family);
|
||||
let summary = match kb_pipeline_demo_scenarios::prepare_metaplex_create_fixture(
|
||||
&http_pool,
|
||||
&profile,
|
||||
workspace_root.as_path(),
|
||||
&kb_pipeline_demo_scenarios::MetaplexCreateFixturePreparationOptions::new(wallet_dir),
|
||||
&options,
|
||||
)
|
||||
.await
|
||||
{
|
||||
@@ -326,84 +454,6 @@ pub(crate) async fn demo_execution_metadata_metaplex_token_metadata_prepare_crea
|
||||
);
|
||||
}
|
||||
|
||||
fn adapt_create_operation_json(
|
||||
operation_json: &str,
|
||||
asset_family: kb_pipeline_demo_scenarios::MetaplexTokenMetadataAssetFamily,
|
||||
) -> std::result::Result<std::string::String, std::string::String> {
|
||||
let mut value: serde_json::Value = match serde_json::from_str(operation_json) {
|
||||
std::result::Result::Ok(parsed) => parsed,
|
||||
std::result::Result::Err(error) => {
|
||||
return std::result::Result::Err(format!(
|
||||
"invalid generated Metaplex Create JSON: {error}"
|
||||
));
|
||||
},
|
||||
};
|
||||
if matches!(
|
||||
asset_family,
|
||||
kb_pipeline_demo_scenarios::MetaplexTokenMetadataAssetFamily::Sft
|
||||
| kb_pipeline_demo_scenarios::MetaplexTokenMetadataAssetFamily::Fungible
|
||||
) {
|
||||
value["master_edition"] = serde_json::Value::Null;
|
||||
}
|
||||
let create = match value
|
||||
.get_mut("create_args")
|
||||
.and_then(|args| return args.get_mut("V1"))
|
||||
.and_then(serde_json::Value::as_object_mut)
|
||||
{
|
||||
std::option::Option::Some(found) => found,
|
||||
std::option::Option::None => {
|
||||
return std::result::Result::Err(
|
||||
"generated Metaplex Create JSON has no create_args.V1 object".to_string(),
|
||||
);
|
||||
},
|
||||
};
|
||||
match asset_family {
|
||||
kb_pipeline_demo_scenarios::MetaplexTokenMetadataAssetFamily::Nft => {
|
||||
create.insert("name".to_string(), serde_json::json!("Khadhroony Devnet NFT"));
|
||||
create.insert("symbol".to_string(), serde_json::json!("KHNFT"));
|
||||
create.insert("token_standard".to_string(), serde_json::json!("NonFungible"));
|
||||
create.insert("collection_details".to_string(), serde_json::Value::Null);
|
||||
create.insert("decimals".to_string(), serde_json::Value::Null);
|
||||
create.insert("print_supply".to_string(), serde_json::json!("Zero"));
|
||||
},
|
||||
kb_pipeline_demo_scenarios::MetaplexTokenMetadataAssetFamily::Sft => {
|
||||
create.insert("name".to_string(), serde_json::json!("Khadhroony Devnet SFT"));
|
||||
create.insert("symbol".to_string(), serde_json::json!("KHSFT"));
|
||||
create.insert("token_standard".to_string(), serde_json::json!("FungibleAsset"));
|
||||
create.insert("collection_details".to_string(), serde_json::Value::Null);
|
||||
create.insert("decimals".to_string(), serde_json::json!(0));
|
||||
create.insert("print_supply".to_string(), serde_json::Value::Null);
|
||||
},
|
||||
kb_pipeline_demo_scenarios::MetaplexTokenMetadataAssetFamily::Fungible => {
|
||||
create.insert("name".to_string(), serde_json::json!("Khadhroony Devnet Fungible"));
|
||||
create.insert("symbol".to_string(), serde_json::json!("KHFUN"));
|
||||
create.insert("token_standard".to_string(), serde_json::json!("Fungible"));
|
||||
create.insert("collection_details".to_string(), serde_json::Value::Null);
|
||||
create.insert("decimals".to_string(), serde_json::json!(0));
|
||||
create.insert("print_supply".to_string(), serde_json::Value::Null);
|
||||
},
|
||||
kb_pipeline_demo_scenarios::MetaplexTokenMetadataAssetFamily::Collection => {
|
||||
create.insert("name".to_string(), serde_json::json!("Khadhroony Devnet Collection"));
|
||||
create.insert("symbol".to_string(), serde_json::json!("KHCOL"));
|
||||
create.insert("token_standard".to_string(), serde_json::json!("NonFungible"));
|
||||
create.insert("collection_details".to_string(), serde_json::json!({"V1": {"size": 0}}));
|
||||
create.insert("decimals".to_string(), serde_json::Value::Null);
|
||||
create.insert("print_supply".to_string(), serde_json::json!("Zero"));
|
||||
},
|
||||
kb_pipeline_demo_scenarios::MetaplexTokenMetadataAssetFamily::ProgrammableNft => {
|
||||
create.insert("name".to_string(), serde_json::json!("Khadhroony Devnet pNFT"));
|
||||
create.insert("symbol".to_string(), serde_json::json!("KHPNFT"));
|
||||
create
|
||||
.insert("token_standard".to_string(), serde_json::json!("ProgrammableNonFungible"));
|
||||
create.insert("collection_details".to_string(), serde_json::Value::Null);
|
||||
create.insert("rule_set".to_string(), serde_json::Value::Null);
|
||||
create.insert("decimals".to_string(), serde_json::Value::Null);
|
||||
create.insert("print_supply".to_string(), serde_json::json!("Zero"));
|
||||
},
|
||||
}
|
||||
return std::result::Result::Ok(crate::pretty_json(&value));
|
||||
}
|
||||
|
||||
/// Prepares one coherent scenario step and all of its stateful reads.
|
||||
pub(crate) async fn demo_execution_metadata_metaplex_token_metadata_prepare_step(
|
||||
state: tauri::State<'_, crate::AppState>,
|
||||
@@ -452,27 +502,17 @@ pub(crate) async fn demo_execution_metadata_metaplex_token_metadata_prepare_step
|
||||
let (fixture_mint, fixture_metadata, fixture_master_edition, operation_json, fixture_state) =
|
||||
if operation == "create" {
|
||||
let fixture =
|
||||
match crate::demo_execution_metadata_metaplex_token_metadata_prepare_create_fixture(
|
||||
state,
|
||||
profile_name,
|
||||
)
|
||||
.await
|
||||
match prepare_create_fixture_for_family(state, profile_name, scenario.asset_family)
|
||||
.await
|
||||
{
|
||||
std::result::Result::Ok(value) => value,
|
||||
std::result::Result::Err(error) => return std::result::Result::Err(error),
|
||||
};
|
||||
let operation_json = match adapt_create_operation_json(
|
||||
fixture.operation_json.as_str(),
|
||||
scenario.asset_family,
|
||||
) {
|
||||
std::result::Result::Ok(value) => value,
|
||||
std::result::Result::Err(error) => return std::result::Result::Err(error),
|
||||
};
|
||||
(
|
||||
fixture.mint,
|
||||
fixture.metadata,
|
||||
fixture.master_edition,
|
||||
operation_json,
|
||||
fixture.operation_json,
|
||||
if fixture.mint_created {
|
||||
"mint_prepared".to_string()
|
||||
} else {
|
||||
|
||||
Reference in New Issue
Block a user