Reputation: 1
I am new to programming in Solana. Here I want to apply the MPL core for my application. There is a feature that a MPL core asset can bind with an "oracle account". This oracle account should be a PDA that containing information for the life cycle of the MPL Core. (correct me if I say it wrong.)
Here is the code:
// https://solana.com/docs/core/pda
// https://github.com/metaplex-foundation/mpl-core/blob/main/clients/js/src/plugins/lifecycleChecks.ts#L42
// let oracle_plugin = Pubkey::from_str("6qjMzebX6DBJMbrNPk2UejZSkF7i8H5Nc5gbQAgKw7ay").unwrap();
let oracle_plugin = LIFE_HELPER_ID;
external_plugin_adapters.push(ExternalPluginAdapterInitInfo::Oracle(OracleInitInfo {
base_address: oracle_plugin,
init_plugin_authority: None,
lifecycle_checks: vec![(
HookableLifecycleEvent::Transfer,
ExternalCheckResult { flags: 4 }, // CAN_REJECT
)],
// https://github.com/metaplex-foundation/mpl-core/blob/7d82981e9be90592579055cfc8f4006aeeff28c3/programs/mpl-core/src/plugins/external_plugin_adapters.rs#L467
base_address_config: Some(ExtraAccount::PreconfiguredAsset {
// TODO: unused parameters?
is_signer: false,
is_writable: false,
}),
results_offset: Some(ValidationResultsOffset::Anchor),
}));
The PreconfiguredAsset
should tell that the PDA should be created from the seeds "mpl-core" and the public key of the Core Asset. Hence, I call another function to create the PDA.
let life_helper_program = ctx.accounts.life_helper_program.to_account_info();
let life_helper_cpi_accounts = LifeHelperAccounts4Init {
signer: ctx.accounts.payer.to_account_info(),
payer: ctx.accounts.payer.to_account_info(),
asset: ctx.accounts.asset.to_account_info(),
oracle_account: ctx.accounts.life_helper_pda.to_account_info(),
system_program: ctx.accounts.system_program.to_account_info(),
};
// https://stackoverflow.com/questions/70675404/cross-program-invocation-with-unauthorized-signer-or-writable-account
// https://solana.com/developers/guides/getstarted/how-to-cpi-with-signer
let payer_seed = ctx.accounts.payer.to_account_info().key();
let asset_seed = ctx.accounts.asset.to_account_info().key();
// let bump_seed = ctx.accounts.life_helper_pda.to_account_info().key();
let bump_seed = &[args.bump];
let signer_seeds: &[&[&[u8]]] = &[&[
payer_seed.as_ref(),
asset_seed.as_ref(),
b"mpl-core",
bump_seed,
]];
msg!("signer_seeds: {:?}", signer_seeds);
let life_helper_ctx =
CpiContext::new(life_helper_program, life_helper_cpi_accounts).with_signer(signer_seeds);
life_helper::cpi::initialize(
life_helper_ctx,
LifeHelperArgs4Init {
transfer_limit: args.transfer_limit,
},
)?;
Another piece of code that is defined in life_helper
program:
#[derive(Accounts)]
pub struct Accounts4Init<'info> {
pub signer: Signer<'info>,
#[account(mut)]
pub payer: Signer<'info>,
/// CHECK: this account will not be checked
pub asset: UncheckedAccount<'info>,
#[account(init, payer = payer, space = Validation::INIT_SPACE, seeds = [b"mpl-core", asset.key().as_ref()], bump)]
pub oracle_account: Account<'info, Validation>,
pub system_program: Program<'info, System>,
}
And this is how I did to create the PDA id:
let asset = Keypair.generate();
const [life_helper_pda, life_helper_seed] = PublicKey.findProgramAddressSync(
[
anchor.utils.bytes.utf8.encode('mpl-core'),
asset.publicKey.toBuffer(),
],
lifeHelperProg.programId
)
The problem is when I test calling the function it sometimes give me the error:
Message: Transaction simulation failed: Error processing Instruction 0: Program failed to complete.
Logs:
[
"Program B28UKH17RsMkqA9n3YbviRMny9yeiBdM7pzjT9LK1JZ invoke [1]",
"Program log: Instruction: CreateTicketV1",
"Program B28UKH17RsMkqA9n3YbviRMny9yeiBdM7pzjT9LK1JZ consumed 6901 of 200000 compute units",
"Program B28UKH17RsMkqA9n3YbviRMny9yeiBdM7pzjT9LK1JZ failed: Could not create program address with signer seeds: Provided seeds do not result in a valid address"
].
Catch the `SendTransactionError` and call `getLogs()` on it for full details.
And sometimes it is ok to run. I don't know what lead to this problem and why sometime s it works sometimes it don't.
It should give correct each time I call the function.
This is my full code: https://github.com/WangWilly/solana-poneglyph/tree/master/contract
Upvotes: 0
Views: 192