Is there a way to check inside the smart contract (in Rust) if another account has a smart-contract associated with it and implements some interface?
In particular, in this function I would like to check if a recipient is a smart contract and if it has a required method:
trait FTReceiver {
fn on_nft_receive(&self, sender: AddressID, token: AddressID) -> bool;
}
pub fn transfer(&mut self, recipient: AccountID, reference: String) {
// note: env::* functions below don't exist!
if env::has_smart_contract(recipient) && env::ctr_implements(recipient, FTReceiver) {
Promise::new(token.clone()).function_call(
"on_ft_receive".into(),
&serde_json::to_vec(&json!({
"sender": env::predecessor_account_id() /*...*/
})),
);
}
}
Here is a very sample crude implemetation:
Receiver interface declaration:
Then checking if the interface is implemented:
And then taking action based on the call result:
Full code: https://github.com/miohtama/advanced-fungible/blob/master/contract/token/src/receiver.rs
Optimally, NEAR should offer a branching primitive in in promise chains, so that the conditional chains could be build right off the start and you would have one less round trip back to your original caller contract after the interface check.