async function sendSafely(boundContractMethod, sendParams, forceSend = false) {
  try {
    // Clone `sendParams` so we aren't exposed to providers that modify `sendParams`.
    const gasEstimate = await boundContractMethod.estimateGas({ ...sendParams })

    return boundContractMethod.send({
      from: "", // FIXME Need systemic handling of default from address.
      ...sendParams,
      gas: gasEstimate
    })
  } catch (exception) {
    // For an always failing transaction, if forceSend is set, send it anyway.
    if (
      exception.message &&
      exception.message.match(/always failing transaction/) &&
      forceSend
    ) {
      return boundContractMethod.send({
        from: "", // FIXME Need systemic handling of default from address.
        ...sendParams
      })
    } else {
      // If we're not force-sending, use `call` to throw the true error reason
      // (`estimateGas` doesn't return error messages, it only throws an
      // out-of-gas).
      // @ts-ignore A newer version of Web3 is needed to include call in TS.
      await boundContractMethod.call({
        from: "",
        ...sendParams
      })

      // If `call` doesn't throw an error, something has gone quite awry; since
      // we couldn't estimate gas, throw the original exception, since that's
      // where things first went sideways.
      throw exception
    }
  }
}
/**
 * Takes a bound web3 contract method (e.g. `myContract.methods.doSomething(param)`
 * and sends it with proper gas estimation and error handling. In particular,
 * runs a gas estimate beforehand to attach an appropriate gas spend, and, if
 * the gas estimation fails due to an always-failing transaction, `call`s the
 * method to get the proper underlying error message. Otherwise, sends the
 * signed transaction normally.
 *
 * @param {ContractSendMethod} boundContractMethod A bound web3 contract method
 *        with `estimateGas`, `send`, and `call` variants available.
 * @param {Partial<SendOptions>} [sendParams] The parameters to pass to
 *        `estimateGas` and `send` for transaction processing.
 * @param {boolean} [forceSend] Force the transaction send through even
 *        if gas estimation fails.
 *
 * @return {Promise<any>} A promise to the result of sending the bound contract
 *         method. Fails the promise if gas estimation fails, extracting an
 *         on-chain error if possible.
 */
Takes a bound web3 contract method `
and sends it with proper gas estimation and error handling. In particular,
runs a gas estimate beforehand to attach an appropriate gas spend, and, if
the gas estimation fails due to an always-failing transaction, `call`s the
method to get the proper underlying error message. Otherwise, sends the
signed transaction normally.



@return {Promise} A promise to the result of sending the bound contract
method. Fails the promise if gas estimation fails, extracting an
on-chain error if possible.
Takes a bound web3 contract method ` and sends it with proper gas estimation and error handling . In particular runs a gas estimate beforehand to attach an appropriate gas spend and if the gas estimation fails due to an always - failing transaction ` call ` s the method to get the proper underlying error message . Otherwise sends the signed transaction normally . @return { Promise } A promise to the result of sending the bound contract method . Fails the promise if gas estimation fails extracting an on - chain error if possible .
async function sendSafely(boundContractMethod, sendParams, forceSend = false) {
  try {
    const gasEstimate = await boundContractMethod.estimateGas({ ...sendParams })
    return boundContractMethod.send({
      from: "", 
      ...sendParams,
      gas: gasEstimate
    })
  } catch (exception) {
    if (
      exception.message &&
      exception.message.match(/always failing transaction/) &&
      forceSend
    ) {
      return boundContractMethod.send({
        from: "", 
        ...sendParams
      })
    } else {
      await boundContractMethod.call({
        from: "",
        ...sendParams
      })
      throw exception
    }
  }
}
async function sendSafely ( boundContractMethod , sendParams , forceSend = false ) { try { const gasEstimate = await boundContractMethod . estimateGas ( { ... sendParams } ) return boundContractMethod . send ( { from : "" , ... sendParams , gas : gasEstimate } ) } catch ( exception ) { if ( exception . message && exception . message . match ( / always failing transaction / ) && forceSend ) { return boundContractMethod . send ( { from : "" , ... sendParams } ) } else { await boundContractMethod . call ( { from : "" , ... sendParams } ) throw exception } } }
Takes a bound web3 contract method (e.g.
Takes a bound web3 contract method ( e . g .
// Clone `sendParams` so we aren't exposed to providers that modify `sendParams`. // FIXME Need systemic handling of default from address. // For an always failing transaction, if forceSend is set, send it anyway. // FIXME Need systemic handling of default from address. // If we're not force-sending, use `call` to throw the true error reason // (`estimateGas` doesn't return error messages, it only throws an // out-of-gas). // @ts-ignore A newer version of Web3 is needed to include call in TS. // If `call` doesn't throw an error, something has gone quite awry; since // we couldn't estimate gas, throw the original exception, since that's // where things first went sideways.