Search code examples
rustrust-cargocryptocurrencynear-sdk-rs

Is there a way to call NonFungibleTokenCore from an external contract in NEAR using ext_contract?


I am using functions called on the dependency trait NonFungibleTokenCore and I would like to use the convivence wrapper of ext_contract to simplify cross contract calls.

Here is my attempt to add it:

#[ext_contract(ext_non_fungible_token)]
trait NFTCore: NonFungibleTokenCore {}

from: https://github.com/roshkins/sputnik-dao-contract/blob/nft-tokensv4/sputnik-nft-staking/src/lib.rs#L18

My code completion using rust-analyzer doesn't provide any completions. When I build it I get this error:

error[E0425]: cannot find function `nft_transfer` in module `ext_non_fungible_token`
   --> sputnik-nft-staking/src/lib.rs:151:33
    |
151 |         ext_non_fungible_token::nft_transfer(sender_id.clone(), token_id.clone(), 0, None,
    |                                 ^^^^^^^^^^^^ not found in `ext_non_fungible_token`

Do you have any ideas of how to properly use the macro?


Solution

  • Unfortunately, the ext_contract proc macro is only aware of the code within that block, and cannot generate code based on the methods of the Supertrait definition of NonFungibleTokenCore here https://github.com/roshkins/sputnik-dao-contract/blob/bc8398257cdbee248fdd6301af0dc41a9b7c5236/sputnik-nft-staking/src/lib.rs#L18.

    For now, you would have to redefine the interface, but I will ask around if there is a cleaner way to do this.

    Something like this might solve your immediate problem:

    #[ext_contract(ext_non_fungible_token)]
    trait NonFungibleTokenCore {
        fn nft_transfer(
            &mut self,
            receiver_id: AccountId,
            token_id: TokenId,
            approval_id: Option<u64>,
            memo: Option<String>,
        );
        fn nft_transfer_call(
            &mut self,
            receiver_id: AccountId,
            token_id: TokenId,
            approval_id: Option<u64>,
            memo: Option<String>,
            msg: String,
        ) -> PromiseOrValue<bool>;
        fn nft_token(&self, token_id: TokenId) -> Option<Token>;
    }