Rust SDK Error: Calling payable functions fails in RustSDK doesn't work

I am adapting the docs in calling a payable function with base asset and using this code snippet to call payable function

// harness.rs
use fuels::{prelude::*, types::ContractId};

abigen!(Contract(name="MyContract", abi="out/debug/test_asset-abi.json"));


#[tokio::test]
async fn test_harness() {
    // Test code here
    let (instance, _id,wallets) = get_contract_instance().await;
    let wallet_1 = wallets.get(0).unwrap();
    let call_params = CallParameters::default().with_amount(1);
    // help here
    let result= instance.clone().with_account(wallet_1.clone()).methods().deposit().append_variable_outputs(1).call_params(call_params).unwrap().call().await.call().unwrap();
    let result2 = instance.methods().test_deposit_asset_id_same_generated().call().await.unwrap().value;
    assert_eq!(result, result2);
}


async fn get_contract_instance() -> (MyContract<WalletUnlocked>, ContractId,Vec<WalletUnlocked>) {
    // Launch a local network and deploy the contract
    let wallets = launch_custom_provider_and_get_wallets(
        WalletsConfig::new(
            Some(3),             /* Three wallets */
            Some(1),             /* Single coin (UTXO) */
            Some(1_000_000_000), /* Amount per coin */
        ),
        None,
        None,
    )
    .await
    .unwrap();
 
    let wallet = wallets.get(0).unwrap().clone();
    
    let id = Contract::load_from(
        "./out/debug/test_asset.bin",
        LoadConfiguration::default(),
    )
    .unwrap()
    .deploy(&wallet, TxPolicies::default())
    .await
    .unwrap();
 
    let instance = MyContract::new(id.clone(), wallet);
 
    (instance, id.into(),wallets)
}

This is my main.sw

// Constant Product AMM - Uniswap V2.
contract;

use std::{
    constants::ZERO_B256,
    hash::sha256,
    asset::transfer,
    hash::Hash,
    asset_id::AssetId,
    asset::{
        burn,
        mint_to,
    },
    contract_id::ContractId,
    call_frames::{
        msg_asset_id,
    },
    context::msg_amount,
    string::String,
};
 

abi MyContract {
    #[storage(read, write)]
    fn deposit()-> b256;
    
    #[storage(read)]
    fn test_deposit_asset_id_same_generated() -> b256;
}


impl MyContract for Contract {
    #[storage(read, write), payable]
    fn deposit() -> b256 {

        let owner = msg_sender().unwrap();
        let asset_id = msg_asset_id().bits();
        let address_from_b256: Address = Address::from(asset_id);
        asset_id
    }


    #[storage(read)]
    fn test_deposit_asset_id_same_generated() -> b256  {
        let token_id = "b256::zero()";
        let token_address =  AssetId::base();
        let sub_id = sha256((token_address, token_id));

        
        let asset_id: b256 = AssetId::new(ContractId::this(), sub_id).bits();
        let address_from_b256: Address = Address::from(asset_id);
    
        asset_id
        
    }

}

This is the error:

error[E0599]: the method `methods` exists for struct `MyContract<&WalletUnlocked>`, but its trait bounds were not satisfied
  --> tests/harness.rs:12:57
   |
3  | abigen!(Contract(name="MyContract", abi="out/debug/test_asset-abi.json"));
   | ------------------------------------------------------------------------- method `methods` not found for this struct
...
12 |     let result= instance.clone().with_account(wallet_1).methods().deposit().append_variable_outputs(1).call_params(call_params).unwrap().call().await.call().unwrap();
   |                                                         ^^^^^^^ method cannot be called on `MyContract<&WalletUnlocked>` due to unsatisfied trait bounds

Please anyone, I am getting cancer from this :stuck_out_tongue:

Interesting, did someone change the docs? @david for this code snippet to call payable function

I just revisted the site and it changed from

let result= instance. Clone().with_account(wallet_1.clone()).methods().deposit().append_variable_outputs(1).call_params(call_params).unwrap().call().await. Call().unwrap();` 

to

let result= instance.clone().with_account(wallet_1.clone()).methods().deposit().append_variable_outputs(1).call_params(call_params).unwrap().call().await. Call().unwrap();

Can we have a page update for each documentation page so that we know when it was updated?

Anyways, I reupdate the code with adding .value.

use fuels::{prelude::*, types::ContractId};

abigen!(Contract(name="MyContract", abi="out/debug/test_asset-abi.json"));


#[tokio::test]
async fn test_harness() {
    // Test code here
    let (instance, _id,wallets) = get_contract_instance().await;
    let wallet_1 = wallets.get(0).unwrap();
    let call_params = CallParameters::default().with_amount(1);
    // help here
    let result= instance.clone().with_account(wallet_1.clone()).methods().deposit().append_variable_outputs(1).call_params(call_params).unwrap().call().await.unwrap().value;
    let result2 = instance.methods().test_deposit_asset_id_same_generated().call().await.unwrap().value;
    assert_eq!(result, result2);
}


async fn get_contract_instance() -> (MyContract<WalletUnlocked>, ContractId,Vec<WalletUnlocked>) {
    // Launch a local network and deploy the contract
    let wallets = launch_custom_provider_and_get_wallets(
        WalletsConfig::new(
            Some(3),             /* Three wallets */
            Some(1),             /* Single coin (UTXO) */
            Some(1_000_000_000), /* Amount per coin */
        ),
        None,
        None,
    )
    .await
    .unwrap();
 
    let wallet = wallets.get(0).unwrap().clone();
    
    let id = Contract::load_from(
        "./out/debug/test_asset.bin",
        LoadConfiguration::default(),
    )
    .unwrap()
    .deploy(&wallet, TxPolicies::default())
    .await
    .unwrap();
 
    let instance = MyContract::new(id.clone(), wallet);
 
    (instance, id.into(),wallets)
}

Instead of having the error @david from above, I got a new error:

   Compiling test_asset v0.1.0 (/home/lokicheck/Desktop/test_asset)
    Finished `test` profile [unoptimized + debuginfo] target(s) in 1m 02s
     Running tests/harness.rs (target/debug/deps/integration_tests-c9599d2b0d721b79)

running 1 test
test test_harness ... FAILED

failures:

---- test_harness stdout ----
thread 'test_harness' panicked at tests/harness.rs:13:137:
called `Result::unwrap()` on an `Err` value: Other("assets forwarded to non-payable method")
note: run with `RUST_BACKTRACE=1` environment variable to display a backtrace


failures:
    test_harness

test result: FAILED. 0 passed; 1 failed; 0 ignored; 0 measured; 0 filtered out; finished in 0.22s

Weird that after changing codes in Sway Contract, we must run forc build before running cargo test everytime. Can we ensure that running cargo test would run forc build first?

This topic was automatically closed 20 days after the last reply. New replies are no longer allowed.