/* * This file is auto-generated using abi-gen. Any changes will be reverted */ // Needed for the promisifed events, some contracts don't have events // tslint:disable:no-unused-variable import { DecodedLogEntryEvent, DecodedLogEntry, DecodedTransactionReceipt } from "@joincivil/typescript-types"; // tslint:enable:no-unused-variable import "rxjs/add/operator/distinctUntilChanged"; import {Contract} from "web3-eth-contract"; import {TransactionConfig, TransactionConfig as SendOptions} from "web3-core"; import { bindNestedAll, isDefined, CivilErrors } from "@joincivil/utils"; import * as Debug from "debug"; import { EthAddress, TxHash } from "@joincivil/typescript-types"; import { streamifyEvent } from "../../../contracts/utils/contracts"; import { EthApi, currentNetwork } from "@joincivil/ethapi"; import { BaseContract } from "../../basecontract"; import { artifacts } from "../artifacts"; // hack(dankins): abi-gen things these are bignumber.js, but they are actually returned as strings // https://github.com/0xProject/0x-monorepo/blob/development/packages/abi-gen/src/utils.ts#L64 type BigNumber = string; const debug = Debug("civil:contracts:MultiSigWalletContract"); export class MultiSigWalletContract extends BaseContract { // tslint:disable:member-ordering public static async singletonTrusted(ethApi: EthApi): Promise { if (!artifacts.MultiSigWallet.networks) { debug("Trying to get singleton from contract without any singleton data"); return undefined; } const networkId = (await currentNetwork(ethApi)).toString(); const networkData = artifacts.MultiSigWallet.networks[networkId]; if (!networkData) { debug("Failed to find network data for network ID " + networkId + ". Supported networks: " + Object.keys(artifacts.MultiSigWallet.networks)); return undefined; } return MultiSigWalletContract.atUntrusted(ethApi, networkData.address); } public static atUntrusted(ethApi: EthApi, address: EthAddress): MultiSigWalletContract { const contract = ethApi.getContractClass(artifacts.MultiSigWallet.abi, address); return new MultiSigWalletContract(contract, ethApi); } // TODO(ritave): This code won't work with smart-contracts with library links // see [ch429] in Clubhouse public static deployTrusted = { async sendTransactionAsync( ethApi: EthApi, initialOwners: string[], initialRequired: BigNumber, options: SendOptions): Promise { if (!options.gas) { options.gas = await MultiSigWalletContract.deployTrusted .estimateGasAsync( ethApi, initialOwners, initialRequired, ); } if (!options.gasPrice) { options.gasPrice = (await ethApi.getGasPrice()).toString(); } const clazz = ethApi.getContractClass(artifacts.MultiSigWallet.abi); return new Promise( (resolve, reject) => { /* There's a bug in Metamask, this callback should be called twice, first when the transaction * gets into mempool, and second when it's mined. But it's called only once, so we have to resolve * the contract on our own */ const tx = clazz.deploy({data: artifacts.MultiSigWallet.bytecode, arguments: [initialOwners, initialRequired, ]}).send(options); return tx.once("transactionHash", resolve) }) }, async estimateGasAsync( ethApi: EthApi, initialOwners: string[], initialRequired: BigNumber, ): Promise { const clazz = ethApi.getContractClass(artifacts.MultiSigWallet.abi); const contractData = clazz.deploy({ data: artifacts.MultiSigWallet.bytecode, arguments: [initialOwners, initialRequired, ] }).encodeABI(); return ethApi.estimateGas({data: contractData}); }, }; // tslint:disable:variable-name public owners = { async callAsync( index_0: BigNumber, ): Promise { const self = this as MultiSigWalletContract; return self.instance.methods.owners(index_0, ).call(); } } public isOwner = { async callAsync( index_0: string, ): Promise { const self = this as MultiSigWalletContract; return self.instance.methods.isOwner(index_0, ).call(); } } public confirmations = { async callAsync( index_0: BigNumber, index_1: string, ): Promise { const self = this as MultiSigWalletContract; return self.instance.methods.confirmations(index_0, index_1, ).call(); } } public transactions = { async callAsync( index_0: BigNumber, ): Promise< [string, BigNumber, string, boolean]> { const self = this as MultiSigWalletContract; return self.instance.methods.transactions(index_0, ).call(); } } public transactionCount = { async callAsync( ): Promise { const self = this as MultiSigWalletContract; return self.instance.methods.transactionCount().call(); } } public MAX_OWNER_COUNT = { async callAsync( ): Promise { const self = this as MultiSigWalletContract; return self.instance.methods.MAX_OWNER_COUNT().call(); } } public required = { async callAsync( ): Promise { const self = this as MultiSigWalletContract; return self.instance.methods.required().call(); } } public addOwner = { async sendTransactionAsync( owner: string, txData?: TransactionConfig, ): Promise { const self = this as MultiSigWalletContract; const txOptions: TransactionConfig = { ...self.configuration.txDefaults, ...txData }; debug(`addOwner(owner: string, )`); debug("addOwner: txOptions:", txOptions); debug("addOwner: Sending with:", owner, ); txOptions.to = self.instance.options.address; txOptions.data = self.instance.methods.addOwner(owner, ).encodeABI(); if (!isDefined(txOptions.gas)) { txOptions.gas = await self.ethApi.estimateGas(txOptions); } if (!isDefined(txOptions.gasPrice)) { const gasPricePromise = self.ethApi.getGasPriceString() txOptions.gasPrice = (await gasPricePromise).toString(); debug("addOwner: new gas price: ", txOptions.gasPrice); } return self.ethApi.sendTransaction(txOptions) }, async estimateGasAsync( owner: string, txData?: TransactionConfig, ): Promise { const self = this as MultiSigWalletContract; const estimateGas = self.instance.methods.addOwner(owner, ).estimateGas try { const estimate = Math.floor(await estimateGas(txData) * self.configuration.estimationMultiplier); debug("addOwner: Gas estimation:", estimate); return estimate; } catch (e) { debug("addOwner: Gas estimation failed, only sensible error is EVM error", e); throw new Error(CivilErrors.EvmException); } }, async getRaw( owner: string, txData?: TransactionConfig, ): Promise { const self = this as MultiSigWalletContract; const options: TransactionConfig = {... txData}; if (!isDefined(options.gas)) { options.gas = await self.addOwner.estimateGasAsync( owner, options, ); } options.data = self.instance.methods.addOwner(owner, ).encodeABI(); return options; }, }; public removeOwner = { async sendTransactionAsync( owner: string, txData?: TransactionConfig, ): Promise { const self = this as MultiSigWalletContract; const txOptions: TransactionConfig = { ...self.configuration.txDefaults, ...txData }; debug(`removeOwner(owner: string, )`); debug("removeOwner: txOptions:", txOptions); debug("removeOwner: Sending with:", owner, ); txOptions.to = self.instance.options.address; txOptions.data = self.instance.methods.removeOwner(owner, ).encodeABI(); if (!isDefined(txOptions.gas)) { txOptions.gas = await self.ethApi.estimateGas(txOptions); } if (!isDefined(txOptions.gasPrice)) { const gasPricePromise = self.ethApi.getGasPriceString() txOptions.gasPrice = (await gasPricePromise).toString(); debug("removeOwner: new gas price: ", txOptions.gasPrice); } return self.ethApi.sendTransaction(txOptions) }, async estimateGasAsync( owner: string, txData?: TransactionConfig, ): Promise { const self = this as MultiSigWalletContract; const estimateGas = self.instance.methods.removeOwner(owner, ).estimateGas try { const estimate = Math.floor(await estimateGas(txData) * self.configuration.estimationMultiplier); debug("removeOwner: Gas estimation:", estimate); return estimate; } catch (e) { debug("removeOwner: Gas estimation failed, only sensible error is EVM error", e); throw new Error(CivilErrors.EvmException); } }, async getRaw( owner: string, txData?: TransactionConfig, ): Promise { const self = this as MultiSigWalletContract; const options: TransactionConfig = {... txData}; if (!isDefined(options.gas)) { options.gas = await self.removeOwner.estimateGasAsync( owner, options, ); } options.data = self.instance.methods.removeOwner(owner, ).encodeABI(); return options; }, }; public replaceOwner = { async sendTransactionAsync( owner: string, newOwner: string, txData?: TransactionConfig, ): Promise { const self = this as MultiSigWalletContract; const txOptions: TransactionConfig = { ...self.configuration.txDefaults, ...txData }; debug(`replaceOwner(owner: string, newOwner: string, )`); debug("replaceOwner: txOptions:", txOptions); debug("replaceOwner: Sending with:", owner, newOwner, ); txOptions.to = self.instance.options.address; txOptions.data = self.instance.methods.replaceOwner(owner, newOwner, ).encodeABI(); if (!isDefined(txOptions.gas)) { txOptions.gas = await self.ethApi.estimateGas(txOptions); } if (!isDefined(txOptions.gasPrice)) { const gasPricePromise = self.ethApi.getGasPriceString() txOptions.gasPrice = (await gasPricePromise).toString(); debug("replaceOwner: new gas price: ", txOptions.gasPrice); } return self.ethApi.sendTransaction(txOptions) }, async estimateGasAsync( owner: string, newOwner: string, txData?: TransactionConfig, ): Promise { const self = this as MultiSigWalletContract; const estimateGas = self.instance.methods.replaceOwner(owner, newOwner, ).estimateGas try { const estimate = Math.floor(await estimateGas(txData) * self.configuration.estimationMultiplier); debug("replaceOwner: Gas estimation:", estimate); return estimate; } catch (e) { debug("replaceOwner: Gas estimation failed, only sensible error is EVM error", e); throw new Error(CivilErrors.EvmException); } }, async getRaw( owner: string, newOwner: string, txData?: TransactionConfig, ): Promise { const self = this as MultiSigWalletContract; const options: TransactionConfig = {... txData}; if (!isDefined(options.gas)) { options.gas = await self.replaceOwner.estimateGasAsync( owner, newOwner, options, ); } options.data = self.instance.methods.replaceOwner(owner, newOwner, ).encodeABI(); return options; }, }; public changeRequirement = { async sendTransactionAsync( newRequired: BigNumber, txData?: TransactionConfig, ): Promise { const self = this as MultiSigWalletContract; const txOptions: TransactionConfig = { ...self.configuration.txDefaults, ...txData }; debug(`changeRequirement(newRequired: BigNumber, )`); debug("changeRequirement: txOptions:", txOptions); debug("changeRequirement: Sending with:", newRequired, ); txOptions.to = self.instance.options.address; txOptions.data = self.instance.methods.changeRequirement(newRequired, ).encodeABI(); if (!isDefined(txOptions.gas)) { txOptions.gas = await self.ethApi.estimateGas(txOptions); } if (!isDefined(txOptions.gasPrice)) { const gasPricePromise = self.ethApi.getGasPriceString() txOptions.gasPrice = (await gasPricePromise).toString(); debug("changeRequirement: new gas price: ", txOptions.gasPrice); } return self.ethApi.sendTransaction(txOptions) }, async estimateGasAsync( newRequired: BigNumber, txData?: TransactionConfig, ): Promise { const self = this as MultiSigWalletContract; const estimateGas = self.instance.methods.changeRequirement(newRequired, ).estimateGas try { const estimate = Math.floor(await estimateGas(txData) * self.configuration.estimationMultiplier); debug("changeRequirement: Gas estimation:", estimate); return estimate; } catch (e) { debug("changeRequirement: Gas estimation failed, only sensible error is EVM error", e); throw new Error(CivilErrors.EvmException); } }, async getRaw( newRequired: BigNumber, txData?: TransactionConfig, ): Promise { const self = this as MultiSigWalletContract; const options: TransactionConfig = {... txData}; if (!isDefined(options.gas)) { options.gas = await self.changeRequirement.estimateGasAsync( newRequired, options, ); } options.data = self.instance.methods.changeRequirement(newRequired, ).encodeABI(); return options; }, }; public submitTransaction = { async sendTransactionAsync( destination: string, value: BigNumber, data: string, txData?: TransactionConfig, ): Promise { const self = this as MultiSigWalletContract; const txOptions: TransactionConfig = { ...self.configuration.txDefaults, ...txData }; debug(`submitTransaction(destination: string, value: BigNumber, data: string, )`); debug("submitTransaction: txOptions:", txOptions); debug("submitTransaction: Sending with:", destination, value, data, ); txOptions.to = self.instance.options.address; txOptions.data = self.instance.methods.submitTransaction(destination, value, data, ).encodeABI(); if (!isDefined(txOptions.gas)) { txOptions.gas = await self.ethApi.estimateGas(txOptions); } if (!isDefined(txOptions.gasPrice)) { const gasPricePromise = self.ethApi.getGasPriceString() txOptions.gasPrice = (await gasPricePromise).toString(); debug("submitTransaction: new gas price: ", txOptions.gasPrice); } return self.ethApi.sendTransaction(txOptions) }, async estimateGasAsync( destination: string, value: BigNumber, data: string, txData?: TransactionConfig, ): Promise { const self = this as MultiSigWalletContract; const estimateGas = self.instance.methods.submitTransaction(destination, value, data, ).estimateGas try { const estimate = Math.floor(await estimateGas(txData) * self.configuration.estimationMultiplier); debug("submitTransaction: Gas estimation:", estimate); return estimate; } catch (e) { debug("submitTransaction: Gas estimation failed, only sensible error is EVM error", e); throw new Error(CivilErrors.EvmException); } }, async getRaw( destination: string, value: BigNumber, data: string, txData?: TransactionConfig, ): Promise { const self = this as MultiSigWalletContract; const options: TransactionConfig = {... txData}; if (!isDefined(options.gas)) { options.gas = await self.submitTransaction.estimateGasAsync( destination, value, data, options, ); } options.data = self.instance.methods.submitTransaction(destination, value, data, ).encodeABI(); return options; }, }; public confirmTransaction = { async sendTransactionAsync( transactionId: BigNumber, txData?: TransactionConfig, ): Promise { const self = this as MultiSigWalletContract; const txOptions: TransactionConfig = { ...self.configuration.txDefaults, ...txData }; debug(`confirmTransaction(transactionId: BigNumber, )`); debug("confirmTransaction: txOptions:", txOptions); debug("confirmTransaction: Sending with:", transactionId, ); txOptions.to = self.instance.options.address; txOptions.data = self.instance.methods.confirmTransaction(transactionId, ).encodeABI(); if (!isDefined(txOptions.gas)) { txOptions.gas = await self.ethApi.estimateGas(txOptions); } if (!isDefined(txOptions.gasPrice)) { const gasPricePromise = self.ethApi.getGasPriceString() txOptions.gasPrice = (await gasPricePromise).toString(); debug("confirmTransaction: new gas price: ", txOptions.gasPrice); } return self.ethApi.sendTransaction(txOptions) }, async estimateGasAsync( transactionId: BigNumber, txData?: TransactionConfig, ): Promise { const self = this as MultiSigWalletContract; const estimateGas = self.instance.methods.confirmTransaction(transactionId, ).estimateGas try { const estimate = Math.floor(await estimateGas(txData) * self.configuration.estimationMultiplier); debug("confirmTransaction: Gas estimation:", estimate); return estimate; } catch (e) { debug("confirmTransaction: Gas estimation failed, only sensible error is EVM error", e); throw new Error(CivilErrors.EvmException); } }, async getRaw( transactionId: BigNumber, txData?: TransactionConfig, ): Promise { const self = this as MultiSigWalletContract; const options: TransactionConfig = {... txData}; if (!isDefined(options.gas)) { options.gas = await self.confirmTransaction.estimateGasAsync( transactionId, options, ); } options.data = self.instance.methods.confirmTransaction(transactionId, ).encodeABI(); return options; }, }; public revokeConfirmation = { async sendTransactionAsync( transactionId: BigNumber, txData?: TransactionConfig, ): Promise { const self = this as MultiSigWalletContract; const txOptions: TransactionConfig = { ...self.configuration.txDefaults, ...txData }; debug(`revokeConfirmation(transactionId: BigNumber, )`); debug("revokeConfirmation: txOptions:", txOptions); debug("revokeConfirmation: Sending with:", transactionId, ); txOptions.to = self.instance.options.address; txOptions.data = self.instance.methods.revokeConfirmation(transactionId, ).encodeABI(); if (!isDefined(txOptions.gas)) { txOptions.gas = await self.ethApi.estimateGas(txOptions); } if (!isDefined(txOptions.gasPrice)) { const gasPricePromise = self.ethApi.getGasPriceString() txOptions.gasPrice = (await gasPricePromise).toString(); debug("revokeConfirmation: new gas price: ", txOptions.gasPrice); } return self.ethApi.sendTransaction(txOptions) }, async estimateGasAsync( transactionId: BigNumber, txData?: TransactionConfig, ): Promise { const self = this as MultiSigWalletContract; const estimateGas = self.instance.methods.revokeConfirmation(transactionId, ).estimateGas try { const estimate = Math.floor(await estimateGas(txData) * self.configuration.estimationMultiplier); debug("revokeConfirmation: Gas estimation:", estimate); return estimate; } catch (e) { debug("revokeConfirmation: Gas estimation failed, only sensible error is EVM error", e); throw new Error(CivilErrors.EvmException); } }, async getRaw( transactionId: BigNumber, txData?: TransactionConfig, ): Promise { const self = this as MultiSigWalletContract; const options: TransactionConfig = {... txData}; if (!isDefined(options.gas)) { options.gas = await self.revokeConfirmation.estimateGasAsync( transactionId, options, ); } options.data = self.instance.methods.revokeConfirmation(transactionId, ).encodeABI(); return options; }, }; public executeTransaction = { async sendTransactionAsync( transactionId: BigNumber, txData?: TransactionConfig, ): Promise { const self = this as MultiSigWalletContract; const txOptions: TransactionConfig = { ...self.configuration.txDefaults, ...txData }; debug(`executeTransaction(transactionId: BigNumber, )`); debug("executeTransaction: txOptions:", txOptions); debug("executeTransaction: Sending with:", transactionId, ); txOptions.to = self.instance.options.address; txOptions.data = self.instance.methods.executeTransaction(transactionId, ).encodeABI(); if (!isDefined(txOptions.gas)) { txOptions.gas = await self.ethApi.estimateGas(txOptions); } if (!isDefined(txOptions.gasPrice)) { const gasPricePromise = self.ethApi.getGasPriceString() txOptions.gasPrice = (await gasPricePromise).toString(); debug("executeTransaction: new gas price: ", txOptions.gasPrice); } return self.ethApi.sendTransaction(txOptions) }, async estimateGasAsync( transactionId: BigNumber, txData?: TransactionConfig, ): Promise { const self = this as MultiSigWalletContract; const estimateGas = self.instance.methods.executeTransaction(transactionId, ).estimateGas try { const estimate = Math.floor(await estimateGas(txData) * self.configuration.estimationMultiplier); debug("executeTransaction: Gas estimation:", estimate); return estimate; } catch (e) { debug("executeTransaction: Gas estimation failed, only sensible error is EVM error", e); throw new Error(CivilErrors.EvmException); } }, async getRaw( transactionId: BigNumber, txData?: TransactionConfig, ): Promise { const self = this as MultiSigWalletContract; const options: TransactionConfig = {... txData}; if (!isDefined(options.gas)) { options.gas = await self.executeTransaction.estimateGasAsync( transactionId, options, ); } options.data = self.instance.methods.executeTransaction(transactionId, ).encodeABI(); return options; }, }; public isConfirmed = { async callAsync( transactionId: BigNumber, ): Promise { const self = this as MultiSigWalletContract; return self.instance.methods.isConfirmed(transactionId, ).call(); } } public getConfirmationCount = { async callAsync( transactionId: BigNumber, ): Promise { const self = this as MultiSigWalletContract; return self.instance.methods.getConfirmationCount(transactionId, ).call(); } } public getTransactionCount = { async callAsync( pending: boolean, executed: boolean, ): Promise { const self = this as MultiSigWalletContract; return self.instance.methods.getTransactionCount(pending, executed, ).call(); } } public getOwners = { async callAsync( ): Promise { const self = this as MultiSigWalletContract; return self.instance.methods.getOwners().call(); } } public getConfirmations = { async callAsync( transactionId: BigNumber, ): Promise { const self = this as MultiSigWalletContract; return self.instance.methods.getConfirmations(transactionId, ).call(); } } public getTransactionIds = { async callAsync( from: BigNumber, to: BigNumber, pending: boolean, executed: boolean, ): Promise { const self = this as MultiSigWalletContract; return self.instance.methods.getTransactionIds(from, to, pending, executed, ).call(); } } public ConfirmationStream = streamifyEvent (this.instance, "Confirmation"); public RevocationStream = streamifyEvent (this.instance, "Revocation"); public SubmissionStream = streamifyEvent (this.instance, "Submission"); public ExecutionStream = streamifyEvent (this.instance, "Execution"); public ExecutionFailureStream = streamifyEvent (this.instance, "ExecutionFailure"); public DepositStream = streamifyEvent (this.instance, "Deposit"); public OwnerAdditionStream = streamifyEvent (this.instance, "OwnerAddition"); public OwnerRemovalStream = streamifyEvent (this.instance, "OwnerRemoval"); public RequirementChangeStream = streamifyEvent (this.instance, "RequirementChange"); // tslint:enable:variable-name private constructor(instance: Contract, ethApi: EthApi) { super(instance, ethApi); // Call methods access this instance while being in a sub-object, we're rebinding what // "this" means for everything in this class, this also requires "noImplicitThis" to be false bindNestedAll(this, ["constructor", "instance", "defaults", "ethApi"]); } // tslint:enable:member-ordering } // tslint:disable:no-namespace export namespace MultiSigWallet { export enum Events { Confirmation = "Confirmation", Revocation = "Revocation", Submission = "Submission", Execution = "Execution", ExecutionFailure = "ExecutionFailure", Deposit = "Deposit", OwnerAddition = "OwnerAddition", OwnerRemoval = "OwnerRemoval", RequirementChange = "RequirementChange", } // tslint:disable:class-name export namespace Args { export interface Confirmation { sender: string; transactionId: BigNumber; } export interface Revocation { sender: string; transactionId: BigNumber; } export interface Submission { transactionId: BigNumber; } export interface Execution { transactionId: BigNumber; } export interface ExecutionFailure { transactionId: BigNumber; } export interface Deposit { sender: string; value: BigNumber; } export interface OwnerAddition { owner: string; } export interface OwnerRemoval { owner: string; } export interface RequirementChange { required: BigNumber; } } // tslint:enable:class-name export namespace Logs { export type Confirmation = DecodedLogEntry; export type Revocation = DecodedLogEntry; export type Submission = DecodedLogEntry; export type Execution = DecodedLogEntry; export type ExecutionFailure = DecodedLogEntry; export type Deposit = DecodedLogEntry; export type OwnerAddition = DecodedLogEntry; export type OwnerRemoval = DecodedLogEntry; export type RequirementChange = DecodedLogEntry; export type All = Logs.Confirmation | Logs.Revocation | Logs.Submission | Logs.Execution | Logs.ExecutionFailure | Logs.Deposit | Logs.OwnerAddition | Logs.OwnerRemoval | Logs.RequirementChange; } export namespace LogEvents { export type Confirmation = DecodedLogEntryEvent; export type Revocation = DecodedLogEntryEvent; export type Submission = DecodedLogEntryEvent; export type Execution = DecodedLogEntryEvent; export type ExecutionFailure = DecodedLogEntryEvent; export type Deposit = DecodedLogEntryEvent; export type OwnerAddition = DecodedLogEntryEvent; export type OwnerRemoval = DecodedLogEntryEvent; export type RequirementChange = DecodedLogEntryEvent; export type All = LogEvents.Confirmation | LogEvents.Revocation | LogEvents.Submission | LogEvents.Execution | LogEvents.ExecutionFailure | LogEvents.Deposit | LogEvents.OwnerAddition | LogEvents.OwnerRemoval | LogEvents.RequirementChange; } export type Receipt = DecodedTransactionReceipt; export type EventReceipt = DecodedTransactionReceipt; } // tslint:enable:no-namespace