This repository has been archived by the owner on Jul 9, 2021. It is now read-only.
-
Notifications
You must be signed in to change notification settings - Fork 465
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Merge pull request #151 from 0xProject/feature/remove-truffle-contracts
Remove truffle contracts dependency
- Loading branch information
Showing
23 changed files
with
658 additions
and
1,145 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,5 +1,10 @@ | ||
# CHANGELOG | ||
|
||
v0.13.0 - _TBD, 2017_ | ||
* Made all the functions submitting transactions to the network to immediately return transaction hash (#151) | ||
* Added `zeroEx.awaitTransactionMinedAsync` (#151) | ||
* Added `TransactionReceiptWithDecodedLogs`, `LogWithDecodedArgs`, `DecodedLogArgs` to public types (#151) | ||
|
||
v0.12.1 - _September 2, 2017_ | ||
* Added the support for [email protected] provider (#142) | ||
* Added the optional `zeroExConfig` parameter to the constructor of `ZeroEx` (#139) | ||
|
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,22 +1,35 @@ | ||
import * as _ from 'lodash'; | ||
import * as BigNumber from 'bignumber.js'; | ||
import * as Web3 from 'web3'; | ||
import * as abiDecoder from 'abi-decoder'; | ||
import {SchemaValidator, schemas} from '0x-json-schemas'; | ||
import {bigNumberConfigs} from './bignumber_config'; | ||
import * as ethUtil from 'ethereumjs-util'; | ||
import contract = require('truffle-contract'); | ||
import findVersions = require('find-versions'); | ||
import compareVersions = require('compare-versions'); | ||
import {Web3Wrapper} from './web3_wrapper'; | ||
import {constants} from './utils/constants'; | ||
import {utils} from './utils/utils'; | ||
import {signatureUtils} from './utils/signature_utils'; | ||
import {assert} from './utils/assert'; | ||
import {artifacts} from './artifacts'; | ||
import {ExchangeWrapper} from './contract_wrappers/exchange_wrapper'; | ||
import {TokenRegistryWrapper} from './contract_wrappers/token_registry_wrapper'; | ||
import {EtherTokenWrapper} from './contract_wrappers/ether_token_wrapper'; | ||
import {TokenWrapper} from './contract_wrappers/token_wrapper'; | ||
import {TokenTransferProxyWrapper} from './contract_wrappers/token_transfer_proxy_wrapper'; | ||
import {ECSignature, ZeroExError, Order, SignedOrder, Web3Provider, ZeroExConfig} from './types'; | ||
import { | ||
ECSignature, | ||
ZeroExError, | ||
Order, | ||
SignedOrder, | ||
Web3Provider, | ||
ZeroExConfig, | ||
TransactionReceipt, | ||
DecodedLogArgs, | ||
TransactionReceiptWithDecodedLogs, | ||
LogWithDecodedArgs, | ||
} from './types'; | ||
|
||
// Customize our BigNumber instances | ||
bigNumberConfigs.configure(); | ||
|
@@ -170,13 +183,17 @@ export class ZeroEx { | |
// We re-assign the send method so that [email protected] providers work with 0x.js | ||
(provider as any).sendAsync = (provider as any).send; | ||
} | ||
this._web3Wrapper = new Web3Wrapper(provider); | ||
this._registerArtifactsWithinABIDecoder(); | ||
const gasPrice = _.isUndefined(config) ? undefined : config.gasPrice; | ||
this.token = new TokenWrapper(this._web3Wrapper, gasPrice); | ||
this.proxy = new TokenTransferProxyWrapper(this._web3Wrapper, gasPrice); | ||
this.exchange = new ExchangeWrapper(this._web3Wrapper, this.token, gasPrice); | ||
this.tokenRegistry = new TokenRegistryWrapper(this._web3Wrapper, gasPrice); | ||
this.etherToken = new EtherTokenWrapper(this._web3Wrapper, this.token, gasPrice); | ||
const defaults = { | ||
gasPrice, | ||
}; | ||
this._web3Wrapper = new Web3Wrapper(provider, defaults); | ||
this.token = new TokenWrapper(this._web3Wrapper); | ||
this.proxy = new TokenTransferProxyWrapper(this._web3Wrapper); | ||
this.exchange = new ExchangeWrapper(this._web3Wrapper, this.token); | ||
this.tokenRegistry = new TokenRegistryWrapper(this._web3Wrapper); | ||
this.etherToken = new EtherTokenWrapper(this._web3Wrapper, this.token); | ||
} | ||
/** | ||
* Sets a new web3 provider for 0x.js. Updating the provider will stop all | ||
|
@@ -249,4 +266,47 @@ export class ZeroEx { | |
|
||
throw new Error(ZeroExError.InvalidSignature); | ||
} | ||
/** | ||
* Waits for a transaction to be mined and returns the transaction receipt. | ||
* @param txHash Transaction hash | ||
* @param pollingIntervalMs How often (in ms) should we check if the transaction is mined. | ||
* @return Transaction receipt with decoded log args. | ||
*/ | ||
public async awaitTransactionMinedAsync( | ||
txHash: string, pollingIntervalMs: number = 1000): Promise<TransactionReceiptWithDecodedLogs> { | ||
const txReceiptPromise = new Promise( | ||
(resolve: (receipt: TransactionReceiptWithDecodedLogs) => void, reject) => { | ||
const intervalId = setInterval(async () => { | ||
const transactionReceipt = await this._web3Wrapper.getTransactionReceiptAsync(txHash); | ||
if (!_.isNull(transactionReceipt)) { | ||
clearInterval(intervalId); | ||
const logsWithDecodedArgs = _.map(transactionReceipt.logs, (log: Web3.LogEntry) => { | ||
const decodedLog = abiDecoder.decodeLogs([log])[0]; | ||
const decodedArgs = decodedLog.events; | ||
const args: DecodedLogArgs = {}; | ||
_.forEach(decodedArgs, arg => { | ||
args[arg.name] = arg.value; | ||
}); | ||
const logWithDecodedArgs: LogWithDecodedArgs = { | ||
...log, | ||
args, | ||
event: decodedLog.name, | ||
}; | ||
return logWithDecodedArgs; | ||
}); | ||
const transactionReceiptWithDecodedLogArgs: TransactionReceiptWithDecodedLogs = { | ||
...transactionReceipt, | ||
logs: logsWithDecodedArgs, | ||
}; | ||
resolve(transactionReceiptWithDecodedLogArgs); | ||
} | ||
}, pollingIntervalMs); | ||
}); | ||
return txReceiptPromise; | ||
} | ||
private _registerArtifactsWithinABIDecoder(): void { | ||
for (const artifact of _.values(artifacts)) { | ||
abiDecoder.addABI(artifact.abi); | ||
} | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,13 @@ | ||
import * as TokenArtifact from './artifacts/Token.json'; | ||
import * as ExchangeArtifact from './artifacts/Exchange.json'; | ||
import * as EtherTokenArtifact from './artifacts/EtherToken.json'; | ||
import * as TokenRegistryArtifact from './artifacts/TokenRegistry.json'; | ||
import * as TokenTransferProxyArtifact from './artifacts/TokenTransferProxy.json'; | ||
|
||
export const artifacts = { | ||
TokenArtifact: TokenArtifact as any as Artifact, | ||
ExchangeArtifact: ExchangeArtifact as any as Artifact, | ||
EtherTokenArtifact: EtherTokenArtifact as any as Artifact, | ||
TokenRegistryArtifact: TokenRegistryArtifact as any as Artifact, | ||
TokenTransferProxyArtifact: TokenTransferProxyArtifact as any as Artifact, | ||
}; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -391,4 +391,4 @@ | |
}, | ||
"schema_version": "0.0.5", | ||
"updated_at": 1503318938233 | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,80 @@ | ||
import * as Web3 from 'web3'; | ||
import * as _ from 'lodash'; | ||
import promisify = require('es6-promisify'); | ||
import {SchemaValidator, schemas} from '0x-json-schemas'; | ||
import {AbiType} from './types'; | ||
|
||
export class Contract implements Web3.ContractInstance { | ||
public address: string; | ||
public abi: Web3.ContractAbi; | ||
private contract: Web3.ContractInstance; | ||
private defaults: Partial<Web3.TxData>; | ||
private validator: SchemaValidator; | ||
// This class instance is going to be populated with functions and events depending on the ABI | ||
// and we don't know their types in advance | ||
[name: string]: any; | ||
constructor(web3ContractInstance: Web3.ContractInstance, defaults: Partial<Web3.TxData>) { | ||
this.contract = web3ContractInstance; | ||
this.address = web3ContractInstance.address; | ||
this.abi = web3ContractInstance.abi; | ||
this.defaults = defaults; | ||
this.populateEvents(); | ||
this.populateFunctions(); | ||
this.validator = new SchemaValidator(); | ||
} | ||
private populateFunctions(): void { | ||
const functionsAbi = _.filter(this.abi, abiPart => abiPart.type === AbiType.Function); | ||
_.forEach(functionsAbi, (functionAbi: Web3.MethodAbi) => { | ||
if (functionAbi.constant) { | ||
const cbStyleCallFunction = this.contract[functionAbi.name].call; | ||
this[functionAbi.name] = { | ||
callAsync: promisify(cbStyleCallFunction, this.contract), | ||
}; | ||
} else { | ||
const cbStyleFunction = this.contract[functionAbi.name]; | ||
const cbStyleEstimateGasFunction = this.contract[functionAbi.name].estimateGas; | ||
this[functionAbi.name] = { | ||
estimateGasAsync: promisify(cbStyleEstimateGasFunction, this.contract), | ||
sendTransactionAsync: this.promisifyWithDefaultParams(cbStyleFunction), | ||
}; | ||
} | ||
}); | ||
} | ||
private populateEvents(): void { | ||
const eventsAbi = _.filter(this.abi, abiPart => abiPart.type === AbiType.Event); | ||
_.forEach(eventsAbi, (eventAbi: Web3.EventAbi) => { | ||
this[eventAbi.name] = this.contract[eventAbi.name]; | ||
}); | ||
} | ||
private promisifyWithDefaultParams(fn: (...args: any[]) => void): (...args: any[]) => Promise<any> { | ||
const promisifiedWithDefaultParams = (...args: any[]) => { | ||
const promise = new Promise((resolve, reject) => { | ||
const lastArg = args[args.length - 1]; | ||
let txData: Partial<Web3.TxData> = {}; | ||
if (this.isTxData(lastArg)) { | ||
txData = args.pop(); | ||
} | ||
txData = { | ||
...this.defaults, | ||
...txData, | ||
}; | ||
const callback = (err: Error, data: any) => { | ||
if (_.isNull(err)) { | ||
resolve(data); | ||
} else { | ||
reject(err); | ||
} | ||
}; | ||
args.push(txData); | ||
args.push(callback); | ||
fn.apply(this.contract, args); | ||
}); | ||
return promise; | ||
}; | ||
return promisifiedWithDefaultParams; | ||
} | ||
private isTxData(lastArg: any): boolean { | ||
const isValid = this.validator.isValid(lastArg, schemas.txDataSchema); | ||
return isValid; | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,53 +1,18 @@ | ||
import * as _ from 'lodash'; | ||
import contract = require('truffle-contract'); | ||
import * as Web3 from 'web3'; | ||
import {Web3Wrapper} from '../web3_wrapper'; | ||
import {ZeroExError, Artifact, ContractInstance} from '../types'; | ||
import {ZeroExError} from '../types'; | ||
import {utils} from '../utils/utils'; | ||
|
||
export class ContractWrapper { | ||
protected _web3Wrapper: Web3Wrapper; | ||
private _gasPrice?: BigNumber.BigNumber; | ||
constructor(web3Wrapper: Web3Wrapper, gasPrice?: BigNumber.BigNumber) { | ||
constructor(web3Wrapper: Web3Wrapper) { | ||
this._web3Wrapper = web3Wrapper; | ||
this._gasPrice = gasPrice; | ||
} | ||
protected async _instantiateContractIfExistsAsync(artifact: Artifact, address?: string): Promise<ContractInstance> { | ||
const c = await contract(artifact); | ||
c.defaults({ | ||
gasPrice: this._gasPrice, | ||
}); | ||
const providerObj = this._web3Wrapper.getCurrentProvider(); | ||
c.setProvider(providerObj); | ||
|
||
const networkIdIfExists = await this._web3Wrapper.getNetworkIdIfExistsAsync(); | ||
const artifactNetworkConfigs = _.isUndefined(networkIdIfExists) ? | ||
undefined : | ||
artifact.networks[networkIdIfExists]; | ||
let contractAddress; | ||
if (!_.isUndefined(address)) { | ||
contractAddress = address; | ||
} else if (!_.isUndefined(artifactNetworkConfigs)) { | ||
contractAddress = artifactNetworkConfigs.address.toLowerCase(); | ||
} | ||
|
||
if (!_.isUndefined(contractAddress)) { | ||
const doesContractExist = await this._web3Wrapper.doesContractExistAtAddressAsync(contractAddress); | ||
if (!doesContractExist) { | ||
throw new Error(ZeroExError.ContractDoesNotExist); | ||
} | ||
} | ||
|
||
try { | ||
const contractInstance = _.isUndefined(address) ? await c.deployed() : await c.at(address); | ||
return contractInstance; | ||
} catch (err) { | ||
const errMsg = `${err}`; | ||
if (_.includes(errMsg, 'not been deployed to detected network')) { | ||
throw new Error(ZeroExError.ContractDoesNotExist); | ||
} else { | ||
utils.consoleLog(`Notice: Error encountered: ${err} ${err.stack}`); | ||
throw new Error(ZeroExError.UnhandledError); | ||
} | ||
} | ||
protected async _instantiateContractIfExistsAsync<A extends Web3.ContractInstance>(artifact: Artifact, | ||
address?: string): Promise<A> { | ||
const contractInstance = | ||
await this._web3Wrapper.getContractInstanceFromArtifactAsync<A>(artifact, address); | ||
return contractInstance; | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.