Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add create_wallet_with_custom_code wallet helper function in miden-lib #766

Closed
partylikeits1983 opened this issue Jun 21, 2024 · 7 comments
Assignees
Labels
enhancement New feature or request
Milestone

Comments

@partylikeits1983
Copy link
Contributor

Feature description

Adding a create_wallet_with_custom_code function would make it easier to create wallets with custom code when using the miden-client.

I propose adding a function in miden-lib/src/accounts/wallets/mod.rs that allows to pass in custom logic when creating a wallet. This function is pretty much a copy of create_basic_wallet but allows to pass in custom masm code when creating the wallet:

pub fn create_wallet_with_custom_code(
    init_seed: [u8; 32],
    auth_scheme: AuthScheme,
    account_type: AccountType,
    account_storage_type: AccountStorageType,
    custom_code: String,
) -> Result<(Account, Word), AccountError> {
    if matches!(account_type, AccountType::FungibleFaucet | AccountType::NonFungibleFaucet) {
        return Err(AccountError::AccountIdInvalidFieldElement(
            "Basic wallet accounts cannot have a faucet account type".to_string(),
        ));
    }

    let (auth_scheme_procedure, storage_slot_0_data): (&str, Word) = match auth_scheme {
        AuthScheme::RpoFalcon512 { pub_key } => ("basic::auth_tx_rpo_falcon512", pub_key.into()),
    };

    let account_code_string: String = format!(
        "
        {custom_code}

        export.{auth_scheme_procedure}
    "
    );
    let account_code_src: &str = &account_code_string;

    let account_code_ast = ModuleAst::parse(account_code_src)
        .map_err(|e| AccountError::AccountCodeAssemblerError(e.into()))?;
    let account_assembler = TransactionKernel::assembler();
    let account_code = AccountCode::new(account_code_ast.clone(), &account_assembler)?;

    let account_storage =
        AccountStorage::new(vec![SlotItem::new_value(0, 0, storage_slot_0_data)], BTreeMap::new())?;

    let account_seed = AccountId::get_account_seed(
        init_seed,
        account_type,
        account_storage_type,
        account_code.root(),
        account_storage.root(),
    )?;

    Ok((Account::new(account_seed, account_code, account_storage)?, account_seed))
}

Why is this feature needed?

Makes it easier to create wallets with custom logic when using Miden client.

@partylikeits1983 partylikeits1983 added the enhancement New feature or request label Jun 21, 2024
@partylikeits1983
Copy link
Contributor Author

The PR: #767

@Dominik1999
Copy link
Collaborator

Dominik1999 commented Jun 24, 2024

this is related #550

The problem is storage and the reserved dataslots. However, I don't see why we can't merge a workaround until we have the correct package format

@bobbinth
Copy link
Contributor

If not critical, I'd prefer not to merge this as we should have a more general solution to accounts with custom code relatively soon (i.e., within the next month or so).

@partylikeits1983
Copy link
Contributor Author

If not critical, I'd prefer not to merge this as we should have a more general solution to accounts with custom code relatively soon (i.e., within the next month or so).

Ok no worries. The partially fillable swap note for the order book note is working and has been extensively tested using mock-datastore.

Is there a way to deploy a custom account to the miden localhost instance? I just need two extra "read-only" procedures in addition to the default account code, get_balance and get_id.

I want to deploy to miden-node this account:

use.miden::contracts::wallets::basic->basic_wallet
use.miden::contracts::auth::basic->basic_eoa
use.miden::account

export.basic_wallet::receive_asset
export.basic_wallet::send_asset
export.basic_eoa::auth_tx_rpo_falcon512

export.account::get_balance
export.account::get_id

@bobbinth
Copy link
Contributor

bobbinth commented Jul 1, 2024

Is there a way to deploy a custom account to the miden localhost instance? I just need two extra "read-only" procedures in addition to the default account code, get_balance and get_id.

The only way to do that is to create an account programmatically (e.g., instantiate the Account struct with the code you'd like), the serialize it into .mac file (via the AccountData struct), and then import the .mac file in the client using the import command.

I think given the code you have above, instantiating AccountData struct and serializing it should be relatively straight-forward.

@bobbinth
Copy link
Contributor

bobbinth commented Oct 26, 2024

After #935 is done (or maybe even as a part of it) we should be able to make account creation with custom code pretty straight-forward.

We'd have some specialized methods for creating basic wallet and authentication components, and then, these could be combined into an account together with some custom components. For example, it could look something like this:

let components = [
    create_basic_wallet_component(),
    create_RpoFalcon512_component(pub_key),
    create_my_custom_component(),
];

let (account, seed) = create_account(init_seed, account_type, storage_mode, components);

This is just an example interface - we could try to make things a bit more ergonomic. Maybe something like this:

let (account, seed) = AccountBuilder::new(init_seed)
    .with_storage_mode(AccountStorageMode::Public)
    .with_basic_wallet()
    .with_component(RpoFalcon512::new(pub_key))
    .with_component(build_my_custom_component())
    .build();

And faucets (or any other account) could be created using the same interface:

let (account, seed) = AccountBuilder::new(init_seed)
    .with_type(AccountType::FungibleFaucet)
    .with_storage_mode(AccountStorageMode::Public)
    .with_component(BasicFungibleFaucet::new(symbol, 8, Felt::new(2 << 63))),
    .with_component(RpoFalcon512::new(pub_key))
    .build();

@bobbinth
Copy link
Contributor

bobbinth commented Nov 5, 2024

Closed by #948.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
enhancement New feature or request
Projects
Status: Done
Development

No branches or pull requests

4 participants