v0.5.2-pre.006-fix-010
This commit is contained in:
@@ -1,8 +1,20 @@
|
||||
<!-- file: ks-pipeline-demo-scenarios/CHANGELOG.md -->
|
||||
<!-- version: 79 -->
|
||||
<!-- version: 81 -->
|
||||
|
||||
# CHANGELOG — ks-pipeline-demo-scenarios
|
||||
|
||||
## `0.5.2-pre.006-delta-fix-006`
|
||||
|
||||
- corrige le wrapper pNFT legacy : il reprend son paramètre `workspace_root` historique et construit le wallet temporaire uniquement dans ce wrapper, tandis que la variante `_with_wallet` conserve le signer explicite ;
|
||||
- retire l'initialisation du champ inexistant `wallet` dans `PreparedToken2022Execution`, le signer restant fourni explicitement par l'appelant lors de la signature après simulation.
|
||||
|
||||
## `0.5.2-pre.006-delta-fix-005`
|
||||
|
||||
- introduit `DevnetExecutionWallet` comme capacité de signature commune aux wallets temporaires et aux `.kswallet` authentifiés, sans accès aux bytes privés ;
|
||||
- résout explicitement `wallet_alias` vers un `.kswallet` déverrouillé et interdit toujours tout fallback silencieux vers le JSON temporaire ;
|
||||
- sépare les chemins persistants et temporaires dans les scénarios/fixtures, puis branche System, Memo, ATA, SPL Token, Token-2022, Solana Program Metadata et Token-2022 Metadata sur un signer explicitement résolu ;
|
||||
- propage le même signer persistant à toutes les campagnes Metaplex du desktop, y compris les parcours multi-signers ; les mints, delegates et destinations réellement jetables restent des keypairs temporaires distinctes.
|
||||
|
||||
## `0.5.2-pre.006`
|
||||
|
||||
- ajoute l'inspection et l'unlock explicites du wallet natif sélectionné par `profile.wallet.wallet_alias`, avec `WalletPassword` fourni uniquement au runtime ;
|
||||
|
||||
@@ -1,11 +1,11 @@
|
||||
<!-- file: ks-pipeline-demo-scenarios/TODO.md -->
|
||||
<!-- version: 44 -->
|
||||
<!-- version: 45 -->
|
||||
|
||||
# TODO — ks-pipeline-demo-scenarios
|
||||
|
||||
## Évolutions générales
|
||||
|
||||
- [ ] `0.5.2` — refactorer les runners Devnet qui appellent encore directement `load_profile_temporary_wallet()` afin qu'ils puissent recevoir une capacité signer issue d'un `.kswallet` explicitement déverrouillé, sans fallback silencieux.
|
||||
- [ ] `0.5.4` — inventorier/classifier les keypairs de fixtures historiques sous `wallets/temporary/**` et préparer leur migration sélective lorsque leur rôle doit devenir persistant.
|
||||
- [ ] `0.5.4` — centraliser les dispatchs, compositions decoder/materializer et critères de complétion encore réutilisables depuis le desktop.
|
||||
- [ ] `0.5.4` — produire la matrice active decoder/materializer/executor/scénario/preuve sans transformer les surfaces réservées en dettes implicites.
|
||||
- [ ] Ajouter au CLI uniquement les préparations de fixtures explicitement justifiées.
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
<!-- file: ks-pipeline-demo-scenarios/USAGE.md -->
|
||||
<!-- version: 32 -->
|
||||
<!-- version: 33 -->
|
||||
|
||||
# Utilisation de ks-pipeline-demo-scenarios
|
||||
|
||||
@@ -312,7 +312,7 @@ cargo test -p ks-pipeline-demo-scenarios optional_devnet_current_operation_from_
|
||||
|
||||
Variables optionnelles :
|
||||
|
||||
- `KS_DEVNET_WALLET_DIR` pour sélectionner le répertoire du wallet persistant ;
|
||||
- `KS_DEVNET_WALLET_DIR` pour surcharger le répertoire legacy de fixtures/wallets temporaires du test opt-in ;
|
||||
- `KS_SECRET_POSTGRES_TEST_URL` est obligatoire pour le test opt-in afin de permettre l’hydratation canonique, l’extraction Core, le replay et la vérification d’idempotence après une soumission ;
|
||||
- `KS_DEVNET_METAPLEX_PREFLIGHT_READS_JSON` pour fournir les lectures stateful avant simulation ;
|
||||
- `KS_DEVNET_METAPLEX_POSTCONDITION_READS_JSON` pour fournir les lectures après confirmation ;
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
// file: ks-pipeline-demo-scenarios/src/lib.rs
|
||||
// version: 30
|
||||
// version: 31
|
||||
|
||||
#![forbid(unsafe_code)]
|
||||
#![deny(unreachable_pub)]
|
||||
@@ -12,6 +12,7 @@ mod environment;
|
||||
mod metadata;
|
||||
mod solana;
|
||||
mod spl;
|
||||
mod wallet;
|
||||
|
||||
/// Readiness report for one Devnet profile PostgreSQL store.
|
||||
pub use self::environment::DevnetProfileStoreReadiness;
|
||||
@@ -29,6 +30,8 @@ pub use self::metadata::metaplex_token_metadata::collection_verify_campaign::Dev
|
||||
pub use self::metadata::metaplex_token_metadata::collection_verify_campaign::DevnetMetaplexCollectionVerifyState;
|
||||
/// Executes one fresh collection parent/member verification campaign on Devnet.
|
||||
pub use self::metadata::metaplex_token_metadata::collection_verify_campaign::execute_devnet_metaplex_collection_verify_campaign;
|
||||
/// Executes one collection verification campaign with an explicit operator wallet.
|
||||
pub use self::metadata::metaplex_token_metadata::collection_verify_campaign::execute_devnet_metaplex_collection_verify_campaign_with_wallet;
|
||||
/// Returns the exact current operations qualified by the collection verification campaign.
|
||||
pub use self::metadata::metaplex_token_metadata::collection_verify_campaign::metaplex_collection_verify_campaign_operation_names;
|
||||
/// Complete evidence produced by one family-specific Metaplex `Create -> Mint` campaign.
|
||||
@@ -37,6 +40,8 @@ pub use self::metadata::metaplex_token_metadata::create_mint_campaign::DevnetMet
|
||||
pub use self::metadata::metaplex_token_metadata::create_mint_campaign::DevnetMetaplexCreateMintTokenState;
|
||||
/// Executes one fresh family-specific Metaplex `Create -> Mint` campaign on Devnet.
|
||||
pub use self::metadata::metaplex_token_metadata::create_mint_campaign::execute_devnet_metaplex_create_mint_campaign;
|
||||
/// Executes one family-specific Metaplex `Create -> Mint` campaign with an explicit operator wallet.
|
||||
pub use self::metadata::metaplex_token_metadata::create_mint_campaign::execute_devnet_metaplex_create_mint_campaign_with_wallet;
|
||||
/// Returns the exact ordered operations covered by the `Create -> Mint` campaign.
|
||||
pub use self::metadata::metaplex_token_metadata::create_mint_campaign::metaplex_create_mint_campaign_operation_names;
|
||||
/// Complete request for one real Devnet Metaplex Token Metadata execution.
|
||||
@@ -51,18 +56,26 @@ pub use self::metadata::metaplex_token_metadata::devnet_execution::devnet_metapl
|
||||
pub use self::metadata::metaplex_token_metadata::devnet_execution::execute_devnet_metaplex_token_metadata;
|
||||
/// Executes one real Devnet Metaplex submission with explicitly authorized extra signers.
|
||||
pub use self::metadata::metaplex_token_metadata::devnet_execution::execute_devnet_metaplex_token_metadata_with_signers;
|
||||
/// Executes one real Devnet Metaplex operation with an explicitly resolved wallet.
|
||||
pub use self::metadata::metaplex_token_metadata::devnet_execution::execute_devnet_metaplex_token_metadata_with_wallet;
|
||||
/// Executes one real Devnet Metaplex submission with an explicit wallet and extra signers.
|
||||
pub use self::metadata::metaplex_token_metadata::devnet_execution::execute_devnet_metaplex_token_metadata_with_wallet_and_signers;
|
||||
/// Returns a formatted JSON template for one named current operation.
|
||||
pub use self::metadata::metaplex_token_metadata::devnet_execution::metaplex_token_metadata_current_operation_json_template;
|
||||
/// Returns the current operation names accepted by automatic Devnet campaigns.
|
||||
pub use self::metadata::metaplex_token_metadata::devnet_execution::metaplex_token_metadata_current_operation_names;
|
||||
/// Simulates one current Metaplex operation against a real Devnet endpoint.
|
||||
pub use self::metadata::metaplex_token_metadata::devnet_execution::simulate_devnet_metaplex_token_metadata;
|
||||
/// Simulates one current Metaplex operation with an explicitly resolved wallet.
|
||||
pub use self::metadata::metaplex_token_metadata::devnet_execution::simulate_devnet_metaplex_token_metadata_with_wallet;
|
||||
/// Exact SPL state transitions exercised around the Token Owned Escrow operations.
|
||||
pub use self::metadata::metaplex_token_metadata::escrow_campaign::DevnetMetaplexEscrowCampaignState;
|
||||
/// Complete evidence retained by one Token Owned Escrow Devnet campaign.
|
||||
pub use self::metadata::metaplex_token_metadata::escrow_campaign::DevnetMetaplexEscrowCampaignSummary;
|
||||
/// Executes a fresh Token Owned Escrow lifecycle on Devnet.
|
||||
pub use self::metadata::metaplex_token_metadata::escrow_campaign::execute_devnet_metaplex_escrow_campaign;
|
||||
/// Executes a Token Owned Escrow lifecycle with an explicit operator wallet.
|
||||
pub use self::metadata::metaplex_token_metadata::escrow_campaign::execute_devnet_metaplex_escrow_campaign_with_wallet;
|
||||
/// Returns the exact ordered Metaplex operations qualified by the escrow campaign.
|
||||
pub use self::metadata::metaplex_token_metadata::escrow_campaign::metaplex_escrow_campaign_operation_names;
|
||||
/// Options for one Metaplex Create fixture preparation.
|
||||
@@ -77,6 +90,8 @@ pub(crate) use self::metadata::metaplex_token_metadata::fixture::classic_fixture
|
||||
pub(crate) use self::metadata::metaplex_token_metadata::fixture::classic_fixture_token_amount;
|
||||
/// Creates or reuses a classic SPL mint and derives its Metaplex PDAs.
|
||||
pub use self::metadata::metaplex_token_metadata::fixture::prepare_metaplex_create_fixture;
|
||||
/// Creates a classic SPL mint fixture using an explicitly resolved operator wallet.
|
||||
pub use self::metadata::metaplex_token_metadata::fixture::prepare_metaplex_create_fixture_with_wallet;
|
||||
/// Reads one classic SPL mint account at or after a minimum context slot.
|
||||
pub(crate) use self::metadata::metaplex_token_metadata::fixture::read_mint_account_at_or_after;
|
||||
/// Reads one classic SPL token account at or after a minimum context slot.
|
||||
@@ -89,6 +104,8 @@ pub(crate) use self::metadata::metaplex_token_metadata::fixture::validate_classi
|
||||
pub use self::metadata::metaplex_token_metadata::maintenance_campaign::DevnetMetaplexMaintenanceCampaignSummary;
|
||||
/// Executes the final bounded current maintenance campaign on Devnet.
|
||||
pub use self::metadata::metaplex_token_metadata::maintenance_campaign::execute_devnet_metaplex_maintenance_campaign;
|
||||
/// Executes the bounded maintenance campaign with an explicit operator wallet.
|
||||
pub use self::metadata::metaplex_token_metadata::maintenance_campaign::execute_devnet_metaplex_maintenance_campaign_with_wallet;
|
||||
/// Returns the exact ordered operations exercised by the maintenance campaign.
|
||||
pub use self::metadata::metaplex_token_metadata::maintenance_campaign::metaplex_maintenance_campaign_operation_names;
|
||||
/// Complete evidence produced by one pNFT lifecycle campaign.
|
||||
@@ -97,6 +114,8 @@ pub use self::metadata::metaplex_token_metadata::pnft_lifecycle_campaign::Devnet
|
||||
pub use self::metadata::metaplex_token_metadata::pnft_lifecycle_campaign::DevnetMetaplexPnftLifecycleState;
|
||||
/// Executes one fresh pNFT delegate/lock/unlock/revoke/transfer campaign on Devnet.
|
||||
pub use self::metadata::metaplex_token_metadata::pnft_lifecycle_campaign::execute_devnet_metaplex_pnft_lifecycle_campaign;
|
||||
/// Executes one pNFT lifecycle campaign with an explicit operator wallet.
|
||||
pub use self::metadata::metaplex_token_metadata::pnft_lifecycle_campaign::execute_devnet_metaplex_pnft_lifecycle_campaign_with_wallet;
|
||||
/// Returns the exact ordered current operations exercised by the pNFT lifecycle campaign.
|
||||
pub use self::metadata::metaplex_token_metadata::pnft_lifecycle_campaign::metaplex_pnft_lifecycle_campaign_operation_names;
|
||||
/// Complete evidence produced by one printable master NFT `Print -> Burn` campaign.
|
||||
@@ -105,6 +124,8 @@ pub use self::metadata::metaplex_token_metadata::print_burn_campaign::DevnetMeta
|
||||
pub use self::metadata::metaplex_token_metadata::print_burn_campaign::DevnetMetaplexPrintBurnState;
|
||||
/// Executes one printable master NFT `Print -> Burn` campaign on Devnet.
|
||||
pub use self::metadata::metaplex_token_metadata::print_burn_campaign::execute_devnet_metaplex_print_burn_campaign;
|
||||
/// Executes one printable master NFT campaign with an explicit operator wallet.
|
||||
pub use self::metadata::metaplex_token_metadata::print_burn_campaign::execute_devnet_metaplex_print_burn_campaign_with_wallet;
|
||||
/// Returns the exact ordered current operations qualified by the print/burn campaign.
|
||||
pub use self::metadata::metaplex_token_metadata::print_burn_campaign::metaplex_print_burn_campaign_operation_names;
|
||||
/// Stable asset family covered by one Metaplex scenario.
|
||||
@@ -127,6 +148,8 @@ pub use self::metadata::metaplex_token_metadata::use_campaign::DevnetMetaplexUse
|
||||
pub use self::metadata::metaplex_token_metadata::use_campaign::DevnetMetaplexUseProbeSummary;
|
||||
/// Executes one bounded current `Use` availability probe on Devnet.
|
||||
pub use self::metadata::metaplex_token_metadata::use_campaign::execute_devnet_metaplex_use_probe;
|
||||
/// Executes one bounded current `Use` probe with an explicit operator wallet.
|
||||
pub use self::metadata::metaplex_token_metadata::use_campaign::execute_devnet_metaplex_use_probe_with_wallet;
|
||||
/// Returns the exact setup and target operations exercised by the `Use` probe.
|
||||
pub use self::metadata::metaplex_token_metadata::use_campaign::metaplex_use_probe_operation_names;
|
||||
/// Maximum evidence entries accepted by one Metaplex validation scenario.
|
||||
@@ -173,14 +196,20 @@ pub use self::metadata::solana_program::campaign::DevnetSolanaProgramMetadataCam
|
||||
pub use self::metadata::solana_program::campaign::DevnetSolanaProgramMetadataCampaignSummary;
|
||||
/// Prepares fresh accounts and executes the nine stable operations on Devnet.
|
||||
pub use self::metadata::solana_program::campaign::execute_devnet_solana_program_metadata_campaign;
|
||||
/// Executes the complete Solana Program Metadata campaign with an explicitly resolved wallet.
|
||||
pub use self::metadata::solana_program::campaign::execute_devnet_solana_program_metadata_campaign_with_wallet;
|
||||
/// Complete request for one Solana Program Metadata Devnet execution.
|
||||
pub use self::metadata::solana_program::devnet_execution::DevnetSolanaProgramMetadataExecutionRequest;
|
||||
/// Complete evidence produced by one Solana Program Metadata Devnet execution.
|
||||
pub use self::metadata::solana_program::devnet_execution::DevnetSolanaProgramMetadataExecutionSummary;
|
||||
/// Executes one Solana Program Metadata simulation or authorized submission.
|
||||
pub use self::metadata::solana_program::devnet_execution::execute_devnet_solana_program_metadata;
|
||||
/// Executes one Solana Program Metadata operation with an explicitly resolved wallet.
|
||||
pub use self::metadata::solana_program::devnet_execution::execute_devnet_solana_program_metadata_with_wallet;
|
||||
/// Simulates one stable Solana Program Metadata operation against Devnet.
|
||||
pub use self::metadata::solana_program::devnet_execution::simulate_devnet_solana_program_metadata;
|
||||
/// Simulates one Solana Program Metadata operation with an explicitly resolved wallet.
|
||||
pub use self::metadata::solana_program::devnet_execution::simulate_devnet_solana_program_metadata_with_wallet;
|
||||
/// Bytes reserved for the public Buffer journey before `Trim`.
|
||||
pub use self::metadata::solana_program::fixture::SOLANA_PROGRAM_METADATA_FIXTURE_BUFFER_DATA_BYTES;
|
||||
/// Options used to prepare one complete Solana Program Metadata fixture.
|
||||
@@ -191,6 +220,8 @@ pub use self::metadata::solana_program::fixture::SolanaProgramMetadataFixturePre
|
||||
pub use self::metadata::solana_program::fixture::SolanaProgramMetadataPreparedStep;
|
||||
/// Creates two unique pre-funded PDAs and the nine typed journey steps.
|
||||
pub use self::metadata::solana_program::fixture::prepare_solana_program_metadata_fixture;
|
||||
/// Creates the Solana Program Metadata fixture with an explicitly resolved wallet.
|
||||
pub use self::metadata::solana_program::fixture::prepare_solana_program_metadata_fixture_with_wallet;
|
||||
/// Stable lifecycle state consumed or produced by one scenario step.
|
||||
pub use self::metadata::solana_program::scenarios::SolanaProgramMetadataFixtureState;
|
||||
/// One ordered multi-step Solana Program Metadata journey.
|
||||
@@ -231,6 +262,8 @@ pub(crate) use self::solana::emit;
|
||||
pub(crate) use self::solana::ensure_not_cancelled;
|
||||
/// Executes one bounded System Program transfer on Devnet.
|
||||
pub use self::solana::execute_devnet_system_transfer;
|
||||
/// Executes one bounded System transfer with an explicitly resolved wallet capability.
|
||||
pub use self::solana::execute_devnet_system_transfer_with_wallet;
|
||||
/// Inspects the persistent native wallet alias selected by one execution profile.
|
||||
pub use self::solana::inspect_selected_profile_wallet;
|
||||
/// Loads the managed temporary wallet used by legacy Devnet scenarios.
|
||||
@@ -247,6 +280,8 @@ pub use self::spl::associated_token_account::DevnetSplAssociatedTokenAccountExec
|
||||
pub use self::spl::associated_token_account::DevnetSplAssociatedTokenAccountExecutionSummary;
|
||||
/// Executes one Devnet Associated Token Account simulation or authorized submission.
|
||||
pub use self::spl::associated_token_account::execute_devnet_spl_associated_token_account;
|
||||
/// Executes one ATA operation with an explicitly resolved wallet capability.
|
||||
pub use self::spl::associated_token_account::execute_devnet_spl_associated_token_account_with_wallet;
|
||||
/// Simulates one Devnet Associated Token Account operation after stateful preflight.
|
||||
pub use self::spl::associated_token_account::simulate_devnet_spl_associated_token_account;
|
||||
/// Complete request for one SPL Memo v4 Devnet execution.
|
||||
@@ -255,6 +290,8 @@ pub use self::spl::memo::DevnetMemoExecutionRequest;
|
||||
pub use self::spl::memo::DevnetMemoExecutionSummary;
|
||||
/// Executes one SPL Memo v4 Devnet simulation or explicitly authorized submission.
|
||||
pub use self::spl::memo::execute_devnet_memo;
|
||||
/// Executes one Memo operation with an explicitly resolved wallet capability.
|
||||
pub use self::spl::memo::execute_devnet_memo_with_wallet;
|
||||
/// Complete request for one Devnet classic SPL Token execution.
|
||||
pub use self::spl::token::execution::DevnetSplTokenExecutionRequest;
|
||||
/// Complete result of one Devnet classic SPL Token execution.
|
||||
@@ -265,6 +302,8 @@ pub(crate) use self::spl::token::execution::canonical_available;
|
||||
pub(crate) use self::spl::token::execution::decode_completed;
|
||||
/// Executes one Devnet classic SPL Token simulation or authorized submission.
|
||||
pub use self::spl::token::execution::execute_devnet_spl_token;
|
||||
/// Executes one SPL Token operation with an explicitly resolved wallet capability.
|
||||
pub use self::spl::token::execution::execute_devnet_spl_token_with_wallet;
|
||||
/// Canonical signature hydration helper shared by Token lifecycle orchestration.
|
||||
pub(crate) use self::spl::token::execution::hydrate_signature;
|
||||
/// Targeted program replay helper shared by Token lifecycle orchestration.
|
||||
@@ -293,6 +332,8 @@ pub use self::spl::token_2022::devnet_execution::DevnetSplToken2022ExecutionRequ
|
||||
pub use self::spl::token_2022::devnet_execution::DevnetSplToken2022ExecutionSummary;
|
||||
/// Executes one Devnet Token-2022 simulation or authorized submission.
|
||||
pub use self::spl::token_2022::devnet_execution::execute_devnet_spl_token_2022;
|
||||
/// Executes one Token-2022 operation with an explicitly resolved wallet capability.
|
||||
pub use self::spl::token_2022::devnet_execution::execute_devnet_spl_token_2022_with_wallet;
|
||||
/// Simulates one Devnet Token-2022 operation after stateful preflight.
|
||||
pub use self::spl::token_2022::devnet_execution::simulate_devnet_spl_token_2022;
|
||||
/// Stable category of one independent Devnet validation scenario.
|
||||
@@ -323,6 +364,8 @@ pub use self::spl::token_2022::metadata::campaign::DevnetToken2022MetadataCampai
|
||||
pub use self::spl::token_2022::metadata::campaign::DevnetToken2022MetadataCampaignSummary;
|
||||
/// Executes all five Token Metadata interface instructions on one fresh Devnet mint.
|
||||
pub use self::spl::token_2022::metadata::campaign::execute_devnet_token_2022_metadata_campaign;
|
||||
/// Executes the Token Metadata campaign with an explicitly resolved wallet.
|
||||
pub use self::spl::token_2022::metadata::campaign::execute_devnet_token_2022_metadata_campaign_with_wallet;
|
||||
/// Returns the exact ordered operation names covered by the Token Metadata campaign.
|
||||
pub use self::spl::token_2022::metadata::campaign::token_2022_metadata_campaign_operation_names;
|
||||
/// Additional metadata key created and removed by the campaign.
|
||||
@@ -341,6 +384,8 @@ pub use self::spl::token_2022::metadata::fixture::Token2022MetadataFixturePrepar
|
||||
pub use self::spl::token_2022::metadata::fixture::Token2022MetadataFixturePreparationSummary;
|
||||
/// Creates one fresh Token-2022 mint with a self-referential Metadata Pointer.
|
||||
pub use self::spl::token_2022::metadata::fixture::prepare_token_2022_metadata_fixture;
|
||||
/// Creates the Token-2022 metadata fixture with an explicitly resolved wallet.
|
||||
pub use self::spl::token_2022::metadata::fixture::prepare_token_2022_metadata_fixture_with_wallet;
|
||||
/// Maximum evidence entries retained by one Token Metadata validation scenario.
|
||||
pub use self::spl::token_2022::metadata::validation::MAX_TOKEN_2022_METADATA_VALIDATION_EVIDENCE;
|
||||
/// One bounded evidence item retained by the Token Metadata validation matrix.
|
||||
@@ -377,6 +422,10 @@ pub use self::spl::token_2022::validation::load_token_2022_validation_matrix;
|
||||
pub use self::spl::token_2022::validation::validate_token_2022_validation_matrix;
|
||||
/// Validates one bounded Token-2022 milestone report.
|
||||
pub use self::spl::token_2022::validation::validate_token_2022_validation_report;
|
||||
/// Resolved temporary or persistent signer capability used by Devnet scenarios.
|
||||
pub use self::wallet::DevnetExecutionWallet;
|
||||
/// Resolves the wallet selected by one Devnet execution profile.
|
||||
pub use self::wallet::resolve_devnet_execution_wallet;
|
||||
|
||||
/// Total transactions reserved by one complete Solana Program Metadata campaign.
|
||||
pub(crate) use self::constants::SOLANA_PROGRAM_METADATA_CAMPAIGN_TRANSACTION_COUNT;
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
// file: ks-pipeline-demo-scenarios/src/metadata/metaplex_token_metadata/collection_verify_campaign.rs
|
||||
// version: 6
|
||||
// version: 7
|
||||
|
||||
//! Confirmed Devnet collection parent/member `Verify -> Unverify` campaign.
|
||||
|
||||
@@ -50,6 +50,34 @@ pub async fn execute_devnet_metaplex_collection_verify_campaign<S, O>(
|
||||
options: &crate::MetaplexCreateFixturePreparationOptions,
|
||||
observer: &O,
|
||||
) -> ks_core::Result<crate::DevnetMetaplexCollectionVerifyCampaignSummary>
|
||||
where
|
||||
S: ks_store::RawTransactionStore
|
||||
+ ks_store::CoreExtractionStore
|
||||
+ ks_store::DecodePipelineStore
|
||||
+ Sync,
|
||||
O: crate::SolanaExecutionObserver,
|
||||
{
|
||||
let temporary = match crate::load_profile_temporary_wallet(profile, workspace_root).await {
|
||||
std::result::Result::Ok(value) => value,
|
||||
std::result::Result::Err(error) => return std::result::Result::Err(error),
|
||||
};
|
||||
let wallet = crate::DevnetExecutionWallet::Temporary(temporary);
|
||||
return execute_devnet_metaplex_collection_verify_campaign_with_wallet(
|
||||
http_pool, store, profile, &wallet, options, observer,
|
||||
)
|
||||
.await;
|
||||
}
|
||||
|
||||
/// Executes one collection verification campaign with an explicit operator wallet.
|
||||
#[allow(clippy::too_many_arguments)]
|
||||
pub async fn execute_devnet_metaplex_collection_verify_campaign_with_wallet<S, O>(
|
||||
http_pool: &ks_onchain_transport::HttpEndpointPool,
|
||||
store: &S,
|
||||
profile: &ks_config::ProfileConfig,
|
||||
wallet: &crate::DevnetExecutionWallet,
|
||||
options: &crate::MetaplexCreateFixturePreparationOptions,
|
||||
observer: &O,
|
||||
) -> ks_core::Result<crate::DevnetMetaplexCollectionVerifyCampaignSummary>
|
||||
where
|
||||
S: ks_store::RawTransactionStore
|
||||
+ ks_store::CoreExtractionStore
|
||||
@@ -65,11 +93,11 @@ where
|
||||
let mut parent_options = options.clone();
|
||||
parent_options.asset_family = crate::MetaplexTokenMetadataAssetFamily::Collection;
|
||||
parent_options.collection_mint = std::option::Option::None;
|
||||
let parent = match crate::execute_devnet_metaplex_create_mint_campaign(
|
||||
let parent = match crate::execute_devnet_metaplex_create_mint_campaign_with_wallet(
|
||||
http_pool,
|
||||
store,
|
||||
profile,
|
||||
workspace_root,
|
||||
wallet,
|
||||
&parent_options,
|
||||
observer,
|
||||
)
|
||||
@@ -81,11 +109,11 @@ where
|
||||
let mut member_options = options.clone();
|
||||
member_options.asset_family = crate::MetaplexTokenMetadataAssetFamily::Nft;
|
||||
member_options.collection_mint = std::option::Option::Some(parent.fixture.mint.clone());
|
||||
let member = match crate::execute_devnet_metaplex_create_mint_campaign(
|
||||
let member = match crate::execute_devnet_metaplex_create_mint_campaign_with_wallet(
|
||||
http_pool,
|
||||
store,
|
||||
profile,
|
||||
workspace_root,
|
||||
wallet,
|
||||
&member_options,
|
||||
observer,
|
||||
)
|
||||
@@ -168,11 +196,11 @@ where
|
||||
options.query_role.as_str(),
|
||||
std::option::Option::Some(fixture_slot),
|
||||
);
|
||||
let verify = match crate::execute_devnet_metaplex_token_metadata(
|
||||
let verify = match crate::execute_devnet_metaplex_token_metadata_with_wallet(
|
||||
http_pool,
|
||||
store,
|
||||
profile,
|
||||
workspace_root,
|
||||
wallet,
|
||||
&verify_request,
|
||||
decoders.as_slice(),
|
||||
materializers.as_slice(),
|
||||
@@ -240,11 +268,11 @@ where
|
||||
options.query_role.as_str(),
|
||||
std::option::Option::Some(verify_slot),
|
||||
);
|
||||
let unverify = match crate::execute_devnet_metaplex_token_metadata(
|
||||
let unverify = match crate::execute_devnet_metaplex_token_metadata_with_wallet(
|
||||
http_pool,
|
||||
store,
|
||||
profile,
|
||||
workspace_root,
|
||||
wallet,
|
||||
&unverify_request,
|
||||
decoders.as_slice(),
|
||||
materializers.as_slice(),
|
||||
@@ -667,7 +695,8 @@ mod tests {
|
||||
if let std::result::Result::Err(error) = store.initialize_store_schema().await {
|
||||
panic!("PostgreSQL schema initialization failed: {error}");
|
||||
}
|
||||
let configured_wallet_dir = std::path::PathBuf::from(profile.wallet.wallet_dir.as_str());
|
||||
let configured_wallet_dir =
|
||||
std::path::PathBuf::from(profile.wallet.temporary_wallet_dir.as_str());
|
||||
let wallet_dir = if configured_wallet_dir.is_absolute() {
|
||||
configured_wallet_dir
|
||||
} else {
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
// file: ks-pipeline-demo-scenarios/src/metadata/metaplex_token_metadata/create_mint_campaign.rs
|
||||
// version: 14
|
||||
// version: 15
|
||||
|
||||
//! Confirmed Devnet `Create -> Mint` campaign for one Metaplex asset family.
|
||||
|
||||
@@ -52,6 +52,34 @@ pub async fn execute_devnet_metaplex_create_mint_campaign<S, O>(
|
||||
options: &crate::MetaplexCreateFixturePreparationOptions,
|
||||
observer: &O,
|
||||
) -> ks_core::Result<crate::DevnetMetaplexCreateMintCampaignSummary>
|
||||
where
|
||||
S: ks_store::RawTransactionStore
|
||||
+ ks_store::CoreExtractionStore
|
||||
+ ks_store::DecodePipelineStore
|
||||
+ Sync,
|
||||
O: crate::SolanaExecutionObserver,
|
||||
{
|
||||
let temporary = match crate::load_profile_temporary_wallet(profile, workspace_root).await {
|
||||
std::result::Result::Ok(value) => value,
|
||||
std::result::Result::Err(error) => return std::result::Result::Err(error),
|
||||
};
|
||||
let wallet = crate::DevnetExecutionWallet::Temporary(temporary);
|
||||
return execute_devnet_metaplex_create_mint_campaign_with_wallet(
|
||||
http_pool, store, profile, &wallet, options, observer,
|
||||
)
|
||||
.await;
|
||||
}
|
||||
|
||||
/// Executes one fresh family-specific `Create -> Mint` campaign with an explicit operator wallet.
|
||||
#[allow(clippy::too_many_arguments)]
|
||||
pub async fn execute_devnet_metaplex_create_mint_campaign_with_wallet<S, O>(
|
||||
http_pool: &ks_onchain_transport::HttpEndpointPool,
|
||||
store: &S,
|
||||
profile: &ks_config::ProfileConfig,
|
||||
wallet: &crate::DevnetExecutionWallet,
|
||||
options: &crate::MetaplexCreateFixturePreparationOptions,
|
||||
observer: &O,
|
||||
) -> ks_core::Result<crate::DevnetMetaplexCreateMintCampaignSummary>
|
||||
where
|
||||
S: ks_store::RawTransactionStore
|
||||
+ ks_store::CoreExtractionStore
|
||||
@@ -64,13 +92,14 @@ where
|
||||
"Metaplex Create -> Mint Devnet campaign requires devnet_send_enabled=true",
|
||||
));
|
||||
}
|
||||
let fixture =
|
||||
match crate::prepare_metaplex_create_fixture(http_pool, profile, workspace_root, options)
|
||||
.await
|
||||
{
|
||||
std::result::Result::Ok(value) => value,
|
||||
std::result::Result::Err(error) => return std::result::Result::Err(error),
|
||||
};
|
||||
let fixture = match crate::prepare_metaplex_create_fixture_with_wallet(
|
||||
http_pool, profile, wallet, options,
|
||||
)
|
||||
.await
|
||||
{
|
||||
std::result::Result::Ok(value) => value,
|
||||
std::result::Result::Err(error) => return std::result::Result::Err(error),
|
||||
};
|
||||
let decoders: std::vec::Vec<std::sync::Arc<dyn ks_lib::DcApiInstructionDecoder>> =
|
||||
std::vec![std::sync::Arc::new(ks_lib::DcMetadataMetaplexTokenMetadataDecoder)];
|
||||
let materializers: std::vec::Vec<std::sync::Arc<dyn ks_lib::MtApiEventMaterializer>> = std::vec![
|
||||
@@ -100,11 +129,11 @@ where
|
||||
std::option::Option::None,
|
||||
false,
|
||||
);
|
||||
let create = match crate::execute_devnet_metaplex_token_metadata(
|
||||
let create = match crate::execute_devnet_metaplex_token_metadata_with_wallet(
|
||||
http_pool,
|
||||
store,
|
||||
profile,
|
||||
workspace_root,
|
||||
wallet,
|
||||
&create_request,
|
||||
decoders.as_slice(),
|
||||
materializers.as_slice(),
|
||||
@@ -239,11 +268,11 @@ where
|
||||
std::option::Option::Some(create_slot),
|
||||
true,
|
||||
);
|
||||
let mint = match crate::execute_devnet_metaplex_token_metadata(
|
||||
let mint = match crate::execute_devnet_metaplex_token_metadata_with_wallet(
|
||||
http_pool,
|
||||
store,
|
||||
profile,
|
||||
workspace_root,
|
||||
wallet,
|
||||
&mint_request,
|
||||
decoders.as_slice(),
|
||||
materializers.as_slice(),
|
||||
@@ -832,7 +861,8 @@ mod tests {
|
||||
if let std::result::Result::Err(error) = store.initialize_store_schema().await {
|
||||
panic!("PostgreSQL schema initialization failed: {error}");
|
||||
}
|
||||
let configured_wallet_dir = std::path::PathBuf::from(profile.wallet.wallet_dir.as_str());
|
||||
let configured_wallet_dir =
|
||||
std::path::PathBuf::from(profile.wallet.temporary_wallet_dir.as_str());
|
||||
let wallet_dir = if configured_wallet_dir.is_absolute() {
|
||||
configured_wallet_dir
|
||||
} else {
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
// file: ks-pipeline-demo-scenarios/src/metadata/metaplex_token_metadata/devnet_execution.rs
|
||||
// version: 23
|
||||
// version: 24
|
||||
|
||||
//! Real Devnet simulation and submission for current Metaplex Token Metadata operations.
|
||||
|
||||
@@ -363,7 +363,6 @@ pub struct DevnetMetaplexTokenMetadataExecutionSummary {
|
||||
}
|
||||
|
||||
struct PreparedMetaplexExecution {
|
||||
wallet: ks_wallet::TemporaryWallet,
|
||||
unsigned: ks_lib::ExSolanaUnsignedTransaction,
|
||||
evidence: ks_lib::ExSolanaSimulationEvidence,
|
||||
summary: crate::DevnetMetaplexTokenMetadataExecutionSummary,
|
||||
@@ -377,6 +376,28 @@ pub async fn simulate_devnet_metaplex_token_metadata<O>(
|
||||
request: &crate::DevnetMetaplexTokenMetadataExecutionRequest,
|
||||
observer: &O,
|
||||
) -> ks_core::Result<crate::DevnetMetaplexTokenMetadataExecutionSummary>
|
||||
where
|
||||
O: crate::SolanaExecutionObserver,
|
||||
{
|
||||
let temporary = match crate::load_profile_temporary_wallet(profile, workspace_root).await {
|
||||
std::result::Result::Ok(value) => value,
|
||||
std::result::Result::Err(error) => return std::result::Result::Err(error),
|
||||
};
|
||||
let wallet = crate::DevnetExecutionWallet::Temporary(temporary);
|
||||
return simulate_devnet_metaplex_token_metadata_with_wallet(
|
||||
http_pool, profile, &wallet, request, observer,
|
||||
)
|
||||
.await;
|
||||
}
|
||||
|
||||
/// Simulates one current Metaplex operation with an explicitly resolved wallet.
|
||||
pub async fn simulate_devnet_metaplex_token_metadata_with_wallet<O>(
|
||||
http_pool: &ks_onchain_transport::HttpEndpointPool,
|
||||
profile: &ks_config::ProfileConfig,
|
||||
wallet: &crate::DevnetExecutionWallet,
|
||||
request: &crate::DevnetMetaplexTokenMetadataExecutionRequest,
|
||||
observer: &O,
|
||||
) -> ks_core::Result<crate::DevnetMetaplexTokenMetadataExecutionSummary>
|
||||
where
|
||||
O: crate::SolanaExecutionObserver,
|
||||
{
|
||||
@@ -385,11 +406,11 @@ where
|
||||
"simulate_devnet_metaplex_token_metadata requires submit=false",
|
||||
));
|
||||
}
|
||||
let prepared =
|
||||
match prepare_execution(http_pool, profile, workspace_root, request, &[], observer).await {
|
||||
std::result::Result::Ok(value) => value,
|
||||
std::result::Result::Err(error) => return std::result::Result::Err(error),
|
||||
};
|
||||
let prepared = match prepare_execution(http_pool, profile, wallet, request, &[], observer).await
|
||||
{
|
||||
std::result::Result::Ok(value) => value,
|
||||
std::result::Result::Err(error) => return std::result::Result::Err(error),
|
||||
};
|
||||
return std::result::Result::Ok(prepared.summary);
|
||||
}
|
||||
|
||||
@@ -412,11 +433,48 @@ where
|
||||
+ Sync,
|
||||
O: crate::SolanaExecutionObserver,
|
||||
{
|
||||
return crate::execute_devnet_metaplex_token_metadata_with_signers(
|
||||
let temporary = match crate::load_profile_temporary_wallet(profile, workspace_root).await {
|
||||
std::result::Result::Ok(value) => value,
|
||||
std::result::Result::Err(error) => return std::result::Result::Err(error),
|
||||
};
|
||||
let wallet = crate::DevnetExecutionWallet::Temporary(temporary);
|
||||
return execute_devnet_metaplex_token_metadata_with_wallet(
|
||||
http_pool,
|
||||
store,
|
||||
profile,
|
||||
workspace_root,
|
||||
&wallet,
|
||||
request,
|
||||
decoders,
|
||||
materializers,
|
||||
observer,
|
||||
)
|
||||
.await;
|
||||
}
|
||||
|
||||
/// Executes one real Devnet Metaplex operation with an explicitly resolved wallet.
|
||||
#[allow(clippy::too_many_arguments)]
|
||||
pub async fn execute_devnet_metaplex_token_metadata_with_wallet<S, O>(
|
||||
http_pool: &ks_onchain_transport::HttpEndpointPool,
|
||||
store: &S,
|
||||
profile: &ks_config::ProfileConfig,
|
||||
wallet: &crate::DevnetExecutionWallet,
|
||||
request: &crate::DevnetMetaplexTokenMetadataExecutionRequest,
|
||||
decoders: &[std::sync::Arc<dyn ks_lib::DcApiInstructionDecoder>],
|
||||
materializers: &[std::sync::Arc<dyn ks_lib::MtApiEventMaterializer>],
|
||||
observer: &O,
|
||||
) -> ks_core::Result<crate::DevnetMetaplexTokenMetadataExecutionSummary>
|
||||
where
|
||||
S: ks_store::RawTransactionStore
|
||||
+ ks_store::CoreExtractionStore
|
||||
+ ks_store::DecodePipelineStore
|
||||
+ Sync,
|
||||
O: crate::SolanaExecutionObserver,
|
||||
{
|
||||
return execute_devnet_metaplex_token_metadata_with_wallet_and_signers(
|
||||
http_pool,
|
||||
store,
|
||||
profile,
|
||||
wallet,
|
||||
request,
|
||||
decoders,
|
||||
materializers,
|
||||
@@ -446,19 +504,52 @@ where
|
||||
+ Sync,
|
||||
O: crate::SolanaExecutionObserver,
|
||||
{
|
||||
let prepared = match prepare_execution(
|
||||
http_pool,
|
||||
profile,
|
||||
workspace_root,
|
||||
request,
|
||||
additional_signers,
|
||||
observer,
|
||||
)
|
||||
.await
|
||||
{
|
||||
let temporary = match crate::load_profile_temporary_wallet(profile, workspace_root).await {
|
||||
std::result::Result::Ok(value) => value,
|
||||
std::result::Result::Err(error) => return std::result::Result::Err(error),
|
||||
};
|
||||
let wallet = crate::DevnetExecutionWallet::Temporary(temporary);
|
||||
return execute_devnet_metaplex_token_metadata_with_wallet_and_signers(
|
||||
http_pool,
|
||||
store,
|
||||
profile,
|
||||
&wallet,
|
||||
request,
|
||||
decoders,
|
||||
materializers,
|
||||
additional_signers,
|
||||
observer,
|
||||
)
|
||||
.await;
|
||||
}
|
||||
|
||||
/// Executes one real Devnet Metaplex submission with an explicit wallet and extra signers.
|
||||
#[allow(clippy::too_many_arguments)]
|
||||
pub async fn execute_devnet_metaplex_token_metadata_with_wallet_and_signers<S, O>(
|
||||
http_pool: &ks_onchain_transport::HttpEndpointPool,
|
||||
store: &S,
|
||||
profile: &ks_config::ProfileConfig,
|
||||
wallet: &crate::DevnetExecutionWallet,
|
||||
request: &crate::DevnetMetaplexTokenMetadataExecutionRequest,
|
||||
decoders: &[std::sync::Arc<dyn ks_lib::DcApiInstructionDecoder>],
|
||||
materializers: &[std::sync::Arc<dyn ks_lib::MtApiEventMaterializer>],
|
||||
additional_signers: &[&(dyn solana_signer::Signer + std::marker::Sync)],
|
||||
observer: &O,
|
||||
) -> ks_core::Result<crate::DevnetMetaplexTokenMetadataExecutionSummary>
|
||||
where
|
||||
S: ks_store::RawTransactionStore
|
||||
+ ks_store::CoreExtractionStore
|
||||
+ ks_store::DecodePipelineStore
|
||||
+ Sync,
|
||||
O: crate::SolanaExecutionObserver,
|
||||
{
|
||||
let prepared =
|
||||
match prepare_execution(http_pool, profile, wallet, request, additional_signers, observer)
|
||||
.await
|
||||
{
|
||||
std::result::Result::Ok(value) => value,
|
||||
std::result::Result::Err(error) => return std::result::Result::Err(error),
|
||||
};
|
||||
if !request.submit {
|
||||
return std::result::Result::Ok(prepared.summary);
|
||||
}
|
||||
@@ -483,7 +574,7 @@ where
|
||||
let signed = match sign_prepared_transaction(
|
||||
prepared.unsigned,
|
||||
&prepared.evidence,
|
||||
prepared.wallet.as_sync_signer(),
|
||||
wallet.as_sync_signer(),
|
||||
additional_signers,
|
||||
) {
|
||||
std::result::Result::Ok(value) => value,
|
||||
@@ -805,7 +896,7 @@ fn replay_summary_diagnostic(
|
||||
async fn prepare_execution<O>(
|
||||
http_pool: &ks_onchain_transport::HttpEndpointPool,
|
||||
profile: &ks_config::ProfileConfig,
|
||||
workspace_root: &std::path::Path,
|
||||
wallet: &crate::DevnetExecutionWallet,
|
||||
request: &crate::DevnetMetaplexTokenMetadataExecutionRequest,
|
||||
additional_signers: &[&(dyn solana_signer::Signer + std::marker::Sync)],
|
||||
observer: &O,
|
||||
@@ -839,11 +930,7 @@ where
|
||||
),
|
||||
));
|
||||
}
|
||||
let wallet = match crate::load_profile_temporary_wallet(profile, workspace_root).await {
|
||||
std::result::Result::Ok(value) => value,
|
||||
std::result::Result::Err(error) => return std::result::Result::Err(error),
|
||||
};
|
||||
let wallet_summary = wallet.summary();
|
||||
let wallet_summary = wallet.identity();
|
||||
let fee_payer = ks_lib::MdPubkey(wallet_summary.public_key.clone());
|
||||
let balance = match http_pool
|
||||
.get_balance_for_role(
|
||||
@@ -1000,7 +1087,6 @@ where
|
||||
};
|
||||
let evidence = unsigned.bind_simulation(simulation.clone());
|
||||
return std::result::Result::Ok(PreparedMetaplexExecution {
|
||||
wallet,
|
||||
unsigned,
|
||||
evidence,
|
||||
summary: crate::DevnetMetaplexTokenMetadataExecutionSummary {
|
||||
@@ -1175,9 +1261,11 @@ fn validate_profile(
|
||||
"Metaplex Devnet orchestration requires a Devnet wallet profile",
|
||||
));
|
||||
}
|
||||
if !profile.wallet.temporary_wallet_enabled || !profile.wallet.temporary_wallet_persist {
|
||||
if profile.wallet.wallet_alias.is_none()
|
||||
&& (!profile.wallet.temporary_wallet_enabled || !profile.wallet.temporary_wallet_persist)
|
||||
{
|
||||
return std::result::Result::Err(ks_core::Error::config(
|
||||
"Metaplex Devnet orchestration requires an enabled persistent temporary wallet",
|
||||
"Metaplex Devnet orchestration requires an enabled persistent temporary wallet when no native wallet alias is selected",
|
||||
));
|
||||
}
|
||||
if !profile.execution.require_simulation {
|
||||
@@ -1416,7 +1504,7 @@ mod tests {
|
||||
};
|
||||
let mut profile = example_devnet_profile();
|
||||
if let std::result::Result::Ok(directory) = std::env::var("KS_DEVNET_WALLET_DIR") {
|
||||
profile.wallet.wallet_dir = directory;
|
||||
profile.wallet.temporary_wallet_dir = directory;
|
||||
}
|
||||
let pool = match ks_onchain_transport::HttpEndpointPool::from_profile(&profile) {
|
||||
std::result::Result::Ok(value) => value,
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
// file: ks-pipeline-demo-scenarios/src/metadata/metaplex_token_metadata/escrow_campaign.rs
|
||||
// version: 6
|
||||
// version: 7
|
||||
|
||||
//! Confirmed Devnet Token Owned Escrow campaign for current Metaplex escrow operations.
|
||||
|
||||
@@ -64,6 +64,34 @@ pub async fn execute_devnet_metaplex_escrow_campaign<S, O>(
|
||||
options: &crate::MetaplexCreateFixturePreparationOptions,
|
||||
observer: &O,
|
||||
) -> ks_core::Result<crate::DevnetMetaplexEscrowCampaignSummary>
|
||||
where
|
||||
S: ks_store::RawTransactionStore
|
||||
+ ks_store::CoreExtractionStore
|
||||
+ ks_store::DecodePipelineStore
|
||||
+ Sync,
|
||||
O: crate::SolanaExecutionObserver,
|
||||
{
|
||||
let temporary = match crate::load_profile_temporary_wallet(profile, workspace_root).await {
|
||||
std::result::Result::Ok(value) => value,
|
||||
std::result::Result::Err(error) => return std::result::Result::Err(error),
|
||||
};
|
||||
let wallet = crate::DevnetExecutionWallet::Temporary(temporary);
|
||||
return execute_devnet_metaplex_escrow_campaign_with_wallet(
|
||||
http_pool, store, profile, &wallet, options, observer,
|
||||
)
|
||||
.await;
|
||||
}
|
||||
|
||||
/// Executes a fresh Token Owned Escrow lifecycle with an explicit operator wallet.
|
||||
#[allow(clippy::too_many_arguments)]
|
||||
pub async fn execute_devnet_metaplex_escrow_campaign_with_wallet<S, O>(
|
||||
http_pool: &ks_onchain_transport::HttpEndpointPool,
|
||||
store: &S,
|
||||
profile: &ks_config::ProfileConfig,
|
||||
wallet: &crate::DevnetExecutionWallet,
|
||||
options: &crate::MetaplexCreateFixturePreparationOptions,
|
||||
observer: &O,
|
||||
) -> ks_core::Result<crate::DevnetMetaplexEscrowCampaignSummary>
|
||||
where
|
||||
S: ks_store::RawTransactionStore
|
||||
+ ks_store::CoreExtractionStore
|
||||
@@ -80,11 +108,11 @@ where
|
||||
clean_fixture_options(options, crate::MetaplexTokenMetadataAssetFamily::Nft);
|
||||
let attribute_options =
|
||||
clean_fixture_options(options, crate::MetaplexTokenMetadataAssetFamily::Fungible);
|
||||
let parent_fixture = match crate::execute_devnet_metaplex_create_mint_campaign(
|
||||
let parent_fixture = match crate::execute_devnet_metaplex_create_mint_campaign_with_wallet(
|
||||
http_pool,
|
||||
store,
|
||||
profile,
|
||||
workspace_root,
|
||||
wallet,
|
||||
&parent_options,
|
||||
observer,
|
||||
)
|
||||
@@ -93,11 +121,11 @@ where
|
||||
std::result::Result::Ok(value) => value,
|
||||
std::result::Result::Err(error) => return std::result::Result::Err(error),
|
||||
};
|
||||
let attribute_fixture = match crate::execute_devnet_metaplex_create_mint_campaign(
|
||||
let attribute_fixture = match crate::execute_devnet_metaplex_create_mint_campaign_with_wallet(
|
||||
http_pool,
|
||||
store,
|
||||
profile,
|
||||
workspace_root,
|
||||
wallet,
|
||||
&attribute_options,
|
||||
observer,
|
||||
)
|
||||
@@ -148,11 +176,11 @@ where
|
||||
parent_options.query_role.as_str(),
|
||||
std::option::Option::None,
|
||||
);
|
||||
let create_escrow = match crate::execute_devnet_metaplex_token_metadata(
|
||||
let create_escrow = match crate::execute_devnet_metaplex_token_metadata_with_wallet(
|
||||
http_pool,
|
||||
store,
|
||||
profile,
|
||||
workspace_root,
|
||||
wallet,
|
||||
&create_request,
|
||||
metaplex_decoders.as_slice(),
|
||||
metaplex_materializers.as_slice(),
|
||||
@@ -195,21 +223,22 @@ where
|
||||
ata_request.submit = true;
|
||||
ata_request.operator_confirmed = true;
|
||||
ata_request.post_validation_max_retries = 20;
|
||||
let escrow_attribute_ata_creation = match crate::execute_devnet_spl_associated_token_account(
|
||||
http_pool,
|
||||
store,
|
||||
profile,
|
||||
workspace_root,
|
||||
&ata_request,
|
||||
ata_decoders.as_slice(),
|
||||
ata_materializers.as_slice(),
|
||||
observer,
|
||||
)
|
||||
.await
|
||||
{
|
||||
std::result::Result::Ok(value) => value,
|
||||
std::result::Result::Err(error) => return std::result::Result::Err(error),
|
||||
};
|
||||
let escrow_attribute_ata_creation =
|
||||
match crate::execute_devnet_spl_associated_token_account_with_wallet(
|
||||
http_pool,
|
||||
store,
|
||||
profile,
|
||||
wallet,
|
||||
&ata_request,
|
||||
ata_decoders.as_slice(),
|
||||
ata_materializers.as_slice(),
|
||||
observer,
|
||||
)
|
||||
.await
|
||||
{
|
||||
std::result::Result::Ok(value) => value,
|
||||
std::result::Result::Err(error) => return std::result::Result::Err(error),
|
||||
};
|
||||
let ata_slot = match validate_ata_setup(&escrow_attribute_ata_creation) {
|
||||
std::result::Result::Ok(value) => value,
|
||||
std::result::Result::Err(error) => return std::result::Result::Err(error),
|
||||
@@ -271,11 +300,11 @@ where
|
||||
deposit_request.submit = true;
|
||||
deposit_request.operator_confirmed = true;
|
||||
deposit_request.post_validation_max_retries = 20;
|
||||
let attribute_deposit = match crate::execute_devnet_spl_token(
|
||||
let attribute_deposit = match crate::execute_devnet_spl_token_with_wallet(
|
||||
http_pool,
|
||||
store,
|
||||
profile,
|
||||
workspace_root,
|
||||
wallet,
|
||||
&deposit_request,
|
||||
token_decoders.as_slice(),
|
||||
token_materializers.as_slice(),
|
||||
@@ -357,11 +386,11 @@ where
|
||||
parent_options.query_role.as_str(),
|
||||
std::option::Option::Some(deposit_slot),
|
||||
);
|
||||
let transfer_out = match crate::execute_devnet_metaplex_token_metadata(
|
||||
let transfer_out = match crate::execute_devnet_metaplex_token_metadata_with_wallet(
|
||||
http_pool,
|
||||
store,
|
||||
profile,
|
||||
workspace_root,
|
||||
wallet,
|
||||
&transfer_request,
|
||||
metaplex_decoders.as_slice(),
|
||||
metaplex_materializers.as_slice(),
|
||||
@@ -443,11 +472,11 @@ where
|
||||
parent_options.query_role.as_str(),
|
||||
std::option::Option::Some(transfer_slot),
|
||||
);
|
||||
let close_escrow = match crate::execute_devnet_metaplex_token_metadata(
|
||||
let close_escrow = match crate::execute_devnet_metaplex_token_metadata_with_wallet(
|
||||
http_pool,
|
||||
store,
|
||||
profile,
|
||||
workspace_root,
|
||||
wallet,
|
||||
&close_request,
|
||||
metaplex_decoders.as_slice(),
|
||||
metaplex_materializers.as_slice(),
|
||||
@@ -992,7 +1021,8 @@ mod tests {
|
||||
if let std::result::Result::Err(error) = store.initialize_store_schema().await {
|
||||
panic!("PostgreSQL schema initialization failed: {error}");
|
||||
}
|
||||
let configured_wallet_dir = std::path::PathBuf::from(profile.wallet.wallet_dir.as_str());
|
||||
let configured_wallet_dir =
|
||||
std::path::PathBuf::from(profile.wallet.temporary_wallet_dir.as_str());
|
||||
let wallet_dir = if configured_wallet_dir.is_absolute() {
|
||||
configured_wallet_dir
|
||||
} else {
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
// file: ks-pipeline-demo-scenarios/src/metadata/metaplex_token_metadata/fixture.rs
|
||||
// version: 22
|
||||
// version: 23
|
||||
|
||||
//! Native Metaplex Token Metadata fixture preparation for Devnet demos.
|
||||
|
||||
@@ -114,6 +114,21 @@ pub async fn prepare_metaplex_create_fixture(
|
||||
profile: &ks_config::ProfileConfig,
|
||||
workspace_root: &std::path::Path,
|
||||
options: &crate::MetaplexCreateFixturePreparationOptions,
|
||||
) -> ks_core::Result<crate::MetaplexCreateFixturePreparationSummary> {
|
||||
let temporary = match crate::load_profile_temporary_wallet(profile, workspace_root).await {
|
||||
std::result::Result::Ok(value) => value,
|
||||
std::result::Result::Err(error) => return std::result::Result::Err(error),
|
||||
};
|
||||
let wallet = crate::DevnetExecutionWallet::Temporary(temporary);
|
||||
return prepare_metaplex_create_fixture_with_wallet(http_pool, profile, &wallet, options).await;
|
||||
}
|
||||
|
||||
/// Creates one family-consistent classic SPL mint using an explicitly resolved operator wallet.
|
||||
pub async fn prepare_metaplex_create_fixture_with_wallet(
|
||||
http_pool: &ks_onchain_transport::HttpEndpointPool,
|
||||
profile: &ks_config::ProfileConfig,
|
||||
wallet: &crate::DevnetExecutionWallet,
|
||||
options: &crate::MetaplexCreateFixturePreparationOptions,
|
||||
) -> ks_core::Result<crate::MetaplexCreateFixturePreparationSummary> {
|
||||
if options.query_role.trim().is_empty() || options.transaction_role.trim().is_empty() {
|
||||
return std::result::Result::Err(ks_core::Error::config(
|
||||
@@ -168,10 +183,6 @@ pub async fn prepare_metaplex_create_fixture(
|
||||
return std::result::Result::Err(error);
|
||||
}
|
||||
}
|
||||
let operator = match crate::load_profile_temporary_wallet(profile, workspace_root).await {
|
||||
std::result::Result::Ok(value) => value,
|
||||
std::result::Result::Err(error) => return std::result::Result::Err(error),
|
||||
};
|
||||
let fixture_dir = options.wallet_dir.join("metaplex_token_metadata_validation");
|
||||
let fixture_store = match ks_wallet::TemporaryWalletStore::new(fixture_dir.clone()) {
|
||||
std::result::Result::Ok(value) => value,
|
||||
@@ -196,7 +207,7 @@ pub async fn prepare_metaplex_create_fixture(
|
||||
std::result::Result::Err(error) => return std::result::Result::Err(error),
|
||||
};
|
||||
let mint_keypair_path = fixture_store.wallet_path(&fixture_alias);
|
||||
let authority = operator.public_key();
|
||||
let authority = wallet.public_key();
|
||||
let mint = mint_wallet.public_key();
|
||||
let mint_decimals = fixture_mint_decimals(options.asset_family);
|
||||
let existing =
|
||||
@@ -216,7 +227,7 @@ pub async fn prepare_metaplex_create_fixture(
|
||||
http_pool,
|
||||
profile,
|
||||
options,
|
||||
&operator,
|
||||
wallet,
|
||||
&mint_wallet,
|
||||
mint_decimals,
|
||||
)
|
||||
@@ -404,7 +415,7 @@ async fn create_native_classic_mint(
|
||||
http_pool: &ks_onchain_transport::HttpEndpointPool,
|
||||
profile: &ks_config::ProfileConfig,
|
||||
options: &crate::MetaplexCreateFixturePreparationOptions,
|
||||
operator: &ks_wallet::TemporaryWallet,
|
||||
operator: &crate::DevnetExecutionWallet,
|
||||
mint_wallet: &ks_wallet::TemporaryWallet,
|
||||
mint_decimals: u8,
|
||||
) -> ks_core::Result<NativeFixturePreparationEvidence> {
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
// file: ks-pipeline-demo-scenarios/src/metadata/metaplex_token_metadata/maintenance_campaign.rs
|
||||
// version: 8
|
||||
// version: 9
|
||||
|
||||
//! Final bounded Devnet qualification campaign for current Metaplex maintenance operations.
|
||||
|
||||
@@ -42,6 +42,34 @@ pub async fn execute_devnet_metaplex_maintenance_campaign<S, O>(
|
||||
options: &crate::MetaplexCreateFixturePreparationOptions,
|
||||
observer: &O,
|
||||
) -> ks_core::Result<crate::DevnetMetaplexMaintenanceCampaignSummary>
|
||||
where
|
||||
S: ks_store::RawTransactionStore
|
||||
+ ks_store::CoreExtractionStore
|
||||
+ ks_store::DecodePipelineStore
|
||||
+ Sync,
|
||||
O: crate::SolanaExecutionObserver,
|
||||
{
|
||||
let temporary = match crate::load_profile_temporary_wallet(profile, workspace_root).await {
|
||||
std::result::Result::Ok(value) => value,
|
||||
std::result::Result::Err(error) => return std::result::Result::Err(error),
|
||||
};
|
||||
let wallet = crate::DevnetExecutionWallet::Temporary(temporary);
|
||||
return execute_devnet_metaplex_maintenance_campaign_with_wallet(
|
||||
http_pool, store, profile, &wallet, options, observer,
|
||||
)
|
||||
.await;
|
||||
}
|
||||
|
||||
/// Executes the bounded Metaplex maintenance campaign with an explicit operator wallet.
|
||||
#[allow(clippy::too_many_arguments)]
|
||||
pub async fn execute_devnet_metaplex_maintenance_campaign_with_wallet<S, O>(
|
||||
http_pool: &ks_onchain_transport::HttpEndpointPool,
|
||||
store: &S,
|
||||
profile: &ks_config::ProfileConfig,
|
||||
wallet: &crate::DevnetExecutionWallet,
|
||||
options: &crate::MetaplexCreateFixturePreparationOptions,
|
||||
observer: &O,
|
||||
) -> ks_core::Result<crate::DevnetMetaplexMaintenanceCampaignSummary>
|
||||
where
|
||||
S: ks_store::RawTransactionStore
|
||||
+ ks_store::CoreExtractionStore
|
||||
@@ -54,13 +82,8 @@ where
|
||||
"Metaplex maintenance campaign requires the classic NFT fixture family",
|
||||
));
|
||||
}
|
||||
let fixture = match crate::execute_devnet_metaplex_create_mint_campaign(
|
||||
http_pool,
|
||||
store,
|
||||
profile,
|
||||
workspace_root,
|
||||
options,
|
||||
observer,
|
||||
let fixture = match crate::execute_devnet_metaplex_create_mint_campaign_with_wallet(
|
||||
http_pool, store, profile, wallet, options, observer,
|
||||
)
|
||||
.await
|
||||
{
|
||||
@@ -91,7 +114,7 @@ where
|
||||
http_pool,
|
||||
store,
|
||||
profile,
|
||||
workspace_root,
|
||||
wallet,
|
||||
options,
|
||||
observer,
|
||||
)
|
||||
@@ -130,7 +153,7 @@ where
|
||||
201,
|
||||
http_pool,
|
||||
profile,
|
||||
workspace_root,
|
||||
wallet,
|
||||
options,
|
||||
observer,
|
||||
)
|
||||
@@ -145,7 +168,7 @@ where
|
||||
75,
|
||||
http_pool,
|
||||
profile,
|
||||
workspace_root,
|
||||
wallet,
|
||||
options,
|
||||
observer,
|
||||
)
|
||||
@@ -163,7 +186,7 @@ where
|
||||
7,
|
||||
http_pool,
|
||||
profile,
|
||||
workspace_root,
|
||||
wallet,
|
||||
options,
|
||||
observer,
|
||||
)
|
||||
@@ -184,7 +207,7 @@ where
|
||||
188,
|
||||
http_pool,
|
||||
profile,
|
||||
workspace_root,
|
||||
wallet,
|
||||
options,
|
||||
observer,
|
||||
)
|
||||
@@ -272,7 +295,7 @@ async fn execute_confirmed_operation<S, O>(
|
||||
http_pool: &ks_onchain_transport::HttpEndpointPool,
|
||||
store: &S,
|
||||
profile: &ks_config::ProfileConfig,
|
||||
workspace_root: &std::path::Path,
|
||||
wallet: &crate::DevnetExecutionWallet,
|
||||
options: &crate::MetaplexCreateFixturePreparationOptions,
|
||||
observer: &O,
|
||||
) -> ks_core::Result<crate::DevnetMetaplexTokenMetadataExecutionSummary>
|
||||
@@ -304,11 +327,11 @@ where
|
||||
request.operator_confirmed = true;
|
||||
request.materialize_after_confirmation = true;
|
||||
request.post_validation_max_retries = 20;
|
||||
return crate::execute_devnet_metaplex_token_metadata(
|
||||
return crate::execute_devnet_metaplex_token_metadata_with_wallet(
|
||||
http_pool,
|
||||
store,
|
||||
profile,
|
||||
workspace_root,
|
||||
wallet,
|
||||
&request,
|
||||
decoders.as_slice(),
|
||||
materializers.as_slice(),
|
||||
@@ -324,7 +347,7 @@ async fn simulate_expected_unavailable<O>(
|
||||
expected_custom_error: u64,
|
||||
http_pool: &ks_onchain_transport::HttpEndpointPool,
|
||||
profile: &ks_config::ProfileConfig,
|
||||
workspace_root: &std::path::Path,
|
||||
wallet: &crate::DevnetExecutionWallet,
|
||||
options: &crate::MetaplexCreateFixturePreparationOptions,
|
||||
observer: &O,
|
||||
) -> ks_core::Result<crate::DevnetMetaplexTokenMetadataExecutionSummary>
|
||||
@@ -337,12 +360,8 @@ where
|
||||
);
|
||||
request.query_role = options.query_role.clone();
|
||||
request.transaction_role = options.transaction_role.clone();
|
||||
let summary = match crate::simulate_devnet_metaplex_token_metadata(
|
||||
http_pool,
|
||||
profile,
|
||||
workspace_root,
|
||||
&request,
|
||||
observer,
|
||||
let summary = match crate::simulate_devnet_metaplex_token_metadata_with_wallet(
|
||||
http_pool, profile, wallet, &request, observer,
|
||||
)
|
||||
.await
|
||||
{
|
||||
@@ -596,7 +615,8 @@ mod tests {
|
||||
if let std::result::Result::Err(error) = store.initialize_store_schema().await {
|
||||
panic!("PostgreSQL schema initialization failed: {error}");
|
||||
}
|
||||
let configured_wallet_dir = std::path::PathBuf::from(profile.wallet.wallet_dir.as_str());
|
||||
let configured_wallet_dir =
|
||||
std::path::PathBuf::from(profile.wallet.temporary_wallet_dir.as_str());
|
||||
let wallet_dir = if configured_wallet_dir.is_absolute() {
|
||||
configured_wallet_dir
|
||||
} else {
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
// file: ks-pipeline-demo-scenarios/src/metadata/metaplex_token_metadata/pnft_lifecycle_campaign.rs
|
||||
// version: 8
|
||||
// version: 10
|
||||
|
||||
//! Confirmed Devnet pNFT delegate, lock, unlock, revoke and transfer campaign.
|
||||
|
||||
@@ -76,6 +76,34 @@ pub async fn execute_devnet_metaplex_pnft_lifecycle_campaign<S, O>(
|
||||
options: &crate::MetaplexCreateFixturePreparationOptions,
|
||||
observer: &O,
|
||||
) -> ks_core::Result<crate::DevnetMetaplexPnftLifecycleCampaignSummary>
|
||||
where
|
||||
S: ks_store::RawTransactionStore
|
||||
+ ks_store::CoreExtractionStore
|
||||
+ ks_store::DecodePipelineStore
|
||||
+ Sync,
|
||||
O: crate::SolanaExecutionObserver,
|
||||
{
|
||||
let temporary = match crate::load_profile_temporary_wallet(profile, workspace_root).await {
|
||||
std::result::Result::Ok(value) => value,
|
||||
std::result::Result::Err(error) => return std::result::Result::Err(error),
|
||||
};
|
||||
let wallet = crate::DevnetExecutionWallet::Temporary(temporary);
|
||||
return execute_devnet_metaplex_pnft_lifecycle_campaign_with_wallet(
|
||||
http_pool, store, profile, &wallet, options, observer,
|
||||
)
|
||||
.await;
|
||||
}
|
||||
|
||||
/// Executes one fresh pNFT lifecycle campaign with an explicit operator wallet.
|
||||
#[allow(clippy::too_many_arguments)]
|
||||
pub async fn execute_devnet_metaplex_pnft_lifecycle_campaign_with_wallet<S, O>(
|
||||
http_pool: &ks_onchain_transport::HttpEndpointPool,
|
||||
store: &S,
|
||||
profile: &ks_config::ProfileConfig,
|
||||
wallet: &crate::DevnetExecutionWallet,
|
||||
options: &crate::MetaplexCreateFixturePreparationOptions,
|
||||
observer: &O,
|
||||
) -> ks_core::Result<crate::DevnetMetaplexPnftLifecycleCampaignSummary>
|
||||
where
|
||||
S: ks_store::RawTransactionStore
|
||||
+ ks_store::CoreExtractionStore
|
||||
@@ -88,13 +116,8 @@ where
|
||||
"Metaplex pNFT lifecycle campaign requires asset_family=programmable_nft",
|
||||
));
|
||||
}
|
||||
let pnft = match crate::execute_devnet_metaplex_create_mint_campaign(
|
||||
http_pool,
|
||||
store,
|
||||
profile,
|
||||
workspace_root,
|
||||
options,
|
||||
observer,
|
||||
let pnft = match crate::execute_devnet_metaplex_create_mint_campaign_with_wallet(
|
||||
http_pool, store, profile, wallet, options, observer,
|
||||
)
|
||||
.await
|
||||
{
|
||||
@@ -205,7 +228,7 @@ where
|
||||
http_pool,
|
||||
store,
|
||||
profile,
|
||||
workspace_root,
|
||||
wallet,
|
||||
options,
|
||||
"delegate-staking",
|
||||
delegate_staking_operation,
|
||||
@@ -261,7 +284,7 @@ where
|
||||
http_pool,
|
||||
store,
|
||||
profile,
|
||||
workspace_root,
|
||||
wallet,
|
||||
options,
|
||||
"lock",
|
||||
lock_operation,
|
||||
@@ -322,7 +345,7 @@ where
|
||||
http_pool,
|
||||
store,
|
||||
profile,
|
||||
workspace_root,
|
||||
wallet,
|
||||
options,
|
||||
"unlock",
|
||||
unlock_operation,
|
||||
@@ -378,7 +401,7 @@ where
|
||||
http_pool,
|
||||
store,
|
||||
profile,
|
||||
workspace_root,
|
||||
wallet,
|
||||
options,
|
||||
"revoke-staking",
|
||||
revoke_operation,
|
||||
@@ -436,7 +459,7 @@ where
|
||||
http_pool,
|
||||
store,
|
||||
profile,
|
||||
workspace_root,
|
||||
wallet,
|
||||
options,
|
||||
"delegate-transfer",
|
||||
delegate_transfer_operation,
|
||||
@@ -495,7 +518,7 @@ where
|
||||
http_pool,
|
||||
store,
|
||||
profile,
|
||||
workspace_root,
|
||||
wallet,
|
||||
options,
|
||||
transfer_operation,
|
||||
destination.1.as_str(),
|
||||
@@ -631,7 +654,7 @@ async fn execute_profile_step<S, O>(
|
||||
http_pool: &ks_onchain_transport::HttpEndpointPool,
|
||||
store: &S,
|
||||
profile: &ks_config::ProfileConfig,
|
||||
workspace_root: &std::path::Path,
|
||||
wallet: &crate::DevnetExecutionWallet,
|
||||
options: &crate::MetaplexCreateFixturePreparationOptions,
|
||||
label: &str,
|
||||
operation: ks_lib::ExMetaplexTokenMetadataOperation,
|
||||
@@ -654,11 +677,11 @@ where
|
||||
request.operator_confirmed = true;
|
||||
request.materialize_after_confirmation = true;
|
||||
request.post_validation_max_retries = 20;
|
||||
return crate::execute_devnet_metaplex_token_metadata(
|
||||
return crate::execute_devnet_metaplex_token_metadata_with_wallet(
|
||||
http_pool,
|
||||
store,
|
||||
profile,
|
||||
workspace_root,
|
||||
wallet,
|
||||
&request,
|
||||
decoders,
|
||||
materializers,
|
||||
@@ -672,7 +695,7 @@ async fn execute_delegate_step<S, O>(
|
||||
http_pool: &ks_onchain_transport::HttpEndpointPool,
|
||||
store: &S,
|
||||
profile: &ks_config::ProfileConfig,
|
||||
workspace_root: &std::path::Path,
|
||||
wallet: &crate::DevnetExecutionWallet,
|
||||
options: &crate::MetaplexCreateFixturePreparationOptions,
|
||||
label: &str,
|
||||
operation: ks_lib::ExMetaplexTokenMetadataOperation,
|
||||
@@ -698,11 +721,11 @@ where
|
||||
request.post_validation_max_retries = 20;
|
||||
request.additional_authorized_signers =
|
||||
std::vec![ks_lib::MdPubkey(delegate_wallet.public_key())];
|
||||
return crate::execute_devnet_metaplex_token_metadata_with_signers(
|
||||
return crate::execute_devnet_metaplex_token_metadata_with_wallet_and_signers(
|
||||
http_pool,
|
||||
store,
|
||||
profile,
|
||||
workspace_root,
|
||||
wallet,
|
||||
&request,
|
||||
decoders,
|
||||
materializers,
|
||||
@@ -717,7 +740,7 @@ async fn execute_delegate_transfer_step<S, O>(
|
||||
http_pool: &ks_onchain_transport::HttpEndpointPool,
|
||||
store: &S,
|
||||
profile: &ks_config::ProfileConfig,
|
||||
workspace_root: &std::path::Path,
|
||||
wallet: &crate::DevnetExecutionWallet,
|
||||
options: &crate::MetaplexCreateFixturePreparationOptions,
|
||||
operation: ks_lib::ExMetaplexTokenMetadataOperation,
|
||||
destination_token_record: &str,
|
||||
@@ -749,11 +772,11 @@ where
|
||||
request.post_validation_max_retries = 20;
|
||||
request.additional_authorized_signers =
|
||||
std::vec![ks_lib::MdPubkey(delegate_wallet.public_key())];
|
||||
return crate::execute_devnet_metaplex_token_metadata_with_signers(
|
||||
return crate::execute_devnet_metaplex_token_metadata_with_wallet_and_signers(
|
||||
http_pool,
|
||||
store,
|
||||
profile,
|
||||
workspace_root,
|
||||
wallet,
|
||||
&request,
|
||||
decoders,
|
||||
materializers,
|
||||
@@ -1090,7 +1113,8 @@ mod tests {
|
||||
if let std::result::Result::Err(error) = store.initialize_store_schema().await {
|
||||
panic!("PostgreSQL schema initialization failed: {error}");
|
||||
}
|
||||
let configured_wallet_dir = std::path::PathBuf::from(profile.wallet.wallet_dir.as_str());
|
||||
let configured_wallet_dir =
|
||||
std::path::PathBuf::from(profile.wallet.temporary_wallet_dir.as_str());
|
||||
let wallet_dir = if configured_wallet_dir.is_absolute() {
|
||||
configured_wallet_dir
|
||||
} else {
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
// file: ks-pipeline-demo-scenarios/src/metadata/metaplex_token_metadata/print_burn_campaign.rs
|
||||
// version: 9
|
||||
// version: 10
|
||||
|
||||
//! Devnet printable master NFT `Print -> Burn` campaign.
|
||||
|
||||
@@ -84,6 +84,34 @@ pub async fn execute_devnet_metaplex_print_burn_campaign<S, O>(
|
||||
options: &crate::MetaplexCreateFixturePreparationOptions,
|
||||
observer: &O,
|
||||
) -> ks_core::Result<crate::DevnetMetaplexPrintBurnCampaignSummary>
|
||||
where
|
||||
S: ks_store::RawTransactionStore
|
||||
+ ks_store::CoreExtractionStore
|
||||
+ ks_store::DecodePipelineStore
|
||||
+ Sync,
|
||||
O: crate::SolanaExecutionObserver,
|
||||
{
|
||||
let temporary = match crate::load_profile_temporary_wallet(profile, workspace_root).await {
|
||||
std::result::Result::Ok(value) => value,
|
||||
std::result::Result::Err(error) => return std::result::Result::Err(error),
|
||||
};
|
||||
let wallet = crate::DevnetExecutionWallet::Temporary(temporary);
|
||||
return execute_devnet_metaplex_print_burn_campaign_with_wallet(
|
||||
http_pool, store, profile, &wallet, options, observer,
|
||||
)
|
||||
.await;
|
||||
}
|
||||
|
||||
/// Executes one printable master NFT `Print -> Burn` campaign with an explicit operator wallet.
|
||||
#[allow(clippy::too_many_arguments)]
|
||||
pub async fn execute_devnet_metaplex_print_burn_campaign_with_wallet<S, O>(
|
||||
http_pool: &ks_onchain_transport::HttpEndpointPool,
|
||||
store: &S,
|
||||
profile: &ks_config::ProfileConfig,
|
||||
wallet: &crate::DevnetExecutionWallet,
|
||||
options: &crate::MetaplexCreateFixturePreparationOptions,
|
||||
observer: &O,
|
||||
) -> ks_core::Result<crate::DevnetMetaplexPrintBurnCampaignSummary>
|
||||
where
|
||||
S: ks_store::RawTransactionStore
|
||||
+ ks_store::CoreExtractionStore
|
||||
@@ -100,11 +128,11 @@ where
|
||||
master_options.asset_family = crate::MetaplexTokenMetadataAssetFamily::Nft;
|
||||
master_options.collection_mint = std::option::Option::None;
|
||||
master_options.print_supply_limit = std::option::Option::Some(1);
|
||||
let master = match crate::execute_devnet_metaplex_create_mint_campaign(
|
||||
let master = match crate::execute_devnet_metaplex_create_mint_campaign_with_wallet(
|
||||
http_pool,
|
||||
store,
|
||||
profile,
|
||||
workspace_root,
|
||||
wallet,
|
||||
&master_options,
|
||||
observer,
|
||||
)
|
||||
@@ -329,11 +357,11 @@ where
|
||||
options.query_role.as_str(),
|
||||
std::option::Option::Some(master_mint_slot),
|
||||
);
|
||||
let print = match crate::execute_devnet_metaplex_token_metadata_with_signers(
|
||||
let print = match crate::execute_devnet_metaplex_token_metadata_with_wallet_and_signers(
|
||||
http_pool,
|
||||
store,
|
||||
profile,
|
||||
workspace_root,
|
||||
wallet,
|
||||
&print_request,
|
||||
decoders.as_slice(),
|
||||
materializers.as_slice(),
|
||||
@@ -498,11 +526,11 @@ where
|
||||
options.query_role.as_str(),
|
||||
std::option::Option::Some(print_slot),
|
||||
);
|
||||
let burn = match crate::execute_devnet_metaplex_token_metadata(
|
||||
let burn = match crate::execute_devnet_metaplex_token_metadata_with_wallet(
|
||||
http_pool,
|
||||
store,
|
||||
profile,
|
||||
workspace_root,
|
||||
wallet,
|
||||
&burn_request,
|
||||
decoders.as_slice(),
|
||||
materializers.as_slice(),
|
||||
@@ -1199,7 +1227,8 @@ mod tests {
|
||||
if let std::result::Result::Err(error) = store.initialize_store_schema().await {
|
||||
panic!("PostgreSQL schema initialization failed: {error}");
|
||||
}
|
||||
let configured_wallet_dir = std::path::PathBuf::from(profile.wallet.wallet_dir.as_str());
|
||||
let configured_wallet_dir =
|
||||
std::path::PathBuf::from(profile.wallet.temporary_wallet_dir.as_str());
|
||||
let wallet_dir = if configured_wallet_dir.is_absolute() {
|
||||
configured_wallet_dir
|
||||
} else {
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
// file: ks-pipeline-demo-scenarios/src/metadata/metaplex_token_metadata/use_campaign.rs
|
||||
// version: 6
|
||||
// version: 7
|
||||
|
||||
//! Bounded Devnet availability probe for the current Metaplex `Use` surface.
|
||||
|
||||
@@ -46,6 +46,34 @@ pub async fn execute_devnet_metaplex_use_probe<S, O>(
|
||||
options: &crate::MetaplexCreateFixturePreparationOptions,
|
||||
observer: &O,
|
||||
) -> ks_core::Result<crate::DevnetMetaplexUseProbeSummary>
|
||||
where
|
||||
S: ks_store::RawTransactionStore
|
||||
+ ks_store::CoreExtractionStore
|
||||
+ ks_store::DecodePipelineStore
|
||||
+ Sync,
|
||||
O: crate::SolanaExecutionObserver,
|
||||
{
|
||||
let temporary = match crate::load_profile_temporary_wallet(profile, workspace_root).await {
|
||||
std::result::Result::Ok(value) => value,
|
||||
std::result::Result::Err(error) => return std::result::Result::Err(error),
|
||||
};
|
||||
let wallet = crate::DevnetExecutionWallet::Temporary(temporary);
|
||||
return execute_devnet_metaplex_use_probe_with_wallet(
|
||||
http_pool, store, profile, &wallet, options, observer,
|
||||
)
|
||||
.await;
|
||||
}
|
||||
|
||||
/// Executes one fresh classic NFT `Use` probe with an explicit operator wallet.
|
||||
#[allow(clippy::too_many_arguments)]
|
||||
pub async fn execute_devnet_metaplex_use_probe_with_wallet<S, O>(
|
||||
http_pool: &ks_onchain_transport::HttpEndpointPool,
|
||||
store: &S,
|
||||
profile: &ks_config::ProfileConfig,
|
||||
wallet: &crate::DevnetExecutionWallet,
|
||||
options: &crate::MetaplexCreateFixturePreparationOptions,
|
||||
observer: &O,
|
||||
) -> ks_core::Result<crate::DevnetMetaplexUseProbeSummary>
|
||||
where
|
||||
S: ks_store::RawTransactionStore
|
||||
+ ks_store::CoreExtractionStore
|
||||
@@ -59,11 +87,11 @@ where
|
||||
));
|
||||
}
|
||||
let fixture_options = options.clone().with_multiple_uses(2);
|
||||
let fixture = match crate::execute_devnet_metaplex_create_mint_campaign(
|
||||
let fixture = match crate::execute_devnet_metaplex_create_mint_campaign_with_wallet(
|
||||
http_pool,
|
||||
store,
|
||||
profile,
|
||||
workspace_root,
|
||||
wallet,
|
||||
&fixture_options,
|
||||
observer,
|
||||
)
|
||||
@@ -93,10 +121,10 @@ where
|
||||
);
|
||||
simulation_request.query_role = fixture_options.query_role.clone();
|
||||
simulation_request.transaction_role = fixture_options.transaction_role.clone();
|
||||
let simulation = match crate::simulate_devnet_metaplex_token_metadata(
|
||||
let simulation = match crate::simulate_devnet_metaplex_token_metadata_with_wallet(
|
||||
http_pool,
|
||||
profile,
|
||||
workspace_root,
|
||||
wallet,
|
||||
&simulation_request,
|
||||
observer,
|
||||
)
|
||||
@@ -139,11 +167,11 @@ where
|
||||
execution_request.post_validation_max_retries = 20;
|
||||
execution_request.postcondition_reads =
|
||||
metadata_read(fixture.fixture.metadata.as_str(), fixture_options.query_role.as_str());
|
||||
let execution = match crate::execute_devnet_metaplex_token_metadata(
|
||||
let execution = match crate::execute_devnet_metaplex_token_metadata_with_wallet(
|
||||
http_pool,
|
||||
store,
|
||||
profile,
|
||||
workspace_root,
|
||||
wallet,
|
||||
&execution_request,
|
||||
decoders.as_slice(),
|
||||
materializers.as_slice(),
|
||||
@@ -444,7 +472,8 @@ mod tests {
|
||||
if let std::result::Result::Err(error) = store.initialize_store_schema().await {
|
||||
panic!("PostgreSQL schema initialization failed: {error}");
|
||||
}
|
||||
let configured_wallet_dir = std::path::PathBuf::from(profile.wallet.wallet_dir.as_str());
|
||||
let configured_wallet_dir =
|
||||
std::path::PathBuf::from(profile.wallet.temporary_wallet_dir.as_str());
|
||||
let wallet_dir = if configured_wallet_dir.is_absolute() {
|
||||
configured_wallet_dir
|
||||
} else {
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
// file: ks-pipeline-demo-scenarios/src/metadata/solana_program/campaign.rs
|
||||
// version: 4
|
||||
// version: 5
|
||||
|
||||
//! Ordered confirmed Devnet campaign for all Solana Program Metadata operations.
|
||||
|
||||
@@ -36,6 +36,28 @@ pub async fn execute_devnet_solana_program_metadata_campaign<O>(
|
||||
options: &crate::SolanaProgramMetadataFixturePreparationOptions,
|
||||
observer: &O,
|
||||
) -> ks_core::Result<crate::DevnetSolanaProgramMetadataCampaignSummary>
|
||||
where
|
||||
O: crate::SolanaExecutionObserver,
|
||||
{
|
||||
let temporary = match crate::load_profile_temporary_wallet(profile, workspace_root).await {
|
||||
std::result::Result::Ok(value) => value,
|
||||
std::result::Result::Err(error) => return std::result::Result::Err(error),
|
||||
};
|
||||
let wallet = crate::DevnetExecutionWallet::Temporary(temporary);
|
||||
return execute_devnet_solana_program_metadata_campaign_with_wallet(
|
||||
http_pool, profile, &wallet, options, observer,
|
||||
)
|
||||
.await;
|
||||
}
|
||||
|
||||
/// Executes the complete Solana Program Metadata campaign with an explicitly resolved wallet.
|
||||
pub async fn execute_devnet_solana_program_metadata_campaign_with_wallet<O>(
|
||||
http_pool: &ks_onchain_transport::HttpEndpointPool,
|
||||
profile: &ks_config::ProfileConfig,
|
||||
wallet: &crate::DevnetExecutionWallet,
|
||||
options: &crate::SolanaProgramMetadataFixturePreparationOptions,
|
||||
observer: &O,
|
||||
) -> ks_core::Result<crate::DevnetSolanaProgramMetadataCampaignSummary>
|
||||
where
|
||||
O: crate::SolanaExecutionObserver,
|
||||
{
|
||||
@@ -44,11 +66,8 @@ where
|
||||
"Solana Program Metadata Devnet campaign requires explicit operator confirmation",
|
||||
));
|
||||
}
|
||||
let fixture = match crate::prepare_solana_program_metadata_fixture(
|
||||
http_pool,
|
||||
profile,
|
||||
workspace_root,
|
||||
options,
|
||||
let fixture = match crate::prepare_solana_program_metadata_fixture_with_wallet(
|
||||
http_pool, profile, wallet, options,
|
||||
)
|
||||
.await
|
||||
{
|
||||
@@ -63,12 +82,8 @@ where
|
||||
request.transaction_role = options.transaction_role.clone();
|
||||
request.submit = true;
|
||||
request.operator_confirmed = true;
|
||||
let execution = match crate::execute_devnet_solana_program_metadata(
|
||||
http_pool,
|
||||
profile,
|
||||
workspace_root,
|
||||
&request,
|
||||
observer,
|
||||
let execution = match crate::execute_devnet_solana_program_metadata_with_wallet(
|
||||
http_pool, profile, wallet, &request, observer,
|
||||
)
|
||||
.await
|
||||
{
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
// file: ks-pipeline-demo-scenarios/src/metadata/solana_program/devnet_execution.rs
|
||||
// version: 5
|
||||
// version: 6
|
||||
|
||||
//! Real Devnet simulation and controlled submission for Solana Program Metadata.
|
||||
|
||||
@@ -155,7 +155,6 @@ pub struct DevnetSolanaProgramMetadataExecutionSummary {
|
||||
}
|
||||
|
||||
struct PreparedSolanaProgramMetadataExecution {
|
||||
wallet: ks_wallet::TemporaryWallet,
|
||||
unsigned: ks_lib::ExSolanaUnsignedTransaction,
|
||||
evidence: ks_lib::ExSolanaSimulationEvidence,
|
||||
summary: crate::DevnetSolanaProgramMetadataExecutionSummary,
|
||||
@@ -169,6 +168,28 @@ pub async fn simulate_devnet_solana_program_metadata<O>(
|
||||
request: &crate::DevnetSolanaProgramMetadataExecutionRequest,
|
||||
observer: &O,
|
||||
) -> ks_core::Result<crate::DevnetSolanaProgramMetadataExecutionSummary>
|
||||
where
|
||||
O: crate::SolanaExecutionObserver,
|
||||
{
|
||||
let temporary = match crate::load_profile_temporary_wallet(profile, workspace_root).await {
|
||||
std::result::Result::Ok(value) => value,
|
||||
std::result::Result::Err(error) => return std::result::Result::Err(error),
|
||||
};
|
||||
let wallet = crate::DevnetExecutionWallet::Temporary(temporary);
|
||||
return simulate_devnet_solana_program_metadata_with_wallet(
|
||||
http_pool, profile, &wallet, request, observer,
|
||||
)
|
||||
.await;
|
||||
}
|
||||
|
||||
/// Simulates one stable Solana Program Metadata operation with an explicitly resolved wallet.
|
||||
pub async fn simulate_devnet_solana_program_metadata_with_wallet<O>(
|
||||
http_pool: &ks_onchain_transport::HttpEndpointPool,
|
||||
profile: &ks_config::ProfileConfig,
|
||||
wallet: &crate::DevnetExecutionWallet,
|
||||
request: &crate::DevnetSolanaProgramMetadataExecutionRequest,
|
||||
observer: &O,
|
||||
) -> ks_core::Result<crate::DevnetSolanaProgramMetadataExecutionSummary>
|
||||
where
|
||||
O: crate::SolanaExecutionObserver,
|
||||
{
|
||||
@@ -177,11 +198,10 @@ where
|
||||
"simulate_devnet_solana_program_metadata requires submit=false",
|
||||
));
|
||||
}
|
||||
let prepared =
|
||||
match prepare_execution(http_pool, profile, workspace_root, request, observer).await {
|
||||
std::result::Result::Ok(value) => value,
|
||||
std::result::Result::Err(error) => return std::result::Result::Err(error),
|
||||
};
|
||||
let prepared = match prepare_execution(http_pool, profile, wallet, request, observer).await {
|
||||
std::result::Result::Ok(value) => value,
|
||||
std::result::Result::Err(error) => return std::result::Result::Err(error),
|
||||
};
|
||||
return std::result::Result::Ok(prepared.summary);
|
||||
}
|
||||
|
||||
@@ -196,11 +216,32 @@ pub async fn execute_devnet_solana_program_metadata<O>(
|
||||
where
|
||||
O: crate::SolanaExecutionObserver,
|
||||
{
|
||||
let prepared =
|
||||
match prepare_execution(http_pool, profile, workspace_root, request, observer).await {
|
||||
std::result::Result::Ok(value) => value,
|
||||
std::result::Result::Err(error) => return std::result::Result::Err(error),
|
||||
};
|
||||
let temporary = match crate::load_profile_temporary_wallet(profile, workspace_root).await {
|
||||
std::result::Result::Ok(value) => value,
|
||||
std::result::Result::Err(error) => return std::result::Result::Err(error),
|
||||
};
|
||||
let wallet = crate::DevnetExecutionWallet::Temporary(temporary);
|
||||
return execute_devnet_solana_program_metadata_with_wallet(
|
||||
http_pool, profile, &wallet, request, observer,
|
||||
)
|
||||
.await;
|
||||
}
|
||||
|
||||
/// Executes one Solana Program Metadata operation with an explicitly resolved wallet.
|
||||
pub async fn execute_devnet_solana_program_metadata_with_wallet<O>(
|
||||
http_pool: &ks_onchain_transport::HttpEndpointPool,
|
||||
profile: &ks_config::ProfileConfig,
|
||||
wallet: &crate::DevnetExecutionWallet,
|
||||
request: &crate::DevnetSolanaProgramMetadataExecutionRequest,
|
||||
observer: &O,
|
||||
) -> ks_core::Result<crate::DevnetSolanaProgramMetadataExecutionSummary>
|
||||
where
|
||||
O: crate::SolanaExecutionObserver,
|
||||
{
|
||||
let prepared = match prepare_execution(http_pool, profile, wallet, request, observer).await {
|
||||
std::result::Result::Ok(value) => value,
|
||||
std::result::Result::Err(error) => return std::result::Result::Err(error),
|
||||
};
|
||||
if !request.submit {
|
||||
return std::result::Result::Ok(prepared.summary);
|
||||
}
|
||||
@@ -230,7 +271,7 @@ where
|
||||
}
|
||||
let signed = match prepared
|
||||
.unsigned
|
||||
.sign_after_simulation(&prepared.evidence, &[prepared.wallet.as_signer()])
|
||||
.sign_after_simulation(&prepared.evidence, &[wallet.as_signer()])
|
||||
{
|
||||
std::result::Result::Ok(value) => value,
|
||||
std::result::Result::Err(error) => return std::result::Result::Err(error),
|
||||
@@ -322,7 +363,7 @@ where
|
||||
async fn prepare_execution<O>(
|
||||
http_pool: &ks_onchain_transport::HttpEndpointPool,
|
||||
profile: &ks_config::ProfileConfig,
|
||||
workspace_root: &std::path::Path,
|
||||
wallet: &crate::DevnetExecutionWallet,
|
||||
request: &crate::DevnetSolanaProgramMetadataExecutionRequest,
|
||||
observer: &O,
|
||||
) -> ks_core::Result<PreparedSolanaProgramMetadataExecution>
|
||||
@@ -355,11 +396,7 @@ where
|
||||
),
|
||||
));
|
||||
}
|
||||
let wallet = match crate::load_profile_temporary_wallet(profile, workspace_root).await {
|
||||
std::result::Result::Ok(value) => value,
|
||||
std::result::Result::Err(error) => return std::result::Result::Err(error),
|
||||
};
|
||||
let wallet_summary = wallet.summary();
|
||||
let wallet_summary = wallet.identity();
|
||||
let fee_payer = ks_lib::MdPubkey(wallet_summary.public_key.clone());
|
||||
let balance = match http_pool
|
||||
.get_balance_for_role(
|
||||
@@ -518,7 +555,6 @@ where
|
||||
};
|
||||
let evidence = unsigned.bind_simulation(simulation.clone());
|
||||
return std::result::Result::Ok(PreparedSolanaProgramMetadataExecution {
|
||||
wallet,
|
||||
unsigned,
|
||||
evidence,
|
||||
summary: crate::DevnetSolanaProgramMetadataExecutionSummary {
|
||||
@@ -625,9 +661,11 @@ fn validate_profile(
|
||||
"Solana Program Metadata orchestration requires a Devnet wallet profile",
|
||||
));
|
||||
}
|
||||
if !profile.wallet.temporary_wallet_enabled || !profile.wallet.temporary_wallet_persist {
|
||||
if profile.wallet.wallet_alias.is_none()
|
||||
&& (!profile.wallet.temporary_wallet_enabled || !profile.wallet.temporary_wallet_persist)
|
||||
{
|
||||
return std::result::Result::Err(ks_core::Error::config(
|
||||
"Solana Program Metadata orchestration requires an enabled persistent temporary wallet",
|
||||
"Solana Program Metadata orchestration requires an enabled persistent temporary wallet when no native wallet alias is selected",
|
||||
));
|
||||
}
|
||||
if !profile.execution.require_simulation {
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
// file: ks-pipeline-demo-scenarios/src/metadata/solana_program/fixture.rs
|
||||
// version: 9
|
||||
// version: 10
|
||||
|
||||
//! Native Solana Program Metadata fixture preparation for Devnet journeys.
|
||||
|
||||
@@ -111,6 +111,24 @@ pub async fn prepare_solana_program_metadata_fixture(
|
||||
profile: &ks_config::ProfileConfig,
|
||||
workspace_root: &std::path::Path,
|
||||
options: &crate::SolanaProgramMetadataFixturePreparationOptions,
|
||||
) -> ks_core::Result<crate::SolanaProgramMetadataFixturePreparationSummary> {
|
||||
let temporary = match crate::load_profile_temporary_wallet(profile, workspace_root).await {
|
||||
std::result::Result::Ok(value) => value,
|
||||
std::result::Result::Err(error) => return std::result::Result::Err(error),
|
||||
};
|
||||
let wallet = crate::DevnetExecutionWallet::Temporary(temporary);
|
||||
return prepare_solana_program_metadata_fixture_with_wallet(
|
||||
http_pool, profile, &wallet, options,
|
||||
)
|
||||
.await;
|
||||
}
|
||||
|
||||
/// Creates two unique pre-funded PDAs with an explicitly resolved execution wallet.
|
||||
pub async fn prepare_solana_program_metadata_fixture_with_wallet(
|
||||
http_pool: &ks_onchain_transport::HttpEndpointPool,
|
||||
profile: &ks_config::ProfileConfig,
|
||||
operator: &crate::DevnetExecutionWallet,
|
||||
options: &crate::SolanaProgramMetadataFixturePreparationOptions,
|
||||
) -> ks_core::Result<crate::SolanaProgramMetadataFixturePreparationSummary> {
|
||||
if options.query_role.trim().is_empty() || options.transaction_role.trim().is_empty() {
|
||||
return std::result::Result::Err(ks_core::Error::config(
|
||||
@@ -119,8 +137,9 @@ pub async fn prepare_solana_program_metadata_fixture(
|
||||
}
|
||||
if profile.wallet.cluster != "devnet"
|
||||
|| !profile.execution.devnet_send_enabled
|
||||
|| !profile.wallet.temporary_wallet_enabled
|
||||
|| !profile.wallet.temporary_wallet_persist
|
||||
|| (profile.wallet.wallet_alias.is_none()
|
||||
&& (!profile.wallet.temporary_wallet_enabled
|
||||
|| !profile.wallet.temporary_wallet_persist))
|
||||
{
|
||||
return std::result::Result::Err(ks_core::Error::config(
|
||||
"Solana Program Metadata fixture requires one persistent send-enabled Devnet profile",
|
||||
@@ -143,10 +162,6 @@ pub async fn prepare_solana_program_metadata_fixture(
|
||||
"Solana Program Metadata fixture preparation requires a Devnet endpoint",
|
||||
));
|
||||
}
|
||||
let operator = match crate::load_profile_temporary_wallet(profile, workspace_root).await {
|
||||
std::result::Result::Ok(value) => value,
|
||||
std::result::Result::Err(error) => return std::result::Result::Err(error),
|
||||
};
|
||||
let authority = ks_lib::MdPubkey(operator.public_key());
|
||||
let described_program = ks_lib::MdPubkey(ks_program_ids::SYSTEM_PROGRAM_ID.to_string());
|
||||
let unique = uuid::Uuid::new_v4().simple().to_string();
|
||||
@@ -282,7 +297,7 @@ pub async fn prepare_solana_program_metadata_fixture(
|
||||
http_pool,
|
||||
profile,
|
||||
options,
|
||||
&operator,
|
||||
operator,
|
||||
buffer.clone(),
|
||||
buffer_prefund_lamports,
|
||||
"buffer",
|
||||
@@ -296,7 +311,7 @@ pub async fn prepare_solana_program_metadata_fixture(
|
||||
http_pool,
|
||||
profile,
|
||||
options,
|
||||
&operator,
|
||||
operator,
|
||||
metadata.clone(),
|
||||
metadata_prefund_lamports,
|
||||
"metadata",
|
||||
@@ -680,7 +695,7 @@ async fn submit_prefund_transfer(
|
||||
http_pool: &ks_onchain_transport::HttpEndpointPool,
|
||||
profile: &ks_config::ProfileConfig,
|
||||
options: &crate::SolanaProgramMetadataFixturePreparationOptions,
|
||||
operator: &ks_wallet::TemporaryWallet,
|
||||
operator: &crate::DevnetExecutionWallet,
|
||||
recipient: ks_lib::MdPubkey,
|
||||
lamports: u64,
|
||||
label: &str,
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
// file: ks-pipeline-demo-scenarios/src/solana.rs
|
||||
// version: 17
|
||||
// version: 18
|
||||
|
||||
//! Devnet Solana execution orchestration with canonical post-validation.
|
||||
|
||||
@@ -260,6 +260,43 @@ pub async fn execute_devnet_system_transfer<S, O>(
|
||||
materializers: &[std::sync::Arc<dyn ks_lib::MtApiEventMaterializer>],
|
||||
observer: &O,
|
||||
) -> ks_core::Result<crate::DevnetSystemTransferSummary>
|
||||
where
|
||||
S: ks_store::RawTransactionStore
|
||||
+ ks_store::CoreExtractionStore
|
||||
+ ks_store::DecodePipelineStore
|
||||
+ Sync,
|
||||
O: crate::SolanaExecutionObserver,
|
||||
{
|
||||
let temporary = match load_profile_temporary_wallet(profile, workspace_root).await {
|
||||
std::result::Result::Ok(value) => value,
|
||||
std::result::Result::Err(error) => return std::result::Result::Err(error),
|
||||
};
|
||||
let wallet = crate::DevnetExecutionWallet::Temporary(temporary);
|
||||
return execute_devnet_system_transfer_with_wallet(
|
||||
http_pool,
|
||||
store,
|
||||
profile,
|
||||
&wallet,
|
||||
request,
|
||||
decoders,
|
||||
materializers,
|
||||
observer,
|
||||
)
|
||||
.await;
|
||||
}
|
||||
|
||||
/// Executes a bounded Devnet System transfer with an explicitly resolved wallet capability.
|
||||
#[allow(clippy::too_many_arguments)]
|
||||
pub async fn execute_devnet_system_transfer_with_wallet<S, O>(
|
||||
http_pool: &ks_onchain_transport::HttpEndpointPool,
|
||||
store: &S,
|
||||
profile: &ks_config::ProfileConfig,
|
||||
wallet: &crate::DevnetExecutionWallet,
|
||||
request: &crate::DevnetSystemTransferRequest,
|
||||
decoders: &[std::sync::Arc<dyn ks_lib::DcApiInstructionDecoder>],
|
||||
materializers: &[std::sync::Arc<dyn ks_lib::MtApiEventMaterializer>],
|
||||
observer: &O,
|
||||
) -> ks_core::Result<crate::DevnetSystemTransferSummary>
|
||||
where
|
||||
S: ks_store::RawTransactionStore
|
||||
+ ks_store::CoreExtractionStore
|
||||
@@ -305,11 +342,7 @@ where
|
||||
if let std::result::Result::Err(error) = cancellation_result {
|
||||
return std::result::Result::Err(error);
|
||||
}
|
||||
let wallet = match load_profile_temporary_wallet(profile, workspace_root).await {
|
||||
std::result::Result::Ok(wallet) => wallet,
|
||||
std::result::Result::Err(error) => return std::result::Result::Err(error),
|
||||
};
|
||||
let wallet_summary = wallet.summary();
|
||||
let wallet_summary = wallet.identity();
|
||||
let source_pubkey = ks_lib::MdPubkey(wallet_summary.public_key.clone());
|
||||
if source_pubkey == request.recipient {
|
||||
return std::result::Result::Err(ks_core::Error::config(
|
||||
@@ -945,9 +978,11 @@ fn validate_devnet_profile(
|
||||
profile.name
|
||||
)));
|
||||
}
|
||||
if !profile.wallet.temporary_wallet_enabled || !profile.wallet.temporary_wallet_persist {
|
||||
if profile.wallet.wallet_alias.is_none()
|
||||
&& (!profile.wallet.temporary_wallet_enabled || !profile.wallet.temporary_wallet_persist)
|
||||
{
|
||||
return std::result::Result::Err(ks_core::Error::config(
|
||||
"Devnet execution requires an enabled persistent temporary wallet",
|
||||
"Devnet execution requires an enabled persistent temporary wallet when no native wallet alias is selected",
|
||||
));
|
||||
}
|
||||
if !profile.execution.require_simulation {
|
||||
@@ -983,7 +1018,7 @@ fn validate_devnet_profile(
|
||||
return std::result::Result::Ok(());
|
||||
}
|
||||
|
||||
/// Resolves the wallet directory selected by one profile relative to the workspace root.
|
||||
/// Resolves the persistent native wallet directory selected by one profile.
|
||||
fn profile_wallet_directory(
|
||||
profile: &ks_config::ProfileConfig,
|
||||
workspace_root: &std::path::Path,
|
||||
@@ -995,6 +1030,18 @@ fn profile_wallet_directory(
|
||||
return workspace_root.join(configured);
|
||||
}
|
||||
|
||||
/// Resolves the profile-specific temporary wallet and fixture directory.
|
||||
fn profile_temporary_wallet_directory(
|
||||
profile: &ks_config::ProfileConfig,
|
||||
workspace_root: &std::path::Path,
|
||||
) -> std::path::PathBuf {
|
||||
let configured = std::path::PathBuf::from(profile.wallet.temporary_wallet_dir.as_str());
|
||||
if configured.is_absolute() {
|
||||
return configured;
|
||||
}
|
||||
return workspace_root.join(configured);
|
||||
}
|
||||
|
||||
/// Inspects the persistent native wallet alias selected by one profile, when configured.
|
||||
pub async fn inspect_selected_profile_wallet(
|
||||
profile: &ks_config::ProfileConfig,
|
||||
@@ -1065,7 +1112,7 @@ pub(crate) async fn load_profile_temporary_wallet(
|
||||
"profile selects a persistent native wallet; temporary-wallet fallback is forbidden",
|
||||
));
|
||||
}
|
||||
let store = match ks_wallet::TemporaryWalletStore::new(profile_wallet_directory(
|
||||
let store = match ks_wallet::TemporaryWalletStore::new(profile_temporary_wallet_directory(
|
||||
profile,
|
||||
workspace_root,
|
||||
)) {
|
||||
@@ -1500,7 +1547,7 @@ mod tests {
|
||||
profile.database.backend = "postgres".to_string();
|
||||
profile.database.postgres.url = database_url;
|
||||
if let std::result::Result::Ok(directory) = std::env::var("KS_DEVNET_WALLET_DIR") {
|
||||
profile.wallet.wallet_dir = directory;
|
||||
profile.wallet.temporary_wallet_dir = directory;
|
||||
}
|
||||
let pool = match ks_onchain_transport::HttpEndpointPool::from_profile(&profile) {
|
||||
std::result::Result::Ok(value) => value,
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
// file: ks-pipeline-demo-scenarios/src/spl/associated_token_account.rs
|
||||
// version: 16
|
||||
// version: 17
|
||||
|
||||
//! Devnet ATA execution with stateful and canonical post-validation.
|
||||
|
||||
@@ -108,7 +108,6 @@ pub struct DevnetSplAssociatedTokenAccountExecutionSummary {
|
||||
}
|
||||
|
||||
struct PreparedAtaExecution {
|
||||
wallet: ks_wallet::TemporaryWallet,
|
||||
unsigned: ks_lib::ExSolanaUnsignedTransaction,
|
||||
evidence: ks_lib::ExSolanaSimulationEvidence,
|
||||
summary: DevnetSplAssociatedTokenAccountExecutionSummary,
|
||||
@@ -130,11 +129,15 @@ where
|
||||
"simulate_devnet_spl_associated_token_account requires submit=false",
|
||||
));
|
||||
}
|
||||
let prepared =
|
||||
match prepare_execution(http_pool, profile, workspace_root, request, observer).await {
|
||||
std::result::Result::Ok(value) => value,
|
||||
std::result::Result::Err(error) => return std::result::Result::Err(error),
|
||||
};
|
||||
let temporary = match crate::load_profile_temporary_wallet(profile, workspace_root).await {
|
||||
std::result::Result::Ok(value) => value,
|
||||
std::result::Result::Err(error) => return std::result::Result::Err(error),
|
||||
};
|
||||
let wallet = crate::DevnetExecutionWallet::Temporary(temporary);
|
||||
let prepared = match prepare_execution(http_pool, profile, &wallet, request, observer).await {
|
||||
std::result::Result::Ok(value) => value,
|
||||
std::result::Result::Err(error) => return std::result::Result::Err(error),
|
||||
};
|
||||
return std::result::Result::Ok(prepared.summary);
|
||||
}
|
||||
|
||||
@@ -157,11 +160,47 @@ where
|
||||
+ Sync,
|
||||
O: crate::SolanaExecutionObserver,
|
||||
{
|
||||
let prepared =
|
||||
match prepare_execution(http_pool, profile, workspace_root, request, observer).await {
|
||||
std::result::Result::Ok(value) => value,
|
||||
std::result::Result::Err(error) => return std::result::Result::Err(error),
|
||||
};
|
||||
let temporary = match crate::load_profile_temporary_wallet(profile, workspace_root).await {
|
||||
std::result::Result::Ok(value) => value,
|
||||
std::result::Result::Err(error) => return std::result::Result::Err(error),
|
||||
};
|
||||
let wallet = crate::DevnetExecutionWallet::Temporary(temporary);
|
||||
return execute_devnet_spl_associated_token_account_with_wallet(
|
||||
http_pool,
|
||||
store,
|
||||
profile,
|
||||
&wallet,
|
||||
request,
|
||||
decoders,
|
||||
materializers,
|
||||
observer,
|
||||
)
|
||||
.await;
|
||||
}
|
||||
|
||||
/// Executes this Devnet operation with an explicitly resolved wallet capability.
|
||||
#[allow(clippy::too_many_arguments)]
|
||||
pub async fn execute_devnet_spl_associated_token_account_with_wallet<S, O>(
|
||||
http_pool: &ks_onchain_transport::HttpEndpointPool,
|
||||
store: &S,
|
||||
profile: &ks_config::ProfileConfig,
|
||||
wallet: &crate::DevnetExecutionWallet,
|
||||
request: &DevnetSplAssociatedTokenAccountExecutionRequest,
|
||||
decoders: &[std::sync::Arc<dyn ks_lib::DcApiInstructionDecoder>],
|
||||
materializers: &[std::sync::Arc<dyn ks_lib::MtApiEventMaterializer>],
|
||||
observer: &O,
|
||||
) -> ks_core::Result<DevnetSplAssociatedTokenAccountExecutionSummary>
|
||||
where
|
||||
S: ks_store::RawTransactionStore
|
||||
+ ks_store::CoreExtractionStore
|
||||
+ ks_store::DecodePipelineStore
|
||||
+ Sync,
|
||||
O: crate::SolanaExecutionObserver,
|
||||
{
|
||||
let prepared = match prepare_execution(http_pool, profile, wallet, request, observer).await {
|
||||
std::result::Result::Ok(value) => value,
|
||||
std::result::Result::Err(error) => return std::result::Result::Err(error),
|
||||
};
|
||||
if !request.submit {
|
||||
return std::result::Result::Ok(prepared.summary);
|
||||
}
|
||||
@@ -191,7 +230,7 @@ where
|
||||
}
|
||||
let signed = match prepared
|
||||
.unsigned
|
||||
.sign_after_simulation(&prepared.evidence, &[prepared.wallet.as_signer()])
|
||||
.sign_after_simulation(&prepared.evidence, &[wallet.as_signer()])
|
||||
{
|
||||
std::result::Result::Ok(value) => value,
|
||||
std::result::Result::Err(error) => return std::result::Result::Err(error),
|
||||
@@ -460,7 +499,7 @@ where
|
||||
async fn prepare_execution<O>(
|
||||
http_pool: &ks_onchain_transport::HttpEndpointPool,
|
||||
profile: &ks_config::ProfileConfig,
|
||||
workspace_root: &std::path::Path,
|
||||
wallet: &crate::DevnetExecutionWallet,
|
||||
request: &DevnetSplAssociatedTokenAccountExecutionRequest,
|
||||
observer: &O,
|
||||
) -> ks_core::Result<PreparedAtaExecution>
|
||||
@@ -491,11 +530,7 @@ where
|
||||
),
|
||||
));
|
||||
}
|
||||
let wallet = match crate::load_profile_temporary_wallet(profile, workspace_root).await {
|
||||
std::result::Result::Ok(value) => value,
|
||||
std::result::Result::Err(error) => return std::result::Result::Err(error),
|
||||
};
|
||||
let wallet_summary = wallet.summary();
|
||||
let wallet_summary = wallet.identity();
|
||||
let fee_payer = ks_lib::MdPubkey(wallet_summary.public_key.clone());
|
||||
let balance = match http_pool
|
||||
.get_balance_for_role(
|
||||
@@ -664,7 +699,7 @@ where
|
||||
materializations: std::vec::Vec::new(),
|
||||
post_execution: std::option::Option::None,
|
||||
};
|
||||
return std::result::Result::Ok(PreparedAtaExecution { wallet, unsigned, evidence, summary });
|
||||
return std::result::Result::Ok(PreparedAtaExecution { unsigned, evidence, summary });
|
||||
}
|
||||
|
||||
fn validate_profile(
|
||||
@@ -676,9 +711,11 @@ fn validate_profile(
|
||||
"SPL Associated Token Account Devnet orchestration requires a Devnet wallet profile",
|
||||
));
|
||||
}
|
||||
if !profile.wallet.temporary_wallet_enabled || !profile.wallet.temporary_wallet_persist {
|
||||
if profile.wallet.wallet_alias.is_none()
|
||||
&& (!profile.wallet.temporary_wallet_enabled || !profile.wallet.temporary_wallet_persist)
|
||||
{
|
||||
return std::result::Result::Err(ks_core::Error::config(
|
||||
"SPL Associated Token Account Devnet orchestration requires an enabled persistent temporary wallet",
|
||||
"SPL Associated Token Account Devnet orchestration requires an enabled persistent temporary wallet when no native wallet alias is selected",
|
||||
));
|
||||
}
|
||||
if !profile.execution.require_simulation {
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
// file: ks-pipeline-demo-scenarios/src/spl/memo.rs
|
||||
// version: 12
|
||||
// version: 13
|
||||
|
||||
//! Devnet SPL Memo v4 execution with canonical post-validation.
|
||||
|
||||
@@ -124,6 +124,43 @@ pub async fn execute_devnet_memo<S, O>(
|
||||
materializers: &[std::sync::Arc<dyn ks_lib::MtApiEventMaterializer>],
|
||||
observer: &O,
|
||||
) -> ks_core::Result<crate::DevnetMemoExecutionSummary>
|
||||
where
|
||||
S: ks_store::RawTransactionStore
|
||||
+ ks_store::CoreExtractionStore
|
||||
+ ks_store::DecodePipelineStore
|
||||
+ Sync,
|
||||
O: crate::SolanaExecutionObserver,
|
||||
{
|
||||
let temporary = match crate::load_profile_temporary_wallet(profile, workspace_root).await {
|
||||
std::result::Result::Ok(value) => value,
|
||||
std::result::Result::Err(error) => return std::result::Result::Err(error),
|
||||
};
|
||||
let wallet = crate::DevnetExecutionWallet::Temporary(temporary);
|
||||
return execute_devnet_memo_with_wallet(
|
||||
http_pool,
|
||||
store,
|
||||
profile,
|
||||
&wallet,
|
||||
request,
|
||||
decoders,
|
||||
materializers,
|
||||
observer,
|
||||
)
|
||||
.await;
|
||||
}
|
||||
|
||||
/// Executes one Devnet Memo operation with an explicitly resolved wallet capability.
|
||||
#[allow(clippy::too_many_arguments)]
|
||||
pub async fn execute_devnet_memo_with_wallet<S, O>(
|
||||
http_pool: &ks_onchain_transport::HttpEndpointPool,
|
||||
store: &S,
|
||||
profile: &ks_config::ProfileConfig,
|
||||
wallet: &crate::DevnetExecutionWallet,
|
||||
request: &crate::DevnetMemoExecutionRequest,
|
||||
decoders: &[std::sync::Arc<dyn ks_lib::DcApiInstructionDecoder>],
|
||||
materializers: &[std::sync::Arc<dyn ks_lib::MtApiEventMaterializer>],
|
||||
observer: &O,
|
||||
) -> ks_core::Result<crate::DevnetMemoExecutionSummary>
|
||||
where
|
||||
S: ks_store::RawTransactionStore
|
||||
+ ks_store::CoreExtractionStore
|
||||
@@ -155,11 +192,7 @@ where
|
||||
),
|
||||
));
|
||||
}
|
||||
let wallet = match crate::load_profile_temporary_wallet(profile, workspace_root).await {
|
||||
std::result::Result::Ok(value) => value,
|
||||
std::result::Result::Err(error) => return std::result::Result::Err(error),
|
||||
};
|
||||
let wallet_summary = wallet.summary();
|
||||
let wallet_summary = wallet.identity();
|
||||
let fee_payer = ks_lib::MdPubkey(wallet_summary.public_key.clone());
|
||||
let balance = match http_pool
|
||||
.get_balance_for_role(
|
||||
@@ -534,9 +567,11 @@ fn validate_profile(
|
||||
"Memo Devnet orchestration requires a Devnet wallet profile",
|
||||
));
|
||||
}
|
||||
if !profile.wallet.temporary_wallet_enabled || !profile.wallet.temporary_wallet_persist {
|
||||
if profile.wallet.wallet_alias.is_none()
|
||||
&& (!profile.wallet.temporary_wallet_enabled || !profile.wallet.temporary_wallet_persist)
|
||||
{
|
||||
return std::result::Result::Err(ks_core::Error::config(
|
||||
"Memo Devnet orchestration requires an enabled persistent temporary wallet",
|
||||
"Memo Devnet orchestration requires an enabled persistent temporary wallet when no native wallet alias is selected",
|
||||
));
|
||||
}
|
||||
if !profile.execution.require_simulation {
|
||||
@@ -825,7 +860,7 @@ mod tests {
|
||||
profile.database.backend = "postgres".to_string();
|
||||
profile.database.postgres.url = database_url;
|
||||
if let std::result::Result::Ok(directory) = std::env::var("KS_DEVNET_WALLET_DIR") {
|
||||
profile.wallet.wallet_dir = directory;
|
||||
profile.wallet.temporary_wallet_dir = directory;
|
||||
}
|
||||
let pool = match ks_onchain_transport::HttpEndpointPool::from_profile(&profile) {
|
||||
std::result::Result::Ok(value) => value,
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
// file: ks-pipeline-demo-scenarios/src/spl/token/execution.rs
|
||||
// version: 16
|
||||
// version: 17
|
||||
|
||||
//! Devnet classic SPL Token execution with stateful and canonical post-validation.
|
||||
|
||||
@@ -105,7 +105,6 @@ pub struct DevnetSplTokenExecutionSummary {
|
||||
}
|
||||
|
||||
struct PreparedTokenExecution {
|
||||
wallet: ks_wallet::TemporaryWallet,
|
||||
unsigned: ks_lib::ExSolanaUnsignedTransaction,
|
||||
evidence: ks_lib::ExSolanaSimulationEvidence,
|
||||
summary: crate::DevnetSplTokenExecutionSummary,
|
||||
@@ -127,11 +126,15 @@ where
|
||||
"simulate_devnet_spl_token requires submit=false",
|
||||
));
|
||||
}
|
||||
let prepared =
|
||||
match prepare_execution(http_pool, profile, workspace_root, request, observer).await {
|
||||
std::result::Result::Ok(value) => value,
|
||||
std::result::Result::Err(error) => return std::result::Result::Err(error),
|
||||
};
|
||||
let temporary = match crate::load_profile_temporary_wallet(profile, workspace_root).await {
|
||||
std::result::Result::Ok(value) => value,
|
||||
std::result::Result::Err(error) => return std::result::Result::Err(error),
|
||||
};
|
||||
let wallet = crate::DevnetExecutionWallet::Temporary(temporary);
|
||||
let prepared = match prepare_execution(http_pool, profile, &wallet, request, observer).await {
|
||||
std::result::Result::Ok(value) => value,
|
||||
std::result::Result::Err(error) => return std::result::Result::Err(error),
|
||||
};
|
||||
return std::result::Result::Ok(prepared.summary);
|
||||
}
|
||||
|
||||
@@ -154,11 +157,47 @@ where
|
||||
+ Sync,
|
||||
O: crate::SolanaExecutionObserver,
|
||||
{
|
||||
let prepared =
|
||||
match prepare_execution(http_pool, profile, workspace_root, request, observer).await {
|
||||
std::result::Result::Ok(value) => value,
|
||||
std::result::Result::Err(error) => return std::result::Result::Err(error),
|
||||
};
|
||||
let temporary = match crate::load_profile_temporary_wallet(profile, workspace_root).await {
|
||||
std::result::Result::Ok(value) => value,
|
||||
std::result::Result::Err(error) => return std::result::Result::Err(error),
|
||||
};
|
||||
let wallet = crate::DevnetExecutionWallet::Temporary(temporary);
|
||||
return execute_devnet_spl_token_with_wallet(
|
||||
http_pool,
|
||||
store,
|
||||
profile,
|
||||
&wallet,
|
||||
request,
|
||||
decoders,
|
||||
materializers,
|
||||
observer,
|
||||
)
|
||||
.await;
|
||||
}
|
||||
|
||||
/// Executes this Devnet operation with an explicitly resolved wallet capability.
|
||||
#[allow(clippy::too_many_arguments)]
|
||||
pub async fn execute_devnet_spl_token_with_wallet<S, O>(
|
||||
http_pool: &ks_onchain_transport::HttpEndpointPool,
|
||||
store: &S,
|
||||
profile: &ks_config::ProfileConfig,
|
||||
wallet: &crate::DevnetExecutionWallet,
|
||||
request: &crate::DevnetSplTokenExecutionRequest,
|
||||
decoders: &[std::sync::Arc<dyn ks_lib::DcApiInstructionDecoder>],
|
||||
materializers: &[std::sync::Arc<dyn ks_lib::MtApiEventMaterializer>],
|
||||
observer: &O,
|
||||
) -> ks_core::Result<crate::DevnetSplTokenExecutionSummary>
|
||||
where
|
||||
S: ks_store::RawTransactionStore
|
||||
+ ks_store::CoreExtractionStore
|
||||
+ ks_store::DecodePipelineStore
|
||||
+ Sync,
|
||||
O: crate::SolanaExecutionObserver,
|
||||
{
|
||||
let prepared = match prepare_execution(http_pool, profile, wallet, request, observer).await {
|
||||
std::result::Result::Ok(value) => value,
|
||||
std::result::Result::Err(error) => return std::result::Result::Err(error),
|
||||
};
|
||||
if !request.submit {
|
||||
return std::result::Result::Ok(prepared.summary);
|
||||
}
|
||||
@@ -188,7 +227,7 @@ where
|
||||
}
|
||||
let signed = match prepared
|
||||
.unsigned
|
||||
.sign_after_simulation(&prepared.evidence, &[prepared.wallet.as_signer()])
|
||||
.sign_after_simulation(&prepared.evidence, &[wallet.as_signer()])
|
||||
{
|
||||
std::result::Result::Ok(value) => value,
|
||||
std::result::Result::Err(error) => return std::result::Result::Err(error),
|
||||
@@ -428,7 +467,7 @@ where
|
||||
async fn prepare_execution<O>(
|
||||
http_pool: &ks_onchain_transport::HttpEndpointPool,
|
||||
profile: &ks_config::ProfileConfig,
|
||||
workspace_root: &std::path::Path,
|
||||
wallet: &crate::DevnetExecutionWallet,
|
||||
request: &crate::DevnetSplTokenExecutionRequest,
|
||||
observer: &O,
|
||||
) -> ks_core::Result<PreparedTokenExecution>
|
||||
@@ -479,11 +518,7 @@ where
|
||||
failed_readiness_message(&readiness),
|
||||
));
|
||||
}
|
||||
let wallet = match crate::load_profile_temporary_wallet(profile, workspace_root).await {
|
||||
std::result::Result::Ok(value) => value,
|
||||
std::result::Result::Err(error) => return std::result::Result::Err(error),
|
||||
};
|
||||
let wallet_summary = wallet.summary();
|
||||
let wallet_summary = wallet.identity();
|
||||
let fee_payer = ks_lib::MdPubkey(wallet_summary.public_key.clone());
|
||||
let balance = match http_pool
|
||||
.get_balance_for_role(
|
||||
@@ -620,7 +655,7 @@ where
|
||||
materializations: std::vec::Vec::new(),
|
||||
post_execution: std::option::Option::None,
|
||||
};
|
||||
return std::result::Result::Ok(PreparedTokenExecution { wallet, unsigned, evidence, summary });
|
||||
return std::result::Result::Ok(PreparedTokenExecution { unsigned, evidence, summary });
|
||||
}
|
||||
|
||||
fn validate_profile(
|
||||
@@ -632,9 +667,11 @@ fn validate_profile(
|
||||
"SPL Token Devnet orchestration requires a Devnet wallet profile",
|
||||
));
|
||||
}
|
||||
if !profile.wallet.temporary_wallet_enabled || !profile.wallet.temporary_wallet_persist {
|
||||
if profile.wallet.wallet_alias.is_none()
|
||||
&& (!profile.wallet.temporary_wallet_enabled || !profile.wallet.temporary_wallet_persist)
|
||||
{
|
||||
return std::result::Result::Err(ks_core::Error::config(
|
||||
"SPL Token Devnet orchestration requires an enabled persistent temporary wallet",
|
||||
"SPL Token Devnet orchestration requires an enabled persistent temporary wallet when no native wallet alias is selected",
|
||||
));
|
||||
}
|
||||
if !profile.execution.require_simulation {
|
||||
@@ -1093,7 +1130,7 @@ mod tests {
|
||||
};
|
||||
let mut profile = example_devnet_profile();
|
||||
if let std::result::Result::Ok(directory) = std::env::var("KS_DEVNET_WALLET_DIR") {
|
||||
profile.wallet.wallet_dir = directory;
|
||||
profile.wallet.temporary_wallet_dir = directory;
|
||||
}
|
||||
let pool = match ks_onchain_transport::HttpEndpointPool::from_profile(&profile) {
|
||||
std::result::Result::Ok(value) => value,
|
||||
@@ -1263,7 +1300,7 @@ mod tests {
|
||||
};
|
||||
let mut profile = example_devnet_profile();
|
||||
if let std::result::Result::Ok(directory) = std::env::var("KS_DEVNET_WALLET_DIR") {
|
||||
profile.wallet.wallet_dir = directory;
|
||||
profile.wallet.temporary_wallet_dir = directory;
|
||||
}
|
||||
let pool = match ks_onchain_transport::HttpEndpointPool::from_profile(&profile) {
|
||||
std::result::Result::Ok(value) => value,
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
// file: ks-pipeline-demo-scenarios/src/spl/token/lifecycle.rs
|
||||
// version: 15
|
||||
// version: 16
|
||||
|
||||
//! Controlled Devnet lifecycle for freshly prepared classic SPL Token accounts.
|
||||
|
||||
@@ -1512,7 +1512,7 @@ mod tests {
|
||||
}
|
||||
let mut profile = example_devnet_profile();
|
||||
if let std::result::Result::Ok(directory) = std::env::var("KS_DEVNET_WALLET_DIR") {
|
||||
profile.wallet.wallet_dir = directory;
|
||||
profile.wallet.temporary_wallet_dir = directory;
|
||||
}
|
||||
let database_url = match std::env::var("KS_SECRET_POSTGRES_TEST_URL") {
|
||||
std::result::Result::Ok(value) => value,
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
// file: ks-pipeline-demo-scenarios/src/spl/token_2022/devnet_execution.rs
|
||||
// version: 10
|
||||
// version: 12
|
||||
|
||||
//! Devnet Token-2022 execution with stateful and canonical post-validation.
|
||||
|
||||
@@ -105,7 +105,6 @@ pub struct DevnetSplToken2022ExecutionSummary {
|
||||
}
|
||||
|
||||
struct PreparedToken2022Execution {
|
||||
wallet: ks_wallet::TemporaryWallet,
|
||||
unsigned: ks_lib::ExSolanaUnsignedTransaction,
|
||||
evidence: ks_lib::ExSolanaSimulationEvidence,
|
||||
summary: crate::DevnetSplToken2022ExecutionSummary,
|
||||
@@ -127,11 +126,15 @@ where
|
||||
"simulate_devnet_spl_token_2022 requires submit=false",
|
||||
));
|
||||
}
|
||||
let prepared =
|
||||
match prepare_execution(http_pool, profile, workspace_root, request, observer).await {
|
||||
std::result::Result::Ok(value) => value,
|
||||
std::result::Result::Err(error) => return std::result::Result::Err(error),
|
||||
};
|
||||
let temporary = match crate::load_profile_temporary_wallet(profile, workspace_root).await {
|
||||
std::result::Result::Ok(value) => value,
|
||||
std::result::Result::Err(error) => return std::result::Result::Err(error),
|
||||
};
|
||||
let wallet = crate::DevnetExecutionWallet::Temporary(temporary);
|
||||
let prepared = match prepare_execution(http_pool, profile, &wallet, request, observer).await {
|
||||
std::result::Result::Ok(value) => value,
|
||||
std::result::Result::Err(error) => return std::result::Result::Err(error),
|
||||
};
|
||||
return std::result::Result::Ok(prepared.summary);
|
||||
}
|
||||
|
||||
@@ -154,11 +157,47 @@ where
|
||||
+ Sync,
|
||||
O: crate::SolanaExecutionObserver,
|
||||
{
|
||||
let prepared =
|
||||
match prepare_execution(http_pool, profile, workspace_root, request, observer).await {
|
||||
std::result::Result::Ok(value) => value,
|
||||
std::result::Result::Err(error) => return std::result::Result::Err(error),
|
||||
};
|
||||
let temporary = match crate::load_profile_temporary_wallet(profile, workspace_root).await {
|
||||
std::result::Result::Ok(value) => value,
|
||||
std::result::Result::Err(error) => return std::result::Result::Err(error),
|
||||
};
|
||||
let wallet = crate::DevnetExecutionWallet::Temporary(temporary);
|
||||
return execute_devnet_spl_token_2022_with_wallet(
|
||||
http_pool,
|
||||
store,
|
||||
profile,
|
||||
&wallet,
|
||||
request,
|
||||
decoders,
|
||||
materializers,
|
||||
observer,
|
||||
)
|
||||
.await;
|
||||
}
|
||||
|
||||
/// Executes this Devnet operation with an explicitly resolved wallet capability.
|
||||
#[allow(clippy::too_many_arguments)]
|
||||
pub async fn execute_devnet_spl_token_2022_with_wallet<S, O>(
|
||||
http_pool: &ks_onchain_transport::HttpEndpointPool,
|
||||
store: &S,
|
||||
profile: &ks_config::ProfileConfig,
|
||||
wallet: &crate::DevnetExecutionWallet,
|
||||
request: &crate::DevnetSplToken2022ExecutionRequest,
|
||||
decoders: &[std::sync::Arc<dyn ks_lib::DcApiInstructionDecoder>],
|
||||
materializers: &[std::sync::Arc<dyn ks_lib::MtApiEventMaterializer>],
|
||||
observer: &O,
|
||||
) -> ks_core::Result<crate::DevnetSplToken2022ExecutionSummary>
|
||||
where
|
||||
S: ks_store::RawTransactionStore
|
||||
+ ks_store::CoreExtractionStore
|
||||
+ ks_store::DecodePipelineStore
|
||||
+ Sync,
|
||||
O: crate::SolanaExecutionObserver,
|
||||
{
|
||||
let prepared = match prepare_execution(http_pool, profile, wallet, request, observer).await {
|
||||
std::result::Result::Ok(value) => value,
|
||||
std::result::Result::Err(error) => return std::result::Result::Err(error),
|
||||
};
|
||||
if !request.submit {
|
||||
return std::result::Result::Ok(prepared.summary);
|
||||
}
|
||||
@@ -188,7 +227,7 @@ where
|
||||
}
|
||||
let signed = match prepared
|
||||
.unsigned
|
||||
.sign_after_simulation(&prepared.evidence, &[prepared.wallet.as_signer()])
|
||||
.sign_after_simulation(&prepared.evidence, &[wallet.as_signer()])
|
||||
{
|
||||
std::result::Result::Ok(value) => value,
|
||||
std::result::Result::Err(error) => return std::result::Result::Err(error),
|
||||
@@ -428,7 +467,7 @@ where
|
||||
async fn prepare_execution<O>(
|
||||
http_pool: &ks_onchain_transport::HttpEndpointPool,
|
||||
profile: &ks_config::ProfileConfig,
|
||||
workspace_root: &std::path::Path,
|
||||
wallet: &crate::DevnetExecutionWallet,
|
||||
request: &crate::DevnetSplToken2022ExecutionRequest,
|
||||
observer: &O,
|
||||
) -> ks_core::Result<PreparedToken2022Execution>
|
||||
@@ -469,11 +508,7 @@ where
|
||||
std::result::Result::Ok(value) => value,
|
||||
std::result::Result::Err(error) => return std::result::Result::Err(error),
|
||||
};
|
||||
let wallet = match crate::load_profile_temporary_wallet(profile, workspace_root).await {
|
||||
std::result::Result::Ok(value) => value,
|
||||
std::result::Result::Err(error) => return std::result::Result::Err(error),
|
||||
};
|
||||
let wallet_summary = wallet.summary();
|
||||
let wallet_summary = wallet.identity();
|
||||
let fee_payer = ks_lib::MdPubkey(wallet_summary.public_key.clone());
|
||||
let balance = match http_pool
|
||||
.get_balance_for_role(
|
||||
@@ -610,12 +645,7 @@ where
|
||||
materializations: std::vec::Vec::new(),
|
||||
post_execution: std::option::Option::None,
|
||||
};
|
||||
return std::result::Result::Ok(PreparedToken2022Execution {
|
||||
wallet,
|
||||
unsigned,
|
||||
evidence,
|
||||
summary,
|
||||
});
|
||||
return std::result::Result::Ok(PreparedToken2022Execution { unsigned, evidence, summary });
|
||||
}
|
||||
|
||||
fn preflight_request(
|
||||
@@ -872,9 +902,11 @@ fn validate_profile(
|
||||
"Token-2022 Devnet orchestration requires a Devnet wallet profile",
|
||||
));
|
||||
}
|
||||
if !profile.wallet.temporary_wallet_enabled || !profile.wallet.temporary_wallet_persist {
|
||||
if profile.wallet.wallet_alias.is_none()
|
||||
&& (!profile.wallet.temporary_wallet_enabled || !profile.wallet.temporary_wallet_persist)
|
||||
{
|
||||
return std::result::Result::Err(ks_core::Error::config(
|
||||
"Token-2022 Devnet orchestration requires an enabled persistent temporary wallet",
|
||||
"Token-2022 Devnet orchestration requires an enabled persistent temporary wallet when no native wallet alias is selected",
|
||||
));
|
||||
}
|
||||
if !profile.execution.require_simulation {
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
// file: ks-pipeline-demo-scenarios/src/spl/token_2022/metadata/campaign.rs
|
||||
// version: 9
|
||||
// version: 10
|
||||
|
||||
//! Ordered confirmed Devnet campaign for the five Token-2022 Token Metadata instructions.
|
||||
|
||||
@@ -50,6 +50,34 @@ pub async fn execute_devnet_token_2022_metadata_campaign<S, O>(
|
||||
options: &crate::Token2022MetadataFixturePreparationOptions,
|
||||
observer: &O,
|
||||
) -> ks_core::Result<crate::DevnetToken2022MetadataCampaignSummary>
|
||||
where
|
||||
S: ks_store::RawTransactionStore
|
||||
+ ks_store::CoreExtractionStore
|
||||
+ ks_store::DecodePipelineStore
|
||||
+ Sync,
|
||||
O: crate::SolanaExecutionObserver,
|
||||
{
|
||||
let temporary = match crate::load_profile_temporary_wallet(profile, workspace_root).await {
|
||||
std::result::Result::Ok(value) => value,
|
||||
std::result::Result::Err(error) => return std::result::Result::Err(error),
|
||||
};
|
||||
let wallet = crate::DevnetExecutionWallet::Temporary(temporary);
|
||||
return execute_devnet_token_2022_metadata_campaign_with_wallet(
|
||||
http_pool, store, profile, &wallet, options, observer,
|
||||
)
|
||||
.await;
|
||||
}
|
||||
|
||||
/// Executes the Token-2022 metadata campaign with an explicitly resolved wallet.
|
||||
#[allow(clippy::too_many_arguments)]
|
||||
pub async fn execute_devnet_token_2022_metadata_campaign_with_wallet<S, O>(
|
||||
http_pool: &ks_onchain_transport::HttpEndpointPool,
|
||||
store: &S,
|
||||
profile: &ks_config::ProfileConfig,
|
||||
wallet: &crate::DevnetExecutionWallet,
|
||||
options: &crate::Token2022MetadataFixturePreparationOptions,
|
||||
observer: &O,
|
||||
) -> ks_core::Result<crate::DevnetToken2022MetadataCampaignSummary>
|
||||
where
|
||||
S: ks_store::RawTransactionStore
|
||||
+ ks_store::CoreExtractionStore
|
||||
@@ -62,11 +90,8 @@ where
|
||||
"Token-2022 Token Metadata Devnet campaign requires explicit operator confirmation",
|
||||
));
|
||||
}
|
||||
let fixture = match crate::prepare_token_2022_metadata_fixture(
|
||||
http_pool,
|
||||
profile,
|
||||
workspace_root,
|
||||
options,
|
||||
let fixture = match crate::prepare_token_2022_metadata_fixture_with_wallet(
|
||||
http_pool, profile, wallet, options,
|
||||
)
|
||||
.await
|
||||
{
|
||||
@@ -90,11 +115,11 @@ where
|
||||
request.submit = true;
|
||||
request.operator_confirmed = true;
|
||||
request.post_validation_max_retries = 20;
|
||||
let execution = match crate::execute_devnet_spl_token_2022(
|
||||
let execution = match crate::execute_devnet_spl_token_2022_with_wallet(
|
||||
http_pool,
|
||||
store,
|
||||
profile,
|
||||
workspace_root,
|
||||
wallet,
|
||||
&request,
|
||||
decoders.as_slice(),
|
||||
materializers.as_slice(),
|
||||
@@ -521,7 +546,8 @@ mod tests {
|
||||
if let std::result::Result::Err(error) = store.initialize_store_schema().await {
|
||||
panic!("PostgreSQL schema initialization failed: {error}");
|
||||
}
|
||||
let configured_wallet_dir = std::path::PathBuf::from(profile.wallet.wallet_dir.as_str());
|
||||
let configured_wallet_dir =
|
||||
std::path::PathBuf::from(profile.wallet.temporary_wallet_dir.as_str());
|
||||
let wallet_dir = if configured_wallet_dir.is_absolute() {
|
||||
configured_wallet_dir
|
||||
} else {
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
// file: ks-pipeline-demo-scenarios/src/spl/token_2022/metadata/fixture.rs
|
||||
// version: 6
|
||||
// version: 7
|
||||
|
||||
//! Native Token-2022 mint preparation for the embedded Token Metadata Devnet campaign.
|
||||
|
||||
@@ -77,6 +77,22 @@ pub async fn prepare_token_2022_metadata_fixture(
|
||||
profile: &ks_config::ProfileConfig,
|
||||
workspace_root: &std::path::Path,
|
||||
options: &crate::Token2022MetadataFixturePreparationOptions,
|
||||
) -> ks_core::Result<crate::Token2022MetadataFixturePreparationSummary> {
|
||||
let temporary = match crate::load_profile_temporary_wallet(profile, workspace_root).await {
|
||||
std::result::Result::Ok(value) => value,
|
||||
std::result::Result::Err(error) => return std::result::Result::Err(error),
|
||||
};
|
||||
let wallet = crate::DevnetExecutionWallet::Temporary(temporary);
|
||||
return prepare_token_2022_metadata_fixture_with_wallet(http_pool, profile, &wallet, options)
|
||||
.await;
|
||||
}
|
||||
|
||||
/// Creates a fresh Token-2022 metadata fixture with an explicitly resolved execution wallet.
|
||||
pub async fn prepare_token_2022_metadata_fixture_with_wallet(
|
||||
http_pool: &ks_onchain_transport::HttpEndpointPool,
|
||||
profile: &ks_config::ProfileConfig,
|
||||
operator: &crate::DevnetExecutionWallet,
|
||||
options: &crate::Token2022MetadataFixturePreparationOptions,
|
||||
) -> ks_core::Result<crate::Token2022MetadataFixturePreparationSummary> {
|
||||
if options.query_role.trim().is_empty() || options.transaction_role.trim().is_empty() {
|
||||
return std::result::Result::Err(ks_core::Error::config(
|
||||
@@ -84,8 +100,9 @@ pub async fn prepare_token_2022_metadata_fixture(
|
||||
));
|
||||
}
|
||||
if profile.wallet.cluster != "devnet"
|
||||
|| !profile.wallet.temporary_wallet_enabled
|
||||
|| !profile.wallet.temporary_wallet_persist
|
||||
|| (profile.wallet.wallet_alias.is_none()
|
||||
&& (!profile.wallet.temporary_wallet_enabled
|
||||
|| !profile.wallet.temporary_wallet_persist))
|
||||
{
|
||||
return std::result::Result::Err(ks_core::Error::config(
|
||||
"Token-2022 metadata fixture requires a persistent Devnet wallet profile",
|
||||
@@ -96,10 +113,6 @@ pub async fn prepare_token_2022_metadata_fixture(
|
||||
"Token-2022 metadata fixture requires enabled Devnet submission and explicit operator confirmation",
|
||||
));
|
||||
}
|
||||
let operator = match crate::load_profile_temporary_wallet(profile, workspace_root).await {
|
||||
std::result::Result::Ok(value) => value,
|
||||
std::result::Result::Err(error) => return std::result::Result::Err(error),
|
||||
};
|
||||
let fixture_store = match ks_wallet::TemporaryWalletStore::new(
|
||||
options.wallet_dir.join("token_2022_metadata_validation"),
|
||||
) {
|
||||
@@ -147,7 +160,7 @@ pub async fn prepare_token_2022_metadata_fixture(
|
||||
http_pool,
|
||||
profile,
|
||||
options,
|
||||
&operator,
|
||||
operator,
|
||||
&mint_wallet,
|
||||
mint_space,
|
||||
rent_budget_space,
|
||||
@@ -285,7 +298,7 @@ async fn create_native_token_2022_metadata_mint(
|
||||
http_pool: &ks_onchain_transport::HttpEndpointPool,
|
||||
profile: &ks_config::ProfileConfig,
|
||||
options: &crate::Token2022MetadataFixturePreparationOptions,
|
||||
operator: &ks_wallet::TemporaryWallet,
|
||||
operator: &crate::DevnetExecutionWallet,
|
||||
mint_wallet: &ks_wallet::TemporaryWallet,
|
||||
mint_space: usize,
|
||||
rent_budget_space: usize,
|
||||
|
||||
138
ks-pipeline-demo-scenarios/src/wallet.rs
Normal file
138
ks-pipeline-demo-scenarios/src/wallet.rs
Normal file
@@ -0,0 +1,138 @@
|
||||
// file: ks-pipeline-demo-scenarios/src/wallet.rs
|
||||
// version: 1
|
||||
|
||||
//! Runtime wallet resolution shared by Devnet demonstration scenarios.
|
||||
|
||||
/// Resolved signing capability used by Devnet demonstration scenarios.
|
||||
///
|
||||
/// The enum owns either the historical managed temporary wallet or an
|
||||
/// authenticated native `.kswallet`. It never exposes private key bytes.
|
||||
pub enum DevnetExecutionWallet {
|
||||
/// Managed temporary wallet used when no persistent alias is selected.
|
||||
Temporary(ks_wallet::TemporaryWallet),
|
||||
/// Authenticated native wallet selected explicitly by alias.
|
||||
Persistent(ks_wallet::UnlockedWallet),
|
||||
}
|
||||
|
||||
impl std::fmt::Debug for crate::DevnetExecutionWallet {
|
||||
fn fmt(&self, formatter: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
|
||||
return formatter
|
||||
.debug_struct("DevnetExecutionWallet")
|
||||
.field("identity", &self.identity())
|
||||
.finish();
|
||||
}
|
||||
}
|
||||
|
||||
impl crate::DevnetExecutionWallet {
|
||||
/// Returns the non-secret resolved wallet identity.
|
||||
pub fn identity(&self) -> ks_wallet::WalletIdentity {
|
||||
return match self {
|
||||
Self::Temporary(wallet) => wallet.identity(),
|
||||
Self::Persistent(wallet) => wallet.identity(),
|
||||
};
|
||||
}
|
||||
|
||||
/// Returns the resolved Solana public key.
|
||||
pub fn public_key(&self) -> std::string::String {
|
||||
return match self {
|
||||
Self::Temporary(wallet) => wallet.public_key(),
|
||||
Self::Persistent(wallet) => wallet.public_key(),
|
||||
};
|
||||
}
|
||||
|
||||
/// Returns whether this execution capability is temporary or native persistent.
|
||||
pub fn persistence(&self) -> ks_wallet::WalletPersistence {
|
||||
return match self {
|
||||
Self::Temporary(wallet) => wallet.persistence(),
|
||||
Self::Persistent(_) => ks_wallet::WalletPersistence::Persistent,
|
||||
};
|
||||
}
|
||||
|
||||
/// Returns the signer interface without exposing private key bytes.
|
||||
pub fn as_signer(&self) -> &dyn solana_signer::Signer {
|
||||
return match self {
|
||||
Self::Temporary(wallet) => wallet.as_signer(),
|
||||
Self::Persistent(wallet) => wallet.as_signer(),
|
||||
};
|
||||
}
|
||||
|
||||
/// Returns the signer interface while preserving `Sync` for async execution paths.
|
||||
pub fn as_sync_signer(&self) -> &(dyn solana_signer::Signer + std::marker::Sync) {
|
||||
return match self {
|
||||
Self::Temporary(wallet) => wallet.as_sync_signer(),
|
||||
Self::Persistent(wallet) => wallet.as_sync_signer(),
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
/// Resolves the execution wallet selected by one profile.
|
||||
///
|
||||
/// A profile with `wallet_alias` requires an explicit runtime password and
|
||||
/// resolves only the native wallet store. A profile without `wallet_alias`
|
||||
/// retains the managed temporary-wallet behavior.
|
||||
pub async fn resolve_devnet_execution_wallet(
|
||||
profile: &ks_config::ProfileConfig,
|
||||
workspace_root: &std::path::Path,
|
||||
password: std::option::Option<ks_wallet::WalletPassword>,
|
||||
) -> ks_core::Result<crate::DevnetExecutionWallet> {
|
||||
if profile.wallet.cluster != "devnet" {
|
||||
return std::result::Result::Err(ks_core::Error::config(
|
||||
"Devnet execution wallet resolution requires a Devnet profile",
|
||||
));
|
||||
}
|
||||
if profile.wallet.wallet_alias.is_some() {
|
||||
let password = match password {
|
||||
std::option::Option::Some(value) => value,
|
||||
std::option::Option::None => {
|
||||
return std::result::Result::Err(ks_core::Error::new(
|
||||
"wallet_persistent_password_required",
|
||||
"selected native wallet requires an explicit runtime password",
|
||||
));
|
||||
},
|
||||
};
|
||||
let wallet =
|
||||
match crate::unlock_selected_profile_wallet(profile, workspace_root, password).await {
|
||||
std::result::Result::Ok(value) => value,
|
||||
std::result::Result::Err(error) => return std::result::Result::Err(error),
|
||||
};
|
||||
tracing::info!(
|
||||
target: "ks-pipeline-demo-scenarios.wallet",
|
||||
action = "resolve_execution_wallet",
|
||||
profile = profile.name.as_str(),
|
||||
wallet_alias = wallet.alias().as_str(),
|
||||
public_key = %wallet.public_key(),
|
||||
persistence = "persistent",
|
||||
"resolved authenticated native wallet for Devnet execution"
|
||||
);
|
||||
return std::result::Result::Ok(crate::DevnetExecutionWallet::Persistent(wallet));
|
||||
}
|
||||
let wallet = match crate::load_profile_temporary_wallet(profile, workspace_root).await {
|
||||
std::result::Result::Ok(value) => value,
|
||||
std::result::Result::Err(error) => return std::result::Result::Err(error),
|
||||
};
|
||||
tracing::debug!(
|
||||
target: "ks-pipeline-demo-scenarios.wallet",
|
||||
action = "resolve_execution_wallet",
|
||||
profile = profile.name.as_str(),
|
||||
wallet_alias = wallet.identity().alias.as_str(),
|
||||
public_key = %wallet.public_key(),
|
||||
persistence = "temporary",
|
||||
"resolved managed temporary wallet for Devnet execution"
|
||||
);
|
||||
return std::result::Result::Ok(crate::DevnetExecutionWallet::Temporary(wallet));
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
#[test]
|
||||
fn debug_contains_only_non_secret_identity() {
|
||||
let alias = ks_wallet::WalletAlias::parse("scenario-temp")
|
||||
.unwrap_or_else(|error| panic!("alias must be valid: {error}"));
|
||||
let wallet =
|
||||
crate::DevnetExecutionWallet::Temporary(ks_wallet::TemporaryWallet::generate(alias));
|
||||
let debug = format!("{wallet:?}");
|
||||
assert!(debug.contains("scenario-temp"));
|
||||
assert!(!debug.contains("keypair"));
|
||||
assert!(!debug.contains("password"));
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user