patractlabs / redspot

Redspot is an Substrate pallet-contracts (ink!) development environment. Compile your contracts and run them on a different networks. Redspot's core forks from Hardhat but changed a lot to suit substrate.
https://redspot.patract.io/
Other
67 stars 22 forks source link

[feature request] chain-as-promise support #82

Open hychen opened 3 years ago

hychen commented 3 years ago

Given a smart contract, say erc20,

When a contract developer wants to check a transaction returns any error, He could check if any promise rejection happened.

Expect that he could do as below:

import { Error } from artificats.erc20;
const contractFactory = await getContractFactory('erc20', creator);
const contract = await contractFactory.deploy('new', 100);
expect(() => await contract.transfer(signer.address))
    .rejectWith(Error.InsufficientAllowance);

Dependencies

RoyTimes commented 3 years ago

I have written a simple code snippet that promisify contract.tx

const writeContract = (extrinsic) => {
  return new Promise((resolve, reject) => {
    extrinsic.signAndSend(this.signer, (result) => {
      // or result.status.isFinalized is you want grandpa finalization 
      if (result.status.isInBlock) {
        resolve(result)
      }
    })
  })
}

// call by
async execContract(message, params) {
  const contract = await this.getContractInstance()
  await this.writeContract(contract.tx[message](
    {gasLimit: -1}, ...params
  ))
}

Not an end solution, but I hope this helps a little bit.

hychen commented 3 years ago

@RoyTimes I thought contract.tx is alrady promisify?

This feature is for adding https://www.chaijs.com/plugins/chai-as-promised/ to @redspot/chai plugin and to make the DX (developer experiences) of Redspot similar to web3.

ii-ii-ii commented 3 years ago

This is a very good point. But I don't think we won't support contract.transfer(signer.address)).rejectWith(Error.InsufficientAllowance) of this form. Instead, it will support matching errors using strings. Like this contract.transfer(signer.address)).rejectWith("InsufficientAllowance") . Because Errors are unlikely to contain all errors, such as those defined on substrate.

hychen commented 3 years ago

Error refers to the error types defined in contract by the contract developers. A example as below

#[ink(contract)]
mod erc20 {
...
   pub enum Errors { ... }
}

The types should theoretically be generated if custom type support (#81 ) is done.

Type support is not essential. However for contract developers, it is much easier to catch bugs before executing by performing type checking.

This is just nice to have. contract.transfer(signer.address)).rejectWith("InsufficientAllowance") works to me.