diff --git a/package.json b/package.json index d356f71..9aa1c36 100644 --- a/package.json +++ b/package.json @@ -67,10 +67,12 @@ }, "dependencies": { "babel-runtime": "^6.26.0", + "eth-sig-util": "^1.4.2", "kleros": "^0.0.5", "kleros-interaction": "^0.0.8", "lodash": "^4.17.4", "truffle-contract": "^2.0.5", - "web3": "^0.20.1" + "web3": "^0.20.1", + "web3-eth-personal": "^1.0.0-beta.34" } } diff --git a/src/constants/error.js b/src/constants/error.js index 5ced8f7..30730fd 100644 --- a/src/constants/error.js +++ b/src/constants/error.js @@ -80,3 +80,8 @@ export const MISSING_STORE_PROVIDER = export const MISSING_CONTRACT_INSTANCE = contractAddress => `No contract instance stored for ${contractAddress}. Please call addContractInstance.` export const ERROR_FETCHING_EVENTS = error => `Unable to fetch events: ${error}` + +// Auth +export const UNABLE_TO_SIGN_TOKEN = `There was an error signing the auth token. Please try again` +export const INVALID_AUTH_TOKEN = msg => + `Authorization Token is invalid: ${msg}` diff --git a/src/contracts/ContractImplementation.js b/src/contracts/ContractImplementation.js index 33c45b0..5dcdcd1 100644 --- a/src/contracts/ContractImplementation.js +++ b/src/contracts/ContractImplementation.js @@ -147,7 +147,6 @@ class ContractImplementation { this._contractLoadedRejecter = reject }) - // we have getters so that abstract classes can provide public access to implementations variables /** * Get the contract address for the currently instantiated contract. * @returns {string} - The address of the contract. diff --git a/src/contracts/abstractions/Arbitrable.js b/src/contracts/abstractions/Arbitrable.js index acc46a8..6a8b58b 100644 --- a/src/contracts/abstractions/Arbitrable.js +++ b/src/contracts/abstractions/Arbitrable.js @@ -160,10 +160,12 @@ class ArbitrableContract extends AbstractContract { getData = async account => { const contractData = await this._contractImplementation.getData() - const storeData = await this._StoreProvider.getContractByAddress( - account, - this._contractImplementation.contractAddress - ) + let storeData = {} + if (account) + storeData = await this._StoreProvider.getContractByAddress( + account, + this._contractImplementation.contractAddress + ) return Object.assign({}, storeData, contractData) } diff --git a/src/contracts/abstractions/Arbitrator.js b/src/contracts/abstractions/Arbitrator.js index d09d54a..907763c 100644 --- a/src/contracts/abstractions/Arbitrator.js +++ b/src/contracts/abstractions/Arbitrator.js @@ -24,8 +24,8 @@ class Arbitrator extends AbstractContract { const _getDisputesForUserFromStore = async account => Promise.all( - (await this._StoreProvider.getDisputesForUser(account)).map(dispute => - this._contractImplementation.getDispute(dispute.disputeId, account) + (await this._StoreProvider.getDisputes(account)).map(dispute => + this._contractImplementation.getDispute(dispute.disputeId) ) ) diff --git a/src/contracts/implementations/arbitrator/KlerosPOC.js b/src/contracts/implementations/arbitrator/KlerosPOC.js index 27c2a4e..6b29731 100644 --- a/src/contracts/implementations/arbitrator/KlerosPOC.js +++ b/src/contracts/implementations/arbitrator/KlerosPOC.js @@ -473,11 +473,12 @@ class KlerosPOC extends ContractImplementation { const openDisputes = await this.getOpenDisputesForSession() const disputes = await Promise.all( - openDisputes.map(async disputeId => { - const draws = await this.getDrawsForJuror(disputeId, account) - - const disputeData = await this.getDispute(disputeId) - disputeData.appealDraws = [] + openDisputes.map(async disputeData => { + const draws = await this.getDrawsForJuror( + disputeData.disputeId, + account + ) + disputeData.appealDraws = disputeData.appealDraws || [] disputeData.appealDraws[disputeData.numberOfAppeals] = draws return disputeData @@ -539,7 +540,7 @@ class KlerosPOC extends ContractImplementation { // If dispute is in the current session, add it to the result array if (dispute.firstSession + dispute.numberOfAppeals === currentSession) - openDisputes.push(disputeId) + openDisputes.push(dispute) // Advance to the next dispute disputeId++ diff --git a/src/kleros.js b/src/kleros.js index 05cd47c..e70e5bb 100644 --- a/src/kleros.js +++ b/src/kleros.js @@ -33,12 +33,14 @@ class Kleros { * use when initializing KlerosPOC * @param {string} arbitrableContractAddress - Address of the arbitrator contract we should * use when initializing KlerosPOC + * @param {string} authToken - Signed token cooresponding to the user profile address. */ constructor( ethereumProvider = isRequired('ethereumProvider'), storeUri = isRequired('storeUri'), arbitratorAddress, - arbitrableContractAddress + arbitrableContractAddress, + authToken ) { // NOTE we default to KlerosPOC and ArbitrableTransaction const _klerosPOC = new contracts.implementations.arbitrator.KlerosPOC( @@ -55,7 +57,7 @@ class Kleros { // **************************** // // KLEROS WRAPPERS this.web3Wrapper = new Web3Wrapper(ethereumProvider) - this.storeWrapper = new StoreProviderWrapper(storeUri) + this.storeWrapper = new StoreProviderWrapper(storeUri, authToken) // ARBITRATOR this.arbitrator = new contracts.abstractions.Arbitrator( _klerosPOC, @@ -78,6 +80,8 @@ class Kleros { this.arbitrable, this.storeWrapper ) + // AUTH + this.auth = new resources.Auth(this.web3Wrapper, this.storeWrapper) } /** @@ -137,6 +141,7 @@ class Kleros { this.arbitrable.setStoreProviderInstance(this.storeWrapper) this.arbitrator.setStoreProviderInstance(this.storeWrapper) this.notifications.setStoreProviderInstance(this.storeWrapper) + this.auth.setStoreProviderInstance(this.storeWrapper) } } diff --git a/src/resources/Auth.js b/src/resources/Auth.js new file mode 100644 index 0000000..b9e2ead --- /dev/null +++ b/src/resources/Auth.js @@ -0,0 +1,78 @@ +import Personal from 'web3-eth-personal' + +import isRequired from '../utils/isRequired' +import { UNABLE_TO_SIGN_TOKEN } from '../constants/error' + +class Auth { + constructor( + web3Wrapper = isRequired('web3Wrapper'), + storeProviderInstance = isRequired('storeProviderInstance') + ) { + this._Web3Wrapper = web3Wrapper + this._StoreProviderInstance = storeProviderInstance + } + + /** + * Set store provider instance. + * @param {object} storeProviderInstance - instance of store provider wrapper. + */ + setStoreProviderInstance = storeProviderInstance => { + this._StoreProviderInstance = storeProviderInstance + } + + /** + * Set an auth token in the Store Provider. Call this instead of validateNewAuthToken + * if you have a signed token saved. + * @param {string} token - Hex representation of signed token. + */ + setAuthToken = token => { + this._StoreProviderInstance.setAuthToken(token) + } + + /** + * Validate a new auth token. Note if you validate a new token old signed tokens + * will not longer be valid regardless of their expiration time. + * @param {string} userAddress - Address of the user profile + * @returns {string} Signed token for future use. + */ + getNewAuthToken = async userAddress => { + const unsignedToken = (await this._StoreProviderInstance.newAuthToken( + userAddress + )).unsignedToken + + const signedToken = await this.signMessage(userAddress, unsignedToken) + // make sure token is valid + if (!await this.validateAuthToken(userAddress, signedToken)) + throw new Error(UNABLE_TO_SIGN_TOKEN) + + return signedToken + } + + /** + * Sign a message with your private key. Uses web3 1.0 personal sign + * @param {string} userAddress - The address with which we want to sign the message + * @param {string} data - Hex encoded data to sign + * @returns {string} signed data + */ + signMessage = (userAddress, data) => { + const ethPersonal = new Personal(this._Web3Wrapper.getProvider()) + return new Promise((resolve, reject) => { + ethPersonal.sign(data, userAddress, (error, result) => { + if (error) reject(error) + + resolve(result) + }) + }) + } + + /** + * Validate an auth token. + * @param {string} userAddress - The address of the user. + * @param {string} authToken - Token to check. + * @returns {Promise} resolves to True if token is valid. + */ + validateAuthToken = (userAddress, authToken) => + this._StoreProviderInstance.isTokenValid(userAddress, authToken) +} + +export default Auth diff --git a/src/resources/Disputes.js b/src/resources/Disputes.js index 262e1a5..19d8ebe 100644 --- a/src/resources/Disputes.js +++ b/src/resources/Disputes.js @@ -79,37 +79,43 @@ class Disputes { // There is no need to handle this event if we are not using the store const disputeId = event.args._disputeID.toNumber() - const contractAddress = this._ArbitratorInstance.getContractAddress() - const existingDispute = await this._StoreProviderInstance.getDispute( - contractAddress, - disputeId + const arbitratorAddress = this._ArbitratorInstance.getContractAddress() + // arbitrator data + const disputeData = await this._ArbitratorInstance.getDispute(disputeId) + // arbitrable contract data + await this._ArbitrableInstance.setContractInstance( + disputeData.arbitrableContractAddress ) - // Add dispute to store if not there - if (_.isNull(existingDispute)) { - // arbitrator data - const disputeData = await this.getDataForDispute(disputeId, account) - // arbitrable contract data - await this._ArbitrableInstance.setContractInstance( - disputeData.arbitrableContractAddress - ) - const arbitrableContractData = await this._ArbitrableInstance.getData() + const arbitrableContractData = await this._ArbitrableInstance.getData( + account + ) + if ( + account === arbitrableContractData.partyA || + account === arbitrableContractData.partyB + ) { // timestamp const blockTimestamp = (await this._ArbitratorInstance.getBlock( event.blockNumber )).timestamp - const appealCreatedAt = disputeData.appealCreatedAt + // Check if dispute has already been stored. This can happen if there was an appeal + const storedDispute = this._StoreProviderInstance.getDisputeDataForUser( + arbitrableContractData.partyA, + arbitratorAddress, + disputeId + ) + const appealCreatedAt = storedDispute.appealCreatedAt || [] appealCreatedAt[disputeData.numberOfAppeals] = blockTimestamp * 1000 - await this._StoreProviderInstance.updateDispute( - contractAddress, + await this._StoreProviderInstance.updateDisputeProfile( + account, + arbitratorAddress, disputeId, { contractAddress: disputeData.arbitrableContractAddress, partyA: arbitrableContractData.partyA, partyB: arbitrableContractData.partyB, - status: disputeData.status, appealCreatedAt } ) @@ -162,35 +168,32 @@ class Disputes { const newPeriod = await this._ArbitratorInstance.getPeriod() // send appeal possible notifications if (newPeriod === arbitratorConstants.PERIOD.APPEAL) { - const disputes = await this._StoreProviderInstance.getDisputesForUser( - account - ) + const disputes = await this._StoreProviderInstance.getDisputes(account) const openDisputes = await this._ArbitratorInstance.getOpenDisputesForSession() const contractAddress = this._ArbitratorInstance.getContractAddress() await Promise.all( - openDisputes.map(async disputeId => { - if ( - _.findIndex( - disputes, - dispute => - dispute.disputeId === disputeId && - dispute.arbitratorAddress === contractAddress - ) >= 0 - ) { + openDisputes.map(async openDispute => { + const disputeIndex = _.findIndex( + disputes, + dispute => + dispute.disputeId === openDispute.disputeId && + dispute.arbitratorAddress === contractAddress + ) + if (disputeIndex >= 0) { // get ruledAt from block timestamp const blockNumber = event.blockNumber const blockTimestamp = (await this._ArbitratorInstance.getBlock( blockNumber )).timestamp - const disputeData = await this.getDataForDispute(disputeId, account) - const appealRuledAt = disputeData.appealRuledAt - appealRuledAt[disputeData.numberOfAppeals] = blockTimestamp * 1000 + const appealRuledAt = disputes[disputeIndex].appealRuledAt || [] + appealRuledAt[openDispute.numberOfAppeals] = blockTimestamp * 1000 - this._StoreProviderInstance.updateDispute( + this._StoreProviderInstance.updateDisputeProfile( + account, contractAddress, - disputeId, + openDispute.disputeId, { appealRuledAt } @@ -211,30 +214,27 @@ class Disputes { const newPeriod = await this._ArbitratorInstance.getPeriod() // send appeal possible notifications if (newPeriod === arbitratorConstants.PERIOD.VOTE) { - const disputes = await this._StoreProviderInstance.getDisputesForUser( - account - ) + const disputes = await this._StoreProviderInstance.getDisputes(account) // contract data const openDisputes = await this._ArbitratorInstance.getOpenDisputesForSession() const contractAddress = this._ArbitratorInstance.getContractAddress() await Promise.all( - openDisputes.map(async disputeId => { - if ( - _.findIndex( - disputes, - dispute => - dispute.disputeId === disputeId && - dispute.arbitratorAddress === contractAddress - ) >= 0 - ) { + openDisputes.map(async openDispute => { + const disputeIndex = _.findIndex( + disputes, + dispute => + dispute.disputeId === openDispute.disputeId && + dispute.arbitratorAddress === contractAddress + ) + if (disputeIndex >= 0) { const deadline = await this._ArbitratorInstance.getDeadlineForOpenDispute() - const disputeData = await this.getDataForDispute(disputeId, account) - const appealDeadlines = disputeData.appealDeadlines - appealDeadlines[disputeData.numberOfAppeals] = deadline + const appealDeadlines = disputes[disputeIndex].appealDeadlines || [] + appealDeadlines[openDispute.numberOfAppeals] = deadline - this._StoreProviderInstance.updateDispute( + this._StoreProviderInstance.updateDisputeProfile( + account, contractAddress, - disputeId, + openDispute.disputeId, { appealDeadlines } @@ -281,7 +281,7 @@ class Disputes { arbitrableContractAddress ) const [arbitrableContractData, evidence] = await Promise.all([ - this._ArbitrableInstance.getData(), + this._ArbitrableInstance.getData(account), this._ArbitrableInstance.getEvidenceForArbitrableContract( arbitrableContractAddress ) @@ -298,15 +298,17 @@ class Disputes { let appealRuledAt = [] let netPNK = 0 try { - const userData = await this._StoreProviderInstance.getDisputeData( + const userData = await this._StoreProviderInstance.getDisputeDataForUser( + account, arbitratorAddress, - disputeId, - account + disputeId ) - if (userData.appealDraws) appealDraws = userData.appealDraws - if (userData.appealCreatedAt) appealCreatedAt = userData.appealCreatedAt - if (userData.appealDeadlines) appealDeadlines = userData.appealDeadlines - if (userData.appealRuledAt) appealRuledAt = userData.appealRuledAt + if (userData.appealDraws) appealDraws = userData.appealDraws || [] + if (userData.appealCreatedAt) + appealCreatedAt = userData.appealCreatedAt || [] + if (userData.appealDeadlines) + appealDeadlines = userData.appealDeadlines || [] + if (userData.appealRuledAt) appealRuledAt = userData.appealRuledAt || [] if (userData.netPNK) netPNK = userData.netPNK // eslint-disable-next-line no-unused-vars } catch (err) { diff --git a/src/resources/Notifications.js b/src/resources/Notifications.js index 7f8b2d2..30218b3 100644 --- a/src/resources/Notifications.js +++ b/src/resources/Notifications.js @@ -147,7 +147,9 @@ class Notifications { contracts.map(async contract => { // load arbitrable contract await this._ArbitrableInstance.setContractInstance(contract.address) - const contractData = await this._ArbitrableInstance.getData() + const contractData = await this._ArbitrableInstance.getData( + contract.partyA + ) const arbitrationCost = await this._ArbitratorInstance.getArbitrationCost( contractData.arbitratorExtraData ) @@ -295,29 +297,28 @@ class Notifications { const arbitratorAddress = this._ArbitratorInstance.getContractAddress() await Promise.all( - openDisputes.map(async disputeId => { + openDisputes.map(async openDispute => { if ( _.findIndex( disputes, dispute => - dispute.disputeId === disputeId && + dispute.disputeId === openDispute.disputeId && dispute.arbitratorAddress === arbitratorAddress ) >= 0 ) { - const dispute = await this._ArbitratorInstance.getDispute(disputeId) const ruling = await this._ArbitratorInstance.currentRulingForDispute( - disputeId, - dispute.numberOfAppeals + openDispute.disputeId, + openDispute.numberOfAppeals ) const notification = await this._newNotification( account, event.transactionHash, - disputeId, // use disputeId instead of logIndex since it doens't have its own event + openDispute.disputeId, // use disputeId instead of logIndex since it doens't have its own event notificationConstants.TYPE.APPEAL_POSSIBLE, 'A ruling has been made. Appeal is possible', { - disputeId: disputeId, + disputeId: openDispute.disputeId, arbitratorAddress, ruling } @@ -625,7 +626,7 @@ class Notifications { // If we have store provider fetch contracts and disputes from the store. if (this._StoreProviderInstance) { - disputes = await this._StoreProviderInstance.getDisputesForUser(account) + disputes = await this._StoreProviderInstance.getDisputes(account) } else if (isJuror) { // We have no way to get contracts. Get disputes from current session // TODO make a function to get open disputes for parites diff --git a/src/resources/index.js b/src/resources/index.js index c3ff838..5c08d4b 100644 --- a/src/resources/index.js +++ b/src/resources/index.js @@ -1,4 +1,5 @@ import Disputes from './Disputes' import Notifications from './Notifications' +import Auth from './Auth' -export { Disputes, Notifications } +export { Disputes, Notifications, Auth } diff --git a/src/utils/StoreProviderWrapper.js b/src/utils/StoreProviderWrapper.js index 14cb501..e43acd0 100644 --- a/src/utils/StoreProviderWrapper.js +++ b/src/utils/StoreProviderWrapper.js @@ -11,9 +11,11 @@ class StoreProviderWrapper { /** * Create a new instance of StoreProviderWrapper. * @param {string} storeProviderUri - The uri of kleros store. + * @param {string} authToken - Signed token cooresponding to user profile address. */ - constructor(storeProviderUri) { + constructor(storeProviderUri, authToken) { this._storeUri = storeProviderUri + this._token = authToken this._storeQueue = new PromiseQueue() } @@ -25,6 +27,12 @@ class StoreProviderWrapper { * @returns {Promise} request promise that resolves to the HTTP response. */ _makeRequest = (verb, uri, body = null) => { + if (verb !== 'GET' && !this._token) { + throw new Error( + 'No auth token set. Cannot make writes to store. Please call setAuthToken or validateNewAuthToken.' + ) + } + const httpRequest = new XMLHttpRequest() return new Promise((resolve, reject) => { try { @@ -34,6 +42,7 @@ class StoreProviderWrapper { 'Content-Type', 'application/json;charset=UTF-8' ) + httpRequest.setRequestHeader('Authorization', this._token) } httpRequest.onreadystatechange = () => { if (httpRequest.readyState === 4) { @@ -42,6 +51,10 @@ class StoreProviderWrapper { body = JSON.parse(httpRequest.responseText) // eslint-disable-next-line no-unused-vars } catch (err) {} + // auth token error + if (httpRequest.status === 401) + reject(errorConstants.INVALID_AUTH_TOKEN(body.error)) + resolve({ body: body, status: httpRequest.status @@ -50,7 +63,7 @@ class StoreProviderWrapper { } httpRequest.send(body) } catch (err) { - reject(err) + reject(errorConstants.REQUEST_FAILED(err)) } }) } @@ -76,47 +89,70 @@ class StoreProviderWrapper { this._storeQueue.fetch(() => this._makeRequest('GET', uri)) // **************************** // - // * Read * // + // * Auth * // // **************************** // /** - * Fetch stored user profile. - * @param {string} userAddress - Address of user. - * @returns {object} - a response object. + * Set the auth token for write requests. + * @param {string} token - Hex string of the signed data token. */ - getUserProfile = async userAddress => { - const httpResponse = await this._makeRequest( + setAuthToken = token => { + this._token = token + } + + /** + * Generate a new unsigned auth token. + * @param {string} userAddress - Address of the user profile. + * @returns {string} Hex encoded unsigned token. + */ + newAuthToken = async userAddress => { + const newTokenResponse = await this._makeRequest( 'GET', - `${this._storeUri}/${userAddress}` + `${this._storeUri}/${userAddress}/authToken` ) - return httpResponse.body + return newTokenResponse.body } /** - * Get all stored data from a dispute. This includes data from the user profile as well - * as the user agnostic dispute data stored separately. - * @param {string} arbitratorAddress - Address of arbitrator contract. - * @param {number} disputeId - Index of the dispute. - * @param {string} userAddress - Address of user. - * @returns {object} - a response object. + * Validate auth token + * @param {string} userAddress - Address of user profile. + * @param {string} token - token to use. Sets token. + * @returns {bool} - True if token is valid. */ - getDisputeData = async (arbitratorAddress, disputeId, userAddress) => { - const userProfile = await this.getUserProfile(userAddress) - if (!userProfile) - throw new Error(errorConstants.PROFILE_NOT_FOUND(userAddress)) + isTokenValid = async (userAddress, token) => { + if (token) this.setAuthToken(token) + + try { + const response = await this._makeRequest( + 'POST', + `${this._storeUri}/${userAddress}/authToken/verify`, + JSON.stringify({}) + ) - let disputeData = _.filter( - userProfile.disputes, - o => - o.arbitratorAddress === arbitratorAddress && o.disputeId === disputeId - ) + return response.status === 201 + // eslint-disable-next-line no-unused-vars + } catch (err) { + return false + } + } + // **************************** // + // * Read * // + // **************************** // + + /** + * Fetch stored user profile. + * @param {string} userAddress - Address of user. + * @returns {object} - a response object. + */ + getUserProfile = async userAddress => { const httpResponse = await this._makeRequest( 'GET', - `${this._storeUri}/arbitrators/${arbitratorAddress}/disputes/${disputeId}` + `${this._storeUri}/${userAddress}` ) - return Object.assign({}, httpResponse.body, disputeData[0]) + + return httpResponse.body } /** @@ -138,32 +174,35 @@ class StoreProviderWrapper { return contract[0] } + /** + * Get all stored data for a dispute. Must exist in User Profile. + * @param {string} userAddress - Address of user. + * @param {string} arbitratorAddress - Address of arbitrator contract. + * @param {number} disputeId - Index of the dispute. + * @returns {object} - a response object. + */ + getDisputeDataForUser = async (userAddress, arbitratorAddress, disputeId) => { + const userProfile = await this.getUserProfile(userAddress) + if (!userProfile) + throw new Error(errorConstants.PROFILE_NOT_FOUND(userAddress)) + + return _.filter( + userProfile.disputes, + o => + o.arbitratorAddress === arbitratorAddress && o.disputeId === disputeId + )[0] + } + /** * Fetch stored disputes for a user. * @param {string} userAddress - Address of user. * @returns {object} - a response object. */ - getDisputesForUser = async userAddress => { + getDisputes = async userAddress => { const userProfile = await this.getUserProfile(userAddress) if (!userProfile) return [] - const disputes = [] - for (let i = 0; i < userProfile.disputes.length; i++) { - const dispute = userProfile.disputes[i] - if (!dispute.arbitratorAddress || _.isNil(dispute.disputeId)) continue - // fetch dispute data - const httpResponse = await this._makeRequest( - 'GET', - `${this._storeUri}/arbitrators/${dispute.arbitratorAddress}/disputes/${ - dispute.disputeId - }` - ) - if (httpResponse.status === 200) { - disputes.push(Object.assign({}, httpResponse.body, dispute)) - } - } - - return disputes + return userProfile.disputes } /** @@ -177,21 +216,6 @@ class StoreProviderWrapper { return userProfile.lastBlock || 0 } - /** - * Fetch user agnostic data stored on a dispute - * @param {string} arbitratorAddress - The address of the arbitrator contract. - * @param {number} disputeId - The index of the dispute. - * @returns {object} - a response object. - */ - getDispute = async (arbitratorAddress, disputeId) => { - const httpResponse = await this._makeRequest( - 'GET', - `${this._storeUri}/arbitrators/${arbitratorAddress}/disputes/${disputeId}` - ) - - return httpResponse.body - } - // **************************** // // * Write * // // **************************** // @@ -265,7 +289,7 @@ class StoreProviderWrapper { `${this._storeUri}/${userAddress}/contracts/${contractAddress}` ) - if (httpResponse.status !== 200) { + if (httpResponse.status !== 201) { throw new Error(errorConstants.REQUEST_FAILED(httpResponse.error)) } @@ -356,33 +380,6 @@ class StoreProviderWrapper { ) } - /** - * Update the user agnostic data on a dispute. - * @param {string} arbitratorAddress - The address of the arbitrator contract. - * @param {number} disputeId - The index of the dispute. - * @param {object} params - The data we are updating. - * @returns {Promise} The resulting dispute data. - */ - updateDispute = async (arbitratorAddress, disputeId, params) => { - const getBodyFn = async () => { - const currentDispute = - (await this.getDispute(arbitratorAddress, disputeId)) || {} - delete currentDispute._id - delete currentDispute.updated_at - - params.arbitratorAddress = arbitratorAddress - params.disputeId = disputeId - - return JSON.stringify({ ...currentDispute, ...params }) - } - - return this.queueWriteRequest( - getBodyFn, - 'POST', - `${this._storeUri}/arbitrators/${arbitratorAddress}/disputes/${disputeId}` - ) - } - /** * Create a new notification in the store. * @param {string} userAddress - The address of the user. diff --git a/src/utils/Web3Wrapper.js b/src/utils/Web3Wrapper.js index 00aa6a1..988d228 100644 --- a/src/utils/Web3Wrapper.js +++ b/src/utils/Web3Wrapper.js @@ -32,6 +32,15 @@ class Web3Wrapper { blockNumber = () => this._web3.eth.blockNumber + sign = (userAddress, data) => + new Promise((resolve, reject) => { + this._web3.eth.sign(userAddress, data, (error, result) => { + if (error) reject(error) + + resolve(result) + }) + }) + getBlock = blockNumber => new Promise((resolve, reject) => { this._web3.eth.getBlock(blockNumber, (error, result) => { diff --git a/tests/integration/storeAuth.test.js b/tests/integration/storeAuth.test.js new file mode 100644 index 0000000..79bc8da --- /dev/null +++ b/tests/integration/storeAuth.test.js @@ -0,0 +1,71 @@ +import Web3 from 'web3' +import sigUtil from 'eth-sig-util' + +import Kleros from '../../src/kleros' +import * as ethConstants from '../../src/constants/eth' + +describe('Auth', () => { + let web3 + let loggedInUserAddress + + beforeAll(async () => { + const provider = await new Web3.providers.HttpProvider( + ethConstants.LOCALHOST_ETH_PROVIDER + ) + web3 = await new Web3(provider) + + loggedInUserAddress = web3.eth.accounts[0] + }) + + it('can sign auth token', async () => { + const mockStoreUri = '' + const ethProvider = new Web3.providers.HttpProvider( + ethConstants.LOCALHOST_ETH_PROVIDER + ) + const mockArbitrator = '0x0' + const mockArbitrable = '0x1' + + const klerosInstance = new Kleros( + ethProvider, + mockStoreUri, + mockArbitrator, + mockArbitrable + ) + + const mockToken = + '0x7b2276657273696f6e223a312c2265787069726174696f6e223a313532353830303831313932307d' + const mockStoreProvider = { + newAuthToken: () => ({ unsignedToken: mockToken }), + setAuthToken: () => true, + isTokenValid: () => true + } + // set new store provider + klerosInstance.auth.setStoreProviderInstance(mockStoreProvider) + + // FIXME testrpc/ganache clients don't support personal_sign yet. Remove this mock once they do. + klerosInstance.auth.signMessage = (userAddress, data) => + new Promise((resolve, reject) => { + web3.eth.sign(userAddress, data, (error, result) => { + if (error) reject(error) + + resolve(result) + }) + }) + + const signedToken = await klerosInstance.auth.getNewAuthToken( + loggedInUserAddress + ) + + expect(signedToken).toBeTruthy() + + // validate token + const msgParams = { + data: mockToken, + sig: signedToken + } + + const authorizedUser = await sigUtil.recoverPersonalSignature(msgParams) + + expect(authorizedUser).toEqual(loggedInUserAddress) + }) +}) diff --git a/tests/unit/contracts/abstractions/Arbitrator.test.js b/tests/unit/contracts/abstractions/Arbitrator.test.js index 04ba45a..37efebd 100644 --- a/tests/unit/contracts/abstractions/Arbitrator.test.js +++ b/tests/unit/contracts/abstractions/Arbitrator.test.js @@ -19,7 +19,7 @@ describe('Arbitrator', () => { disputeId: '1' } const mockStoreProvider = { - getDisputesForUser: mockGetDisputesForUser.mockReturnValue( + getDisputes: mockGetDisputesForUser.mockReturnValue( _asyncMockResponse([mockDispute]) ), setUpUserProfile: mockShouldNotCall @@ -51,7 +51,7 @@ describe('Arbitrator', () => { disputeId: '1' } const mockStoreProvider = { - getDisputesForUser: mockGetDisputesForUser.mockReturnValue( + getDisputes: mockGetDisputesForUser.mockReturnValue( _asyncMockResponse([mockDispute]) ), setUpUserProfile: mockSetUpUserProfile.mockReturnValue( @@ -91,7 +91,7 @@ describe('Arbitrator', () => { appealDraws: [1] } const mockStoreProvider = { - getDisputesForUser: mockGetDisputesForUser.mockReturnValue( + getDisputes: mockGetDisputesForUser.mockReturnValue( _asyncMockResponse([mockDispute]) ), setUpUserProfile: mockSetUpUserProfile.mockReturnValue( diff --git a/tests/unit/resources/Disputes.test.js b/tests/unit/resources/Disputes.test.js index 0013ca2..7ef7e78 100644 --- a/tests/unit/resources/Disputes.test.js +++ b/tests/unit/resources/Disputes.test.js @@ -178,7 +178,7 @@ describe('Disputes', () => { } const mockStoreProvider = { getContractByAddress: jest.fn().mockReturnValue(mockContract), - getDisputeData: jest.fn().mockReturnValue(mockUserData) + getDisputeDataForUser: jest.fn().mockReturnValue(mockUserData) } disputesInstance.setStoreProviderInstance(mockStoreProvider) @@ -293,7 +293,7 @@ describe('Disputes', () => { } const mockStoreProvider = { getContractByAddress: jest.fn().mockReturnValue(mockContract), - getDisputeData: jest.fn().mockReturnValue(mockUserData) + getDisputeDataForUser: jest.fn().mockReturnValue(mockUserData) } disputesInstance.setStoreProviderInstance(mockStoreProvider) @@ -410,7 +410,7 @@ describe('Disputes', () => { } const mockStoreProvider = { getContractByAddress: jest.fn().mockReturnValue(mockContract), - getDisputeData: jest.fn().mockReturnValue(mockUserData) + getDisputeDataForUser: jest.fn().mockReturnValue(mockUserData) } disputesInstance.setStoreProviderInstance(mockStoreProvider) diff --git a/yarn.lock b/yarn.lock index d970577..a50f7f4 100644 --- a/yarn.lock +++ b/yarn.lock @@ -232,6 +232,13 @@ abbrev@1: version "1.1.1" resolved "https://registry.yarnpkg.com/abbrev/-/abbrev-1.1.1.tgz#f8f2c887ad10bf67f634f005b6987fed3179aac8" +accepts@~1.3.5: + version "1.3.5" + resolved "https://registry.yarnpkg.com/accepts/-/accepts-1.3.5.tgz#eb777df6011723a3b14e8a72c0805c8e86746bd2" + dependencies: + mime-types "~2.1.18" + negotiator "0.6.1" + acorn-dynamic-import@^3.0.0: version "3.0.0" resolved "https://registry.yarnpkg.com/acorn-dynamic-import/-/acorn-dynamic-import-3.0.0.tgz#901ceee4c7faaef7e07ad2a47e890675da50a278" @@ -342,6 +349,10 @@ any-observable@^0.2.0: version "0.2.0" resolved "https://registry.yarnpkg.com/any-observable/-/any-observable-0.2.0.tgz#c67870058003579009083f54ac0abafb5c33d242" +any-promise@1.3.0: + version "1.3.0" + resolved "https://registry.yarnpkg.com/any-promise/-/any-promise-1.3.0.tgz#abc6afeedcea52e809cdc0376aed3ce39635d17f" + anymatch@^1.3.0: version "1.3.2" resolved "https://registry.yarnpkg.com/anymatch/-/anymatch-1.3.2.tgz#553dcb8f91e3c889845dfdba34c77721b90b9d7a" @@ -417,6 +428,10 @@ array-find-index@^1.0.1: version "1.0.2" resolved "https://registry.yarnpkg.com/array-find-index/-/array-find-index-1.0.2.tgz#df010aa1287e164bbda6f9723b0a96a1ec4187a1" +array-flatten@1.1.1: + version "1.1.1" + resolved "https://registry.yarnpkg.com/array-flatten/-/array-flatten-1.1.1.tgz#9a5f699051b1e7073328f2a008968b64ea2955d2" + array-ify@^1.0.0: version "1.0.0" resolved "https://registry.yarnpkg.com/array-ify/-/array-ify-1.0.0.tgz#9e528762b4a9066ad163a6962a364418e9626ece" @@ -1343,6 +1358,16 @@ binaryextensions@2: version "2.1.1" resolved "https://registry.yarnpkg.com/binaryextensions/-/binaryextensions-2.1.1.tgz#3209a51ca4a4ad541a3b8d3d6a6d5b83a2485935" +bindings@^1.2.1: + version "1.3.0" + resolved "https://registry.yarnpkg.com/bindings/-/bindings-1.3.0.tgz#b346f6ecf6a95f5a815c5839fc7cdb22502f1ed7" + +bip66@^1.1.3: + version "1.1.5" + resolved "https://registry.yarnpkg.com/bip66/-/bip66-1.1.5.tgz#01fa8748785ca70955d5011217d1b3139969ca22" + dependencies: + safe-buffer "^5.0.1" + block-stream@*: version "0.0.9" resolved "https://registry.yarnpkg.com/block-stream/-/block-stream-0.0.9.tgz#13ebfe778a03205cfe03751481ebb4b3300c126a" @@ -1361,10 +1386,25 @@ bn.js@4.11.6: version "4.11.6" resolved "https://registry.yarnpkg.com/bn.js/-/bn.js-4.11.6.tgz#53344adb14617a13f6e8dd2ce28905d1c0ba3215" -bn.js@^4.0.0, bn.js@^4.1.0, bn.js@^4.1.1, bn.js@^4.4.0: +bn.js@^4.0.0, bn.js@^4.1.0, bn.js@^4.1.1, bn.js@^4.10.0, bn.js@^4.11.0, bn.js@^4.11.3, bn.js@^4.11.6, bn.js@^4.4.0: version "4.11.8" resolved "https://registry.yarnpkg.com/bn.js/-/bn.js-4.11.8.tgz#2cde09eb5ee341f484746bb0309b3253b1b1442f" +body-parser@1.18.2, body-parser@^1.16.0: + version "1.18.2" + resolved "https://registry.yarnpkg.com/body-parser/-/body-parser-1.18.2.tgz#87678a19d84b47d859b83199bd59bce222b10454" + dependencies: + bytes "3.0.0" + content-type "~1.0.4" + debug "2.6.9" + depd "~1.1.1" + http-errors "~1.6.2" + iconv-lite "0.4.19" + on-finished "~2.3.0" + qs "6.5.1" + raw-body "2.3.2" + type-is "~1.6.15" + boolbase@~1.0.0: version "1.0.0" resolved "https://registry.yarnpkg.com/boolbase/-/boolbase-1.0.0.tgz#68dff5fbe60c51eb37725ea9e3ed310dcc1e776e" @@ -1444,6 +1484,17 @@ browserify-aes@^1.0.0, browserify-aes@^1.0.4: inherits "^2.0.1" safe-buffer "^5.0.1" +browserify-aes@^1.0.6: + version "1.2.0" + resolved "https://registry.yarnpkg.com/browserify-aes/-/browserify-aes-1.2.0.tgz#326734642f403dabc3003209853bb70ad428ef48" + dependencies: + buffer-xor "^1.0.3" + cipher-base "^1.0.0" + create-hash "^1.1.0" + evp_bytestokey "^1.0.3" + inherits "^2.0.1" + safe-buffer "^5.0.1" + browserify-cipher@^1.0.0: version "1.0.0" resolved "https://registry.yarnpkg.com/browserify-cipher/-/browserify-cipher-1.0.0.tgz#9988244874bf5ed4e28da95666dcd66ac8fc363a" @@ -1467,6 +1518,12 @@ browserify-rsa@^4.0.0: bn.js "^4.1.0" randombytes "^2.0.1" +browserify-sha3@^0.0.1: + version "0.0.1" + resolved "https://registry.yarnpkg.com/browserify-sha3/-/browserify-sha3-0.0.1.tgz#3ff34a3006ef15c0fb3567e541b91a2340123d11" + dependencies: + js-sha3 "^0.3.1" + browserify-sign@^4.0.0: version "4.0.4" resolved "https://registry.yarnpkg.com/browserify-sign/-/browserify-sign-4.0.4.tgz#aa4eb68e5d7b658baa6bf6a57e630cbd7a93d298" @@ -1505,6 +1562,10 @@ bser@^2.0.0: dependencies: node-int64 "^0.4.0" +buffer-to-arraybuffer@^0.0.5: + version "0.0.5" + resolved "https://registry.yarnpkg.com/buffer-to-arraybuffer/-/buffer-to-arraybuffer-0.0.5.tgz#6064a40fa76eb43c723aba9ef8f6e1216d10511a" + buffer-xor@^1.0.3: version "1.0.3" resolved "https://registry.yarnpkg.com/buffer-xor/-/buffer-xor-1.0.3.tgz#26e61ed1422fb70dd42e6e36729ed51d855fe8d9" @@ -1525,6 +1586,10 @@ builtin-status-codes@^3.0.0: version "3.0.0" resolved "https://registry.yarnpkg.com/builtin-status-codes/-/builtin-status-codes-3.0.0.tgz#85982878e21b98e1c66425e03d0174788f569ee8" +bytes@3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/bytes/-/bytes-3.0.0.tgz#d32815404d689699f85a4ea4fa8755dd13a96048" + cacache@^10.0.1: version "10.0.4" resolved "https://registry.yarnpkg.com/cacache/-/cacache-10.0.4.tgz#6452367999eff9d4188aefd9a14e9d7c6a263460" @@ -1979,10 +2044,18 @@ contains-path@^0.1.0: version "0.1.0" resolved "https://registry.yarnpkg.com/contains-path/-/contains-path-0.1.0.tgz#fe8cf184ff6670b6baef01a9d4861a5cbec4120a" +content-disposition@0.5.2: + version "0.5.2" + resolved "https://registry.yarnpkg.com/content-disposition/-/content-disposition-0.5.2.tgz#0cf68bb9ddf5f2be7961c3a85178cb85dba78cb4" + content-type-parser@^1.0.2: version "1.0.2" resolved "https://registry.yarnpkg.com/content-type-parser/-/content-type-parser-1.0.2.tgz#caabe80623e63638b2502fd4c7f12ff4ce2352e7" +content-type@~1.0.4: + version "1.0.4" + resolved "https://registry.yarnpkg.com/content-type/-/content-type-1.0.4.tgz#e138cc75e040c727b1966fe5e5f8c9aee256fe3b" + conventional-changelog-angular@^1.3.3, conventional-changelog-angular@^1.6.6: version "1.6.6" resolved "https://registry.yarnpkg.com/conventional-changelog-angular/-/conventional-changelog-angular-1.6.6.tgz#b27f2b315c16d0a1f23eb181309d0e6a4698ea0f" @@ -2131,6 +2204,14 @@ convert-source-map@^1.4.0, convert-source-map@^1.5.0: version "1.5.1" resolved "https://registry.yarnpkg.com/convert-source-map/-/convert-source-map-1.5.1.tgz#b8278097b9bc229365de5c62cf5fcaed8b5599e5" +cookie-signature@1.0.6: + version "1.0.6" + resolved "https://registry.yarnpkg.com/cookie-signature/-/cookie-signature-1.0.6.tgz#e303a882b342cc3ee8ca513a79999734dab3ae2c" + +cookie@0.3.1: + version "0.3.1" + resolved "https://registry.yarnpkg.com/cookie/-/cookie-0.3.1.tgz#e7e0a1f9ef43b4c8ba925c5c5a96e806d16873bb" + copy-concurrently@^1.0.0: version "1.0.5" resolved "https://registry.yarnpkg.com/copy-concurrently/-/copy-concurrently-1.0.5.tgz#92297398cae34937fcafd6ec8139c18051f0b5e0" @@ -2158,6 +2239,13 @@ core-util-is@1.0.2, core-util-is@~1.0.0: version "1.0.2" resolved "https://registry.yarnpkg.com/core-util-is/-/core-util-is-1.0.2.tgz#b5fd54220aa2bc5ab57aab7140c940754503c1a7" +cors@^2.8.1: + version "2.8.4" + resolved "https://registry.yarnpkg.com/cors/-/cors-2.8.4.tgz#2bd381f2eb201020105cd50ea59da63090694686" + dependencies: + object-assign "^4" + vary "^1" + cosmiconfig@^3.1.0: version "3.1.0" resolved "https://registry.yarnpkg.com/cosmiconfig/-/cosmiconfig-3.1.0.tgz#640a94bf9847f321800403cd273af60665c73397" @@ -2354,7 +2442,7 @@ dateformat@^3.0.0: version "3.0.3" resolved "https://registry.yarnpkg.com/dateformat/-/dateformat-3.0.3.tgz#a6e37499a4d9a9cf85ef5872044d62901c9889ae" -debug@^2.0.0, debug@^2.1.0, debug@^2.2.0, debug@^2.3.3, debug@^2.6.8, debug@^2.6.9: +debug@2.6.9, debug@^2.0.0, debug@^2.1.0, debug@^2.2.0, debug@^2.3.3, debug@^2.6.8, debug@^2.6.9: version "2.6.9" resolved "https://registry.yarnpkg.com/debug/-/debug-2.6.9.tgz#5d128515df134ff327e90a4c93f4e077a536341f" dependencies: @@ -2381,7 +2469,7 @@ decode-uri-component@^0.2.0: version "0.2.0" resolved "https://registry.yarnpkg.com/decode-uri-component/-/decode-uri-component-0.2.0.tgz#eb3913333458775cb84cd1a1fae062106bb87545" -decompress-response@^3.2.0: +decompress-response@^3.2.0, decompress-response@^3.3.0: version "3.3.0" resolved "https://registry.yarnpkg.com/decompress-response/-/decompress-response-3.3.0.tgz#80a4dd323748384bfa248083622aedec982adff3" dependencies: @@ -2455,6 +2543,14 @@ delegates@^1.0.0: version "1.0.0" resolved "https://registry.yarnpkg.com/delegates/-/delegates-1.0.0.tgz#84c6e159b81904fdca59a0ef44cd870d31250f9a" +depd@1.1.1: + version "1.1.1" + resolved "https://registry.yarnpkg.com/depd/-/depd-1.1.1.tgz#5783b4e1c459f06fa5ca27f991f3d06e7a310359" + +depd@~1.1.1, depd@~1.1.2: + version "1.1.2" + resolved "https://registry.yarnpkg.com/depd/-/depd-1.1.2.tgz#9bcd52e14c097763e749b274c4346ed2e560b5a9" + des.js@^1.0.0: version "1.0.0" resolved "https://registry.yarnpkg.com/des.js/-/des.js-1.0.0.tgz#c074d2e2aa6a8a9a07dbd61f9a15c2cd83ec8ecc" @@ -2462,6 +2558,10 @@ des.js@^1.0.0: inherits "^2.0.1" minimalistic-assert "^1.0.0" +destroy@~1.0.4: + version "1.0.4" + resolved "https://registry.yarnpkg.com/destroy/-/destroy-1.0.4.tgz#978857442c44749e4206613e37946205826abd80" + detect-conflict@^1.0.0: version "1.0.1" resolved "https://registry.yarnpkg.com/detect-conflict/-/detect-conflict-1.0.1.tgz#088657a66a961c05019db7c4230883b1c6b4176e" @@ -2608,6 +2708,14 @@ dotgitignore@^1.0.3: find-up "^2.1.0" minimatch "^3.0.4" +drbg.js@^1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/drbg.js/-/drbg.js-1.0.1.tgz#3e36b6c42b37043823cdbc332d58f31e2445480b" + dependencies: + browserify-aes "^1.0.6" + create-hash "^1.1.2" + create-hmac "^1.1.4" + duplexer3@^0.1.4: version "0.1.4" resolved "https://registry.yarnpkg.com/duplexer3/-/duplexer3-0.1.4.tgz#ee01dd1cac0ed3cbc7fdbea37dc0a8f1ce002ce2" @@ -2631,6 +2739,10 @@ editions@^1.3.3: version "1.3.4" resolved "https://registry.yarnpkg.com/editions/-/editions-1.3.4.tgz#3662cb592347c3168eb8e498a0ff73271d67f50b" +ee-first@1.1.1: + version "1.1.1" + resolved "https://registry.yarnpkg.com/ee-first/-/ee-first-1.1.1.tgz#590c61156b0ae2f4f0255732a158b266bc56b21d" + ejs@^2.3.1: version "2.5.7" resolved "https://registry.yarnpkg.com/ejs/-/ejs-2.5.7.tgz#cc872c168880ae3c7189762fd5ffc00896c9518a" @@ -2643,7 +2755,7 @@ elegant-spinner@^1.0.1: version "1.0.1" resolved "https://registry.yarnpkg.com/elegant-spinner/-/elegant-spinner-1.0.1.tgz#db043521c95d7e303fd8f345bedc3349cfb0729e" -elliptic@^6.0.0: +elliptic@^6.0.0, elliptic@^6.2.3, elliptic@^6.4.0: version "6.4.0" resolved "https://registry.yarnpkg.com/elliptic/-/elliptic-6.4.0.tgz#cac9af8762c85836187003c8dfe193e5e2eae5df" dependencies: @@ -2663,6 +2775,10 @@ emojis-list@^2.0.0: version "2.1.0" resolved "https://registry.yarnpkg.com/emojis-list/-/emojis-list-2.1.0.tgz#4daa4d9db00f9819880c79fa457ae5b09a1fd389" +encodeurl@~1.0.2: + version "1.0.2" + resolved "https://registry.yarnpkg.com/encodeurl/-/encodeurl-1.0.2.tgz#ad3ff4c86ec2d029322f5a02c3a9a606c95b3f59" + encoding@^0.1.11: version "0.1.12" resolved "https://registry.yarnpkg.com/encoding/-/encoding-0.1.12.tgz#538b66f3ee62cd1ab51ec323829d1f9480c74beb" @@ -2737,7 +2853,7 @@ es-to-primitive@^1.1.1: is-date-object "^1.0.1" is-symbol "^1.0.1" -escape-html@1.0.3: +escape-html@1.0.3, escape-html@~1.0.3: version "1.0.3" resolved "https://registry.yarnpkg.com/escape-html/-/escape-html-1.0.3.tgz#0258eae4d3d0c0974de1c169188ef0051d1d1988" @@ -3053,12 +3169,54 @@ esutils@^2.0.2: version "2.0.2" resolved "https://registry.yarnpkg.com/esutils/-/esutils-2.0.2.tgz#0abf4f1caa5bcb1f7a9d8acc6dea4faaa04bac9b" +etag@~1.8.1: + version "1.8.1" + resolved "https://registry.yarnpkg.com/etag/-/etag-1.8.1.tgz#41ae2eeb65efa62268aebfea83ac7d79299b0887" + eth-contract-class@0.0.6: version "0.0.6" resolved "https://registry.yarnpkg.com/eth-contract-class/-/eth-contract-class-0.0.6.tgz#398b8952149cc747cb959fa8b5d480288c7a8bce" dependencies: web3-core-promievent "^1.0.0-beta.21" +eth-lib@0.1.27: + version "0.1.27" + resolved "https://registry.yarnpkg.com/eth-lib/-/eth-lib-0.1.27.tgz#f0b0fd144f865d2d6bf8257a40004f2e75ca1dd6" + dependencies: + bn.js "^4.11.6" + elliptic "^6.4.0" + keccakjs "^0.2.1" + nano-json-stream-parser "^0.1.2" + servify "^0.1.12" + ws "^3.0.0" + xhr-request-promise "^0.1.2" + +eth-sig-util@^1.4.2: + version "1.4.2" + resolved "https://registry.yarnpkg.com/eth-sig-util/-/eth-sig-util-1.4.2.tgz#8d958202c7edbaae839707fba6f09ff327606210" + dependencies: + ethereumjs-abi "git+https://github.com/ethereumjs/ethereumjs-abi.git" + ethereumjs-util "^5.1.1" + +"ethereumjs-abi@git+https://github.com/ethereumjs/ethereumjs-abi.git": + version "0.6.5" + resolved "git+https://github.com/ethereumjs/ethereumjs-abi.git#4ea2fdfed09e8f99117d9362d17c6b01b64a2bcf" + dependencies: + bn.js "^4.10.0" + ethereumjs-util "^5.0.0" + +ethereumjs-util@^5.0.0, ethereumjs-util@^5.1.1: + version "5.2.0" + resolved "https://registry.yarnpkg.com/ethereumjs-util/-/ethereumjs-util-5.2.0.tgz#3e0c0d1741471acf1036052d048623dee54ad642" + dependencies: + bn.js "^4.11.0" + create-hash "^1.1.2" + ethjs-util "^0.1.3" + keccak "^1.0.2" + rlp "^2.0.0" + safe-buffer "^5.1.1" + secp256k1 "^3.0.1" + ethjs-abi@0.1.8: version "0.1.8" resolved "https://registry.yarnpkg.com/ethjs-abi/-/ethjs-abi-0.1.8.tgz#cd288583ed628cdfadaf8adefa3ba1dbcbca6c18" @@ -3075,6 +3233,20 @@ ethjs-abi@^0.2.1: js-sha3 "0.5.5" number-to-bn "1.7.0" +ethjs-unit@0.1.6: + version "0.1.6" + resolved "https://registry.yarnpkg.com/ethjs-unit/-/ethjs-unit-0.1.6.tgz#c665921e476e87bce2a9d588a6fe0405b2c41699" + dependencies: + bn.js "4.11.6" + number-to-bn "1.7.0" + +ethjs-util@^0.1.3: + version "0.1.4" + resolved "https://registry.yarnpkg.com/ethjs-util/-/ethjs-util-0.1.4.tgz#1c8b6879257444ef4d3f3fbbac2ded12cd997d93" + dependencies: + is-hex-prefixed "1.0.0" + strip-hex-prefix "1.0.0" + eventemitter3@1.1.1: version "1.1.1" resolved "https://registry.yarnpkg.com/eventemitter3/-/eventemitter3-1.1.1.tgz#47786bdaa087caf7b1b75e73abc5c7d540158cd0" @@ -3181,6 +3353,41 @@ expect@^22.4.0: jest-message-util "^22.4.0" jest-regex-util "^22.1.0" +express@^4.14.0: + version "4.16.3" + resolved "https://registry.yarnpkg.com/express/-/express-4.16.3.tgz#6af8a502350db3246ecc4becf6b5a34d22f7ed53" + dependencies: + accepts "~1.3.5" + array-flatten "1.1.1" + body-parser "1.18.2" + content-disposition "0.5.2" + content-type "~1.0.4" + cookie "0.3.1" + cookie-signature "1.0.6" + debug "2.6.9" + depd "~1.1.2" + encodeurl "~1.0.2" + escape-html "~1.0.3" + etag "~1.8.1" + finalhandler "1.1.1" + fresh "0.5.2" + merge-descriptors "1.0.1" + methods "~1.1.2" + on-finished "~2.3.0" + parseurl "~1.3.2" + path-to-regexp "0.1.7" + proxy-addr "~2.0.3" + qs "6.5.1" + range-parser "~1.2.0" + safe-buffer "5.1.1" + send "0.16.2" + serve-static "1.13.2" + setprototypeof "1.1.0" + statuses "~1.4.0" + type-is "~1.6.16" + utils-merge "1.0.1" + vary "~1.1.2" + extend-shallow@^2.0.1: version "2.0.1" resolved "https://registry.yarnpkg.com/extend-shallow/-/extend-shallow-2.0.1.tgz#51af7d614ad9a9f610ea1bafbb989d6b1c56890f" @@ -3325,6 +3532,18 @@ fill-range@^4.0.0: repeat-string "^1.6.1" to-regex-range "^2.1.0" +finalhandler@1.1.1: + version "1.1.1" + resolved "https://registry.yarnpkg.com/finalhandler/-/finalhandler-1.1.1.tgz#eebf4ed840079c83f4249038c9d703008301b105" + dependencies: + debug "2.6.9" + encodeurl "~1.0.2" + escape-html "~1.0.3" + on-finished "~2.3.0" + parseurl "~1.3.2" + statuses "~1.4.0" + unpipe "~1.0.0" + find-cache-dir@^1.0.0: version "1.0.0" resolved "https://registry.yarnpkg.com/find-cache-dir/-/find-cache-dir-1.0.0.tgz#9288e3e9e3cc3748717d39eade17cf71fc30ee6f" @@ -3396,6 +3615,12 @@ flush-write-stream@^1.0.0: inherits "^2.0.1" readable-stream "^2.0.4" +for-each@^0.3.2: + version "0.3.2" + resolved "https://registry.yarnpkg.com/for-each/-/for-each-0.3.2.tgz#2c40450b9348e97f281322593ba96704b9abd4d4" + dependencies: + is-function "~1.0.0" + for-in@^1.0.1, for-in@^1.0.2: version "1.0.2" resolved "https://registry.yarnpkg.com/for-in/-/for-in-1.0.2.tgz#81068d295a8142ec0ac726c6e2200c30fb6d5e80" @@ -3430,12 +3655,20 @@ form-data@~2.3.1: combined-stream "1.0.6" mime-types "^2.1.12" +forwarded@~0.1.2: + version "0.1.2" + resolved "https://registry.yarnpkg.com/forwarded/-/forwarded-0.1.2.tgz#98c23dab1175657b8c0573e8ceccd91b0ff18c84" + fragment-cache@^0.2.1: version "0.2.1" resolved "https://registry.yarnpkg.com/fragment-cache/-/fragment-cache-0.2.1.tgz#4290fad27f13e89be7f33799c6bc5a0abfff0d19" dependencies: map-cache "^0.2.2" +fresh@0.5.2: + version "0.5.2" + resolved "https://registry.yarnpkg.com/fresh/-/fresh-0.5.2.tgz#3d8cadd90d976569fa835ab1f8e4b23a105605a7" + from2@^2.1.0: version "2.3.0" resolved "https://registry.yarnpkg.com/from2/-/from2-2.3.0.tgz#8bfb5502bde4a4d36cfdeea007fcca21d7e382af" @@ -3705,7 +3938,7 @@ global-prefix@^1.0.1: is-windows "^1.0.1" which "^1.2.14" -global@^4.3.2: +global@^4.3.2, global@~4.3.0: version "4.3.2" resolved "https://registry.yarnpkg.com/global/-/global-4.3.2.tgz#e76989268a6c74c38908b1305b10fc0e394e9d0f" dependencies: @@ -4009,6 +4242,28 @@ htmlparser2@~3.8.1: entities "1.0" readable-stream "1.1" +http-errors@1.6.2: + version "1.6.2" + resolved "https://registry.yarnpkg.com/http-errors/-/http-errors-1.6.2.tgz#0a002cc85707192a7e7946ceedc11155f60ec736" + dependencies: + depd "1.1.1" + inherits "2.0.3" + setprototypeof "1.0.3" + statuses ">= 1.3.1 < 2" + +http-errors@~1.6.2: + version "1.6.3" + resolved "https://registry.yarnpkg.com/http-errors/-/http-errors-1.6.3.tgz#8b55680bb4be283a0b5bf4ea2e38580be1d9320d" + dependencies: + depd "~1.1.2" + inherits "2.0.3" + setprototypeof "1.1.0" + statuses ">= 1.4.0 < 2" + +http-https@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/http-https/-/http-https-1.0.0.tgz#2f908dd5f1db4068c058cd6e6d4ce392c913389b" + http-signature@~1.1.0: version "1.1.1" resolved "https://registry.yarnpkg.com/http-signature/-/http-signature-1.1.1.tgz#df72e267066cd0ac67fb76adf8e134a8fbcf91bf" @@ -4104,7 +4359,7 @@ inflight@^1.0.4: once "^1.3.0" wrappy "1" -inherits@2, inherits@^2.0.1, inherits@^2.0.3, inherits@~2.0.0, inherits@~2.0.1, inherits@~2.0.3: +inherits@2, inherits@2.0.3, inherits@^2.0.1, inherits@^2.0.3, inherits@~2.0.0, inherits@~2.0.1, inherits@~2.0.3: version "2.0.3" resolved "https://registry.yarnpkg.com/inherits/-/inherits-2.0.3.tgz#633c2c83e3da42a502f52466022480f4208261de" @@ -4185,6 +4440,10 @@ invert-kv@^1.0.0: version "1.0.0" resolved "https://registry.yarnpkg.com/invert-kv/-/invert-kv-1.0.0.tgz#104a8e4aaca6d3d8cd157a8ef8bfab2d7a3ffdb6" +ipaddr.js@1.6.0: + version "1.6.0" + resolved "https://registry.yarnpkg.com/ipaddr.js/-/ipaddr.js-1.6.0.tgz#e3fa357b773da619f26e95f049d055c72796f86b" + is-accessor-descriptor@^0.1.6: version "0.1.6" resolved "https://registry.yarnpkg.com/is-accessor-descriptor/-/is-accessor-descriptor-0.1.6.tgz#a9e12cb3ae8d876727eeef3843f8a0897b5c98d6" @@ -4326,6 +4585,10 @@ is-fullwidth-code-point@^2.0.0: version "2.0.0" resolved "https://registry.yarnpkg.com/is-fullwidth-code-point/-/is-fullwidth-code-point-2.0.0.tgz#a3b30a5c4f199183167aaab93beefae3ddfb654f" +is-function@^1.0.1, is-function@~1.0.0: + version "1.0.1" + resolved "https://registry.yarnpkg.com/is-function/-/is-function-1.0.1.tgz#12cfb98b65b57dd3d193a3121f5f6e2f437602b5" + is-generator-fn@^1.0.0: version "1.0.0" resolved "https://registry.yarnpkg.com/is-generator-fn/-/is-generator-fn-1.0.0.tgz#969d49e1bb3329f6bb7f09089be26578b2ddd46a" @@ -4470,7 +4733,7 @@ is-text-path@^1.0.0: dependencies: text-extensions "^1.0.0" -is-typedarray@~1.0.0: +is-typedarray@^1.0.0, is-typedarray@~1.0.0: version "1.0.0" resolved "https://registry.yarnpkg.com/is-typedarray/-/is-typedarray-1.0.0.tgz#e479c80858df0c1b11ddda6940f96011fcda4a9a" @@ -4889,6 +5152,10 @@ js-sha3@0.5.5: version "0.5.5" resolved "https://registry.yarnpkg.com/js-sha3/-/js-sha3-0.5.5.tgz#baf0c0e8c54ad5903447df96ade7a4a1bca79a4a" +js-sha3@^0.3.1: + version "0.3.1" + resolved "https://registry.yarnpkg.com/js-sha3/-/js-sha3-0.3.1.tgz#86122802142f0828502a0d1dee1d95e253bb0243" + js-tokens@^3.0.0, js-tokens@^3.0.2: version "3.0.2" resolved "https://registry.yarnpkg.com/js-tokens/-/js-tokens-3.0.2.tgz#9866df395102130e38f7f996bceb65443209c25b" @@ -5046,6 +5313,22 @@ jsx-ast-utils@^2.0.0, jsx-ast-utils@^2.0.1: dependencies: array-includes "^3.0.3" +keccak@^1.0.2: + version "1.4.0" + resolved "https://registry.yarnpkg.com/keccak/-/keccak-1.4.0.tgz#572f8a6dbee8e7b3aa421550f9e6408ca2186f80" + dependencies: + bindings "^1.2.1" + inherits "^2.0.3" + nan "^2.2.1" + safe-buffer "^5.1.0" + +keccakjs@^0.2.1: + version "0.2.1" + resolved "https://registry.yarnpkg.com/keccakjs/-/keccakjs-0.2.1.tgz#1d633af907ef305bbf9f2fa616d56c44561dfa4d" + dependencies: + browserify-sha3 "^0.0.1" + sha3 "^1.1.0" + kind-of@^3.0.2, kind-of@^3.0.3, kind-of@^3.2.0: version "3.2.2" resolved "https://registry.yarnpkg.com/kind-of/-/kind-of-3.2.2.tgz#31ea21a734bab9bbb0f32466d893aea51e4a3c64" @@ -5561,6 +5844,10 @@ mdast-util-compact@^1.0.0: unist-util-modify-children "^1.0.0" unist-util-visit "^1.1.0" +media-typer@0.3.0: + version "0.3.0" + resolved "https://registry.yarnpkg.com/media-typer/-/media-typer-0.3.0.tgz#8710d7af0aa626f8fffa1ce00168545263255748" + mem-fs-editor@^3.0.0: version "3.0.2" resolved "https://registry.yarnpkg.com/mem-fs-editor/-/mem-fs-editor-3.0.2.tgz#dd0a6eaf2bb8a6b37740067aa549eb530105af9f" @@ -5626,6 +5913,10 @@ meow@^4.0.0: redent "^2.0.0" trim-newlines "^2.0.0" +merge-descriptors@1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/merge-descriptors/-/merge-descriptors-1.0.1.tgz#b00aaa556dd8b44568150ec9d1b953f3f90cbb61" + merge-stream@^1.0.1: version "1.0.1" resolved "https://registry.yarnpkg.com/merge-stream/-/merge-stream-1.0.1.tgz#4041202d508a342ba00174008df0c251b8c135e1" @@ -5636,6 +5927,10 @@ merge@^1.1.3, merge@^1.2.0: version "1.2.0" resolved "https://registry.yarnpkg.com/merge/-/merge-1.2.0.tgz#7531e39d4949c281a66b8c5a6e0265e8b05894da" +methods@~1.1.2: + version "1.1.2" + resolved "https://registry.yarnpkg.com/methods/-/methods-1.1.2.tgz#5529a4d67654134edcc5266656835b0f851afcee" + micromatch@^2.1.5, micromatch@^2.3.11, micromatch@^2.3.7: version "2.3.11" resolved "https://registry.yarnpkg.com/micromatch/-/micromatch-2.3.11.tgz#86677c97d1720b363431d04d0d15293bd38c1565" @@ -5683,12 +5978,16 @@ mime-db@~1.33.0: version "1.33.0" resolved "https://registry.yarnpkg.com/mime-db/-/mime-db-1.33.0.tgz#a3492050a5cb9b63450541e39d9788d2272783db" -mime-types@^2.1.12, mime-types@~2.1.17, mime-types@~2.1.7: +mime-types@^2.1.12, mime-types@~2.1.17, mime-types@~2.1.18, mime-types@~2.1.7: version "2.1.18" resolved "https://registry.yarnpkg.com/mime-types/-/mime-types-2.1.18.tgz#6f323f60a83d11146f831ff11fd66e2fe5503bb8" dependencies: mime-db "~1.33.0" +mime@1.4.1: + version "1.4.1" + resolved "https://registry.yarnpkg.com/mime/-/mime-1.4.1.tgz#121f9ebc49e3766f311a76e1fa1c8003c4b03aa6" + mimic-fn@^1.0.0: version "1.2.0" resolved "https://registry.yarnpkg.com/mimic-fn/-/mimic-fn-1.2.0.tgz#820c86a39334640e99516928bd03fca88057d022" @@ -5818,10 +6117,18 @@ mute-stream@0.0.7: version "0.0.7" resolved "https://registry.yarnpkg.com/mute-stream/-/mute-stream-0.0.7.tgz#3075ce93bc21b8fab43e1bc4da7e8115ed1e7bab" +nan@2.10.0, nan@^2.2.1, nan@^2.3.3: + version "2.10.0" + resolved "https://registry.yarnpkg.com/nan/-/nan-2.10.0.tgz#96d0cd610ebd58d4b4de9cc0c6828cda99c7548f" + nan@^2.3.0: version "2.9.2" resolved "https://registry.yarnpkg.com/nan/-/nan-2.9.2.tgz#f564d75f5f8f36a6d9456cca7a6c4fe488ab7866" +nano-json-stream-parser@^0.1.2: + version "0.1.2" + resolved "https://registry.yarnpkg.com/nano-json-stream-parser/-/nano-json-stream-parser-0.1.2.tgz#0cc8f6d0e2b622b479c40d499c46d64b755c6f5f" + nanomatch@^1.2.9: version "1.2.9" resolved "https://registry.yarnpkg.com/nanomatch/-/nanomatch-1.2.9.tgz#879f7150cb2dab7a471259066c104eee6e0fa7c2" @@ -5843,6 +6150,10 @@ natural-compare@^1.4.0: version "1.4.0" resolved "https://registry.yarnpkg.com/natural-compare/-/natural-compare-1.4.0.tgz#4abebfeed7541f2c27acfb29bdbbd15c8d5ba4f7" +negotiator@0.6.1: + version "0.6.1" + resolved "https://registry.yarnpkg.com/negotiator/-/negotiator-0.6.1.tgz#2b327184e8992101177b28563fb5e7102acd0ca9" + neo-async@^2.5.0: version "2.5.0" resolved "https://registry.yarnpkg.com/neo-async/-/neo-async-2.5.0.tgz#76b1c823130cca26acfbaccc8fbaf0a2fa33b18f" @@ -6026,7 +6337,7 @@ oauth-sign@~0.8.1, oauth-sign@~0.8.2: version "0.8.2" resolved "https://registry.yarnpkg.com/oauth-sign/-/oauth-sign-0.8.2.tgz#46a6ab7f0aead8deae9ec0565780b7d4efeb9d43" -object-assign@^4.0.1, object-assign@^4.1.0, object-assign@^4.1.1: +object-assign@^4, object-assign@^4.0.1, object-assign@^4.1.0, object-assign@^4.1.1: version "4.1.1" resolved "https://registry.yarnpkg.com/object-assign/-/object-assign-4.1.1.tgz#2109adc7965887cfc05cbbd442cac8bfbb360863" @@ -6068,6 +6379,18 @@ object.pick@^1.3.0: dependencies: isobject "^3.0.1" +oboe@2.1.3: + version "2.1.3" + resolved "https://registry.yarnpkg.com/oboe/-/oboe-2.1.3.tgz#2b4865dbd46be81225713f4e9bfe4bcf4f680a4f" + dependencies: + http-https "^1.0.0" + +on-finished@~2.3.0: + version "2.3.0" + resolved "https://registry.yarnpkg.com/on-finished/-/on-finished-2.3.0.tgz#20f1336481b083cd75337992a16971aa2d906947" + dependencies: + ee-first "1.1.1" + once@^1.3.0, once@^1.3.1, once@^1.3.3, once@^1.4.0: version "1.4.0" resolved "https://registry.yarnpkg.com/once/-/once-1.4.0.tgz#583b1aa775961d4b113ac17d9c50baef9dd76bd1" @@ -6250,6 +6573,13 @@ parse-glob@^3.0.4: is-extglob "^1.0.0" is-glob "^2.0.0" +parse-headers@^2.0.0: + version "2.0.1" + resolved "https://registry.yarnpkg.com/parse-headers/-/parse-headers-2.0.1.tgz#6ae83a7aa25a9d9b700acc28698cd1f1ed7e9536" + dependencies: + for-each "^0.3.2" + trim "0.0.1" + parse-json@^2.2.0: version "2.2.0" resolved "https://registry.yarnpkg.com/parse-json/-/parse-json-2.2.0.tgz#f480f40434ef80741f8469099f8dea18f55a4dc9" @@ -6281,6 +6611,10 @@ parse5@^1.5.1: version "1.5.1" resolved "https://registry.yarnpkg.com/parse5/-/parse5-1.5.1.tgz#9b7f3b0de32be78dc2401b17573ccaf0f6f59d94" +parseurl@~1.3.2: + version "1.3.2" + resolved "https://registry.yarnpkg.com/parseurl/-/parseurl-1.3.2.tgz#fc289d4ed8993119460c156253262cdc8de65bf3" + pascalcase@^0.1.1: version "0.1.1" resolved "https://registry.yarnpkg.com/pascalcase/-/pascalcase-0.1.1.tgz#b363e55e8006ca6fe21784d2db22bd15d7917f14" @@ -6315,6 +6649,10 @@ path-parse@^1.0.5: version "1.0.5" resolved "https://registry.yarnpkg.com/path-parse/-/path-parse-1.0.5.tgz#3c1adf871ea9cd6c9431b6ea2bd74a0ff055c4c1" +path-to-regexp@0.1.7: + version "0.1.7" + resolved "https://registry.yarnpkg.com/path-to-regexp/-/path-to-regexp-0.1.7.tgz#df604178005f522f15eb4490e7247a1bfaa67f8c" + path-type@^1.0.0: version "1.1.0" resolved "https://registry.yarnpkg.com/path-type/-/path-type-1.1.0.tgz#59c44f7ee491da704da415da5a4070ba4f8fe441" @@ -6572,6 +6910,13 @@ prop-types@^15.6.0: loose-envify "^1.3.1" object-assign "^4.1.1" +proxy-addr@~2.0.3: + version "2.0.3" + resolved "https://registry.yarnpkg.com/proxy-addr/-/proxy-addr-2.0.3.tgz#355f262505a621646b3130a728eb647e22055341" + dependencies: + forwarded "~0.1.2" + ipaddr.js "1.6.0" + prr@~1.0.1: version "1.0.1" resolved "https://registry.yarnpkg.com/prr/-/prr-1.0.1.tgz#d3fc114ba06995a45ec6893f484ceb1d78f5f476" @@ -6621,13 +6966,21 @@ q@^1.4.1, q@^1.5.1: version "1.5.1" resolved "https://registry.yarnpkg.com/q/-/q-1.5.1.tgz#7e32f75b41381291d04611f1bf14109ac00651d7" +qs@6.5.1, qs@~6.5.1: + version "6.5.1" + resolved "https://registry.yarnpkg.com/qs/-/qs-6.5.1.tgz#349cdf6eef89ec45c12d7d5eb3fc0c870343a6d8" + qs@~6.4.0: version "6.4.0" resolved "https://registry.yarnpkg.com/qs/-/qs-6.4.0.tgz#13e26d28ad6b0ffaa91312cd3bf708ed351e7233" -qs@~6.5.1: - version "6.5.1" - resolved "https://registry.yarnpkg.com/qs/-/qs-6.5.1.tgz#349cdf6eef89ec45c12d7d5eb3fc0c870343a6d8" +query-string@^5.0.1: + version "5.1.1" + resolved "https://registry.yarnpkg.com/query-string/-/query-string-5.1.1.tgz#a78c012b71c17e05f2e3fa2319dd330682efb3cb" + dependencies: + decode-uri-component "^0.2.0" + object-assign "^4.1.0" + strict-uri-encode "^1.0.0" querystring-es3@^0.2.0: version "0.2.1" @@ -6661,6 +7014,23 @@ randomfill@^1.0.3: randombytes "^2.0.5" safe-buffer "^5.1.0" +randomhex@0.1.5: + version "0.1.5" + resolved "https://registry.yarnpkg.com/randomhex/-/randomhex-0.1.5.tgz#baceef982329091400f2a2912c6cd02f1094f585" + +range-parser@~1.2.0: + version "1.2.0" + resolved "https://registry.yarnpkg.com/range-parser/-/range-parser-1.2.0.tgz#f49be6b487894ddc40dcc94a322f611092e00d5e" + +raw-body@2.3.2: + version "2.3.2" + resolved "https://registry.yarnpkg.com/raw-body/-/raw-body-2.3.2.tgz#bcd60c77d3eb93cde0050295c3f379389bc88f89" + dependencies: + bytes "3.0.0" + http-errors "1.6.2" + iconv-lite "0.4.19" + unpipe "1.0.0" + rc@^1.1.7: version "1.2.5" resolved "https://registry.yarnpkg.com/rc/-/rc-1.2.5.tgz#275cd687f6e3b36cc756baa26dfee80a790301fd" @@ -7119,6 +7489,10 @@ ripemd160@^2.0.0, ripemd160@^2.0.1: hash-base "^2.0.0" inherits "^2.0.1" +rlp@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/rlp/-/rlp-2.0.0.tgz#9db384ff4b89a8f61563d92395d8625b18f3afb0" + run-async@^0.1.0: version "0.1.0" resolved "https://registry.yarnpkg.com/run-async/-/run-async-0.1.0.tgz#c8ad4a5e110661e402a7d21b530e009f25f8e389" @@ -7161,7 +7535,7 @@ rxjs@^5.0.0-beta.11, rxjs@^5.4.2: dependencies: symbol-observable "1.0.1" -safe-buffer@^5.0.1, safe-buffer@^5.1.0, safe-buffer@^5.1.1, safe-buffer@~5.1.0, safe-buffer@~5.1.1: +safe-buffer@5.1.1, safe-buffer@^5.0.1, safe-buffer@^5.1.0, safe-buffer@^5.1.1, safe-buffer@~5.1.0, safe-buffer@~5.1.1: version "5.1.1" resolved "https://registry.yarnpkg.com/safe-buffer/-/safe-buffer-5.1.1.tgz#893312af69b2123def71f57889001671eeb2c853" @@ -7200,14 +7574,64 @@ scoped-regex@^1.0.0: version "1.0.0" resolved "https://registry.yarnpkg.com/scoped-regex/-/scoped-regex-1.0.0.tgz#a346bb1acd4207ae70bd7c0c7ca9e566b6baddb8" +secp256k1@^3.0.1: + version "3.5.0" + resolved "https://registry.yarnpkg.com/secp256k1/-/secp256k1-3.5.0.tgz#677d3b8a8e04e1a5fa381a1ae437c54207b738d0" + dependencies: + bindings "^1.2.1" + bip66 "^1.1.3" + bn.js "^4.11.3" + create-hash "^1.1.2" + drbg.js "^1.0.1" + elliptic "^6.2.3" + nan "^2.2.1" + safe-buffer "^5.1.0" + "semver@2 || 3 || 4 || 5", semver@5.5.0, semver@^5.1.0, semver@^5.3.0, semver@^5.4.1, semver@^5.5.0: version "5.5.0" resolved "https://registry.yarnpkg.com/semver/-/semver-5.5.0.tgz#dc4bbc7a6ca9d916dee5d43516f0092b58f7b8ab" +send@0.16.2: + version "0.16.2" + resolved "https://registry.yarnpkg.com/send/-/send-0.16.2.tgz#6ecca1e0f8c156d141597559848df64730a6bbc1" + dependencies: + debug "2.6.9" + depd "~1.1.2" + destroy "~1.0.4" + encodeurl "~1.0.2" + escape-html "~1.0.3" + etag "~1.8.1" + fresh "0.5.2" + http-errors "~1.6.2" + mime "1.4.1" + ms "2.0.0" + on-finished "~2.3.0" + range-parser "~1.2.0" + statuses "~1.4.0" + serialize-javascript@^1.4.0: version "1.4.0" resolved "https://registry.yarnpkg.com/serialize-javascript/-/serialize-javascript-1.4.0.tgz#7c958514db6ac2443a8abc062dc9f7886a7f6005" +serve-static@1.13.2: + version "1.13.2" + resolved "https://registry.yarnpkg.com/serve-static/-/serve-static-1.13.2.tgz#095e8472fd5b46237db50ce486a43f4b86c6cec1" + dependencies: + encodeurl "~1.0.2" + escape-html "~1.0.3" + parseurl "~1.3.2" + send "0.16.2" + +servify@^0.1.12: + version "0.1.12" + resolved "https://registry.yarnpkg.com/servify/-/servify-0.1.12.tgz#142ab7bee1f1d033b66d0707086085b17c06db95" + dependencies: + body-parser "^1.16.0" + cors "^2.8.1" + express "^4.14.0" + request "^2.79.0" + xhr "^2.3.3" + set-blocking@^2.0.0, set-blocking@~2.0.0: version "2.0.0" resolved "https://registry.yarnpkg.com/set-blocking/-/set-blocking-2.0.0.tgz#045f9782d011ae9a6803ddd382b24392b3d890f7" @@ -7244,6 +7668,14 @@ setimmediate@^1.0.4, setimmediate@^1.0.5: version "1.0.5" resolved "https://registry.yarnpkg.com/setimmediate/-/setimmediate-1.0.5.tgz#290cbb232e306942d7d7ea9b83732ab7856f8285" +setprototypeof@1.0.3: + version "1.0.3" + resolved "https://registry.yarnpkg.com/setprototypeof/-/setprototypeof-1.0.3.tgz#66567e37043eeb4f04d91bd658c0cbefb55b8e04" + +setprototypeof@1.1.0: + version "1.1.0" + resolved "https://registry.yarnpkg.com/setprototypeof/-/setprototypeof-1.1.0.tgz#d0bd85536887b6fe7c0d818cb962d9d91c54e656" + sha.js@^2.4.0, sha.js@^2.4.8: version "2.4.10" resolved "https://registry.yarnpkg.com/sha.js/-/sha.js-2.4.10.tgz#b1fde5cd7d11a5626638a07c604ab909cfa31f9b" @@ -7251,6 +7683,12 @@ sha.js@^2.4.0, sha.js@^2.4.8: inherits "^2.0.1" safe-buffer "^5.0.1" +sha3@^1.1.0: + version "1.2.2" + resolved "https://registry.yarnpkg.com/sha3/-/sha3-1.2.2.tgz#a66c5098de4c25bc88336ec8b4817d005bca7ba9" + dependencies: + nan "2.10.0" + shebang-command@^1.2.0: version "1.2.0" resolved "https://registry.yarnpkg.com/shebang-command/-/shebang-command-1.2.0.tgz#44aac65b695b03398968c39f363fee5deafdf1ea" @@ -7285,6 +7723,18 @@ signal-exit@^3.0.0, signal-exit@^3.0.2: version "3.0.2" resolved "https://registry.yarnpkg.com/signal-exit/-/signal-exit-3.0.2.tgz#b5fdc08f1287ea1178628e415e25132b73646c6d" +simple-concat@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/simple-concat/-/simple-concat-1.0.0.tgz#7344cbb8b6e26fb27d66b2fc86f9f6d5997521c6" + +simple-get@^2.7.0: + version "2.8.1" + resolved "https://registry.yarnpkg.com/simple-get/-/simple-get-2.8.1.tgz#0e22e91d4575d87620620bc91308d57a77f44b5d" + dependencies: + decompress-response "^3.3.0" + once "^1.3.1" + simple-concat "^1.0.0" + slash@^1.0.0: version "1.0.0" resolved "https://registry.yarnpkg.com/slash/-/slash-1.0.0.tgz#c41f2f6c39fc16d1cd17ad4b5d896114ae470d55" @@ -7504,6 +7954,14 @@ static-extend@^0.1.1: define-property "^0.2.5" object-copy "^0.1.0" +"statuses@>= 1.3.1 < 2", "statuses@>= 1.4.0 < 2": + version "1.5.0" + resolved "https://registry.yarnpkg.com/statuses/-/statuses-1.5.0.tgz#161c7dac177659fd9811f43771fa99381478628c" + +statuses@~1.4.0: + version "1.4.0" + resolved "https://registry.yarnpkg.com/statuses/-/statuses-1.4.0.tgz#bb73d446da2796106efcc1b601a253d6c46bd087" + stealthy-require@^1.1.0: version "1.1.1" resolved "https://registry.yarnpkg.com/stealthy-require/-/stealthy-require-1.1.1.tgz#35b09875b4ff49f26a777e509b3090a3226bf24b" @@ -7546,6 +8004,10 @@ stream-to-observable@^0.2.0: dependencies: any-observable "^0.2.0" +strict-uri-encode@^1.0.0: + version "1.1.0" + resolved "https://registry.yarnpkg.com/strict-uri-encode/-/strict-uri-encode-1.1.0.tgz#279b225df1d582b1f54e65addd4352e18faa0713" + string-length@^2.0.0: version "2.0.0" resolved "https://registry.yarnpkg.com/string-length/-/string-length-2.0.0.tgz#d40dbb686a3ace960c1cffca562bf2c45f8363ed" @@ -7922,7 +8384,7 @@ through@2, "through@>=2.2.7 <3", through@^2.3.6: version "2.3.8" resolved "https://registry.yarnpkg.com/through/-/through-2.3.8.tgz#0dd4c9ffaabc357960b1b724115d7e0e86a2e1f5" -timed-out@^4.0.0: +timed-out@^4.0.0, timed-out@^4.0.1: version "4.0.1" resolved "https://registry.yarnpkg.com/timed-out/-/timed-out-4.0.1.tgz#f32eacac5a175bea25d7fab565ab3ed8741ef56f" @@ -8067,6 +8529,19 @@ type-check@~0.3.2: dependencies: prelude-ls "~1.1.2" +type-is@~1.6.15, type-is@~1.6.16: + version "1.6.16" + resolved "https://registry.yarnpkg.com/type-is/-/type-is-1.6.16.tgz#f89ce341541c672b25ee7ae3c73dee3b2be50194" + dependencies: + media-typer "0.3.0" + mime-types "~2.1.18" + +typedarray-to-buffer@^3.1.2: + version "3.1.5" + resolved "https://registry.yarnpkg.com/typedarray-to-buffer/-/typedarray-to-buffer-3.1.5.tgz#a97ee7a9ff42691b9f783ff1bc5112fe3fca9080" + dependencies: + is-typedarray "^1.0.0" + typedarray@^0.0.6: version "0.0.6" resolved "https://registry.yarnpkg.com/typedarray/-/typedarray-0.0.6.tgz#867ac74e3864187b1d3d47d996a78ec5c8830777" @@ -8112,6 +8587,14 @@ uid-number@^0.0.6: version "0.0.6" resolved "https://registry.yarnpkg.com/uid-number/-/uid-number-0.0.6.tgz#0ea10e8035e8eb5b8e4449f06da1c730663baa81" +ultron@~1.1.0: + version "1.1.1" + resolved "https://registry.yarnpkg.com/ultron/-/ultron-1.1.1.tgz#9fe1536a10a664a65266a1e3ccf85fd36302bc9c" + +underscore@1.8.3: + version "1.8.3" + resolved "https://registry.yarnpkg.com/underscore/-/underscore-1.8.3.tgz#4f3fb53b106e6097fcf9cb4109f2a5e9bdfa5022" + underscore@~1.6.0: version "1.6.0" resolved "https://registry.yarnpkg.com/underscore/-/underscore-1.6.0.tgz#8b38b10cacdef63337b8b24e4ff86d45aea529a8" @@ -8192,6 +8675,10 @@ unist-util-visit@^1.1.0: dependencies: unist-util-is "^2.1.1" +unpipe@1.0.0, unpipe@~1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/unpipe/-/unpipe-1.0.0.tgz#b2bf4ee8514aae6165b4817829d21b2ef49904ec" + unset-value@^1.0.0: version "1.0.0" resolved "https://registry.yarnpkg.com/unset-value/-/unset-value-1.0.0.tgz#8376873f7d2335179ffb1e6fc3a8ed0dfc8ab559" @@ -8219,6 +8706,10 @@ url-parse-lax@^1.0.0: dependencies: prepend-http "^1.0.1" +url-set-query@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/url-set-query/-/url-set-query-1.0.0.tgz#016e8cfd7c20ee05cafe7795e892bd0702faa339" + url-to-options@^1.0.1: version "1.0.1" resolved "https://registry.yarnpkg.com/url-to-options/-/url-to-options-1.0.1.tgz#1505a03a289a48cbd7a434efbaeec5055f5633a9" @@ -8246,6 +8737,10 @@ user-home@^1.1.1: version "1.1.1" resolved "https://registry.yarnpkg.com/user-home/-/user-home-1.1.1.tgz#2b5be23a32b63a7c9deb8d0f28d485724a3df190" +utf8@2.1.1: + version "2.1.1" + resolved "https://registry.yarnpkg.com/utf8/-/utf8-2.1.1.tgz#2e01db02f7d8d0944f77104f1609eb0c304cf768" + utf8@^2.1.1: version "2.1.2" resolved "https://registry.yarnpkg.com/utf8/-/utf8-2.1.2.tgz#1fa0d9270e9be850d9b05027f63519bf46457d96" @@ -8267,6 +8762,10 @@ util@0.10.3, util@^0.10.3: dependencies: inherits "2.0.1" +utils-merge@1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/utils-merge/-/utils-merge-1.0.1.tgz#9f95710f50a267947b2ccc124741c1028427e713" + uuid@^3.0.0, uuid@^3.1.0: version "3.2.1" resolved "https://registry.yarnpkg.com/uuid/-/uuid-3.2.1.tgz#12c528bb9d58d0b9265d9a2f6f0fe8be17ff1f14" @@ -8288,6 +8787,10 @@ validate-npm-package-license@^3.0.1: spdx-correct "^2.0.4" spdx-expression-parse "^3.0.0" +vary@^1, vary@~1.1.2: + version "1.1.2" + resolved "https://registry.yarnpkg.com/vary/-/vary-1.1.2.tgz#2299f02c6ded30d4a5961b0b9f74524a18f634fc" + verror@1.10.0: version "1.10.0" resolved "https://registry.yarnpkg.com/verror/-/verror-1.10.0.tgz#3a105ca17053af55d6e270c1f8288682e18da400" @@ -8393,6 +8896,31 @@ watchpack@^1.4.0: chokidar "^1.7.0" graceful-fs "^4.1.2" +web3-core-helpers@1.0.0-beta.34: + version "1.0.0-beta.34" + resolved "https://registry.yarnpkg.com/web3-core-helpers/-/web3-core-helpers-1.0.0-beta.34.tgz#b168da00d3e19e156bc15ae203203dd4dfee2d03" + dependencies: + underscore "1.8.3" + web3-eth-iban "1.0.0-beta.34" + web3-utils "1.0.0-beta.34" + +web3-core-method@1.0.0-beta.34: + version "1.0.0-beta.34" + resolved "https://registry.yarnpkg.com/web3-core-method/-/web3-core-method-1.0.0-beta.34.tgz#ec163c8a2c490fa02a7ec15559fa7307fc7cc6dd" + dependencies: + underscore "1.8.3" + web3-core-helpers "1.0.0-beta.34" + web3-core-promievent "1.0.0-beta.34" + web3-core-subscriptions "1.0.0-beta.34" + web3-utils "1.0.0-beta.34" + +web3-core-promievent@1.0.0-beta.34: + version "1.0.0-beta.34" + resolved "https://registry.yarnpkg.com/web3-core-promievent/-/web3-core-promievent-1.0.0-beta.34.tgz#a4f4fa6784bb293e82c60960ae5b56a94cd03edc" + dependencies: + any-promise "1.3.0" + eventemitter3 "1.1.1" + web3-core-promievent@^1.0.0-beta.21: version "1.0.0-beta.30" resolved "https://registry.yarnpkg.com/web3-core-promievent/-/web3-core-promievent-1.0.0-beta.30.tgz#6205192bfb097441132226a5939ec5aed3a8a291" @@ -8400,6 +8928,93 @@ web3-core-promievent@^1.0.0-beta.21: bluebird "3.3.1" eventemitter3 "1.1.1" +web3-core-requestmanager@1.0.0-beta.34: + version "1.0.0-beta.34" + resolved "https://registry.yarnpkg.com/web3-core-requestmanager/-/web3-core-requestmanager-1.0.0-beta.34.tgz#01f8f6cf2ae6b6f0b70c38bae1ef741b5bab215c" + dependencies: + underscore "1.8.3" + web3-core-helpers "1.0.0-beta.34" + web3-providers-http "1.0.0-beta.34" + web3-providers-ipc "1.0.0-beta.34" + web3-providers-ws "1.0.0-beta.34" + +web3-core-subscriptions@1.0.0-beta.34: + version "1.0.0-beta.34" + resolved "https://registry.yarnpkg.com/web3-core-subscriptions/-/web3-core-subscriptions-1.0.0-beta.34.tgz#9fed144033f221c3cf21060302ffdaf5ef2de2de" + dependencies: + eventemitter3 "1.1.1" + underscore "1.8.3" + web3-core-helpers "1.0.0-beta.34" + +web3-core@1.0.0-beta.34: + version "1.0.0-beta.34" + resolved "https://registry.yarnpkg.com/web3-core/-/web3-core-1.0.0-beta.34.tgz#121be8555e9fb00d2c5d05ddd3381d0c9e46987e" + dependencies: + web3-core-helpers "1.0.0-beta.34" + web3-core-method "1.0.0-beta.34" + web3-core-requestmanager "1.0.0-beta.34" + web3-utils "1.0.0-beta.34" + +web3-eth-iban@1.0.0-beta.34: + version "1.0.0-beta.34" + resolved "https://registry.yarnpkg.com/web3-eth-iban/-/web3-eth-iban-1.0.0-beta.34.tgz#9af458605867ccf74ea979aaf326b38ba6a5ba0c" + dependencies: + bn.js "4.11.6" + web3-utils "1.0.0-beta.34" + +web3-eth-personal@^1.0.0-beta.34: + version "1.0.0-beta.34" + resolved "https://registry.yarnpkg.com/web3-eth-personal/-/web3-eth-personal-1.0.0-beta.34.tgz#9afba167342ebde5420bcd5895c3f6c34388f205" + dependencies: + web3-core "1.0.0-beta.34" + web3-core-helpers "1.0.0-beta.34" + web3-core-method "1.0.0-beta.34" + web3-net "1.0.0-beta.34" + web3-utils "1.0.0-beta.34" + +web3-net@1.0.0-beta.34: + version "1.0.0-beta.34" + resolved "https://registry.yarnpkg.com/web3-net/-/web3-net-1.0.0-beta.34.tgz#427cea2f431881449c8e38d523290f173f9ff63d" + dependencies: + web3-core "1.0.0-beta.34" + web3-core-method "1.0.0-beta.34" + web3-utils "1.0.0-beta.34" + +web3-providers-http@1.0.0-beta.34: + version "1.0.0-beta.34" + resolved "https://registry.yarnpkg.com/web3-providers-http/-/web3-providers-http-1.0.0-beta.34.tgz#e561b52bbb43766282007d40285bfe3550c27e7a" + dependencies: + web3-core-helpers "1.0.0-beta.34" + xhr2 "0.1.4" + +web3-providers-ipc@1.0.0-beta.34: + version "1.0.0-beta.34" + resolved "https://registry.yarnpkg.com/web3-providers-ipc/-/web3-providers-ipc-1.0.0-beta.34.tgz#a1b77f1a306d73649a9c039052e40cb71328d00a" + dependencies: + oboe "2.1.3" + underscore "1.8.3" + web3-core-helpers "1.0.0-beta.34" + +web3-providers-ws@1.0.0-beta.34: + version "1.0.0-beta.34" + resolved "https://registry.yarnpkg.com/web3-providers-ws/-/web3-providers-ws-1.0.0-beta.34.tgz#7de70f1b83f2de36476772156becfef6e3516eb3" + dependencies: + underscore "1.8.3" + web3-core-helpers "1.0.0-beta.34" + websocket "git://github.com/frozeman/WebSocket-Node.git#browserifyCompatible" + +web3-utils@1.0.0-beta.34: + version "1.0.0-beta.34" + resolved "https://registry.yarnpkg.com/web3-utils/-/web3-utils-1.0.0-beta.34.tgz#9411fc39aaef39ca4e06169f762297d9ff020970" + dependencies: + bn.js "4.11.6" + eth-lib "0.1.27" + ethjs-unit "0.1.6" + number-to-bn "1.7.0" + randomhex "0.1.5" + underscore "1.8.3" + utf8 "2.1.1" + web3@^0.20.1: version "0.20.5" resolved "https://registry.yarnpkg.com/web3/-/web3-0.20.5.tgz#c5048d35f7bf4e2c4c280ce51fbbbc951290b165" @@ -8519,6 +9134,15 @@ webpack@^4.0.1: watchpack "^1.4.0" webpack-sources "^1.0.1" +"websocket@git://github.com/frozeman/WebSocket-Node.git#browserifyCompatible": + version "1.0.24" + resolved "git://github.com/frozeman/WebSocket-Node.git#7004c39c42ac98875ab61126e5b4a925430f592c" + dependencies: + debug "^2.2.0" + nan "^2.3.3" + typedarray-to-buffer "^3.1.2" + yaeti "^0.0.6" + whatwg-encoding@^1.0.1, whatwg-encoding@^1.0.3: version "1.0.3" resolved "https://registry.yarnpkg.com/whatwg-encoding/-/whatwg-encoding-1.0.3.tgz#57c235bc8657e914d24e1a397d3c82daee0a6ba3" @@ -8619,6 +9243,14 @@ write@^0.2.1: dependencies: mkdirp "^0.5.1" +ws@^3.0.0: + version "3.3.3" + resolved "https://registry.yarnpkg.com/ws/-/ws-3.3.3.tgz#f1cf84fe2d5e901ebce94efaece785f187a228f2" + dependencies: + async-limiter "~1.0.0" + safe-buffer "~5.1.0" + ultron "~1.1.0" + ws@^4.0.0: version "4.1.0" resolved "https://registry.yarnpkg.com/ws/-/ws-4.1.0.tgz#a979b5d7d4da68bf54efe0408967c324869a7289" @@ -8634,10 +9266,37 @@ x-is-string@^0.1.0: version "0.1.0" resolved "https://registry.yarnpkg.com/x-is-string/-/x-is-string-0.1.0.tgz#474b50865af3a49a9c4657f05acd145458f77d82" -xhr2@*: +xhr-request-promise@^0.1.2: + version "0.1.2" + resolved "https://registry.yarnpkg.com/xhr-request-promise/-/xhr-request-promise-0.1.2.tgz#343c44d1ee7726b8648069682d0f840c83b4261d" + dependencies: + xhr-request "^1.0.1" + +xhr-request@^1.0.1: + version "1.1.0" + resolved "https://registry.yarnpkg.com/xhr-request/-/xhr-request-1.1.0.tgz#f4a7c1868b9f198723444d82dcae317643f2e2ed" + dependencies: + buffer-to-arraybuffer "^0.0.5" + object-assign "^4.1.1" + query-string "^5.0.1" + simple-get "^2.7.0" + timed-out "^4.0.1" + url-set-query "^1.0.0" + xhr "^2.0.4" + +xhr2@*, xhr2@0.1.4: version "0.1.4" resolved "https://registry.yarnpkg.com/xhr2/-/xhr2-0.1.4.tgz#7f87658847716db5026323812f818cadab387a5f" +xhr@^2.0.4, xhr@^2.3.3: + version "2.4.1" + resolved "https://registry.yarnpkg.com/xhr/-/xhr-2.4.1.tgz#ba982cced205ae5eec387169ac9dc77ca4853d38" + dependencies: + global "~4.3.0" + is-function "^1.0.1" + parse-headers "^2.0.0" + xtend "^4.0.0" + "xml-name-validator@>= 2.0.1 < 3.0.0": version "2.0.1" resolved "https://registry.yarnpkg.com/xml-name-validator/-/xml-name-validator-2.0.1.tgz#4d8b8f1eccd3419aa362061becef515e1e559635" @@ -8662,6 +9321,10 @@ y18n@^4.0.0: version "4.0.0" resolved "https://registry.yarnpkg.com/y18n/-/y18n-4.0.0.tgz#95ef94f85ecc81d007c264e190a120f0a3c8566b" +yaeti@^0.0.6: + version "0.0.6" + resolved "https://registry.yarnpkg.com/yaeti/-/yaeti-0.0.6.tgz#f26f484d72684cf42bedfb76970aa1608fbf9577" + yallist@^2.1.2: version "2.1.2" resolved "https://registry.yarnpkg.com/yallist/-/yallist-2.1.2.tgz#1c11f9218f076089a47dd512f93c6699a6a81d52"