Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Implemented custom contract set loading #110

Merged
merged 1 commit into from
Apr 4, 2018
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
17 changes: 10 additions & 7 deletions package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

4 changes: 2 additions & 2 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@
"lint": "eslint ./",
"doc": "cd docs/source/ && sphinx-build . ../build && node -e 'require(\"open\")(\"../build/index.html\")'",
"compile": "cd node_modules/@gnosis.pm/gnosis-core-contracts && truffle compile",
"migrate": "npm run migrate-core && npm run migrate-oly",
"migrate": "npm run migrate-core",
"migrate-core": "cd node_modules/@gnosis.pm/gnosis-core-contracts && truffle migrate",
"migrate-oly": "cd node_modules/@gnosis.pm/olympia-token && truffle migrate",
"netreset": "npm run netreset-core && npm run netreset-oly",
Expand Down Expand Up @@ -38,6 +38,7 @@
"license": "MIT",
"homepage": "https://github.com/gnosis/gnosis.js#readme",
"devDependencies": {
"@gnosis.pm/olympia-token": "^1.2.1",
"babel-cli": "^6.26.0",
"babel-core": "^6.26.0",
"babel-eslint": "^8.2.2",
Expand Down Expand Up @@ -71,7 +72,6 @@
},
"dependencies": {
"@gnosis.pm/gnosis-core-contracts": "^1.0.3",
"@gnosis.pm/olympia-token": "^1.2.1",
"babel-polyfill": "^6.26.0",
"babel-runtime": "^6.26.0",
"decimal.js": "^10.0.0",
Expand Down
48 changes: 31 additions & 17 deletions src/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -49,9 +49,6 @@ const contractArtifacts = [
'StandardMarketFactory',
].map((name) => require(`@gnosis.pm/gnosis-core-contracts/build/contracts/${name}.json`))

contractArtifacts.push(require('@gnosis.pm/olympia-token/build/contracts/OlympiaToken.json'))
contractArtifacts.push(require('@gnosis.pm/olympia-token/build/contracts/AddressRegistry.json'))

const instanceModules = [oracles, events, markets]

/**
Expand Down Expand Up @@ -117,7 +114,6 @@ class Gnosis {
* - `Market <https://gnosis.github.io/gnosis-contracts/docs/Market>`_
* - `StandardMarket <https://gnosis.github.io/gnosis-contracts/docs/StandardMarket>`_
* - `Standard Market Factory <https://gnosis.github.io/gnosis-contracts/docs/StandardMarketFactory>`_
* - `OlympiaToken <https://github.com/gnosis/olympia-token>`_
*
* These are configured to use the web3 provider specified in Gnosis.create or subsequently modified with Gnosis.setWeb3Provider. The default gas costs for these abstractions are set to the maximum cost of their respective entries found in the `gas-stats.json` file built from the `core contracts <https://github.com/gnosis/gnosis-contracts#readme>`_. Additionally, the default message sender (i.e. `from` address) is set via the optional `defaultAccount` param in Gnosis.setWeb3Provider.
*
Expand Down Expand Up @@ -150,6 +146,7 @@ class Gnosis {
})

this.TruffleContract = TruffleContract
this.instanceNames = {}

instanceModules.forEach((module) => {
Object.keys(module).forEach((instanceProp) => {
Expand Down Expand Up @@ -243,19 +240,8 @@ class Gnosis {
*/
this.trySettingContractInstance('lmsrMarketMaker', this.contracts.LMSRMarketMaker),

/**
* If `OlympiaToken <https://github.com/gnosis/olympia-token>`_ is deployed to the current network (this should only work for Rinkeby), this will be set to an OlympiaToken contract abstraction pointing at the deployment address.
*
* @member {Contract} Gnosis#olympiaToken
*/
this.trySettingContractInstance('olympiaToken', this.contracts.OlympiaToken),

/**
* If `AddressRegistry <https://github.com/gnosis/olympia-token>`_ is deployed to the current network (this should only work for Rinkeby), this will be set to an AddressRegistry contract abstraction pointing at the deployment address. This is intended for use with Olympia.
*
* @member {Contract} Gnosis#olympiaAddressRegistry
*/
this.trySettingContractInstance('olympiaAddressRegistry', this.contracts.AddressRegistry),
..._.toPairs(this.instanceNames).map(([cName, iName]) =>
this.trySettingContractInstance(iName, this.contracts[cName])),
])
}

Expand All @@ -270,6 +256,34 @@ class Gnosis {
}
}

/**
* Imports contracts into this Gnosis instance using an object mapping contract names to their corresponding Truffle artifacts. Additionally, attempt to set attributes on the Gnosis instance corresponding to `instanceNames`.
*
* Note: this method is asynchronous and will return a Promise
*
* @param {Object} artifacts - Object mapping contract names to Truffle artifacts.
* @param {Object} instanceNames - Object mapping contract names to the name of an attribute on the Gnosis instance which will represent the deployed version of the contract, analogous to :attr:`standardMarketFactory` or :attr:`lmsrMarketMaker`.
*/
async importContracts(artifacts, instanceNames) {
_.forOwn(artifacts, (artifact, name) => {
if(this.contracts[name]) {
throw new Error(`custom contract ${ name } already exists in contract set!`)
}

const contract = TruffleContract(artifact)
contract.setProvider(this.web3.currentProvider)
contract.defaults({
from: this.defaultAccount
})

this.contracts[name] = contract
})

Object.assign(this.instanceNames, instanceNames)

await Promise.all(_.toPairs(instanceNames).map(([cName, iName]) =>
this.trySettingContractInstance(iName, this.contracts[cName])))
}

setDefaultAccount (account) {
/**
Expand Down
25 changes: 22 additions & 3 deletions test/test_gnosis.js
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
import assert from 'assert'
import ganache from 'ganache-cli'
import olympiaArtifacts from '@gnosis.pm/olympia-token'
import Gnosis from '../src/index'
import {
description,
Expand Down Expand Up @@ -77,12 +78,30 @@ describe('Gnosis', function () {
assert.equal(gnosis.etherToken.address, '0xc02aaa39b223fe8d0a0e5c4f27ead9083c756cc2')
})

it('initializes on Rinkeby with Olympia related contracts', async () => {
let gnosis = await Gnosis.create({
ethereum: ganache.provider({ network_id: 4 }),
it('can import custom deployed smart contract sets with config data', async () => {
let gnosis = await Gnosis.create(options)

await gnosis.importContracts(olympiaArtifacts, {
OlympiaToken: 'olympiaToken',
AddressRegistry: 'olympiaAddressRegistry',
})

assert.notEqual(gnosis.contracts.PlayToken, null)
assert.equal(gnosis.olympiaToken, undefined)
assert.equal(gnosis.olympiaAddressRegistry, undefined)

await gnosis.setWeb3Provider(ganache.provider({ network_id: 4 }))

assert.equal(gnosis.olympiaToken.address, '0xa0c107db0e9194c18359d3265289239453b56cf2')
assert.equal(gnosis.olympiaAddressRegistry.address, '0x79da1c9ef6bf6bc64e66f8abffddc1a093e50f13')

// TODO: Truffle contracts cache the address last used to represent deployed contracts
// even after the provider has changed to provide for another network.
// When this behavior is no longer the case, the next bit can be uncommented and should pass.
// await gnosis.setWeb3Provider(ganache.provider())

// assert.equal(gnosis.olympiaToken, undefined)
// assert.equal(gnosis.olympiaAddressRegistry, undefined)
})

it('reports more informative error messages and logs messages', async () => {
Expand Down