0

On NEARprotocol, I want to call another contract from within a contract (Rust). I tried env::Promise but could not retrieve the call answer. What is the right approach here? Also, the near-sdk crate docs give the example &"bob_near".to_string(), is that equivalent to the id bob.near or a typo?

Here are the relevant excerpts of my code:

near_sdk::setup_alloc!();

#[ext_contract]
pub trait AEXToken {
    fn collect_premie(&mut self, account_id: ValidAccountId) -> bool;
    fn get_min_balance(&self) -> u128;
}
#[near_bindgen]
#[derive(BorshDeserialize, BorshSerialize, PanicOnDefault)]
pub struct Contract {
    tokens: NonFungibleToken,
    metadata: LazyOption<NFTContractMetadata>,
    aex_tokenId: ValidAccountId,
}

#[near_bindgen]
impl Contract {
    pub fn nft_mint(&mut self) -> Token {
        let amount: Balance = env::attached_deposit();
        aex_token::get_min_balance(&self.aex_tokenId.to_string(), 0, 1_000);
        let min_balance: u128 = env::promise_return(1);
        assert!(min_balance < amount);
3lLobo
  • 1
  • 1

1 Answers1

1

I think you're misunderstanding the way this works. the promise does not return in this same method. it's executed in some subsequent block, as soon as possible depending on network congestion, usually within 1 block.

The return value will land in another method as a callback. See this example and several others in the same examples folder with the SDK

calling out

/// Call functions a, b, and c asynchronously and handle results with `handle_callbacks`.
pub fn call_all(fail_b: bool, c_value: u8) -> Promise {
    let gas_per_promise = env::prepaid_gas() / 5;
    ext::a(env::current_account_id(), 0, gas_per_promise)
        .and(ext::b(fail_b, env::current_account_id(), 0, gas_per_promise))
        .and(ext::c(c_value, env::current_account_id(), 0, gas_per_promise))
        .then(ext::handle_callbacks(env::current_account_id(), 0, gas_per_promise))
}

receiving callback

/// Receives the callbacks from the other promises called.
#[private]
pub fn handle_callbacks(
    #[callback_unwrap] a: u8,
    #[callback_result] b: Result<String, PromiseError>,
    #[callback_result] c: Result<u8, PromiseError>,
) -> (bool, bool) {
    require!(a == A_VALUE, "Promise returned incorrect value");
    if let Ok(s) = b.as_ref() {
        require!(s == "Some string");
    }
    (b.is_err(), c.is_err())
}

and this might help with a little more explanation around it https://www.near-sdk.io/cross-contract/callbacks


so your call out

aex_token::get_min_balance(&self.aex_tokenId.to_string(), 0, 1_000);

should be chained using then to a callback where you execute this check

let min_balance: u128 = env::promise_return(1);
assert!(min_balance < amount);
amgando
  • 1,563
  • 8
  • 12