uno-sdk 3.0.3

A IDL library for Etherfuse Uno.
Documentation
use solana_program_test::{tokio, ProgramTest, ProgramTestContext};
use solana_sdk::{
    native_token::LAMPORTS_PER_SOL,
    signature::{Keypair, Signer},
    transaction::Transaction,
};
use uno_sdk::{
    accounts::Nonce,
    find_nonce_pda,
    instructions::{CreateNonce, CreateNonceInstructionArgs},
    types::Discriminator,
    ID as UNO_ID,
};
use uuid::Uuid;

struct ExecutionContext {
    user: Keypair,
    context: ProgramTestContext,
}

async fn setup() -> ExecutionContext {
    let mut pt = ProgramTest::new("uno", UNO_ID, None);
    pt.set_compute_max_units(1_400_000);
    pt.prefer_bpf(false);
    let user = Keypair::new();
    let context = pt.start_with_context().await;
    context
        .banks_client
        .process_transaction(Transaction::new_signed_with_payer(
            &[solana_sdk::system_instruction::transfer(
                &context.payer.pubkey(),
                &user.pubkey(),
                LAMPORTS_PER_SOL,
            )],
            Some(&context.payer.pubkey()),
            &[&context.payer],
            context.last_blockhash,
        ))
        .await
        .expect("Failed to fund user account");
    ExecutionContext { user, context }
}

#[tokio::test]
async fn create_nonce() {
    let ExecutionContext { user, context } = setup().await;
    let id = Uuid::new_v4();
    let id_bytes = id.as_bytes();
    let create_nonce_ix_args = CreateNonceInstructionArgs { id: *id_bytes };
    let nonce_pda = find_nonce_pda(&id_bytes).0;
    let create_nonce_ix = CreateNonce {
        user: user.pubkey(),
        nonce: nonce_pda,
        system_program: solana_program::system_program::ID,
    }
    .instruction(create_nonce_ix_args);

    let transaction = Transaction::new_signed_with_payer(
        &[create_nonce_ix],
        Some(&user.pubkey()),
        &[&user],
        context.last_blockhash,
    );

    let signature = transaction.signatures[0];

    // Process transaction and handle errors
    let result = context.banks_client.process_transaction(transaction).await;
    match &result {
        Ok(_) => println!("Transaction succeeded"),
        Err(err) => {
            println!("Transaction failed with error: {:?}", err);
            // Try to get transaction status
            if let Ok(Some(status)) = context.banks_client.get_transaction_status(signature).await {
                println!("Transaction status: {:?}", status);
            }
        }
    }
    assert!(result.is_ok());

    let account = context.banks_client.get_account(nonce_pda).await.unwrap();
    assert!(account.is_some());
    let account_info = account.unwrap();
    let account_owner = account_info.owner;
    let account_data = account_info.data;
    assert_eq!(account_owner, UNO_ID);
    let nonce = Nonce::from_bytes(&account_data).unwrap();
    assert_eq!(nonce.discriminator, Discriminator::Nonce);
}