Hey team.
This code works well for CLI and local deploy. But for mainnet I receive unexpected InsufficientAllowance for canister DFINITY Canister Candid UI
valueFinal = await agentMotodex.value_in_main_coin(parseInt(args[0]))
// Call the icrc2_approve() function
approveArgs = {
fee: [],
memo: [],
from_subaccount: [],
created_at_time: [],
amount: valueFinal,
expected_allowance: [],
expires_at: [],
spender: {
owner: motoDEXprincipal, //i also tried the canisterId of the canister i launched
subaccount: [],
},
};
icrc2_approve = await agentICP.icrc2_approve(approveArgs);
console.log(" icrc2_approve " + JSON.stringify(stringFrom(icrc2_approve)))
if (icrc2_approve.Ok) {
console.log('Approve successful, transaction ID:', icrc2_approve.Ok);
const purchase = await agentMotodex.purchase(parseInt(args[0]));
if (purchase.Ok) {
console.log('purchase successful, token ID:', purchase.Ok);
response = [purchase.Ok + '',"done"];
} else {
console.error('purchase failed:', purchase.Err);
response = "fail";
}
} else {
console.error('Approve failed:', icrc2_approve.Err);
response = "fail";
}
In rust is its:
let price_for_type = value_in_main_coin(type_nft);
ic_cdk::print(format!("price_for_type {}", price_for_type));
let transfer_result = transfer_coin_to_owner(price_for_type);
and async fn transfer_coin_to_owner:
async fn transfer_coin_to_owner(amount: u64) -> Result<BlockIndex, String> {
let transfer_result = transfer_coin_to_owner(price_for_type);
async fn transfer_coin_to_owner(amount: u64) -> Result<BlockIndex, String> {
let owner = STATE.with(|s| s.borrow_mut().contract.get_game_server());
let to_principal = owner.owner;
ic_cdk::print(format!("to_principal: {}", to_principal));
ic_cdk::print(format!("amount {}", amount));
let caller_acc = Account::from(ic_cdk::caller());
ic_cdk::print(format!("caller_acc {}", caller_acc));
ic_cdk::println!(
"Transferring {} tokens from {} to {}",
&amount,
&caller_acc,
&to_principal,
);
let transfer_from_args = TransferFromArgs {
from: caller_acc,
to: Account::from(to_principal),
amount: amount.into(),
fee: None,
memo: None,
spender_subaccount: None,
created_at_time: None,
};
// Attempt the asynchronous call to another canister function.
let transfer_result =
ic_cdk::call::<(TransferFromArgs,), (Result<BlockIndex, TransferFromError>,)>(
Principal::from_text("ryjl3-tyaaa-aaaaa-aaaba-cai")
.expect("Could not decode the principal."),
"icrc2_transfer_from",
(transfer_from_args,),
)
.await
.map_err(|e| format!("failed to call ledger: {:?}", e))?
.0;
// Check the result of the transfer.
match transfer_result {
Ok(block_index) => {
// If the transfer was successful, execute the additional code.
ic_cdk::print(format!("transfer successful in block {}", block_index));
Ok(block_index)
}
Err(e) => {
// If there was an error with the transfer, handle it accordingly.
// For example, you might log the error or return it.
Err(format!("ledger transfer error: {:?}", e))
}
}
}