Search code examples
javascriptrustnearprotocol

How do you call a payable method from the js client?


Imagine you got a smart contract method that expects a deposit attached to a method call, something like this rust method:

#[payable]
pub fn spend(&mu self, age: u8){
    assert!(env::attached_deposit() > 0,
            "Insufficient deposit.");
.
.
.
}

now you setup your contract using near-api-js and proceed to call it. How can one call this method and attach some Near to it in the client side js?


Solution

  • You set up your contract as usual:

    const contract = await new nearlib.Contract(
        walletConnection.account(),
        nearConfig.contractName,
        {
          // View methods are read only. They don't modify the state, but usually return some value.
          viewMethods: ["getCorgi", "getCorgisList", "displayGolbalCorgis"],
          // Change methods can modify the state. But you don't receive the returned value when called.
          changeMethods: ["transferCorgi", "createCorgi", "deleteCorgi"],
          // Sender is the account ID to initialize transactions.
          sender: walletConnection.getAccountId(),
        }
      );
    

    Usually, you call change methods as:

    await contract.transferCorgi({"receiver": "frol.near", "id": "corgi_xxx", "message": "hello"})
    

    However, when you want to attach some NEAR tokens or increase gas allowance, you need to specify optional positional arguments after the arguments:

    await contract.changeMethodName(args: object, gas: BN, amount: BN)
    

    NOTES:

    1. BN is a big number representation
    2. the default gas allowance is 300 Tgas [300 * 10^12 gas], learn more: FAQ on Gas in the documentation, NEP67
    3. amount is specified in yoctoNEAR (1 NEAR is 10^24 yoctoNEAR)

    For example:

    const ONE_NEAR = new BN("1000000000000000000000000")
    await contract.createCorgi({"id": "corgi_xxx"}, new BN("3000000000000"), ONE_NEAR)