diff --git a/.gitignore b/.gitignore index b38db2f..510842c 100644 --- a/.gitignore +++ b/.gitignore @@ -1,2 +1,4 @@ node_modules/ +package-lock.json build/ +*.*swp diff --git a/README.md b/README.md index 8962103..f708ad5 100644 --- a/README.md +++ b/README.md @@ -1,15 +1,31 @@ ### Dev: -- `$ git clone https://github.com/DOSNetwork/eth-contracts` +- `$ git clone https://github.com/DOSNetwork/smart-contracts` - `$ npm install` - `$ npm -g install truffle` -- `$ npm install -g ganache-cli` or installing its [graphic interface](https://truffleframework.com/ganache) +- `$ npm -g install ganache-cli` or installing its [graphic interface](https://truffleframework.com/ganache) - Required truffle/solcjs version: >= 0.5 ### Compile: - `$ truffle compile` -### Deploy: +### Deploy to local development network: +- `$ ganache-cli` - `$ truffle migrate --reset` + +### Deploy to rinkeby testnet without dryrun: +- `$ truffle compile --all` +- `$ truffle migrate --reset --network rinkeby --skip-dry-run` + + +### Deploy to mainnet without dryrun: +- `$ truffle compile --all` +- `$ truffle migrate --reset --network live --skip-dry-run` + + ### Test: +- `$ ganache-cli -a 20`; // Config more than 10 test accounts - `$ truffle test` + +### Deployed: +See `deployed.json`. diff --git a/contracts/CoingeckoParserV2.sol b/contracts/CoingeckoParserV2.sol new file mode 100644 index 0000000..e08437f --- /dev/null +++ b/contracts/CoingeckoParserV2.sol @@ -0,0 +1,53 @@ +pragma solidity ^0.5.0; + +import "./lib/SafeMath.sol"; +import "./lib/StringUtils.sol"; + +// A simple parser to parse coingecko api data. +// Coingecko data api: https://www.coingecko.com/en/api. +// e.g. source: "https://api.coingecko.com/api/v3/simple/price?vs_currencies=usd&ids=ethereum,bitcoin,polkadot,huobi-token" +// e.g. selector: "$..usd" +// e.g. Return: "[48766,1524.21,13.99,34.64]" +contract CoingeckoParserV2 { + using StringUtils for *; + using SafeMath for uint; + + string public constant description = "Coingecko API Data Parser V2"; + uint private constant ten = 10; + + // e.g.: + // floatStr2Uint("123.4567", 0) => 123 + // floatStr2Uint("123.4567", 2) => 12345 + // floatStr2Uint("123.4567", 8) => 12345670000 + function floatStr2Uint(string memory raw, uint decimal) public pure returns(uint) { + uint integral = raw.str2Uint(); + uint fractional = 0; + uint dotIdx = raw.indexOf('.'); + uint fracIdx = dotIdx + 1; + if (dotIdx != bytes(raw).length && fracIdx < bytes(raw).length) { + string memory fracStr = raw.subStr(fracIdx, decimal); + fractional = fracStr.str2Uint(); + if (decimal > bytes(fracStr).length) { + fractional = fractional.mul(ten.pow(decimal - bytes(fracStr).length)); + } + } + return integral.mul(ten.pow(decimal)).add(fractional); + } + + function floatBytes2UintArray(bytes memory raw, uint decimal) public pure returns (uint[] memory) { + uint len = raw.length; + string[] memory s_arr = string(raw.subStr(1, len - 2)).split(','); + uint[] memory uint_arr = new uint[](s_arr.length); + for (uint i = 0; i < s_arr.length; i++) { + uint_arr[i] = floatStr2Uint(s_arr[i], decimal); + } + return uint_arr; + } + + // e.g.: + // floatStrs2UintArray("[48766,1524.21,13.99,34.64]", 8) => [4876600000000,152421000000,1399000000,3464000000] + // floatStrs2UintArray("[12.34]", 8) => [1234000000] + function floatStrs2UintArray(string memory raw, uint decimal) public pure returns (uint[] memory) { + return floatBytes2UintArray(bytes(raw), decimal); + } +} diff --git a/contracts/CommitReveal.sol b/contracts/CommitReveal.sol new file mode 100644 index 0000000..1594e5c --- /dev/null +++ b/contracts/CommitReveal.sol @@ -0,0 +1,119 @@ +pragma solidity ^0.5.0; + +contract DOSAddressBridgeI { + function getProxyAddress() public view returns(address); +} + +contract CommitReveal { + struct Participant { + uint secret; + bytes32 commitment; + bool revealed; + } + + struct Campaign { + uint startBlock; + uint commitDuration; // in blocks + uint revealDuration; // in blocks + uint revealThreshold; + uint commitNum; + uint revealNum; + uint generatedRandom; + mapping(address => Participant) participants; + mapping(bytes32 => bool) commitments; + } + + Campaign[] public campaigns; + DOSAddressBridgeI public addressBridge; + + modifier checkCommit(uint _cid, bytes32 _commitment) { + Campaign storage c = campaigns[_cid]; + require(_cid != 0 && + block.number >= c.startBlock && + block.number < c.startBlock + c.commitDuration, + "not-in-commit"); + require(_commitment != "", "empty-commitment"); + require(!c.commitments[_commitment], "duplicate-commitment"); + _; + } + modifier checkReveal(uint _cid) { + Campaign storage c = campaigns[_cid]; + require(_cid != 0 && + block.number >= c.startBlock + c.commitDuration && + block.number < c.startBlock + c.commitDuration + c.revealDuration, + "not-in-reveal"); + _; + } + modifier checkFinish(uint _cid) { + Campaign storage c = campaigns[_cid]; + require(_cid != 0 && + block.number >= c.startBlock + c.commitDuration + c.revealDuration, + "commit-reveal-not-finished"); + _; + } + modifier onlyFromProxy() { + require(msg.sender == addressBridge.getProxyAddress(), "not-from-dos-proxy"); + _; + } + + event LogStartCommitReveal(uint cid, uint startBlock, uint commitDuration, uint revealDuration, uint revealThreshold); + event LogCommit(uint cid, address from, bytes32 commitment); + event LogReveal(uint cid, address from, uint secret); + event LogRandom(uint cid, uint random); + event LogRandomFailure(uint cid, uint commitNum, uint revealNum, uint revealThreshold); + + constructor(address _bridgeAddr) public { + // campaigns[0] is not used. + campaigns.length++; + addressBridge = DOSAddressBridgeI(_bridgeAddr); + } + + // Returns new campaignId. + function startCommitReveal( + uint _startBlock, + uint _commitDuration, + uint _revealDuration, + uint _revealThreshold + ) + public + onlyFromProxy + returns(uint) + { + uint newCid = campaigns.length; + campaigns.push(Campaign(_startBlock, _commitDuration, _revealDuration, _revealThreshold, 0, 0, 0)); + emit LogStartCommitReveal(newCid, _startBlock, _commitDuration, _revealDuration, _revealThreshold); + return newCid; + } + + function commit(uint _cid, bytes32 _secretHash) public checkCommit(_cid, _secretHash) { + Campaign storage c = campaigns[_cid]; + c.commitments[_secretHash] = true; + c.participants[msg.sender] = Participant(0, _secretHash, false); + c.commitNum++; + emit LogCommit(_cid, msg.sender, _secretHash); + } + + function reveal(uint _cid, uint _secret) public checkReveal(_cid) { + Campaign storage c = campaigns[_cid]; + Participant storage p = c.participants[msg.sender]; + require(!p.revealed && keccak256(abi.encodePacked(_secret)) == p.commitment, + "revealed-secret-not-match-commitment"); + p.secret = _secret; + p.revealed = true; + c.revealNum++; + c.generatedRandom ^= _secret; + emit LogReveal(_cid, msg.sender, _secret); + } + + // Return value of 0 representing invalid random output. + function getRandom(uint _cid) public checkFinish(_cid) returns (uint) { + Campaign storage c = campaigns[_cid]; + if (c.revealNum >= c.revealThreshold) { + emit LogRandom(_cid, c.generatedRandom); + return c.generatedRandom; + } else{ + emit LogRandomFailure(_cid, c.commitNum, c.revealNum, c.revealThreshold); + return 0; + } + } +} diff --git a/contracts/ContractGateway.sol b/contracts/ContractGateway.sol new file mode 100644 index 0000000..d542762 --- /dev/null +++ b/contracts/ContractGateway.sol @@ -0,0 +1,275 @@ +pragma solidity ^0.5.0; + +/** + * @title Proxy + * @dev Implements delegation of calls to other contracts, with proper + * forwarding of return values and bubbling of failures. + * It defines a fallback function that delegates all calls to the address + * returned by the abstract _implementation() internal function. + */ +contract Proxy { + /** + * @dev Fallback function. + * Implemented entirely in `_fallback`. + */ + function () payable external { + _fallback(); + } + + /** + * @return The Address of the implementation. + */ + function _implementation() internal view returns (address); + + /** + * @dev Delegates execution to an implementation contract. + * This is a low level function that doesn't return to its internal call site. + * It will return to the external caller whatever the implementation returns. + * @param implementation Address to delegate. + */ + function _delegate(address implementation) internal { + assembly { + // Copy msg.data. We take full control of memory in this inline assembly + // block because it will not return to Solidity code. We overwrite the + // Solidity scratch pad at memory position 0. + calldatacopy(0, 0, calldatasize) + + // Call the implementation. + // out and outsize are 0 because we don't know the size yet. + let result := delegatecall(gas, implementation, 0, calldatasize, 0, 0) + + // Copy the returned data. + returndatacopy(0, 0, returndatasize) + + switch result + // delegatecall returns 0 on error. + case 0 { revert(0, returndatasize) } + default { return(0, returndatasize) } + } + } + + /** + * @dev Function that is run as the first thing in the fallback function. + * Can be redefined in derived contracts to add functionality. + * Redefinitions must call super._willFallback(). + */ + function _willFallback() internal { + } + + /** + * @dev fallback implementation. + * Extracted to enable manual triggering. + */ + function _fallback() internal { + _willFallback(); + _delegate(_implementation()); + } +} + + +/** + * @title UpgradeabilityProxy + * @dev This contract implements a proxy that allows to change the + * implementation address to which it will delegate. + * Such a change is called an implementation upgrade. + */ +contract UpgradeabilityProxy is Proxy { + /** + * @dev Emitted when the implementation is upgraded. + * @param implementation Address of the new implementation. + */ + event Upgraded(address implementation); + + /** + * @dev Storage slot with the address of the current implementation. + * This is the keccak-256 hash of "eip1967.proxy.implementation" subtracted by 1, and is + * validated in the constructor. + */ + bytes32 private constant IMPLEMENTATION_SLOT = 0x360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc; + + /** + * @dev Contract constructor. + * @param _implementation Address of the initial implementation. + */ + constructor(address _implementation) public payable { + assert(IMPLEMENTATION_SLOT == bytes32(uint256(keccak256('eip1967.proxy.implementation')) - 1)); + + _setImplementation(_implementation); + } + + function isContract(address addr) internal view returns (bool) { + uint256 size; + // solium-disable-next-line security/no-inline-assembly + assembly { size := extcodesize(addr) } + return size > 0; + } + + /** + * @dev Returns the current implementation. + * @return Address of the current implementation + */ + function _implementation() internal view returns (address impl) { + bytes32 slot = IMPLEMENTATION_SLOT; + assembly { + impl := sload(slot) + } + } + + /** + * @dev Upgrades the proxy to a new implementation. + * @param newImplementation Address of the new implementation. + */ + function _upgradeTo(address newImplementation) internal { + _setImplementation(newImplementation); + emit Upgraded(newImplementation); + } + + /** + * @dev Sets the implementation address of the proxy. + * @param newImplementation Address of the new implementation. + */ + function _setImplementation(address newImplementation) private { + require(isContract(newImplementation), "Cannot set a proxy implementation to a non-contract address"); + + bytes32 slot = IMPLEMENTATION_SLOT; + + assembly { + sstore(slot, newImplementation) + } + } +} + + +/** + * @title AdminUpgradeabilityProxy + * @dev This contract combines an upgradeability proxy with an authorization + * mechanism for administrative tasks. + * All external functions in this contract must be guarded by the + * `ifAdmin` modifier. See ethereum/solidity#3864 for a Solidity + * feature proposal that would enable this to be done automatically. + */ +contract AdminUpgradeabilityProxy is UpgradeabilityProxy { + /** + * @dev Emitted when the administration has been transferred. + * @param previousAdmin Address of the previous admin. + * @param newAdmin Address of the new admin. + */ + event AdminChanged(address previousAdmin, address newAdmin); + + /** + * @dev Storage slot with the admin of the contract. + * This is the keccak-256 hash of "eip1967.proxy.admin" subtracted by 1, and is + * validated in the constructor. + */ + bytes32 private constant ADMIN_SLOT = 0xb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d6103; + + /** + * @dev Modifier to check whether the `msg.sender` is the admin. + * If it is, it will run the function. Otherwise, it will delegate the call + * to the implementation. + */ + modifier ifAdmin() { + if (msg.sender == _admin()) { + _; + } else { + _fallback(); + } + } + + /** + * Contract constructor. + * It sets the `msg.sender` as the proxy administrator. + * @param _implementation address of the initial implementation. + */ + constructor(address _implementation) UpgradeabilityProxy(_implementation) public { + assert(ADMIN_SLOT == bytes32(uint256(keccak256('eip1967.proxy.admin')) - 1)); + + _setAdmin(msg.sender); + } + + /** + * @return The address of the proxy admin. + */ + function admin() external ifAdmin returns (address) { + return _admin(); + } + + /** + * @return The address of the implementation. + */ + function implementation() external ifAdmin returns (address) { + return _implementation(); + } + + /** + * @dev Changes the admin of the proxy. + * Only the current admin can call this function. + * @param newAdmin Address to transfer proxy administration to. + */ + function changeAdmin(address newAdmin) external ifAdmin { + require(newAdmin != address(0), "Cannot change the admin of a proxy to the zero address"); + emit AdminChanged(_admin(), newAdmin); + _setAdmin(newAdmin); + } + + /** + * @dev Upgrade the backing implementation of the proxy. + * Only the admin can call this function. + * @param newImplementation Address of the new implementation. + */ + function upgradeTo(address newImplementation) external ifAdmin { + _upgradeTo(newImplementation); + } + + /** + * @dev Upgrade the backing implementation of the proxy and call a function + * on the new implementation. + * This is useful to initialize the proxied contract. + * @param newImplementation Address of the new implementation. + * @param data Data to send as msg.data in the low level call. + * It should include the signature and the parameters of the function to be + * called, as described in + * https://solidity.readthedocs.io/en/develop/abi-spec.html#function-selector-and-argument-encoding. + */ + function upgradeToAndCall(address newImplementation, bytes calldata data) payable external ifAdmin { + _upgradeTo(newImplementation); + (bool success,) = newImplementation.delegatecall(data); + require(success); + } + + /** + * @return The admin slot. + */ + function _admin() internal view returns (address adm) { + bytes32 slot = ADMIN_SLOT; + assembly { + adm := sload(slot) + } + } + + /** + * @dev Sets the address of the proxy admin. + * @param newAdmin Address of the new proxy admin. + */ + function _setAdmin(address newAdmin) internal { + bytes32 slot = ADMIN_SLOT; + + assembly { + sstore(slot, newAdmin) + } + } + + /** + * @dev Only fall back when the sender is not the admin. + */ + function _willFallback() internal { + require(msg.sender != _admin(), "Cannot call fallback function from the proxy admin"); + super._willFallback(); + } +} + + +contract ContractGateway is AdminUpgradeabilityProxy { + constructor(address _implementation) public AdminUpgradeabilityProxy(_implementation) { + } +} diff --git a/contracts/DOSAddressBridge.sol b/contracts/DOSAddressBridge.sol index 4ab5aaa..c558575 100644 --- a/contracts/DOSAddressBridge.sol +++ b/contracts/DOSAddressBridge.sol @@ -1,18 +1,24 @@ -pragma solidity >= 0.4.24; +pragma solidity ^0.5.0; import "./Ownable.sol"; contract DOSAddressBridge is Ownable { // Deployed DOSProxy contract address. address private _proxyAddress; + // Deployed CommitReveal contract address. + address private _commitrevealAddress; // Deployed DOSPayment contract address. address private _paymentAddress; - // Deployed DOSRegistry contract address. - address private _registryAddress; + // Deployed StakingGateway contract address. + address private _stakingAddress; + // BootStrap node lists. + string private _bootStrapUrl; event ProxyAddressUpdated(address previousProxy, address newProxy); + event CommitRevealAddressUpdated(address previousAddr, address newAddr); event PaymentAddressUpdated(address previousPayment, address newPayment); - event RegistryAddressUpdated(address previousRegistry, address newRegistry); + event StakingAddressUpdated(address previousStaking, address newStaking); + event BootStrapUrlUpdated(string previousURL, string newURL); function getProxyAddress() public view returns (address) { return _proxyAddress; @@ -23,6 +29,15 @@ contract DOSAddressBridge is Ownable { _proxyAddress = newAddr; } + function getCommitRevealAddress() public view returns (address) { + return _commitrevealAddress; + } + + function setCommitRevealAddress(address newAddr) public onlyOwner { + emit CommitRevealAddressUpdated(_commitrevealAddress, newAddr); + _commitrevealAddress = newAddr; + } + function getPaymentAddress() public view returns (address) { return _paymentAddress; } @@ -32,12 +47,21 @@ contract DOSAddressBridge is Ownable { _paymentAddress = newAddr; } - function getRegistryAddress() public view returns (address) { - return _registryAddress; + function getStakingAddress() public view returns (address) { + return _stakingAddress; + } + + function setStakingAddress(address newAddr) public onlyOwner { + emit StakingAddressUpdated(_stakingAddress, newAddr); + _stakingAddress = newAddr; + } + + function getBootStrapUrl() public view returns (string memory) { + return _bootStrapUrl; } - function setRegistryAddress(address newAddr) public onlyOwner { - emit RegistryAddressUpdated(_registryAddress, newAddr); - _registryAddress = newAddr; + function setBootStrapUrl(string memory url) public onlyOwner { + emit BootStrapUrlUpdated(_bootStrapUrl, url); + _bootStrapUrl = url; } } diff --git a/contracts/DOSOnChainSDK-bsc.sol b/contracts/DOSOnChainSDK-bsc.sol new file mode 100644 index 0000000..5582ef7 --- /dev/null +++ b/contracts/DOSOnChainSDK-bsc.sol @@ -0,0 +1,122 @@ +pragma solidity ^0.5.0; + +import "./Ownable.sol"; + +contract IProxy { + function query(address, uint, string memory, string memory) public returns (uint); + function requestRandom(address, uint) public returns (uint); +} + +contract IPayment { + function setPaymentMethod(address payer, address tokenAddr) public; + function defaultTokenAddr() public returns(address); +} + +contract IAddressBridge { + function getProxyAddress() public view returns (address); + function getPaymentAddress() public view returns (address); +} + +contract IERC20 { + function balanceOf(address who) public view returns (uint); + function transfer(address to, uint value) public returns (bool); + function approve(address spender, uint value) public returns (bool); +} + +contract DOSOnChainSDK is Ownable { + IProxy dosProxy; + IAddressBridge dosAddrBridge = IAddressBridge(0x70157cf10404170EEc183043354D0a886Fa51d73); + + modifier resolveAddress { + address proxyAddr = dosAddrBridge.getProxyAddress(); + if (address(dosProxy) != proxyAddr) { + dosProxy = IProxy(proxyAddr); + } + _; + } + + modifier auth { + // Filter out malicious __callback__ caller. + require(msg.sender == dosAddrBridge.getProxyAddress(), "Unauthenticated response"); + _; + } + + // @dev: call setup function first and transfer DOS tokens into deployed contract as oracle fees. + function DOSSetup() public onlyOwner { + address paymentAddr = dosAddrBridge.getPaymentAddress(); + address defaultToken = IPayment(dosAddrBridge.getPaymentAddress()).defaultTokenAddr(); + IERC20(defaultToken).approve(paymentAddr, uint(-1)); + IPayment(dosAddrBridge.getPaymentAddress()).setPaymentMethod(address(this), defaultToken); + } + + // @dev: refund all unused fees to caller. + function DOSRefund() public onlyOwner { + address token = IPayment(dosAddrBridge.getPaymentAddress()).defaultTokenAddr(); + uint amount = IERC20(token).balanceOf(address(this)); + IERC20(token).transfer(msg.sender, amount); + } + + // @dev: Call this function to get a unique queryId to differentiate + // parallel requests. A return value of 0x0 stands for error and a + // related event would be emitted. + // @timeout: Estimated timeout in seconds specified by caller; e.g. 15. + // Response is not guaranteed if processing time exceeds this. + // @dataSource: Data source destination specified by caller. + // E.g.: 'https://api.coinbase.com/v2/prices/ETH-USD/spot' + // @selector: A selector expression provided by caller to filter out + // specific data fields out of the raw response. The response + // data format (json, xml/html, and more) is identified from + // the selector expression. + // E.g. Use "$.data.amount" to extract "194.22" out. + // { + // "data":{ + // "base":"ETH", + // "currency":"USD", + // "amount":"194.22" + // } + // } + // Check below documentation for details. + // (https://dosnetwork.github.io/docs/#/contents/blockchains/ethereum?id=selector). + function DOSQuery(uint timeout, string memory dataSource, string memory selector) + internal + resolveAddress + returns (uint) + { + return dosProxy.query(address(this), timeout, dataSource, selector); + } + + // @dev: Must override __callback__ to process a corresponding response. A + // user-defined event could be added to notify the Dapp frontend that + // the response is ready. + // @queryId: A unique queryId returned by DOSQuery() for callers to + // differentiate parallel responses. + // @result: Response for the specified queryId. + function __callback__(uint queryId, bytes calldata result) external { + // To be overridden in the caller contract. + } + + // @dev: Call this function to request either a fast but insecure random + // number or a safe and secure random number delivered back + // asynchronously through the __callback__ function. + // Depending on the mode, the return value would be a random number + // (for fast mode) or a requestId (for safe mode). + // @seed: Optional random seed provided by caller. + function DOSRandom(uint seed) + internal + resolveAddress + returns (uint) + { + return dosProxy.requestRandom(address(this), seed); + } + + // @dev: Must override __callback__ to process a corresponding random + // number. A user-defined event could be added to notify the Dapp + // frontend that a new secure random number is generated. + // @requestId: A unique requestId returned by DOSRandom() for requester to + // differentiate random numbers generated concurrently. + // @generatedRandom: Generated secure random number for the specific + // requestId. + function __callback__(uint requestId, uint generatedRandom) external auth { + // To be overridden in the caller contract. + } +} diff --git a/contracts/DOSOnChainSDK-bsctest.sol b/contracts/DOSOnChainSDK-bsctest.sol new file mode 100644 index 0000000..0858edd --- /dev/null +++ b/contracts/DOSOnChainSDK-bsctest.sol @@ -0,0 +1,122 @@ +pragma solidity ^0.5.0; + +import "./Ownable.sol"; + +contract IProxy { + function query(address, uint, string memory, string memory) public returns (uint); + function requestRandom(address, uint) public returns (uint); +} + +contract IPayment { + function setPaymentMethod(address payer, address tokenAddr) public; + function defaultTokenAddr() public returns(address); +} + +contract IAddressBridge { + function getProxyAddress() public view returns (address); + function getPaymentAddress() public view returns (address); +} + +contract IERC20 { + function balanceOf(address who) public view returns (uint); + function transfer(address to, uint value) public returns (bool); + function approve(address spender, uint value) public returns (bool); +} + +contract DOSOnChainSDK is Ownable { + IProxy dosProxy; + IAddressBridge dosAddrBridge = IAddressBridge(0xb20BE4f55Aca452a60b8812F051c39C302161BE7); + + modifier resolveAddress { + address proxyAddr = dosAddrBridge.getProxyAddress(); + if (address(dosProxy) != proxyAddr) { + dosProxy = IProxy(proxyAddr); + } + _; + } + + modifier auth { + // Filter out malicious __callback__ caller. + require(msg.sender == dosAddrBridge.getProxyAddress(), "Unauthenticated response"); + _; + } + + // @dev: call setup function first and transfer DOS tokens into deployed contract as oracle fees. + function DOSSetup() public onlyOwner { + address paymentAddr = dosAddrBridge.getPaymentAddress(); + address defaultToken = IPayment(dosAddrBridge.getPaymentAddress()).defaultTokenAddr(); + IERC20(defaultToken).approve(paymentAddr, uint(-1)); + IPayment(dosAddrBridge.getPaymentAddress()).setPaymentMethod(address(this), defaultToken); + } + + // @dev: refund all unused fees to caller. + function DOSRefund() public onlyOwner { + address token = IPayment(dosAddrBridge.getPaymentAddress()).defaultTokenAddr(); + uint amount = IERC20(token).balanceOf(address(this)); + IERC20(token).transfer(msg.sender, amount); + } + + // @dev: Call this function to get a unique queryId to differentiate + // parallel requests. A return value of 0x0 stands for error and a + // related event would be emitted. + // @timeout: Estimated timeout in seconds specified by caller; e.g. 15. + // Response is not guaranteed if processing time exceeds this. + // @dataSource: Data source destination specified by caller. + // E.g.: 'https://api.coinbase.com/v2/prices/ETH-USD/spot' + // @selector: A selector expression provided by caller to filter out + // specific data fields out of the raw response. The response + // data format (json, xml/html, and more) is identified from + // the selector expression. + // E.g. Use "$.data.amount" to extract "194.22" out. + // { + // "data":{ + // "base":"ETH", + // "currency":"USD", + // "amount":"194.22" + // } + // } + // Check below documentation for details. + // (https://dosnetwork.github.io/docs/#/contents/blockchains/ethereum?id=selector). + function DOSQuery(uint timeout, string memory dataSource, string memory selector) + internal + resolveAddress + returns (uint) + { + return dosProxy.query(address(this), timeout, dataSource, selector); + } + + // @dev: Must override __callback__ to process a corresponding response. A + // user-defined event could be added to notify the Dapp frontend that + // the response is ready. + // @queryId: A unique queryId returned by DOSQuery() for callers to + // differentiate parallel responses. + // @result: Response for the specified queryId. + function __callback__(uint queryId, bytes calldata result) external { + // To be overridden in the caller contract. + } + + // @dev: Call this function to request either a fast but insecure random + // number or a safe and secure random number delivered back + // asynchronously through the __callback__ function. + // Depending on the mode, the return value would be a random number + // (for fast mode) or a requestId (for safe mode). + // @seed: Optional random seed provided by caller. + function DOSRandom(uint seed) + internal + resolveAddress + returns (uint) + { + return dosProxy.requestRandom(address(this), seed); + } + + // @dev: Must override __callback__ to process a corresponding random + // number. A user-defined event could be added to notify the Dapp + // frontend that a new secure random number is generated. + // @requestId: A unique requestId returned by DOSRandom() for requester to + // differentiate random numbers generated concurrently. + // @generatedRandom: Generated secure random number for the specific + // requestId. + function __callback__(uint requestId, uint generatedRandom) external auth { + // To be overridden in the caller contract. + } +} diff --git a/contracts/DOSOnChainSDK-heco.sol b/contracts/DOSOnChainSDK-heco.sol new file mode 100644 index 0000000..dd476d6 --- /dev/null +++ b/contracts/DOSOnChainSDK-heco.sol @@ -0,0 +1,122 @@ +pragma solidity ^0.5.0; + +import "./Ownable.sol"; + +contract IProxy { + function query(address, uint, string memory, string memory) public returns (uint); + function requestRandom(address, uint) public returns (uint); +} + +contract IPayment { + function setPaymentMethod(address payer, address tokenAddr) public; + function defaultTokenAddr() public returns(address); +} + +contract IAddressBridge { + function getProxyAddress() public view returns (address); + function getPaymentAddress() public view returns (address); +} + +contract IERC20 { + function balanceOf(address who) public view returns (uint); + function transfer(address to, uint value) public returns (bool); + function approve(address spender, uint value) public returns (bool); +} + +contract DOSOnChainSDK is Ownable { + IProxy dosProxy; + IAddressBridge dosAddrBridge = IAddressBridge(0x9Ee7F642d3955ecf17D7223705DCb285dbA679fc); + + modifier resolveAddress { + address proxyAddr = dosAddrBridge.getProxyAddress(); + if (address(dosProxy) != proxyAddr) { + dosProxy = IProxy(proxyAddr); + } + _; + } + + modifier auth { + // Filter out malicious __callback__ caller. + require(msg.sender == dosAddrBridge.getProxyAddress(), "Unauthenticated response"); + _; + } + + // @dev: call setup function first and transfer DOS tokens into deployed contract as oracle fees. + function DOSSetup() public onlyOwner { + address paymentAddr = dosAddrBridge.getPaymentAddress(); + address defaultToken = IPayment(dosAddrBridge.getPaymentAddress()).defaultTokenAddr(); + IERC20(defaultToken).approve(paymentAddr, uint(-1)); + IPayment(dosAddrBridge.getPaymentAddress()).setPaymentMethod(address(this), defaultToken); + } + + // @dev: refund all unused fees to caller. + function DOSRefund() public onlyOwner { + address token = IPayment(dosAddrBridge.getPaymentAddress()).defaultTokenAddr(); + uint amount = IERC20(token).balanceOf(address(this)); + IERC20(token).transfer(msg.sender, amount); + } + + // @dev: Call this function to get a unique queryId to differentiate + // parallel requests. A return value of 0x0 stands for error and a + // related event would be emitted. + // @timeout: Estimated timeout in seconds specified by caller; e.g. 15. + // Response is not guaranteed if processing time exceeds this. + // @dataSource: Data source destination specified by caller. + // E.g.: 'https://api.coinbase.com/v2/prices/ETH-USD/spot' + // @selector: A selector expression provided by caller to filter out + // specific data fields out of the raw response. The response + // data format (json, xml/html, and more) is identified from + // the selector expression. + // E.g. Use "$.data.amount" to extract "194.22" out. + // { + // "data":{ + // "base":"ETH", + // "currency":"USD", + // "amount":"194.22" + // } + // } + // Check below documentation for details. + // (https://dosnetwork.github.io/docs/#/contents/blockchains/ethereum?id=selector). + function DOSQuery(uint timeout, string memory dataSource, string memory selector) + internal + resolveAddress + returns (uint) + { + return dosProxy.query(address(this), timeout, dataSource, selector); + } + + // @dev: Must override __callback__ to process a corresponding response. A + // user-defined event could be added to notify the Dapp frontend that + // the response is ready. + // @queryId: A unique queryId returned by DOSQuery() for callers to + // differentiate parallel responses. + // @result: Response for the specified queryId. + function __callback__(uint queryId, bytes calldata result) external { + // To be overridden in the caller contract. + } + + // @dev: Call this function to request either a fast but insecure random + // number or a safe and secure random number delivered back + // asynchronously through the __callback__ function. + // Depending on the mode, the return value would be a random number + // (for fast mode) or a requestId (for safe mode). + // @seed: Optional random seed provided by caller. + function DOSRandom(uint seed) + internal + resolveAddress + returns (uint) + { + return dosProxy.requestRandom(address(this), seed); + } + + // @dev: Must override __callback__ to process a corresponding random + // number. A user-defined event could be added to notify the Dapp + // frontend that a new secure random number is generated. + // @requestId: A unique requestId returned by DOSRandom() for requester to + // differentiate random numbers generated concurrently. + // @generatedRandom: Generated secure random number for the specific + // requestId. + function __callback__(uint requestId, uint generatedRandom) external auth { + // To be overridden in the caller contract. + } +} diff --git a/contracts/DOSOnChainSDK-hecotest.sol b/contracts/DOSOnChainSDK-hecotest.sol new file mode 100644 index 0000000..2278f4e --- /dev/null +++ b/contracts/DOSOnChainSDK-hecotest.sol @@ -0,0 +1,122 @@ +pragma solidity ^0.5.0; + +import "./Ownable.sol"; + +contract IProxy { + function query(address, uint, string memory, string memory) public returns (uint); + function requestRandom(address, uint) public returns (uint); +} + +contract IPayment { + function setPaymentMethod(address payer, address tokenAddr) public; + function defaultTokenAddr() public returns(address); +} + +contract IAddressBridge { + function getProxyAddress() public view returns (address); + function getPaymentAddress() public view returns (address); +} + +contract IERC20 { + function balanceOf(address who) public view returns (uint); + function transfer(address to, uint value) public returns (bool); + function approve(address spender, uint value) public returns (bool); +} + +contract DOSOnChainSDK is Ownable { + IProxy dosProxy; + IAddressBridge dosAddrBridge = IAddressBridge(0x797D0f474dDcAa8F4066A263684B540C074801b3); + + modifier resolveAddress { + address proxyAddr = dosAddrBridge.getProxyAddress(); + if (address(dosProxy) != proxyAddr) { + dosProxy = IProxy(proxyAddr); + } + _; + } + + modifier auth { + // Filter out malicious __callback__ caller. + require(msg.sender == dosAddrBridge.getProxyAddress(), "Unauthenticated response"); + _; + } + + // @dev: call setup function first and transfer DOS tokens into deployed contract as oracle fees. + function DOSSetup() public onlyOwner { + address paymentAddr = dosAddrBridge.getPaymentAddress(); + address defaultToken = IPayment(dosAddrBridge.getPaymentAddress()).defaultTokenAddr(); + IERC20(defaultToken).approve(paymentAddr, uint(-1)); + IPayment(dosAddrBridge.getPaymentAddress()).setPaymentMethod(address(this), defaultToken); + } + + // @dev: refund all unused fees to caller. + function DOSRefund() public onlyOwner { + address token = IPayment(dosAddrBridge.getPaymentAddress()).defaultTokenAddr(); + uint amount = IERC20(token).balanceOf(address(this)); + IERC20(token).transfer(msg.sender, amount); + } + + // @dev: Call this function to get a unique queryId to differentiate + // parallel requests. A return value of 0x0 stands for error and a + // related event would be emitted. + // @timeout: Estimated timeout in seconds specified by caller; e.g. 15. + // Response is not guaranteed if processing time exceeds this. + // @dataSource: Data source destination specified by caller. + // E.g.: 'https://api.coinbase.com/v2/prices/ETH-USD/spot' + // @selector: A selector expression provided by caller to filter out + // specific data fields out of the raw response. The response + // data format (json, xml/html, and more) is identified from + // the selector expression. + // E.g. Use "$.data.amount" to extract "194.22" out. + // { + // "data":{ + // "base":"ETH", + // "currency":"USD", + // "amount":"194.22" + // } + // } + // Check below documentation for details. + // (https://dosnetwork.github.io/docs/#/contents/blockchains/ethereum?id=selector). + function DOSQuery(uint timeout, string memory dataSource, string memory selector) + internal + resolveAddress + returns (uint) + { + return dosProxy.query(address(this), timeout, dataSource, selector); + } + + // @dev: Must override __callback__ to process a corresponding response. A + // user-defined event could be added to notify the Dapp frontend that + // the response is ready. + // @queryId: A unique queryId returned by DOSQuery() for callers to + // differentiate parallel responses. + // @result: Response for the specified queryId. + function __callback__(uint queryId, bytes calldata result) external { + // To be overridden in the caller contract. + } + + // @dev: Call this function to request either a fast but insecure random + // number or a safe and secure random number delivered back + // asynchronously through the __callback__ function. + // Depending on the mode, the return value would be a random number + // (for fast mode) or a requestId (for safe mode). + // @seed: Optional random seed provided by caller. + function DOSRandom(uint seed) + internal + resolveAddress + returns (uint) + { + return dosProxy.requestRandom(address(this), seed); + } + + // @dev: Must override __callback__ to process a corresponding random + // number. A user-defined event could be added to notify the Dapp + // frontend that a new secure random number is generated. + // @requestId: A unique requestId returned by DOSRandom() for requester to + // differentiate random numbers generated concurrently. + // @generatedRandom: Generated secure random number for the specific + // requestId. + function __callback__(uint requestId, uint generatedRandom) external auth { + // To be overridden in the caller contract. + } +} diff --git a/contracts/DOSOnChainSDK.sol b/contracts/DOSOnChainSDK.sol index 6957146..d3fbc2a 100644 --- a/contracts/DOSOnChainSDK.sol +++ b/contracts/DOSOnChainSDK.sol @@ -1,30 +1,59 @@ -pragma solidity >= 0.4.24; +pragma solidity ^0.5.0; -import "./lib/utils.sol"; +import "./Ownable.sol"; -contract DOSProxyInterface { +contract IProxy { function query(address, uint, string memory, string memory) public returns (uint); - function requestRandom(address, uint8, uint) public returns (uint); + function requestRandom(address, uint) public returns (uint); } -contract DOSAddressBridgeInterface { +contract IPayment { + function setPaymentMethod(address payer, address tokenAddr) public; + function defaultTokenAddr() public returns(address); +} + +contract IAddressBridge { function getProxyAddress() public view returns (address); + function getPaymentAddress() public view returns (address); } -contract DOSOnChainSDK { - using utils for *; +contract IERC20 { + function balanceOf(address who) public view returns (uint); + function transfer(address to, uint value) public returns (bool); + function approve(address spender, uint value) public returns (bool); +} - DOSProxyInterface dosProxy; - DOSAddressBridgeInterface dosAddrBridge = - DOSAddressBridgeInterface(0xe987926A226932DFB1f71FA316461db272E05317); +contract DOSOnChainSDK is Ownable { + IProxy dosProxy; + IAddressBridge dosAddrBridge = IAddressBridge(0x98A0E7026778840Aacd28B9c03137D32e06F5ff1); modifier resolveAddress { - dosProxy = DOSProxyInterface(dosAddrBridge.getProxyAddress()); + address proxyAddr = dosAddrBridge.getProxyAddress(); + if (address(dosProxy) != proxyAddr) { + dosProxy = IProxy(proxyAddr); + } + _; + } + + modifier auth { + // Filter out malicious __callback__ caller. + require(msg.sender == dosAddrBridge.getProxyAddress(), "Unauthenticated response"); _; } - function fromDOSProxyContract() internal view returns (address) { - return dosAddrBridge.getProxyAddress(); + // @dev: call setup function first and transfer DOS tokens into deployed contract as oracle fees. + function DOSSetup() public onlyOwner { + address paymentAddr = dosAddrBridge.getPaymentAddress(); + address defaultToken = IPayment(dosAddrBridge.getPaymentAddress()).defaultTokenAddr(); + IERC20(defaultToken).approve(paymentAddr, uint(-1)); + IPayment(dosAddrBridge.getPaymentAddress()).setPaymentMethod(address(this), defaultToken); + } + + // @dev: refund all unused fees to caller. + function DOSRefund() public onlyOwner { + address token = IPayment(dosAddrBridge.getPaymentAddress()).defaultTokenAddr(); + uint amount = IERC20(token).balanceOf(address(this)); + IERC20(token).transfer(msg.sender, amount); } // @dev: Call this function to get a unique queryId to differentiate @@ -49,8 +78,8 @@ contract DOSOnChainSDK { // Check below documentation for details. // (https://dosnetwork.github.io/docs/#/contents/blockchains/ethereum?id=selector). function DOSQuery(uint timeout, string memory dataSource, string memory selector) - resolveAddress internal + resolveAddress returns (uint) { return dosProxy.query(address(this), timeout, dataSource, selector); @@ -62,7 +91,7 @@ contract DOSOnChainSDK { // @queryId: A unique queryId returned by DOSQuery() for callers to // differentiate parallel responses. // @result: Response for the specified queryId. - function __callback__(uint queryId, bytes memory result) public { + function __callback__(uint queryId, bytes calldata result) external { // To be overridden in the caller contract. } @@ -71,23 +100,13 @@ contract DOSOnChainSDK { // asynchronously through the __callback__ function. // Depending on the mode, the return value would be a random number // (for fast mode) or a requestId (for safe mode). - // @mode: 1: safe mode - The asynchronous but safe way to generate a new - // secure random number by a group of off-chain - // clients using VRF and Threshold Signature. There - // would be a fee to run in safe mode. - // 0: fast mode - Return a random number in one invocation directly. - // The returned random is the sha3 hash of latest - // generated random number by DOS Network combining - // with the optional seed. - // Thus the result should NOT be considered safe and - // is for testing purpose only. It's free of charge. // @seed: Optional random seed provided by caller. - function DOSRandom(uint8 mode, uint seed) - resolveAddress + function DOSRandom(uint seed) internal + resolveAddress returns (uint) { - return dosProxy.requestRandom(address(this), mode, seed); + return dosProxy.requestRandom(address(this), seed); } // @dev: Must override __callback__ to process a corresponding random @@ -97,7 +116,7 @@ contract DOSOnChainSDK { // differentiate random numbers generated concurrently. // @generatedRandom: Generated secure random number for the specific // requestId. - function __callback__(uint requestId, uint generatedRandom) public { + function __callback__(uint requestId, uint generatedRandom) external auth { // To be overridden in the caller contract. } } diff --git a/contracts/DOSPayment.sol b/contracts/DOSPayment.sol new file mode 100644 index 0000000..951c2ec --- /dev/null +++ b/contracts/DOSPayment.sol @@ -0,0 +1,234 @@ +pragma solidity ^0.5.0; + +contract ERC20 { + function balanceOf(address who) public view returns (uint); + function decimals() public view returns (uint); + function transfer(address to, uint value) public returns (bool); + function transferFrom(address from, address to, uint value) public returns (bool); +} + +contract DOSAddressBridgeInterface { + function getProxyAddress() public view returns (address); +} + +contract DOSPayment { + enum ServiceType { + SystemRandom, + UserRandom, + UserQuery + } + + struct FeeList { + // ServiceType => serviceFee + mapping(uint => uint) serviceFee; + uint submitterCut; + uint guardianFee; + } + + struct Payment { + address payer; + address tokenAddr; + uint serviceType; + uint amount; + } + + address public admin; + // payer addr => payment token addr + mapping(address => address) public paymentMethods; + // tokenAddr => feeList + mapping(address => FeeList) public feeLists; + // requestID => Payment + mapping(uint => Payment) public payments; + // node address => {tokenAddr => amount} + mapping(address => mapping(address => uint)) private _balances; + + uint constant public defaultSubmitterCut = 4; + uint constant public defaultSystemRandomFee = 5 * 1e18; // 5 tokens + uint constant public defaultUserRandomFee = 5 * 1e18; // 5 tokens + uint constant public defaultUserQueryFee = 5 * 1e18; // 5 tokens + uint constant public defaultGuardianFee = 5 * 1e18; // 5 tokens + + address public guardianFundsAddr; + address public guardianFundsTokenAddr; + address public bridgeAddr; + address public defaultTokenAddr; + + event UpdatePaymentAdmin(address oldAdmin, address newAdmin); + event LogChargeServiceFee(address payer, address tokenAddr, uint requestID, uint serviceType, uint fee); + event LogRefundServiceFee(address payer, address tokenAddr, uint requestID, uint serviceType, uint fee); + event LogRecordServiceFee(address nodeAddr, address tokenAddr, uint requestID, uint serviceType, uint fee, bool isSubmitter); + event LogClaimGuardianFee(address nodeAddr, address tokenAddr, uint feeForSubmitter, address sender); + + modifier onlyFromProxy { + require(msg.sender == DOSAddressBridgeInterface(bridgeAddr).getProxyAddress(), "not-from-dos-proxy"); + _; + } + + modifier onlySupportedToken(address tokenAddr) { + require(isSupportedToken(tokenAddr), "not-supported-token-addr"); + _; + } + + modifier hasPayment(uint requestID) { + require(payments[requestID].amount != 0, "no-fee-amount"); + require(payments[requestID].payer != address(0x0), "no-payer-info"); + require(payments[requestID].tokenAddr != address(0x0), "no-fee-token-info"); + _; + } + + constructor(address _bridgeAddr, address _guardianFundsAddr, address _tokenAddr) public { + initialize(_bridgeAddr, _guardianFundsAddr, _tokenAddr); + } + + function initialize(address _bridgeAddr, address _guardianFundsAddr, address _tokenAddr) public { + require(bridgeAddr == address(0x0) && defaultTokenAddr == address(0x0), "already-initialized"); + + admin = msg.sender; + bridgeAddr = _bridgeAddr; + guardianFundsAddr = _guardianFundsAddr; + guardianFundsTokenAddr = _tokenAddr; + defaultTokenAddr = _tokenAddr; + + FeeList storage feeList = feeLists[_tokenAddr]; + feeList.serviceFee[uint(ServiceType.SystemRandom)] = defaultSystemRandomFee; + feeList.serviceFee[uint(ServiceType.UserRandom)] = defaultUserRandomFee; + feeList.serviceFee[uint(ServiceType.UserQuery)] = defaultUserQueryFee; + feeList.submitterCut = defaultSubmitterCut; + feeList.guardianFee = defaultGuardianFee; + } + + function isSupportedToken(address tokenAddr) public view returns(bool) { + if (tokenAddr == address(0x0)) return false; + if (feeLists[tokenAddr].serviceFee[uint(ServiceType.SystemRandom)] == 0) return false; + if (feeLists[tokenAddr].serviceFee[uint(ServiceType.UserRandom)] == 0) return false; + if (feeLists[tokenAddr].serviceFee[uint(ServiceType.UserQuery)] == 0) return false; + return true; + } + + modifier onlyAdmin { + require(msg.sender == admin, "onlyAdmin"); + _; + } + + function setAdmin(address newAdmin) public onlyAdmin { + require(newAdmin != address(0)); + emit UpdatePaymentAdmin(admin, newAdmin); + admin = newAdmin; + } + + function setPaymentMethod(address payer, address tokenAddr) public onlySupportedToken(tokenAddr) { + paymentMethods[payer] = tokenAddr; + } + + function setServiceFee(address tokenAddr, uint serviceType, uint fee) public onlyAdmin { + require(tokenAddr != address(0x0), "not-valid-token-addr"); + feeLists[tokenAddr].serviceFee[serviceType] = fee; + } + + function setGuardianFee(address tokenAddr, uint fee) public onlyAdmin { + require(tokenAddr != address(0x0), "not-valid-token-addr"); + feeLists[tokenAddr].guardianFee = fee; + } + + function setFeeDividend(address tokenAddr, uint submitterCut) public onlyAdmin { + require(tokenAddr != address(0x0), "not-valid-token-addr"); + feeLists[tokenAddr].submitterCut = submitterCut; + } + + function setGuardianFunds(address fundsAddr, address tokenAddr) public onlyAdmin onlySupportedToken(tokenAddr) { + guardianFundsAddr = fundsAddr; + guardianFundsTokenAddr = tokenAddr; + } + + function getServiceTypeFee(address tokenAddr, uint serviceType) public view returns(uint) { + require(tokenAddr != address(0x0) && feeLists[tokenAddr].guardianFee != 0 && feeLists[tokenAddr].submitterCut != 0, + "not-valid-token-addr"); + return feeLists[tokenAddr].serviceFee[serviceType]; + } + + function hasServiceFee(address payer, uint serviceType) public view returns (bool) { + if (payer == DOSAddressBridgeInterface(bridgeAddr).getProxyAddress()) return true; + address tokenAddr = paymentMethods[payer]; + // Get fee by tokenAddr and serviceType + uint fee = feeLists[tokenAddr].serviceFee[serviceType]; + return ERC20(tokenAddr).balanceOf(payer) >= fee; + } + + function chargeServiceFee(address payer, uint requestID, uint serviceType) public onlyFromProxy { + address tokenAddr = paymentMethods[payer]; + // Get fee by tokenAddr and serviceType + uint fee = feeLists[tokenAddr].serviceFee[serviceType]; + payments[requestID] = Payment(payer, tokenAddr, serviceType, fee); + emit LogChargeServiceFee(payer, tokenAddr, requestID, serviceType, fee); + ERC20(tokenAddr).transferFrom(payer, address(this), fee); + } + + function refundServiceFee(uint requestID) public onlyAdmin hasPayment(requestID) { + uint fee = payments[requestID].amount; + uint serviceType = payments[requestID].serviceType; + address tokenAddr = payments[requestID].tokenAddr; + address payer = payments[requestID].payer; + delete payments[requestID]; + emit LogRefundServiceFee(payer, tokenAddr, requestID, serviceType, fee); + ERC20(tokenAddr).transfer(payer, fee); + } + + function recordServiceFee(uint requestID, address submitter, address[] memory workers) public onlyFromProxy hasPayment(requestID) { + address tokenAddr = payments[requestID].tokenAddr; + uint feeUnit = payments[requestID].amount / 10; + uint serviceType = payments[requestID].serviceType; + delete payments[requestID]; + + FeeList storage feeList = feeLists[tokenAddr]; + uint feeForSubmitter = feeUnit * feeList.submitterCut; + _balances[submitter][tokenAddr] += feeForSubmitter; + emit LogRecordServiceFee(submitter, tokenAddr, requestID, serviceType, feeForSubmitter, true); + uint feeForWorker = feeUnit * (10 - feeList.submitterCut) / (workers.length - 1); + for (uint i = 0; i < workers.length; i++) { + if (workers[i] != submitter) { + _balances[workers[i]][tokenAddr] += feeForWorker; + emit LogRecordServiceFee(workers[i], tokenAddr, requestID, serviceType, feeForWorker, false); + } + } + } + + function claimGuardianReward(address guardianAddr) public onlyFromProxy { + require(guardianFundsAddr != address(0x0), "not-valid-guardian-fund-addr"); + require(guardianFundsTokenAddr != address(0x0), "not-valid-guardian-token-addr"); + uint fee = feeLists[guardianFundsTokenAddr].guardianFee; + emit LogClaimGuardianFee(guardianAddr, guardianFundsTokenAddr, fee, msg.sender); + ERC20(guardianFundsTokenAddr).transferFrom(guardianFundsAddr, guardianAddr,fee); + } + + // @dev: node runners call to withdraw recorded service fees. + function nodeClaim() public returns(uint) { + return nodeClaim(msg.sender, defaultTokenAddr, msg.sender); + } + + // @dev: node runners call to withdraw recorded service fees to specified address. + function nodeClaim(address to) public returns(uint) { + return nodeClaim(msg.sender, defaultTokenAddr, to); + } + + function nodeClaim(address nodeAddr, address tokenAddr, address to) internal returns(uint) { + uint amount = _balances[nodeAddr][tokenAddr]; + if (amount != 0) { + delete _balances[nodeAddr][tokenAddr]; + ERC20(tokenAddr).transfer(to, amount); + } + return amount; + } + + function nodeFeeBalance(address nodeAddr) public view returns (uint) { + return nodeFeeBalance(nodeAddr, defaultTokenAddr); + } + + function nodeFeeBalance(address nodeAddr, address tokenAddr) public view returns (uint) { + return _balances[nodeAddr][tokenAddr]; + } + + function paymentInfo(uint requestID) public view returns (address, uint) { + Payment storage payment = payments[requestID]; + return (payment.tokenAddr, payment.amount); + } +} diff --git a/contracts/DOSProxy.sol b/contracts/DOSProxy.sol index 2f9ddfd..6a7fa74 100644 --- a/contracts/DOSProxy.sol +++ b/contracts/DOSProxy.sol @@ -1,131 +1,441 @@ -pragma solidity >= 0.4.24; -// Not enabled for production yet. -//pragma experimental ABIEncoderV2; +pragma solidity ^0.5.0; import "./lib/BN256.sol"; -contract UserContractInterface { +contract IUserContract { // Query callback. - function __callback__(uint, bytes memory) public; + function __callback__(uint, bytes calldata) external; // Random number callback. - function __callback__(uint, uint) public; + function __callback__(uint, uint) external; +} + +contract ICommitReveal { + function startCommitReveal(uint, uint, uint, uint) public returns(uint); + function getRandom(uint) public returns(uint); +} + +contract IDOSAddressBridge { + function getCommitRevealAddress() public view returns(address); + function getPaymentAddress() public view returns(address); + function getStakingAddress() public view returns(address); +} + +contract IDOSPayment { + function hasServiceFee(address, uint) public view returns (bool); + function chargeServiceFee(address, uint, uint) public; + function recordServiceFee(uint, address, address[] memory) public; + function claimGuardianReward(address) public; + function setPaymentMethod(address, address) public; +} + +contract IDOSStaking { + function nodeStart(address _nodeAddr) public; + function nodeStop(address _nodeAddr) public; + function isValidStakingNode(address _nodeAddr) public view returns(bool); } contract DOSProxy { using BN256 for *; + // Metadata of pending request. struct PendingRequest { uint requestId; - BN256.G2Point handledGroup; - // User contract issued the query. + uint groupId; + BN256.G2Point handledGroupPubKey; + // Calling contract who issues the request. address callbackAddr; } - uint requestIdSeed; - uint groupSize; - uint[] nodeId; + // Metadata of registered group. + struct Group { + uint groupId; + BN256.G2Point groupPubKey; + uint life; + uint birthBlkN; + address[] members; + } + + // Metadata of a to-be-registered group whose members are determined already. + struct PendingGroup { + uint groupId; + uint startBlkNum; + mapping(bytes32 => uint) pubKeyCounts; + // 0x1 (HEAD) -> member1 -> member2 -> ... -> memberN -> 0x1 (HEAD) + mapping(address => address) memberList; + } + + address private owner; + uint public initBlkN; // calling requestId => PendingQuery metadata mapping(uint => PendingRequest) PendingRequests; - // Note: Make atomic changes to group metadata below. - BN256.G2Point[] groupPubKeys; - // groupIdentifier => isExisted - mapping(bytes32 => bool) groups; - //publicKey => publicKey appearance - mapping(bytes32 => uint) pubKeyCounter; - // Note: Make atomic changes to randomness metadata below. + + uint public relayRespondLimit = 128; // in blocks + uint public refreshSystemRandomHardLimit = 8192; // in blocks + uint public groupMaturityPeriod = refreshSystemRandomHardLimit * 32; // in blocks + uint public lifeDiversity = refreshSystemRandomHardLimit; // in blocks + // avoid looping in a big loop that causing over gas. + uint public loopLimit = 50; + + // Minimum 4 groups to bootstrap + uint public bootstrapGroups = 4; + // When regrouping, picking @groupToPick working groups, plus one group from pending nodes. + uint public groupToPick = 2; + uint public groupSize = 3; + + // Bootstrapping related arguments, in blocks. + uint public bootstrapCommitDuration = 60; + uint public bootstrapRevealDuration = 60; + uint public bootstrapStartThreshold = groupSize * bootstrapGroups; + uint public bootstrapRound; + uint public bootstrapEndBlk; + + IDOSAddressBridge public addressBridge; + address public proxyFundsAddr; + address public proxyFundsTokenAddr; + + uint private constant UINTMAX = uint(-1); + // Dummy head and placeholder used in linkedlists. + uint private constant HEAD_I = 0x1; + address private constant HEAD_A = address(0x1); + + // Linkedlist of newly registered ungrouped nodes, with HEAD points to the earliest and pendingNodeTail points to the latest. + // Initial state: pendingNodeList[HEAD_A] == HEAD_A && pendingNodeTail == HEAD_A. + mapping(address => address) public pendingNodeList; + address public pendingNodeTail; + uint public numPendingNodes; + + // node => working/pending GroupId + // Unregisted node: { nodeAddr : 0 } + // { nodeAddr : HEAD_I } -> registered node but not in any group + mapping(address => uint) public nodeToGroupId; + + // groupId => Group + mapping(uint => Group) workingGroups; + // Index:groupId + uint[] public workingGroupIds; + uint[] public expiredWorkingGroupIds; + + // groupId => PendingGroup + mapping(uint => PendingGroup) public pendingGroups; + uint public pendingGroupMaxLife = 20; // in blocks + + // Initial state: pendingGroupList[HEAD_I] == HEAD_I && pendingGroupTail == HEAD_I + mapping(uint => uint) public pendingGroupList; + uint public pendingGroupTail; + uint public numPendingGroups; + + uint public cachedUpdatedBlock; uint public lastUpdatedBlock; uint public lastRandomness; - BN256.G2Point lastHandledGroup; - uint8 constant TrafficSystemRandom = 0; - uint8 constant TrafficUserRandom = 1; - uint8 constant TrafficUserQuery = 2; + uint public lastFormGrpReqId; + Group lastHandledGroup; + + // Only whitelised guardian are permitted to kick off signalUnregister process + // TODO : Chose a random group to check and has a consensus about which nodes should be unregister in v2.0. + mapping(address => bool) public guardianListed; + enum TrafficType { + SystemRandom, + UserRandom, + UserQuery + } - event LogUrl( - uint queryId, - uint timeout, - string dataSource, - string selector, - uint randomness, - // Log G2Point struct directly is an experimental feature, use with care. - uint[4] dispatchedGroup - ); - event LogRequestUserRandom( - uint requestId, - uint lastSystemRandomness, - uint userSeed, - uint[4] dispatchedGroup - ); + event LogUrl(uint queryId, uint timeout, string dataSource, string selector, uint randomness, uint dispatchedGroupId); + event LogRequestUserRandom(uint requestId, uint lastSystemRandomness, uint userSeed, uint dispatchedGroupId); event LogNonSupportedType(string invalidSelector); event LogNonContractCall(address from); event LogCallbackTriggeredFor(address callbackAddr); event LogRequestFromNonExistentUC(); - event LogUpdateRandom(uint lastRandomness, uint[4] dispatchedGroup); - event LogValidationResult( - uint8 trafficType, - uint trafficId, - bytes message, - uint[2] signature, - uint[4] pubKey, - bool pass - ); - event LogInsufficientGroupNumber(); - event LogGrouping(uint[] NodeId); - event LogPublicKeyAccepted(uint x1, uint x2, uint y1, uint y2); - - // whitelist state variables used only for alpha release. - // Index starting from 1. - address[22] whitelists; - // whitelisted address => index in whitelists. - mapping(address => uint) isWhitelisted; - bool public whitelistInitialized = false; - event WhitelistAddressTransferred(address previous, address curr); - - modifier onlyWhitelisted { - uint idx = isWhitelisted[msg.sender]; - require(idx != 0 && whitelists[idx] == msg.sender, "Not whitelisted!"); + event LogUpdateRandom(uint lastRandomness, uint dispatchedGroupId); + event LogValidationResult(uint8 trafficType, uint trafficId, bytes message, uint[2] signature, uint[4] pubKey, bool pass); + event LogInsufficientPendingNode(uint numPendingNodes); + event LogInsufficientWorkingGroup(uint numWorkingGroups, uint numPendingGroups); + event LogGrouping(uint groupId, address[] nodeId); + event LogPublicKeyAccepted(uint groupId, uint[4] pubKey, uint numWorkingGroups); + event LogPublicKeySuggested(uint groupId, uint pubKeyCount); + event LogGroupDissolve(uint groupId); + event LogRegisteredNewPendingNode(address node); + event LogUnRegisteredNewPendingNode(address node, uint8 unregisterFrom); + event LogGroupingInitiated(uint pendingNodePool, uint groupsize); + event LogNoPendingGroup(uint groupId); + event LogPendingGroupRemoved(uint groupId); + event LogMessage(string info); + event GuardianReward(uint blkNum, address guardian); + + modifier onlyOwner { + require(msg.sender == owner); _; } - function initWhitelist(address[21] memory addresses) public { - require(!whitelistInitialized, "Whitelist already initialized!"); + modifier fromValidStakingNode { + require(IDOSStaking(addressBridge.getStakingAddress()).isValidStakingNode(msg.sender), + "invalid-staking-node"); + _; + } - for (uint idx = 0; idx < 21; idx++) { - whitelists[idx+1] = addresses[idx]; - isWhitelisted[addresses[idx]] = idx+1; - } - whitelistInitialized = true; + modifier hasOracleFee(address from, uint serviceType) { + require( + IDOSPayment(addressBridge.getPaymentAddress()).hasServiceFee(from, serviceType), + "not-enough-fee-to-oracle"); + _; } - function getWhitelistAddress(uint idx) public view returns (address) { - require(idx > 0 && idx <= 21, "Index out of range"); - return whitelists[idx]; + modifier onlyGuardianListed { + require(guardianListed[msg.sender], "not-guardian"); + _; } - function transferWhitelistAddress(address newWhitelistedAddr) - public - onlyWhitelisted - { - require(newWhitelistedAddr != address(0x0) && newWhitelistedAddr != msg.sender); + constructor(address _bridgeAddr, address _proxyFundsAddr, address _proxyFundsTokenAddr) public { + owner = msg.sender; + initBlkN = block.number; + pendingNodeList[HEAD_A] = HEAD_A; + pendingNodeTail = HEAD_A; + pendingGroupList[HEAD_I] = HEAD_I; + pendingGroupTail = HEAD_I; + addressBridge = IDOSAddressBridge(_bridgeAddr); + proxyFundsAddr = _proxyFundsAddr; + proxyFundsTokenAddr = _proxyFundsTokenAddr; + IDOSPayment(addressBridge.getPaymentAddress()).setPaymentMethod(proxyFundsAddr, proxyFundsTokenAddr); + } + + function addToGuardianList(address _addr) public onlyOwner { + guardianListed[_addr] = true; + } + + function removeFromGuardianList(address _addr) public onlyOwner { + delete guardianListed[_addr]; + } + + function setProxyFund(address newFund, address newFundToken) public onlyOwner { + require(newFund != proxyFundsAddr && newFund != address(0x0), "invalid-parameter"); + require(newFundToken != proxyFundsTokenAddr && newFundToken != address(0x0), "invalid-parameter"); + proxyFundsAddr = newFund; + proxyFundsTokenAddr = newFundToken; + IDOSPayment(addressBridge.getPaymentAddress()).setPaymentMethod(proxyFundsAddr, proxyFundsTokenAddr); + } + + // groupSize must be an odd number. + function setGroupSize(uint newSize) public onlyOwner { + require(newSize != groupSize && newSize % 2 != 0, "invalid-parameter"); + groupSize = newSize; + } + + function setBootstrapStartThreshold(uint newThreshold) public onlyOwner { + require(newThreshold != bootstrapStartThreshold, "invalid-parameter"); + bootstrapStartThreshold = newThreshold; + } + + function setBootstrapCommitDuration(uint newDuration) public onlyOwner { + require(newDuration != bootstrapCommitDuration && newDuration != 0, "invalid-parameter"); + bootstrapCommitDuration = newDuration; + } + + function setBootstrapRevealDuration(uint newDuration) public onlyOwner { + require(newDuration != bootstrapRevealDuration && newDuration != 0, "invalid-parameter"); + bootstrapRevealDuration = newDuration; + } + + function setGroupMaturityPeriod(uint newPeriod) public onlyOwner { + require(newPeriod != groupMaturityPeriod && newPeriod != 0, "invalid-parameter"); + groupMaturityPeriod = newPeriod; + } + + function setLifeDiversity(uint newDiversity) public onlyOwner { + require(newDiversity != lifeDiversity && newDiversity != 0, "invalid-parameter"); + lifeDiversity = newDiversity; + } + + function setPendingGroupMaxLife(uint newLife) public onlyOwner { + require(newLife != pendingGroupMaxLife && newLife != 0, "invalid-parameter"); + pendingGroupMaxLife = newLife; + } + + function setRelayRespondLimit(uint newLimit) public onlyOwner { + require(newLimit != relayRespondLimit, "invalid-parameter"); + relayRespondLimit = newLimit; + } - emit WhitelistAddressTransferred(msg.sender, newWhitelistedAddr); - whitelists[isWhitelisted[msg.sender]] = newWhitelistedAddr; + function setSystemRandomHardLimit(uint newLimit) public onlyOwner { + require(newLimit != refreshSystemRandomHardLimit && newLimit != 0, "invalid-parameter"); + refreshSystemRandomHardLimit = newLimit; } - function getCodeSize(address addr) internal view returns (uint size) { + function getWorkingGroupById(uint groupId) public view returns(uint, uint[4] memory, uint, uint, address[] memory) { + BN256.G2Point storage pubKey = workingGroups[groupId].groupPubKey; + return ( + workingGroups[groupId].groupId, + [pubKey.x[0], pubKey.x[1], pubKey.y[0], pubKey.y[1]], + workingGroups[groupId].life, + workingGroups[groupId].birthBlkN, + workingGroups[groupId].members + ); + } + + function getCodeSize(address addr) private view returns (uint size) { assembly { size := extcodesize(addr) } } + function dispatchJobCore(TrafficType trafficType, uint pseudoSeed) private returns(uint idx) { + uint dissolveIdx = 0; + do { + if (workingGroupIds.length == 0) { + return UINTMAX; + } + if (dissolveIdx >= workingGroupIds.length || + dissolveIdx >= loopLimit) { + uint rnd = uint(keccak256(abi.encodePacked(trafficType, pseudoSeed, lastRandomness, block.number))); + return rnd % workingGroupIds.length; + } + Group storage group = workingGroups[workingGroupIds[dissolveIdx]]; + if (groupMaturityPeriod + group.birthBlkN + group.life <= block.number) { + // Dissolving expired working groups happens in another phase for gas reasons. + expiredWorkingGroupIds.push(workingGroupIds[dissolveIdx]); + workingGroupIds[dissolveIdx] = workingGroupIds[workingGroupIds.length - 1]; + workingGroupIds.length--; + } + dissolveIdx++; + } while (true); + } + + function dispatchJob(TrafficType trafficType, uint pseudoSeed) private returns(uint) { + kickoffRandomOnCondition(); + return dispatchJobCore(trafficType, pseudoSeed); + } + + function kickoffRandomOnCondition() private returns (bool) { + if (lastUpdatedBlock + refreshSystemRandomHardLimit > block.number || cachedUpdatedBlock + relayRespondLimit > block.number) { + return false; + } + + uint idx = dispatchJobCore(TrafficType.SystemRandom, uint(blockhash(block.number - 1))); + // TODO: keep id receipt and handle later in v2.0. + if (idx == UINTMAX) { + emit LogMessage("no-live-wgrp,try-bootstrap"); + return false; + } + + cachedUpdatedBlock = block.number; + lastHandledGroup = workingGroups[workingGroupIds[idx]]; + // Signal off-chain clients + emit LogUpdateRandom(lastRandomness, lastHandledGroup.groupId); + IDOSPayment(addressBridge.getPaymentAddress()).chargeServiceFee(proxyFundsAddr, /*requestId=*/lastRandomness, uint(TrafficType.SystemRandom)); + return true; + } + + function insertToPendingGroupListTail(uint groupId) private { + pendingGroupList[groupId] = pendingGroupList[pendingGroupTail]; + pendingGroupList[pendingGroupTail] = groupId; + pendingGroupTail = groupId; + numPendingGroups++; + } + + function insertToPendingNodeListTail(address node) private { + pendingNodeList[node] = pendingNodeList[pendingNodeTail]; + pendingNodeList[pendingNodeTail] = node; + pendingNodeTail = node; + numPendingNodes++; + } + + function insertToPendingNodeListHead(address node) private { + pendingNodeList[node] = pendingNodeList[HEAD_A]; + pendingNodeList[HEAD_A] = node; + numPendingNodes++; + } + + function insertToListHead(mapping(uint => uint) storage list, uint id) private { + list[id] = list[HEAD_I]; + list[HEAD_I] = id; + } + + /// Remove Node from a storage linkedlist. + function removeNodeFromList(mapping(address => address) storage list, address node) private returns(address, bool) { + (address prev, bool found) = findNodeFromList(list, node); + if (found) { + list[prev] = list[node]; + delete list[node]; + } + return (prev, found); + } + + /// Find Node from a storage linkedlist. + function findNodeFromList(mapping(address => address) storage list, address node) private view returns(address, bool) { + address prev = HEAD_A; + address curr = list[prev]; + while (curr != HEAD_A && curr != node) { + prev = curr; + curr = list[prev]; + } + if (curr == HEAD_A) { + return (HEAD_A, false); + } else { + return (prev, true); + } + } + + /// Remove id from a storage linkedlist. Need to check tail after this done + function removeIdFromList(mapping(uint => uint) storage list, uint id) private returns(uint, bool) { + uint prev = HEAD_I; + uint curr = list[prev]; + while (curr != HEAD_I && curr != id) { + prev = curr; + curr = list[prev]; + } + if (curr == HEAD_I) { + return (HEAD_I, false); + } else { + list[prev] = list[curr]; + delete list[curr]; + return (prev, true); + } + } + + /// Remove node from a storage linkedlist. + function checkAndRemoveFromPendingGroup(address node) private returns(bool) { + uint prev = HEAD_I; + uint curr = pendingGroupList[prev]; + while (curr != HEAD_I) { + PendingGroup storage pgrp = pendingGroups[curr]; + (, bool found) = findNodeFromList(pgrp.memberList, node); + if (found) { + cleanUpPendingGroup(curr, node); + return true; + } + prev = curr; + curr = pendingGroupList[prev]; + } + return false; + } + + /// @notice Caller ensures no index overflow. Put members back to pendingNodeList's tail if necessary. + /// Skip pushing member into pendingNodeList if that_member == skipNode, even when backToPendingPool is set. + function dissolveWorkingGroup(uint groupId, bool backToPendingPool, address skipNode) private { + /// Deregister expired working group and remove metadata. + Group storage grp = workingGroups[groupId]; + for (uint i = 0; i < grp.members.length; i++) { + address member = grp.members[i]; + // Update nodeToGroupId[member] and put members back to pendingNodeList's tail if necessary. + // Notice: Guardian may need to signal group formation. + if (nodeToGroupId[member] == groupId) { + nodeToGroupId[member] = HEAD_I; + if (backToPendingPool && member != skipNode && pendingNodeList[member] == address(0)) { + insertToPendingNodeListTail(member); + } + } + } + delete workingGroups[groupId]; + emit LogGroupDissolve(groupId); + } + // Returns query id. - // TODO: restrict query from subscribed/paid calling contracts. function query( address from, uint timeout, - string memory dataSource, - string memory selector + string calldata dataSource, + string calldata selector ) - public + external + hasOracleFee(from, uint(TrafficType.UserQuery)) returns (uint) { if (getCodeSize(from) > 0) { @@ -134,60 +444,65 @@ contract DOSProxy { // Starts with '$': response format is parsed as json. // Starts with '/': response format is parsed as xml/html. if (bs.length == 0 || bs[0] == '$' || bs[0] == '/') { - uint queryId = uint(keccak256(abi.encodePacked( - ++requestIdSeed, from, timeout, dataSource, selector))); - uint idx = lastRandomness % groupPubKeys.length; - PendingRequests[queryId] = - PendingRequest(queryId, groupPubKeys[idx], from); + uint queryId = uint(keccak256(abi.encode(block.timestamp, from, timeout, dataSource, selector))); + uint idx = dispatchJob(TrafficType.UserQuery, queryId); + // TODO: keep id receipt and handle later in v2.0. + if (idx == UINTMAX) { + emit LogMessage("skipped-user-query-no-live-wgrp"); + return 0; + } + Group storage grp = workingGroups[workingGroupIds[idx]]; + PendingRequests[queryId] = PendingRequest(queryId, grp.groupId, grp.groupPubKey, from); emit LogUrl( queryId, timeout, dataSource, selector, lastRandomness, - getGroupPubKey(idx) + grp.groupId ); + IDOSPayment(addressBridge.getPaymentAddress()).chargeServiceFee(from, queryId, uint(TrafficType.UserQuery)); return queryId; } else { emit LogNonSupportedType(selector); - return 0x0; + return 0; } } else { // Skip if @from is not contract address. emit LogNonContractCall(from); - return 0x0; + return 0; } } // Request a new user-level random number. - function requestRandom(address from, uint8 mode, uint userSeed) + function requestRandom(address from, uint userSeed) public + hasOracleFee(from, uint(TrafficType.UserRandom)) returns (uint) { - // fast mode - if (mode == 0) { - return uint(keccak256(abi.encodePacked( - ++requestIdSeed,lastRandomness, userSeed))); - } else if (mode == 1) { - // safe mode - // TODO: restrict request from paid calling contract address. - uint requestId = uint(keccak256(abi.encodePacked( - ++requestIdSeed, from, userSeed))); - uint idx = lastRandomness % groupPubKeys.length; - PendingRequests[requestId] = - PendingRequest(requestId, groupPubKeys[idx], from); - // sign(requestId ||lastSystemRandomness || userSeed) with - // selected group - emit LogRequestUserRandom( - requestId, - lastRandomness, - userSeed, - getGroupPubKey(idx) - ); - return requestId; - } else { - revert("Non-supported random request"); + uint requestId = uint(keccak256(abi.encode(block.timestamp, from, userSeed))); + uint idx = dispatchJob(TrafficType.UserRandom, requestId); + // TODO: keep id receipt and handle later in v2.0. + if (idx == UINTMAX) { + emit LogMessage("skipped-user-rnd-no-live-wgrp"); + return 0; } + Group storage grp = workingGroups[workingGroupIds[idx]]; + PendingRequests[requestId] = PendingRequest(requestId, grp.groupId, grp.groupPubKey, from); + // sign(requestId ||lastSystemRandomness || userSeed || + // selected sender in group) + emit LogRequestUserRandom( + requestId, + lastRandomness, + userSeed, + grp.groupId + ); + IDOSPayment(addressBridge.getPaymentAddress()).chargeServiceFee( + from == address(this) ? proxyFundsAddr : from, + requestId, + uint(TrafficType.UserRandom) + ); + return requestId; } // Random submitter validation + group signature verification. @@ -198,15 +513,10 @@ contract DOSProxy { BN256.G1Point memory signature, BN256.G2Point memory grpPubKey ) - internal - onlyWhitelisted + private returns (bool) { - // Validation - // TODO - // 1. Check msg.sender from registered and staked node operator. - // 2. Check msg.sender is a member in Group(grpPubKey). - // Clients actually signs (data || addr(selected_submitter)). + // Validation. Clients actually signs (data || addr(selected_submitter)). bytes memory message = abi.encodePacked(data, msg.sender); // Verification @@ -231,131 +541,433 @@ contract DOSProxy { function triggerCallback( uint requestId, uint8 trafficType, - bytes memory result, - uint[2] memory sig + bytes calldata result, + uint[2] calldata sig ) - public + external + fromValidStakingNode { + address ucAddr = PendingRequests[requestId].callbackAddr; + if (ucAddr == address(0x0)) { + emit LogRequestFromNonExistentUC(); + return; + } + if (!validateAndVerify( trafficType, requestId, result, BN256.G1Point(sig[0], sig[1]), - PendingRequests[requestId].handledGroup)) + PendingRequests[requestId].handledGroupPubKey)) { return; } - address ucAddr = PendingRequests[requestId].callbackAddr; - if (ucAddr == address(0x0)) { - emit LogRequestFromNonExistentUC(); - return; - } - emit LogCallbackTriggeredFor(ucAddr); delete PendingRequests[requestId]; - if (trafficType == TrafficUserQuery) { - UserContractInterface(ucAddr).__callback__(requestId, result); - } else if (trafficType == TrafficUserRandom) { + if (trafficType == uint8(TrafficType.UserQuery)) { + IUserContract(ucAddr).__callback__(requestId, result); + } else if (trafficType == uint8(TrafficType.UserRandom)) { // Safe random number is the collectively signed threshold signature // of the message (requestId || lastRandomness || userSeed || // selected sender in group). - UserContractInterface(ucAddr).__callback__( + emit LogMessage("UserRandom"); + IUserContract(ucAddr).__callback__( requestId, uint(keccak256(abi.encodePacked(sig[0], sig[1])))); } else { - revert("Unsupported traffic type"); + revert("unsupported-traffic-type"); } + Group memory grp = workingGroups[PendingRequests[requestId].groupId]; + IDOSPayment(addressBridge.getPaymentAddress()).recordServiceFee(requestId, msg.sender, grp.members); } - function toBytes(uint x) internal pure returns (bytes memory b) { + function toBytes(uint x) private pure returns (bytes memory b) { b = new bytes(32); assembly { mstore(add(b, 32), x) } } // System-level secure distributed random number generator. - function updateRandomness(uint[2] memory sig) public { + function updateRandomness(uint[2] calldata sig) external fromValidStakingNode { if (!validateAndVerify( - TrafficSystemRandom, + uint8(TrafficType.SystemRandom), lastRandomness, toBytes(lastRandomness), BN256.G1Point(sig[0], sig[1]), - lastHandledGroup)) + lastHandledGroup.groupPubKey)) { return; } + + cachedUpdatedBlock = 0; + lastUpdatedBlock = block.number; + uint claimFeeId = lastRandomness; // Update new randomness = sha3(collectively signed group signature) lastRandomness = uint(keccak256(abi.encodePacked(sig[0], sig[1]))); - lastUpdatedBlock = block.number - 1; - uint idx = lastRandomness % groupPubKeys.length; - lastHandledGroup = groupPubKeys[idx]; - // Signal selected off-chain clients to collectively generate a new - // system level random number for next round. - emit LogUpdateRandom(lastRandomness, getGroupPubKey(idx)); - } - - // For alpha. To trigger first random number after grouping has done - // or timeout. - function fireRandom() public onlyWhitelisted { - lastRandomness = uint(keccak256(abi.encode(blockhash(block.number - 1)))); - lastUpdatedBlock = block.number - 1; - uint idx = lastRandomness % groupPubKeys.length; - lastHandledGroup = groupPubKeys[idx]; - // Signal off-chain clients - emit LogUpdateRandom(lastRandomness, getGroupPubKey(idx)); + IDOSPayment(addressBridge.getPaymentAddress()).recordServiceFee(claimFeeId, msg.sender, lastHandledGroup.members); } - function handleTimeout() public onlyWhitelisted { - uint currentBlockNumber = block.number - 1; - if (currentBlockNumber - lastUpdatedBlock > 5) { - fireRandom(); + function cleanUpPendingGroup(uint gid, address skipNode) private { + PendingGroup storage pgrp = pendingGroups[gid]; + address member = pgrp.memberList[HEAD_A]; + while (member != HEAD_A) { + // 1. Put member that shouldn't be skipped back to pendingNodeList's head if it's not in any workingGroup. + // Dissolved pendingGroup members have priority to form into a workingGroup. + if (nodeToGroupId[member] == HEAD_I && member != skipNode && pendingNodeList[member] == address(0)) { + insertToPendingNodeListHead(member); + } + member = pgrp.memberList[member]; } + // 2. Update pendingGroupList + (uint prev, bool removed) = removeIdFromList(pendingGroupList, gid); + // Reset pendingGroupTail if necessary. + if (removed && pendingGroupTail == gid) { + pendingGroupTail = prev; + } + + // 3. Update pendingGroup + delete pendingGroups[gid]; + numPendingGroups--; + emit LogPendingGroupRemoved(gid); } - function setPublicKey(uint x1, uint x2, uint y1, uint y2) - public - onlyWhitelisted - { - bytes32 groupId = keccak256(abi.encodePacked(x1, x2, y1, y2)); - require(!groups[groupId], "group has already registered"); + /// Guardian node functions + /// @dev Guardian signals expiring system randomness and kicks off distributed random engine again. + /// Anyone including but not limited to DOS client node can be a guardian and claim rewards. + function signalRandom() public { + if (kickoffRandomOnCondition()) { + emit GuardianReward(block.number, msg.sender); + IDOSPayment(addressBridge.getPaymentAddress()).claimGuardianReward(msg.sender); + } else { + emit LogMessage("sys-random-not-expired"); + } + } - pubKeyCounter[groupId] = pubKeyCounter[groupId] + 1; - if (pubKeyCounter[groupId] > groupSize / 2) { - groupPubKeys.push(BN256.G2Point([x1, x2], [y1, y2])); - groups[groupId] = true; - delete(pubKeyCounter[groupId]); - emit LogPublicKeyAccepted(x1, x2, y1, y2); + /// @dev Guardian signals to dissolve expired (workingGroup + pendingGroup) and claim guardian rewards. + function signalGroupDissolve() public { + // Clean up oldest expired PendingGroup and related metadata. Might be due to failed DKG. + uint gid = pendingGroupList[HEAD_I]; + if (gid != HEAD_I && pendingGroups[gid].startBlkNum + pendingGroupMaxLife < block.number) { + cleanUpPendingGroup(gid, HEAD_A); + emit GuardianReward(block.number, msg.sender); + IDOSPayment(addressBridge.getPaymentAddress()).claimGuardianReward(msg.sender); + } else { + emit LogMessage("no-expired-pgrp-to-clean"); + } + } + /// @dev Guardian signals to trigger group formation when there're enough pending nodes. + /// If there aren't enough working groups to choose to dossolve, probably a new bootstrap is needed. + function signalGroupFormation() public { + if (formGroup()) { + emit GuardianReward(block.number, msg.sender); + IDOSPayment(addressBridge.getPaymentAddress()).claimGuardianReward(msg.sender); + } else { + emit LogMessage("no-grp-formation"); } } + function signalBootstrap(uint _cid) public { + require(bootstrapRound == _cid, "not-in-bootstrap"); - function getGroupPubKey(uint idx) public view returns (uint[4] memory) { - require(idx < groupPubKeys.length, "group index out of range"); + if (block.number <= bootstrapEndBlk) { + emit LogMessage("wait-to-collect-more-entropy"); + return; + } + if (numPendingNodes < bootstrapStartThreshold) { + emit LogMessage("not-enough-p-node-to-bootstrap"); + return; + } + // Reset. + bootstrapRound = 0; + bootstrapEndBlk = 0; + uint rndSeed = ICommitReveal(addressBridge.getCommitRevealAddress()).getRandom(_cid); + if (rndSeed == 0) { + emit LogMessage("bootstrap-commit-reveal-failure"); + return; + } + cachedUpdatedBlock = 0; + lastUpdatedBlock = block.number; + lastRandomness = uint(keccak256(abi.encodePacked(lastRandomness, rndSeed))); + + uint arrSize = bootstrapStartThreshold / groupSize * groupSize; + address[] memory candidates = new address[](arrSize); + + pick(arrSize, 0, candidates); + shuffle(candidates, lastRandomness); + regroup(candidates, arrSize / groupSize); + emit GuardianReward(block.number, msg.sender); + IDOSPayment(addressBridge.getPaymentAddress()).claimGuardianReward(msg.sender); + } + // TODO: Chose a random group to check and has a consensus about which nodes should be unregister in v2.0 + function signalUnregister(address member) public onlyGuardianListed { + if (unregister(member)) { + emit GuardianReward(block.number, msg.sender); + IDOSPayment(addressBridge.getPaymentAddress()).claimGuardianReward(msg.sender); + } else { + emit LogMessage("nothing-to-unregister"); + } + } + /// End of Guardian functions - return [ - groupPubKeys[idx].x[0], groupPubKeys[idx].x[1], - groupPubKeys[idx].y[0], groupPubKeys[idx].y[1] - ]; + function unregisterNode() public fromValidStakingNode returns (bool) { + return unregister(msg.sender); } - function uploadNodeId(uint id) public onlyWhitelisted { - nodeId.push(id); + // Returns true if successfully unregistered node. + function unregister(address node) private returns (bool) { + uint groupId = nodeToGroupId[node]; + bool removed = false; + uint8 unregisteredFrom = 0; + // Check if node is in workingGroups or expiredWorkingGroup + if (groupId != 0 && groupId != HEAD_I) { + dissolveWorkingGroup(groupId, true, node); + for (uint idx = 0; idx < workingGroupIds.length; idx++) { + if (workingGroupIds[idx] == groupId) { + if (idx != (workingGroupIds.length - 1)) { + workingGroupIds[idx] = workingGroupIds[workingGroupIds.length - 1]; + } + workingGroupIds.length--; + removed = true; + unregisteredFrom |= 0x1; + break; + } + } + if (!removed) { + for (uint idx = 0; idx < expiredWorkingGroupIds.length; idx++) { + if (expiredWorkingGroupIds[idx] == groupId) { + if (idx != (expiredWorkingGroupIds.length - 1)) { + expiredWorkingGroupIds[idx] = expiredWorkingGroupIds[expiredWorkingGroupIds.length - 1]; + } + expiredWorkingGroupIds.length--; + removed = true; + unregisteredFrom |= 0x2; + break; + } + } + } + } + + // Check if node is in pendingGroups + if (!removed && checkAndRemoveFromPendingGroup(node)) { + unregisteredFrom |= 0x4; + } + + // Check if node is in pendingNodeList + if (pendingNodeList[node] != address(0)) { + // Update pendingNodeList + address prev; + (prev, removed) = removeNodeFromList(pendingNodeList, node); + if (removed) { + numPendingNodes--; + // Reset pendingNodeTail if necessary. + if (pendingNodeTail == node) { + pendingNodeTail = prev; + } + unregisteredFrom |= 0x8; + } + } + delete nodeToGroupId[node]; + IDOSStaking(addressBridge.getStakingAddress()).nodeStop(node); + emit LogUnRegisteredNewPendingNode(node, unregisteredFrom); + return (unregisteredFrom != 0); + } + + function getWorkingGroupSize() public view returns (uint) { + return workingGroupIds.length; + } + + function getExpiredWorkingGroupSize() public view returns (uint) { + return expiredWorkingGroupIds.length; } - function grouping(uint size) public onlyWhitelisted { - groupSize = size; - uint[] memory toBeGrouped = new uint[](size); - if (nodeId.length < size) { - emit LogInsufficientGroupNumber(); + function registerNewNode() public fromValidStakingNode { + // Duplicated pending node + if (pendingNodeList[msg.sender] != address(0)) { return; } - for (uint i = 0; i < size; i++) { - toBeGrouped[i] = nodeId[nodeId.length - 1]; - nodeId.length--; + // Already registered in pending or working groups + if (nodeToGroupId[msg.sender] != 0) { + return; + } + nodeToGroupId[msg.sender] = HEAD_I; + insertToPendingNodeListTail(msg.sender); + emit LogRegisteredNewPendingNode(msg.sender); + IDOSStaking(addressBridge.getStakingAddress()).nodeStart(msg.sender); + formGroup(); + } + + // Form into new working groups or bootstrap if necessary. + // Return true if forms a new group. + function formGroup() private returns(bool) { + // Clean up oldest expiredWorkingGroup and push back nodes to pendingNodeList if: + // 1. There's not enough pending nodes to form a group; + // 2. There's no working group and not enough pending nodes to restart bootstrap. + if (numPendingNodes < groupSize || + (workingGroupIds.length == 0 && numPendingNodes < bootstrapStartThreshold)) { + if (expiredWorkingGroupIds.length > 0) { + dissolveWorkingGroup(expiredWorkingGroupIds[0], true, HEAD_A); + expiredWorkingGroupIds[0] = expiredWorkingGroupIds[expiredWorkingGroupIds.length - 1]; + expiredWorkingGroupIds.length--; + } + } + + if (numPendingNodes < groupSize) { + emit LogInsufficientPendingNode(numPendingNodes); + return false; + } + + if (workingGroupIds.length > 0) { + if (expiredWorkingGroupIds.length >= groupToPick) { + if (lastFormGrpReqId == 0) { + lastFormGrpReqId = requestRandom(address(this), block.number); + if (lastFormGrpReqId == 0) return false; + emit LogGroupingInitiated(numPendingNodes, groupSize); + return true; + } else { + emit LogMessage("already-in-formation"); + return false; + } + } else { + emit LogMessage("skipped-formation-not-enough-expired-wgrp"); + } + } else if (numPendingNodes >= bootstrapStartThreshold) { // No working group alive and satisfies system re-bootstrap condition. + if (bootstrapRound == 0) { + bootstrapRound = ICommitReveal(addressBridge.getCommitRevealAddress()).startCommitReveal( + block.number, + bootstrapCommitDuration, + bootstrapRevealDuration, + bootstrapStartThreshold + ); + bootstrapEndBlk = block.number + bootstrapCommitDuration + bootstrapRevealDuration; + return true; + } else { + emit LogMessage("already-in-bootstrap"); + } } - emit LogGrouping(toBeGrouped); + return false; } - function resetContract() public onlyWhitelisted { - nodeId.length = 0; - groupPubKeys.length = 0; + // callback to handle re-grouping using generated random number as random seed. + function __callback__(uint requestId, uint rndSeed) external { + require(msg.sender == address(this), "unauthenticated-resp"); + require(expiredWorkingGroupIds.length >= groupToPick, "regroup-not-enough-expired-wgrp"); + require(numPendingNodes >= groupSize, "regroup-not-enough-p-node"); + + lastFormGrpReqId = 0; + uint arrSize = groupSize * (groupToPick + 1); + address[] memory candidates = new address[](arrSize); + for (uint i = 0; i < groupToPick; i++) { + uint idx = uint(keccak256(abi.encodePacked(rndSeed, requestId, i))) % expiredWorkingGroupIds.length; + Group storage grpToDissolve = workingGroups[expiredWorkingGroupIds[idx]]; + for (uint j = 0; j < groupSize; j++) { + candidates[i * groupSize + j] = grpToDissolve.members[j]; + } + // Do not put selected to-be-dissolved expired working group back to pending node pool. + dissolveWorkingGroup(grpToDissolve.groupId, false, HEAD_A); + expiredWorkingGroupIds[idx] = expiredWorkingGroupIds[expiredWorkingGroupIds.length - 1]; + expiredWorkingGroupIds.length--; + } + + pick(groupSize, groupSize * groupToPick, candidates); + shuffle(candidates, rndSeed); + regroup(candidates, groupToPick + 1); } -} \ No newline at end of file + + // Pick @num nodes from pendingNodeList's head and put into the @candidates array from @startIndex. + function pick(uint num, uint startIndex, address[] memory candidates) private { + for (uint i = 0; i < num; i++) { + address curr = pendingNodeList[HEAD_A]; + pendingNodeList[HEAD_A] = pendingNodeList[curr]; + delete pendingNodeList[curr]; + candidates[startIndex + i] = curr; + } + numPendingNodes -= num; + // Reset pendingNodeTail if necessary. + if (numPendingNodes == 0) { + pendingNodeTail = HEAD_A; + } + } + + // Shuffle a memory array using a secure random seed. + function shuffle(address[] memory arr, uint rndSeed) private pure { + for (uint i = arr.length - 1; i > 0; i--) { + uint j = uint(keccak256(abi.encodePacked(rndSeed, i, arr[i]))) % (i + 1); + address tmp = arr[i]; + arr[i] = arr[j]; + arr[j] = tmp; + } + } + + // Regroup a shuffled node array. + function regroup(address[] memory candidates, uint num) private { + require(candidates.length == groupSize * num, "candidate-length-mismatch"); + + address[] memory members = new address[](groupSize); + uint groupId; + for (uint i = 0; i < num; i++) { + groupId = 0; + for (uint j = 0; j < groupSize; j++) { + members[j] = candidates[i * groupSize + j]; + groupId = uint(keccak256(abi.encodePacked(groupId, members[j]))); + } + // groupId = sha3{ sha3(...(sha3(sha3(member 1), member 2), ...), member n), timestamp} + // This ensures unique groupId even for the same members. + groupId = uint(keccak256(abi.encodePacked(groupId, block.timestamp))); + pendingGroups[groupId] = PendingGroup(groupId, block.number); + mapping(address => address) storage memberList = pendingGroups[groupId].memberList; + memberList[HEAD_A] = HEAD_A; + for (uint j = 0; j < groupSize; j++) { + memberList[members[j]] = memberList[HEAD_A]; + memberList[HEAD_A] = members[j]; + } + insertToPendingGroupListTail(groupId); + emit LogGrouping(groupId, members); + } + } + + function registerGroupPubKey(uint groupId, uint[4] calldata suggestedPubKey) + external + fromValidStakingNode + { + PendingGroup storage pgrp = pendingGroups[groupId]; + if (pgrp.groupId == 0) { + emit LogNoPendingGroup(groupId); + return; + } + + require(pgrp.memberList[msg.sender] != address(0), "not-from-authorized-grp-member"); + + bytes32 hashedPubKey = keccak256(abi.encodePacked( + suggestedPubKey[0], suggestedPubKey[1], suggestedPubKey[2], suggestedPubKey[3])); + pgrp.pubKeyCounts[hashedPubKey]++; + emit LogPublicKeySuggested(groupId, pgrp.pubKeyCounts[hashedPubKey]); + if (pgrp.pubKeyCounts[hashedPubKey] > groupSize / 2) { + address[] memory memberArray = new address[](groupSize); + uint idx = 0; + address member = pgrp.memberList[HEAD_A]; + while (member != HEAD_A) { + memberArray[idx++] = member; + nodeToGroupId[member] = groupId; + member = pgrp.memberList[member]; + } + + workingGroupIds.push(groupId); + workingGroups[groupId] = Group( + groupId, + BN256.G2Point([suggestedPubKey[0], suggestedPubKey[1]], [suggestedPubKey[2], suggestedPubKey[3]]), + numPendingGroups * lifeDiversity, + block.number, + memberArray + ); + // Update pendingGroupList + (uint prev, bool removed) = removeIdFromList(pendingGroupList, groupId); + // Reset pendingGroupTail if necessary. + if (removed && pendingGroupTail == groupId) { + pendingGroupTail = prev; + } + // Update pendingGroup + delete pendingGroups[groupId]; + numPendingGroups--; + emit LogPendingGroupRemoved(groupId); + emit LogPublicKeyAccepted(groupId, suggestedPubKey, workingGroupIds.length); + } + } +} diff --git a/contracts/MegaStream.sol b/contracts/MegaStream.sol new file mode 100644 index 0000000..88988b9 --- /dev/null +++ b/contracts/MegaStream.sol @@ -0,0 +1,134 @@ +pragma solidity ^0.5.0; + +import "./DOSOnChainSDK.sol"; + +contract IParser { + function floatBytes2UintArray(bytes memory raw, uint decimal) public view returns(uint[] memory); +} + +contract IStreamsManager { + function megaUpdate(uint[] calldata data) external returns(bool); +} + +contract MegaStream is DOSOnChainSDK { + uint public windowSize = 1200; // 20 minutes + // Number of decimals the reported price data use. + uint public decimal; + uint public lastTime; + string public megaDescription; + string public megaSource; + string public megaSelector; + // Data parser, may be configured along with data source change + address public parser; + address public streamsManager; + // Stream data is either updated once per windowSize or the deviation requirement is met, whichever comes first. + // Anyone can trigger an update on windowSize expiration, but only governance approved ones can be deviation updater to get rid of sybil attacks. + mapping(address => bool) private deviationGuardian; + mapping(uint => bool) private _valid; + + event ParamsUpdated( + string oldDescription, string newDescription, + string oldSource, string newSource, + string oldSelector, string newSelector, + uint oldDecimal, uint newDecimal + ); + event WindowUpdated(uint oldWindow, uint newWindow); + event ParserUpdated(address oldParser, address newParser); + event ManagerUpdated(address oldParser, address newParser); + event DataUpdated(uint timestamp, uint price); + event PulledTrigger(address trigger, uint qId); + event BulletCaught(uint qId); + event AddGuardian(address guardian); + event RemoveGuardian(address guardian); + + modifier isContract(address addr) { + uint codeSize = 0; + assembly { + codeSize := extcodesize(addr) + } + require(codeSize > 0, "not-smart-contract"); + _; + } + + constructor( + string memory _description, + string memory _source, + string memory _selector, + uint _decimal, + address _parser + ) + public + isContract(_parser) + { + // @dev: setup and then transfer DOS tokens into deployed contract + // as oracle fees. + // Unused fees can be reclaimed by calling DOSRefund() function of SDK contract. + super.DOSSetup(); + megaDescription = _description; + megaSource = _source; + megaSelector = _selector; + decimal = _decimal; + parser = _parser; + emit ParamsUpdated("", _description, "", _source, "", _selector, 0, _decimal); + emit ParserUpdated(address(0), _parser); + } + + function strEqual(string memory a, string memory b) private pure returns (bool) { + return keccak256(abi.encodePacked(a)) == keccak256(abi.encodePacked(b)); + } + + function updateWindowSize(uint newWindow) public onlyOwner { + emit WindowUpdated(windowSize, newWindow); + windowSize = newWindow; + } + function updateParams(string memory _description, string memory _source, string memory _selector, uint _decimal) public onlyOwner { + emit ParamsUpdated( + megaDescription, _description, + megaSource, _source, + megaSelector, _selector, + decimal, _decimal + ); + if (!strEqual(megaDescription, _description)) megaDescription = _description; + if (!strEqual(megaSource, _source)) megaSource = _source; + if (!strEqual(megaSelector, _selector)) megaSelector = _selector; + if (decimal != _decimal) decimal = _decimal; + } + function updateParser(address newParser) public onlyOwner isContract(newParser) { + emit ParserUpdated(parser, newParser); + parser = newParser; + } + function updateManager(address _manager) public onlyOwner isContract(_manager) { + emit ManagerUpdated(streamsManager, _manager); + streamsManager = _manager; + } + function addGuardian(address guardian) public onlyOwner { + if (!deviationGuardian[guardian]) { + deviationGuardian[guardian] = true; + emit AddGuardian(guardian); + } + } + function removeGuardian(address guardian) public onlyOwner { + if (deviationGuardian[guardian]) { + delete deviationGuardian[guardian]; + emit RemoveGuardian(guardian); + } + } + + function pullTrigger() public { + if(lastTime + windowSize >= block.timestamp && !deviationGuardian[msg.sender]) return; + + uint id = DOSQuery(30, megaSource, megaSelector); + if (id != 0) { + _valid[id] = true; + emit PulledTrigger(msg.sender, id); + } + } + + function __callback__(uint id, bytes calldata result) external auth { + require(_valid[id], "invalid-request-id"); + uint[] memory prices = IParser(parser).floatBytes2UintArray(result, decimal); + if (IStreamsManager(streamsManager).megaUpdate(prices)) emit BulletCaught(id); + delete _valid[id]; + lastTime = block.timestamp; + } +} diff --git a/contracts/Ownable.sol b/contracts/Ownable.sol index 9e1971c..2b8bff9 100644 --- a/contracts/Ownable.sol +++ b/contracts/Ownable.sol @@ -1,4 +1,4 @@ -pragma solidity >= 0.4.24; +pragma solidity ^0.5.0; /** * @title Ownable diff --git a/contracts/Staking.sol b/contracts/Staking.sol new file mode 100644 index 0000000..4abb997 --- /dev/null +++ b/contracts/Staking.sol @@ -0,0 +1,708 @@ +pragma solidity ^0.5.0; + +import "./lib/math.sol"; + +/** + * @title Staking and delegation contract + * @author DOS Network + */ + +contract ERC20I { + function balanceOf(address who) public view returns (uint); + function decimals() public view returns (uint); + function transfer(address to, uint value) public returns (bool); + function transferFrom(address from, address to, uint value) public returns (bool); + function approve(address spender, uint value) public returns (bool); +} + +contract AddressBridgeI { + function getProxyAddress() public view returns(address); +} + +contract Staking { + using DSMath for *; + + uint public constant ONEYEAR = 365 days; + uint public constant DOSDECIMAL = 18; + uint public constant DBDECIMAL = 0; + uint public constant LISTHEAD = 0x1; + uint public initBlkN; + address public admin; + address public DOSTOKEN; + address public DBTOKEN ; + address public stakingRewardsVault; + address public bridgeAddr; // DOS address bridge + uint public minStakePerNode; + uint public dropburnMaxQuota; + uint public totalStakedTokens; + uint public circulatingSupply; + uint public unbondDuration; + uint public lastRateUpdatedTime; // in seconds + uint public accumulatedRewardIndex; // Multiplied by 1e10 + + struct Node { + address ownerAddr; + uint rewardCut; // %, [0, 100). + uint stakedDB; // [0, dropburnMaxQuota] + uint selfStakedAmount; + uint totalOtherDelegatedAmount; + uint accumulatedRewards; + uint accumulatedRewardIndex; + uint pendingWithdrawToken; + uint pendingWithdrawDB; + uint lastStartTime; + bool running; + string description; + address[] nodeDelegators; + // release time => UnbondRequest metadata + mapping (uint => UnbondRequest) unbondRequests; + // LISTHEAD => release time 1 => ... => release time m => LISTHEAD + mapping (uint => uint) releaseTime; + string logoUrl; + } + + struct UnbondRequest { + uint dosAmount; + uint dbAmount; + } + + struct Delegation { + address delegatedNode; + uint delegatedAmount; + uint accumulatedRewards; // in tokens + uint accumulatedRewardIndex; + uint pendingWithdraw; + + // release time => UnbondRequest metadata + mapping (uint => UnbondRequest) unbondRequests; + // LISTHEAD => release time 1 => ... => release time m => LISTHEAD + mapping (uint => uint) releaseTime; + } + + // 1:1 node address => Node metadata + mapping (address => Node) public nodes; + address[] public nodeAddrs; + + // node runner's main address => {node addresses} + mapping (address => mapping(address => bool)) public nodeRunners; + // 1:n token holder address => {delegated node 1 : Delegation, ..., delegated node n : Delegation} + mapping (address => mapping(address => Delegation)) public delegators; + + event UpdateStakingAdmin(address oldAdmin, address newAdmin); + event UpdateDropBurnMaxQuota(uint oldQuota, uint newQuota); + event UpdateUnbondDuration(uint oldDuration, uint newDuration); + event UpdateCirculatingSupply(uint oldCirculatingSupply, uint newCirculatingSupply); + event UpdateMinStakePerNode(uint oldMinStakePerNode, uint newMinStakePerNode); + event NewNode(address indexed owner, address indexed nodeAddress, uint selfStakedAmount, uint stakedDB, uint rewardCut); + event Delegate(address indexed from, address indexed to, uint amount); + event ReDelegate(address indexed from, address indexed to, uint amount); + event Withdraw(address indexed from, address indexed to, bool nodeRunner, uint tokenAmount, uint dbAmount); + event Unbond(address indexed from, address indexed to, bool nodeRunner, uint tokenAmount, uint dropburnAmount); + event ClaimReward(address indexed to, bool nodeRunner, uint amount); + + constructor(address _dostoken, address _dbtoken, address _vault, address _bridgeAddr) public { + initialize(_dostoken, _dbtoken, _vault, _bridgeAddr); + } + + function initialize(address _dostoken, address _dbtoken, address _vault, address _bridgeAddr) public { + require(initBlkN == 0, "already-initialized"); + + initBlkN = block.number; + admin = msg.sender; + DOSTOKEN = _dostoken; + DBTOKEN = _dbtoken; + stakingRewardsVault = _vault; + bridgeAddr = _bridgeAddr; + minStakePerNode = 800000 * (10 ** DOSDECIMAL); + dropburnMaxQuota = 3; + circulatingSupply = 160000000 * (10 ** DOSDECIMAL); + unbondDuration = 7 days; + } + + modifier onlyAdmin { + require(msg.sender == admin, "onlyAdmin"); + _; + } + + function setAdmin(address newAdmin) public onlyAdmin { + require(newAdmin != address(0)); + emit UpdateStakingAdmin(admin, newAdmin); + admin = newAdmin; + } + + /// @dev used when drop burn max quota duration is changed + function setDropBurnMaxQuota(uint _quota) public onlyAdmin { + require(_quota != dropburnMaxQuota && _quota < 10, "valid-dropburnMaxQuota-0-to-9"); + emit UpdateDropBurnMaxQuota(dropburnMaxQuota, _quota); + dropburnMaxQuota = _quota; + } + + /// @dev used when withdraw duration is changed + function setUnbondDuration(uint _duration) public onlyAdmin { + emit UpdateUnbondDuration(unbondDuration, _duration); + unbondDuration = _duration; + } + + /// @dev used when locked token is unlocked + function setCirculatingSupply(uint _newSupply) public onlyAdmin { + require(circulatingSupply >= totalStakedTokens,"CirculatingSupply < totalStakedTokens"); + + updateGlobalRewardIndex(); + emit UpdateCirculatingSupply(circulatingSupply, _newSupply); + circulatingSupply = _newSupply; + } + + /// @dev used when minStakePerNode is updated + function setMinStakePerNode(uint _minStake) public onlyAdmin { + emit UpdateMinStakePerNode(minStakePerNode, _minStake); + minStakePerNode = _minStake; + } + + function getNodeAddrs() public view returns(address[] memory) { + return nodeAddrs; + } + + modifier checkStakingValidity(uint _tokenAmount, uint _dropburnAmount, uint _rewardCut) { + require(0 <= _rewardCut && _rewardCut < 100, "not-valid-rewardCut-in-0-to-99"); + require(_tokenAmount >= minStakePerNode.mul(10.sub(DSMath.min(_dropburnAmount, dropburnMaxQuota))).div(10), + "not-enough-dos-token-to-start-node"); + _; + } + + modifier onlyFromProxy() { + require(msg.sender == AddressBridgeI(bridgeAddr).getProxyAddress(), "not-from-dos-proxy"); + _; + } + + function isValidStakingNode(address nodeAddr) public view returns(bool) { + Node storage node = nodes[nodeAddr]; + uint _tokenAmount = node.selfStakedAmount; + uint _dropburnAmount = node.stakedDB; + if (_tokenAmount >= minStakePerNode.mul(10.sub(DSMath.min(_dropburnAmount, dropburnMaxQuota))).div(10)) { + return true; + } + return false; + } + + function newNode( + address _nodeAddr, + uint _tokenAmount, + uint _dropburnAmount, + uint _rewardCut, + string memory _desc, + string memory _logoUrl) + public checkStakingValidity(_tokenAmount, _dropburnAmount, _rewardCut) + { + require(!nodeRunners[msg.sender][_nodeAddr], "node-already-registered"); + require(nodes[_nodeAddr].ownerAddr == address(0), "node-already-registered"); + + nodeRunners[msg.sender][_nodeAddr] = true; + address[] memory nodeDelegators; + nodes[_nodeAddr] = Node(msg.sender, _rewardCut, _dropburnAmount, _tokenAmount, 0, 0, 0, 0, 0, 0, false, _desc, nodeDelegators, _logoUrl); + nodes[_nodeAddr].releaseTime[LISTHEAD] = LISTHEAD; + nodeAddrs.push(_nodeAddr); + // This would change interest rate + totalStakedTokens = totalStakedTokens.add(_tokenAmount); + // Deposit tokens. + ERC20I(DOSTOKEN).transferFrom(msg.sender, address(this), _tokenAmount); + if (_dropburnAmount > 0) { + ERC20I(DBTOKEN).transferFrom(msg.sender, address(this), _dropburnAmount); + } + emit NewNode(msg.sender, _nodeAddr, _tokenAmount, _dropburnAmount, _rewardCut); + } + + function nodeStart(address _nodeAddr) public onlyFromProxy { + require(nodes[_nodeAddr].ownerAddr != address(0), "node-not-registered"); + Node storage node = nodes[_nodeAddr]; + if (!node.running) { + node.running = true; + node.lastStartTime = now; + updateGlobalRewardIndex(); + node.accumulatedRewardIndex = accumulatedRewardIndex; + for (uint i = 0; i < node.nodeDelegators.length; i++) { + Delegation storage delegator = delegators[node.nodeDelegators[i]][_nodeAddr]; + delegator.accumulatedRewardIndex = accumulatedRewardIndex; + } + } + } + + function nodeStop(address _nodeAddr) public onlyFromProxy { + require(nodes[_nodeAddr].ownerAddr != address(0), "node-not-registered"); + nodeStopInternal(_nodeAddr); + } + + function nodeStopInternal(address _nodeAddr) internal { + Node storage node = nodes[_nodeAddr]; + if (node.running) { + updateGlobalRewardIndex(); + node.accumulatedRewards = getNodeRewardTokens(_nodeAddr); + node.accumulatedRewardIndex = accumulatedRewardIndex; + for (uint i = 0; i < node.nodeDelegators.length; i++) { + Delegation storage delegator = delegators[node.nodeDelegators[i]][_nodeAddr]; + delegator.accumulatedRewards = getDelegatorRewardTokens(node.nodeDelegators[i], _nodeAddr); + delegator.accumulatedRewardIndex = accumulatedRewardIndex; + } + node.running = false; + } + } + + // For node runners to configure new staking settings. + function updateNodeStaking( + address _nodeAddr, + uint _newTokenAmount, + uint _newDropburnAmount, + uint _newCut, + string memory _newDesc, + string memory _newLogoUrl) + public + { + require(nodeRunners[msg.sender][_nodeAddr], "node-not-owned-by-msgSender"); + + Node storage node = nodes[_nodeAddr]; + // _newCut with value uint(-1) means skipping this config. + if (_newCut != uint(-1)) { + require(_newCut >= 0 && _newCut < 100, "not-valid-rewardCut-in-0-to-99"); + // TODO: Update rewardCut affects delegators' reward calculation. + node.rewardCut = _newCut; + } + if (_newDropburnAmount != 0) { + node.stakedDB = node.stakedDB.add(_newDropburnAmount); + ERC20I(DBTOKEN).transferFrom(msg.sender, address(this), _newDropburnAmount); + } + if (_newTokenAmount != 0) { + node.selfStakedAmount = node.selfStakedAmount.add(_newTokenAmount); + if (node.running) { + // Update global accumulated interest index. + updateGlobalRewardIndex(); + node.accumulatedRewards = getNodeRewardTokens(_nodeAddr); + node.accumulatedRewardIndex = accumulatedRewardIndex; + } + // This would change interest rate + totalStakedTokens = totalStakedTokens.add(_newTokenAmount); + ERC20I(DOSTOKEN).transferFrom(msg.sender, address(this), _newTokenAmount); + } + if (bytes(_newDesc).length > 0 && bytes(_newDesc).length <= 32) { + node.description = _newDesc; + } + if (bytes(_newLogoUrl).length > 0) { + node.logoUrl = _newLogoUrl; + } + } + + // Token holders (delegators) call this function. It's allowed to delegate to the same node multiple times if possible. + // Note: Re-delegate is not supported. + function delegate(uint _tokenAmount, address _nodeAddr) public { + Node storage node = nodes[_nodeAddr]; + require(node.ownerAddr != address(0), "node-not-exist"); + require(msg.sender != node.ownerAddr, "node-owner-cannot-self-delegate"); + + Delegation storage delegator = delegators[msg.sender][_nodeAddr]; + require(delegator.delegatedNode == address(0) || delegator.delegatedNode == _nodeAddr, "invalid-delegated-node-addr"); + + node.totalOtherDelegatedAmount = node.totalOtherDelegatedAmount.add(_tokenAmount); + if (node.running) { + // Update global accumulated interest index. + updateGlobalRewardIndex(); + node.accumulatedRewards = getNodeRewardTokens(_nodeAddr); + node.accumulatedRewardIndex = accumulatedRewardIndex; + delegator.accumulatedRewards = getDelegatorRewardTokens(msg.sender, _nodeAddr); + delegator.accumulatedRewardIndex = accumulatedRewardIndex; + } + delegator.delegatedAmount = delegator.delegatedAmount.add(_tokenAmount); + if (delegator.delegatedNode == address(0)) { + // New delegation + delegator.delegatedNode = _nodeAddr; + delegator.releaseTime[LISTHEAD] = LISTHEAD; + node.nodeDelegators.push(msg.sender); + } + // This would change interest rate + totalStakedTokens = totalStakedTokens.add(_tokenAmount); + ERC20I(DOSTOKEN).transferFrom(msg.sender, address(this), _tokenAmount); + emit Delegate(msg.sender, _nodeAddr, _tokenAmount); + } + + function nodeUnregister(address _nodeAddr) public { + require(nodeRunners[msg.sender][_nodeAddr], "node-not-owned-by-msgSender"); + Node storage node = nodes[_nodeAddr]; + nodeStopInternal(_nodeAddr); + nodeUnbondInternal(node.selfStakedAmount, node.stakedDB, _nodeAddr); + } + + function nodeTryDelete(address _nodeAddr) internal { + if (!nodes[_nodeAddr].running && + nodes[_nodeAddr].selfStakedAmount == 0 && + nodes[_nodeAddr].stakedDB == 0 && + nodes[_nodeAddr].totalOtherDelegatedAmount == 0 && + nodes[_nodeAddr].accumulatedRewards == 0 && + nodes[_nodeAddr].nodeDelegators.length == 0 && + nodes[_nodeAddr].pendingWithdrawToken == 0 && + nodes[_nodeAddr].pendingWithdrawDB == 0 + ) { + delete nodeRunners[nodes[_nodeAddr].ownerAddr][_nodeAddr]; + delete nodes[_nodeAddr]; + for (uint idx = 0; idx < nodeAddrs.length; idx++) { + if (nodeAddrs[idx] == _nodeAddr) { + nodeAddrs[idx] = nodeAddrs[nodeAddrs.length - 1]; + nodeAddrs.length--; + return; + } + } + } + } + // Used by node runners to unbond their stakes. + // Unbonded tokens are locked for 7 days, during the unbonding period they're not eligible for staking rewards. + function nodeUnbond(uint _tokenAmount, uint _dropburnAmount, address _nodeAddr) public { + require(nodeRunners[msg.sender][_nodeAddr], "node-not-owned-by-msgSender"); + Node storage node = nodes[_nodeAddr]; + + require(_tokenAmount <= node.selfStakedAmount, "invalid-to-unbond-more-than-staked-amount"); + require(_dropburnAmount <= node.stakedDB, "invalid-to-unbond-more-than-staked-DropBurn-amount"); + require(node.selfStakedAmount.sub(_tokenAmount) >= + minStakePerNode.mul(10.sub(DSMath.min(node.stakedDB.sub(_dropburnAmount), dropburnMaxQuota))).div(10), + "invalid-unbond-to-maintain-staking-requirement"); + nodeUnbondInternal(_tokenAmount, _dropburnAmount, _nodeAddr); + } + // Used by node runners to unbond their stakes. + // Unbonded tokens are locked for 7 days, during the unbonding period they're not eligible for staking rewards. + function nodeUnbondInternal(uint _tokenAmount, uint _dropburnAmount, address _nodeAddr) internal { + require(nodeRunners[msg.sender][_nodeAddr], "node-not-owned-by-msgSender"); + Node storage node = nodes[_nodeAddr]; + if (node.running) { + updateGlobalRewardIndex(); + node.accumulatedRewards = getNodeRewardTokens(_nodeAddr); + node.accumulatedRewardIndex = accumulatedRewardIndex; + } + // This would change interest rate + totalStakedTokens = totalStakedTokens.sub(_tokenAmount); + node.selfStakedAmount = node.selfStakedAmount.sub(_tokenAmount); + node.pendingWithdrawToken = node.pendingWithdrawToken.add(_tokenAmount); + node.stakedDB = node.stakedDB.sub(_dropburnAmount); + node.pendingWithdrawDB = node.pendingWithdrawDB.add(_dropburnAmount); + + if (_tokenAmount > 0 || _dropburnAmount > 0) { + // create an UnbondRequest + uint releaseTime = now.add(unbondDuration); + node.unbondRequests[releaseTime] = UnbondRequest(_tokenAmount, _dropburnAmount); + node.releaseTime[releaseTime] = node.releaseTime[LISTHEAD]; + node.releaseTime[LISTHEAD] = releaseTime; + } + + emit Unbond(msg.sender, _nodeAddr, true, _tokenAmount, _dropburnAmount); + } + + // Used by token holders (delegators) to unbond their delegations. + function delegatorUnbond(uint _tokenAmount, address _nodeAddr) public { + Delegation storage delegator = delegators[msg.sender][_nodeAddr]; + require(nodes[_nodeAddr].ownerAddr != address(0), "node-not-exist"); + require(delegator.delegatedNode == _nodeAddr, "invalid-unbond-from-non-delegated-node"); + require(_tokenAmount <= delegator.delegatedAmount, "invalid-unbond-more-than-delegated-amount"); + if (nodes[_nodeAddr].running) { + updateGlobalRewardIndex(); + delegator.accumulatedRewards = getDelegatorRewardTokens(msg.sender, _nodeAddr); + delegator.accumulatedRewardIndex = accumulatedRewardIndex; + nodes[_nodeAddr].accumulatedRewards = getNodeRewardTokens(_nodeAddr); + nodes[_nodeAddr].accumulatedRewardIndex = accumulatedRewardIndex; + } + // This would change interest rate + totalStakedTokens = totalStakedTokens.sub(_tokenAmount); + delegator.delegatedAmount = delegator.delegatedAmount.sub(_tokenAmount); + delegator.pendingWithdraw = delegator.pendingWithdraw.add(_tokenAmount); + nodes[_nodeAddr].totalOtherDelegatedAmount = nodes[_nodeAddr].totalOtherDelegatedAmount.sub(_tokenAmount); + + if (_tokenAmount > 0) { + // create a UnbondRequest + uint releaseTime = now.add(unbondDuration); + delegator.unbondRequests[releaseTime] = UnbondRequest(_tokenAmount, 0); + delegator.releaseTime[releaseTime] = delegator.releaseTime[LISTHEAD]; + delegator.releaseTime[LISTHEAD] = releaseTime; + } + + emit Unbond(msg.sender, _nodeAddr, false, _tokenAmount, 0); + } + + function withdrawAll(mapping(uint => uint) storage releaseTimeList, mapping(uint => UnbondRequest) storage requestList) + internal + returns(uint, uint) + { + uint accumulatedDos = 0; + uint accumulatedDropburn = 0; + uint prev = LISTHEAD; + uint curr = releaseTimeList[prev]; + while (curr != LISTHEAD && curr > now) { + prev = curr; + curr = releaseTimeList[prev]; + } + if (releaseTimeList[prev] != LISTHEAD) { + releaseTimeList[prev] = LISTHEAD; + } + // All next items are withdrawable. + while (curr != LISTHEAD) { + accumulatedDos = accumulatedDos.add(requestList[curr].dosAmount); + accumulatedDropburn = accumulatedDropburn.add(requestList[curr].dbAmount); + prev = curr; + curr = releaseTimeList[prev]; + delete releaseTimeList[prev]; + delete requestList[prev]; + } + return (accumulatedDos, accumulatedDropburn); + } + + /// @dev A view version of above call with equivalent functionality, used by other view functions. + function withdrawable(mapping(uint => uint) storage releaseTimeList, mapping(uint => UnbondRequest) storage requestList) + internal + view + returns(uint, uint) + { + uint accumulatedDos = 0; + uint accumulatedDropburn = 0; + uint prev = LISTHEAD; + uint curr = releaseTimeList[prev]; + while (curr != LISTHEAD && curr > now) { + prev = curr; + curr = releaseTimeList[prev]; + } + // All next items are withdrawable. + while (curr != LISTHEAD) { + accumulatedDos = accumulatedDos.add(requestList[curr].dosAmount); + accumulatedDropburn = accumulatedDropburn.add(requestList[curr].dbAmount); + prev = curr; + curr = releaseTimeList[prev]; + + } + return (accumulatedDos, accumulatedDropburn); + } + + // Node runners call this function to withdraw available unbonded tokens after unbond period. + function nodeWithdraw(address _nodeAddr) public { + Node storage node = nodes[_nodeAddr]; + require(node.ownerAddr == msg.sender, "non-owner-not-authorized-to-withdraw"); + + (uint tokenAmount, uint dropburnAmount) = withdrawAll(node.releaseTime, node.unbondRequests); + node.pendingWithdrawToken = node.pendingWithdrawToken.sub(tokenAmount); + node.pendingWithdrawDB = node.pendingWithdrawDB.sub(dropburnAmount); + + nodeTryDelete(_nodeAddr); + + if (tokenAmount > 0) { + ERC20I(DOSTOKEN).transfer(msg.sender, tokenAmount); + } + if (dropburnAmount > 0) { + ERC20I(DBTOKEN).transfer(msg.sender, dropburnAmount); + } + emit Withdraw(_nodeAddr, msg.sender, true, tokenAmount, dropburnAmount); + } + + // Delegators call this function to withdraw available unbonded tokens from a specific node after unbond period. + function delegatorWithdraw(address _nodeAddr) public { + Delegation storage delegator = delegators[msg.sender][_nodeAddr]; + require(nodes[_nodeAddr].ownerAddr != address(0), "node-not-exist"); + require(delegator.delegatedNode == _nodeAddr, "cannot-withdraw-from-non-delegated-node"); + + (uint tokenAmount, ) = withdrawAll(delegator.releaseTime, delegator.unbondRequests); + if (tokenAmount > 0) { + delegator.pendingWithdraw = delegator.pendingWithdraw.sub(tokenAmount); + if (delegator.delegatedAmount == 0 && delegator.pendingWithdraw == 0 && delegator.accumulatedRewards == 0) { + delete delegators[msg.sender][_nodeAddr]; + uint idx = 0; + for (; idx < nodes[_nodeAddr].nodeDelegators.length; idx++) { + if (nodes[_nodeAddr].nodeDelegators[idx] == msg.sender) { + break; + } + } + if (idx < nodes[_nodeAddr].nodeDelegators.length) { + nodes[_nodeAddr].nodeDelegators[idx] = nodes[_nodeAddr].nodeDelegators[nodes[_nodeAddr].nodeDelegators.length - 1]; + nodes[_nodeAddr].nodeDelegators.length--; + } + nodeTryDelete(_nodeAddr); + } + + ERC20I(DOSTOKEN).transfer(msg.sender, tokenAmount); + } + emit Withdraw(_nodeAddr, msg.sender, false, tokenAmount, 0); + } + + // re-delegate from nodeA to nodeB with no need of unbonding; collecting staking rewards if any. + function reDelegate(address _fromNode, address _toNode, uint _tokenAmount) public { + if (_tokenAmount == 0) return; + require(_fromNode != _toNode, "duplicate-nodes"); + Node storage from = nodes[_fromNode]; + Node storage to = nodes[_toNode]; + require(from.ownerAddr != address(0), "fromNode-no-exist"); + require(to.ownerAddr != address(0), "toNode-no-exist"); + require(msg.sender != to.ownerAddr, "node-owner-cannot-reDelegate-to-self"); + Delegation storage delegatorFrom = delegators[msg.sender][_fromNode]; + require(delegatorFrom.delegatedNode == _fromNode, "reDelegate-from-non-delegated"); + require(_tokenAmount <= delegatorFrom.delegatedAmount, "reDelegate-exceeded-stake-amount"); + Delegation storage delegatorTo = delegators[msg.sender][_toNode]; + require(delegatorTo.delegatedNode == address(0) || delegatorTo.delegatedNode == _toNode, "reDelegate-to-invalid-node"); + + uint claimReward = 0; + updateGlobalRewardIndex(); + if (from.running) { + claimReward += getDelegatorRewardTokens(msg.sender, _fromNode); + delegatorFrom.accumulatedRewards = 0; + delegatorFrom.accumulatedRewardIndex = accumulatedRewardIndex; + from.accumulatedRewards = getNodeRewardTokens(_fromNode); + from.accumulatedRewardIndex = accumulatedRewardIndex; + } + if (to.running) { + to.accumulatedRewards = getNodeRewardTokens(_toNode); + to.accumulatedRewardIndex = accumulatedRewardIndex; + claimReward += getDelegatorRewardTokens(msg.sender, _toNode); + delegatorTo.accumulatedRewards = 0; + delegatorTo.accumulatedRewardIndex = accumulatedRewardIndex; + } + delegatorFrom.delegatedAmount = delegatorFrom.delegatedAmount.sub(_tokenAmount); + delegatorTo.delegatedAmount = delegatorTo.delegatedAmount.add(_tokenAmount); + from.totalOtherDelegatedAmount = from.totalOtherDelegatedAmount.sub(_tokenAmount); + to.totalOtherDelegatedAmount = to.totalOtherDelegatedAmount.add(_tokenAmount); + + // Remove from _fromNode's nodeDelegators list if fully re-delegat & no pending withdrawable tokens + if (delegatorFrom.delegatedAmount == 0 && delegatorFrom.pendingWithdraw == 0) { + delete delegators[msg.sender][_fromNode]; + uint idx = 0; + for (; idx < from.nodeDelegators.length; idx++) { + if (from.nodeDelegators[idx] == msg.sender) { + break; + } + } + if (idx < from.nodeDelegators.length) { + from.nodeDelegators[idx] = from.nodeDelegators[from.nodeDelegators.length - 1]; + from.nodeDelegators.length--; + } + nodeTryDelete(_fromNode); + } + + if (delegatorTo.delegatedNode == address(0)) { + // reDelegated to previously non-delegated node + delegatorTo.delegatedNode = _toNode; + delegatorTo.releaseTime[LISTHEAD] = LISTHEAD; + to.nodeDelegators.push(msg.sender); + } + + emit ReDelegate(_fromNode, _toNode, _tokenAmount); + + if (claimReward > 0) { + ERC20I(DOSTOKEN).transferFrom(stakingRewardsVault, msg.sender, claimReward); + emit ClaimReward(msg.sender, false, claimReward); + } + } + + function nodeWithdrawable(address _owner, address _nodeAddr) public view returns(uint, uint) { + Node storage node = nodes[_nodeAddr]; + if (node.ownerAddr != _owner) return (0, 0); + return withdrawable(node.releaseTime, node.unbondRequests); + } + + function delegatorWithdrawable(address _owner, address _nodeAddr) public view returns(uint) { + Delegation storage delegator = delegators[_owner][_nodeAddr]; + if (delegator.delegatedNode != _nodeAddr) return 0; + uint tokenAmount = 0; + (tokenAmount, ) = withdrawable(delegator.releaseTime, delegator.unbondRequests); + return tokenAmount; + } + + function nodeClaimReward(address _nodeAddr) public { + Node storage node = nodes[_nodeAddr]; + require(node.ownerAddr == msg.sender, "non-owner-not-authorized-to-claim"); + updateGlobalRewardIndex(); + uint claimedReward = getNodeRewardTokens(_nodeAddr); + node.accumulatedRewards = 0; + node.accumulatedRewardIndex = accumulatedRewardIndex; + // This would change interest rate + circulatingSupply = circulatingSupply.add(claimedReward); + ERC20I(DOSTOKEN).transferFrom(stakingRewardsVault, msg.sender, claimedReward); + emit ClaimReward(msg.sender, true, claimedReward); + } + + function delegatorClaimReward(address _nodeAddr) public { + Delegation storage delegator = delegators[msg.sender][_nodeAddr]; + require(nodes[_nodeAddr].ownerAddr != address(0), "node-not-exist"); + require(delegator.delegatedNode == _nodeAddr, "cannot-claim-from-non-delegated-node"); + updateGlobalRewardIndex(); + uint claimedReward = getDelegatorRewardTokens(msg.sender, _nodeAddr); + + if (delegator.delegatedAmount == 0 && delegator.pendingWithdraw == 0) { + delete delegators[msg.sender][_nodeAddr]; + } else { + delegator.accumulatedRewards = 0; + delegator.accumulatedRewardIndex = accumulatedRewardIndex; + } + // This would change interest rate + circulatingSupply = circulatingSupply.add(claimedReward); + ERC20I(DOSTOKEN).transferFrom(stakingRewardsVault, msg.sender, claimedReward); + emit ClaimReward(msg.sender, false, claimedReward); + } + + function getNodeUptime(address nodeAddr) public view returns(uint) { + Node storage node = nodes[nodeAddr]; + if (node.running) { + return now.sub(node.lastStartTime); + } else { + return 0; + } + } + + // return a percentage in [4.00, 80.00] (400, 8000) + function getCurrentAPR() public view returns (uint) { + if (totalStakedTokens == 0) { + return 8000; + } + uint localinverseStakeRatio = circulatingSupply.mul(1e4).div(totalStakedTokens); + if (localinverseStakeRatio > 20 * 1e4) { + // staking rate <= 5%, APR 80% + return 8000; + } else { + return localinverseStakeRatio.div(25); + } + } + + function rewardRateDelta() internal view returns (uint) { + return now.sub(lastRateUpdatedTime).mul(getCurrentAPR()).mul(1e6).div(ONEYEAR); + } + + function updateGlobalRewardIndex() internal { + accumulatedRewardIndex = accumulatedRewardIndex.add(rewardRateDelta()); + lastRateUpdatedTime = now; + } + + function getNodeRewardsCore(Node storage _n, uint _indexRT) internal view returns(uint) { + if (!_n.running) return _n.accumulatedRewards; + return + _n.accumulatedRewards.add( + _n.selfStakedAmount.add(_n.totalOtherDelegatedAmount.mul(_n.rewardCut).div(100)).mul( + _indexRT.sub(_n.accumulatedRewardIndex) + ).div(1e10) + ); + } + + function getDelegatorRewardsCore(Node storage _n, Delegation storage _d, uint _indexRT) internal view returns(uint) { + if (!_n.running) return _d.accumulatedRewards; + return + _d.accumulatedRewards.add( + _d.delegatedAmount.mul(100.sub(_n.rewardCut)).div(100).mul( + _indexRT.sub(_d.accumulatedRewardIndex) + ).div(1e10) + ); + } + + function getNodeRewardTokens(address _nodeAddr) internal view returns(uint) { + return getNodeRewardsCore(nodes[_nodeAddr], accumulatedRewardIndex); + } + + /// @dev returns realtime node staking rewards without any state change (specifically the global accumulatedRewardIndex) + function getNodeRewardTokensRT(address _nodeAddr) public view returns(uint) { + uint indexRT = accumulatedRewardIndex.add(rewardRateDelta()); + return getNodeRewardsCore(nodes[_nodeAddr], indexRT); + } + + function getDelegatorRewardTokens(address _delegator, address _nodeAddr) internal view returns(uint) { + return getDelegatorRewardsCore(nodes[_nodeAddr], delegators[_delegator][_nodeAddr], accumulatedRewardIndex); + } + + /// @dev returns realtime delegator's staking rewards without any state change (specifically the global accumulatedRewardIndex) + function getDelegatorRewardTokensRT(address _delegator, address _nodeAddr) public view returns(uint) { + uint indexRT = accumulatedRewardIndex.add(rewardRateDelta()); + return getDelegatorRewardsCore(nodes[_nodeAddr], delegators[_delegator][_nodeAddr], indexRT); + } +} diff --git a/contracts/Stream.sol b/contracts/Stream.sol new file mode 100644 index 0000000..9f9bce0 --- /dev/null +++ b/contracts/Stream.sol @@ -0,0 +1,352 @@ +pragma solidity ^0.5.0; +pragma experimental ABIEncoderV2; + +import "./lib/SafeMath.sol"; +import "./DOSOnChainSDK.sol"; + +contract IParser { + function floatBytes2UintArray(bytes memory raw, uint decimal) public view returns(uint[] memory); +} + +contract Stream is DOSOnChainSDK { + using SafeMath for uint; + + uint private constant ONEHOUR = 1 hours; + uint private constant ONEDAY = 1 days; + // overflow flag + uint private constant UINT_MAX = uint(-1); + uint public windowSize = 1200; // 20 minutes + // e.g. ETH / USD + string public description; + string public source; + string public selector; + uint public sId; + // Absolute price deviation percentage * 1000, i.e. 1 represents 1/1000 price change. + uint public deviation = 5; + // Number of decimals the reported price data use. + uint public decimal; + // Data parser, may be configured along with data source change + address public parser; + address public streamManager; + bool public whitelistEnabled; + // Reader whitelist + mapping(address => bool) private whitelist; + // Stream data is either updated once per windowSize or the deviation requirement is met, whichever comes first. + // Anyone can trigger an update on windowSize expiration, but only governance approved ones can be deviation updater to get rid of sybil attacks. + mapping(address => bool) private deviationGuardian; + mapping(uint => bool) private _valid; + + struct Observation { + uint timestamp; + uint price; + } + Observation[] private observations; + + event ParamsUpdated( + string oldDescription, string newDescription, + string oldSource, string newSource, + string oldSelector, string newSelector, + uint oldDecmial, uint newDecimal + ); + event WindowUpdated(uint oldWindow, uint newWindow); + event DeviationUpdated(uint oldDeviation, uint newDeviation); + event ParserUpdated(address oldParser, address newParser); + event DataUpdated(uint timestamp, uint price); + event PulledTrigger(address trigger, uint qId); + event BulletCaught(uint qId); + event AddAccess(address reader); + event RemoveAccess(address reader); + event AccessStatusUpdated(bool oldStatus, bool newStatus); + event AddGuardian(address guardian); + event RemoveGuardian(address guardian); + + modifier accessible { + require(!whitelistEnabled || hasAccess(msg.sender), "!accessible"); + _; + } + + modifier isContract(address addr) { + uint codeSize = 0; + assembly { + codeSize := extcodesize(addr) + } + require(codeSize > 0, "not-smart-contract"); + _; + } + + modifier onlyUpdater { + require(msg.sender == streamManager, "!updater"); + _; + } + + constructor( + string memory _description, + string memory _source, + string memory _selector, + uint _decimal, + address _parser, + address _manager + ) + public + isContract(_parser) + isContract(_manager) + { + // @dev: setup and then transfer DOS tokens into deployed contract + // as oracle fees. + // Unused fees can be reclaimed by calling DOSRefund() function of SDK contract. + super.DOSSetup(); + description = _description; + source = _source; + selector = _selector; + decimal = _decimal; + parser = _parser; + streamManager = _manager; + addReader(_manager); + emit ParamsUpdated("", _description, "", _source, "", _selector, 0, _decimal); + emit ParserUpdated(address(0), _parser); + } + + function strEqual(string memory a, string memory b) private pure returns (bool) { + return keccak256(abi.encodePacked(a)) == keccak256(abi.encodePacked(b)); + } + + function updateParams(string memory _description, string memory _source, string memory _selector, uint _decimal, uint _sId) public onlyOwner { + emit ParamsUpdated( + description, _description, + source, _source, + selector, _selector, + decimal, _decimal + ); + if (!strEqual(description, _description)) description = _description; + if (!strEqual(source, _source)) source = _source; + if (!strEqual(selector, _selector)) selector = _selector; + if (decimal != _decimal) decimal = _decimal; + if (sId != _sId) sId = _sId; + } + // This will erase all observed data! + function updateWindowSize(uint newWindow) public onlyOwner { + emit WindowUpdated(windowSize, newWindow); + windowSize = newWindow; + observations.length = 0; + } + function updateDeviation(uint newDeviation) public onlyOwner { + require(newDeviation >= 0 && newDeviation <= 1000, "should-be-in-0-1000"); + emit DeviationUpdated(deviation, newDeviation); + deviation = newDeviation; + } + function updateParser(address newParser) public onlyOwner isContract(newParser) { + emit ParserUpdated(parser, newParser); + parser = newParser; + } + function addReader(address reader) public onlyOwner { + if (!whitelist[reader]) { + whitelist[reader] = true; + emit AddAccess(reader); + } + } + function removeReader(address reader) public onlyOwner { + if (whitelist[reader]) { + delete whitelist[reader]; + emit RemoveAccess(reader); + } + } + function toggleAccessStatus() public onlyOwner { + emit AccessStatusUpdated(whitelistEnabled, !whitelistEnabled); + whitelistEnabled = !whitelistEnabled; + } + function addGuardian(address guardian) public onlyOwner { + if (!deviationGuardian[guardian]) { + deviationGuardian[guardian] = true; + emit AddGuardian(guardian); + } + } + function removeGuardian(address guardian) public onlyOwner { + if (deviationGuardian[guardian]) { + delete deviationGuardian[guardian]; + emit RemoveGuardian(guardian); + } + } + + function hasAccess(address reader) public view returns(bool) { + return whitelist[reader] || reader == tx.origin; + } + + function numPoints() public view returns(uint) { + return observations.length; + } + function num24hPoints() public view returns(uint) { + uint idx = binarySearch(ONEDAY); + if (idx == UINT_MAX) return observations.length; + return observations.length - idx; + } + + // Observation[] is sorted by timestamp in ascending order. Return the maximum index {i}, satisfying that: observations[i].timestamp <= observations[end].timestamp.sub(timedelta) + // Return UINT_MAX if not enough data points. + function binarySearch(uint timedelta) public view returns (uint) { + if (observations.length == 0) return uint(-1); + + int index = -1; + int l = 0; + int r = int(observations.length.sub(1)); + uint key = observations[uint(r)].timestamp.sub(timedelta); + while (l <= r) { + int m = (l + r) / 2; + uint m_val = observations[uint(m)].timestamp; + if (m_val <= key) { + index = m; + l = m + 1; + } else { + r = m - 1; + } + } + return uint(index); + } + + function stale(uint age) public view returns(bool) { + uint lastTime = observations.length > 0 ? observations[observations.length - 1].timestamp : 0; + return block.timestamp > lastTime.add(age); + } + + function pullTrigger() public { + if(!stale(windowSize) && !deviationGuardian[msg.sender]) return; + + uint id = DOSQuery(30, source, selector); + if (id != 0) { + _valid[id] = true; + emit PulledTrigger(msg.sender, id); + } + } + + function __callback__(uint id, bytes calldata result) external auth { + require(_valid[id], "invalid-request-id"); + uint[] memory priceData = IParser(parser).floatBytes2UintArray(result, decimal); + if (update(priceData[sId])) emit BulletCaught(id); + delete _valid[id]; + } + + function shouldUpdate(uint price) public view returns(bool) { + uint lastPrice = observations.length > 0 ? observations[observations.length - 1].price : 0; + uint delta = price > lastPrice ? (price - lastPrice) : (lastPrice - price); + return stale(windowSize) || (deviation > 0 && delta >= lastPrice.mul(deviation).div(1000)); + } + + function update(uint price) private returns(bool) { + if (shouldUpdate(price)) { + observations.push(Observation(block.timestamp, price)); + emit DataUpdated(block.timestamp, price); + return true; + } + return false; + } + + function megaUpdate(uint price) public onlyUpdater returns(bool) { + return update(price); + } + + // @dev Returns any specific historical data point. + // Accessible by whitelisted contracts or EOA user. + function result(uint idx) public view accessible returns (uint _price, uint _timestamp) { + require(idx < observations.length); + return (observations[idx].price, observations[idx].timestamp); + } + + // @dev Returns data [observations[startIdx], observations[lastIdx]], inclusive. + function results(uint startIdx, uint lastIdx) public view accessible returns (Observation[] memory) { + require(startIdx <= lastIdx && lastIdx < observations.length); + Observation[] memory ret = new Observation[](lastIdx - startIdx + 1); + for (uint i = startIdx; i <= lastIdx; i++) { + ret[i - startIdx] = observations[i]; + } + return ret; + } + function last24hResults() public view accessible returns (Observation[] memory) { + if (observations.length == 0) return (new Observation[](0)); + + uint lastIdx = observations.length - 1; + uint startIdx = binarySearch(ONEDAY); + if (startIdx == UINT_MAX) startIdx = 0; + return results(startIdx, lastIdx); + } + + // @dev Returns the most freshed (latest reported) data point. + // Accessible by whitelisted contracts or EOA. + // Return latest reported price & timestamp data. + function latestResult() public view accessible returns (uint _lastPrice, uint _lastUpdatedTime) { + require(observations.length > 0); + Observation storage last = observations[observations.length - 1]; + return (last.price, last.timestamp); + } + + // @dev Returns time-weighted average price (TWAP) of (observations[start] : observations[end]). + // Accessible by whitelisted contracts or EOA. + function twapResult(uint start) public view accessible returns (uint) { + require(start < observations.length, "index-overflow"); + + uint end = observations.length - 1; + uint cumulativePrice = 0; + for (uint i = start; i < end; i++) { + cumulativePrice = cumulativePrice.add(observations[i].price.mul(observations[i+1].timestamp.sub(observations[i].timestamp))); + } + uint timeElapsed = observations[end].timestamp.sub(observations[start].timestamp); + return cumulativePrice.div(timeElapsed); + } + + // @dev Below are a series of inhouse TWAP functions for the ease of developers. + // Accessible by whitelisted contracts or EOA user. + // More TWAP functions can be built by the above twapResult(startIdx) function. + function TWAP1Hour() public view accessible returns (uint) { + require(!stale(ONEHOUR), "1h-outdated-data"); + uint idx = binarySearch(ONEHOUR); + require(idx != UINT_MAX, "not-enough-observation-data-for-1h"); + return twapResult(idx); + } + + function TWAP2Hour() public view accessible returns (uint) { + require(!stale(ONEHOUR * 2), "2h-outdated-data"); + uint idx = binarySearch(ONEHOUR * 2); + require(idx != UINT_MAX, "not-enough-observation-data-for-2h"); + return twapResult(idx); + } + + function TWAP4Hour() public view accessible returns (uint) { + require(!stale(ONEHOUR * 4), "4h-outdated-data"); + uint idx = binarySearch(ONEHOUR * 4); + require(idx != UINT_MAX, "not-enough-observation-data-for-4h"); + return twapResult(idx); + } + + function TWAP6Hour() public view accessible returns (uint) { + require(!stale(ONEHOUR * 6), "6h-outdated-data"); + uint idx = binarySearch(ONEHOUR * 6); + require(idx != UINT_MAX, "not-enough-observation-data-for-6h"); + return twapResult(idx); + } + + function TWAP8Hour() public view accessible returns (uint) { + require(!stale(ONEHOUR * 8), "8h-outdated-data"); + uint idx = binarySearch(ONEHOUR * 8); + require(idx != UINT_MAX, "not-enough-observation-data-for-8h"); + return twapResult(idx); + } + + function TWAP12Hour() public view accessible returns (uint) { + require(!stale(ONEHOUR * 12), "12h-outdated-data"); + uint idx = binarySearch(ONEHOUR * 12); + require(idx != UINT_MAX, "not-enough-observation-data-for-12h"); + return twapResult(idx); + } + + function TWAP1Day() public view accessible returns (uint) { + require(!stale(ONEDAY), "1d-outdated-data"); + uint idx = binarySearch(ONEDAY); + require(idx != UINT_MAX, "not-enough-observation-data-for-1d"); + return twapResult(idx); + } + + function TWAP1Week() public view accessible returns (uint) { + require(!stale(ONEDAY * 7), "1w-outdated-data"); + uint idx = binarySearch(ONEDAY * 7); + require(idx != UINT_MAX, "not-enough-observation-data-for-1week"); + return twapResult(idx); + } +} diff --git a/contracts/StreamsManager.sol b/contracts/StreamsManager.sol new file mode 100644 index 0000000..0de5e1a --- /dev/null +++ b/contracts/StreamsManager.sol @@ -0,0 +1,182 @@ +pragma solidity ^0.5.0; +pragma experimental ABIEncoderV2; + +import "./lib/StringUtils.sol"; +import "./interfaces/StreamInterface.sol"; + +// StreamsManager manages group of data streams from the same meta data source (e.g. Coingecko, Coinbase, etc.) +// Readable only by Data Stream UI or EOAs, not by dependant smart contracts / projects. +contract StreamsManager { + using StringUtils for *; + + string public name; + address public governance; + address public pendingGovernance; + // Valid index starts from 1. + address[] public _streams; + // sorted streams according to stream.description() + address[] private _sortedStreams; + // stream => index in streams array + mapping(address=>uint) public streamsIdx; + + event GovernanceProposed(address pendingGov); + event GovernanceAccepted(address newGov); + event StreamAdded(address stream, uint numStreams); + event StreamAddressUpdated(address oldStreamAddr, address newStreamAddr); + event StreamRemoved(address stream); + + modifier onlyGovernance { + require(msg.sender == governance, "!governance"); + _; + } + modifier accessible(address stream) { + require(streamsIdx[stream] != 0 && stream == _streams[streamsIdx[stream]], "!exist"); + require(msg.sender == tx.origin, "!accessible-by-non-eoa"); + _; + } + modifier onlyMegaStream { + require(msg.sender == _streams[0], "!from-megaStream"); + _; + } + + constructor(string memory _name, address megaStream) public { + name = _name; + governance = msg.sender; + _streams.push(megaStream); + streamsIdx[megaStream] = 0; + } + + function setGovernance(address _governance) public onlyGovernance { + pendingGovernance = _governance; + emit GovernanceProposed(_governance); + } + function acceptGovernance() public { + require(msg.sender == pendingGovernance, "!pendingGovernance"); + governance = pendingGovernance; + pendingGovernance = address(0); + emit GovernanceAccepted(governance); + } + function quickSortBySelector(address[] memory arr, uint left, uint right) public view { + if (left >= right) return; + // p = the pivot element + address p = arr[(left + right) / 2]; + uint i = left; + uint j = right; + while (i < j) { + while (IStream(arr[i]).selector().strCompare(IStream(p).selector()) < 0) ++i; + // arr[j] > p means p still to the left, so j > 0 + while (IStream(arr[j]).selector().strCompare(IStream(p).selector()) > 0) --j; + if (IStream(arr[i]).selector().strCompare(IStream(arr[j]).selector()) > 0) + (arr[i], arr[j]) = (arr[j], arr[i]); + else + ++i; + } + + // Note --j was only done when a[j] > p. So we know: a[j] == p, a[j] > p + if (j > left) quickSortBySelector(arr, left, j - 1); // j > left, so j > 0 + quickSortBySelector(arr, j + 1, right); + } + function sortStreams() private { + address[] memory s = new address[](_streams.length - 1); + for (uint i = 1; i < _streams.length; i++) { + s[i-1] = _streams[i]; + } + quickSortBySelector(s, 0, s.length - 1); + _sortedStreams = s; + } + function sortedStreams() public view returns(address[] memory) { + return _sortedStreams; + } + function addStream(address stream) public onlyGovernance { + require(streamsIdx[stream] == 0, "existed"); + _streams.push(stream); + streamsIdx[stream] = _streams.length - 1; + emit StreamAdded(stream, _streams.length - 1); + sortStreams(); + } + function updateStream(address stream, address newStream) public onlyGovernance { + require(streamsIdx[stream] != 0, "!exist"); + require(streamsIdx[newStream] == 0, "existed"); + _streams[streamsIdx[stream]] = newStream; + streamsIdx[newStream] = streamsIdx[stream]; + delete streamsIdx[stream]; + emit StreamAddressUpdated(stream, newStream); + sortStreams(); + } + function removeStream(address stream) public onlyGovernance { + uint streamId = streamsIdx[stream]; + require(streamId != 0, "!exist"); + if (_streams.length > 2) { + _streams[streamId] = _streams[_streams.length - 1]; + streamsIdx[_streams[streamId]] = streamId; + } + _streams.length--; + delete streamsIdx[stream]; + emit StreamRemoved(stream); + sortStreams(); + } + + function megaUpdate(uint[] calldata data) external onlyMegaStream returns(bool) { + bool ret = false; + for (uint i = 0; i < data.length; i++) { + ret = IStream(_sortedStreams[i]).megaUpdate(data[i]) || ret; + } + return ret; + } + + function streams() public view returns(address[] memory) { + return _streams; + } + + function decimal(address stream) public view accessible(stream) returns(uint) { + return IStream(stream).decimal(); + } + function windowSize(address stream) public view accessible(stream) returns(uint) { + return IStream(stream).windowSize(); + } + function description(address stream) public view accessible(stream) returns(string memory) { + return IStream(stream).description(); + } + function deviation(address stream) public view accessible(stream) returns(uint) { + return IStream(stream).deviation(); + } + function numPoints(address stream) public view accessible(stream) returns(uint) { + return IStream(stream).numPoints(); + } + function num24hPoints(address stream) public view accessible(stream) returns(uint) { + return IStream(stream).num24hPoints(); + } + function latestResult(address stream) public view accessible(stream) returns(uint, uint) { + return IStream(stream).latestResult(); + } + function last24hResults(address stream) public view accessible(stream) returns(IStream.Observation[] memory) { + return IStream(stream).last24hResults(); + } + function results(address stream, uint startIdx, uint lastIdx) public view accessible(stream) returns(IStream.Observation[] memory) { + return IStream(stream).results(startIdx, lastIdx); + } + function TWAP1Hour(address stream) public view accessible(stream) returns(uint) { + return IStream(stream).TWAP1Hour(); + } + function TWAP2Hour(address stream) public view accessible(stream) returns(uint) { + return IStream(stream).TWAP2Hour(); + } + function TWAP4Hour(address stream) public view accessible(stream) returns(uint) { + return IStream(stream).TWAP4Hour(); + } + function TWAP6Hour(address stream) public view accessible(stream) returns(uint) { + return IStream(stream).TWAP6Hour(); + } + function TWAP8Hour(address stream) public view accessible(stream) returns(uint) { + return IStream(stream).TWAP8Hour(); + } + function TWAP12Hour(address stream) public view accessible(stream) returns(uint) { + return IStream(stream).TWAP12Hour(); + } + function TWAP1Day(address stream) public view accessible(stream) returns(uint) { + return IStream(stream).TWAP1Day(); + } + function TWAP1Week(address stream) public view accessible(stream) returns(uint) { + return IStream(stream).TWAP1Week(); + } +} diff --git a/contracts/TestToken.sol b/contracts/TestToken.sol new file mode 100644 index 0000000..f1b717b --- /dev/null +++ b/contracts/TestToken.sol @@ -0,0 +1,61 @@ +pragma solidity >=0.5.0 <0.6.0; + +import "./lib/SafeMath.sol"; + +contract TestToken { + using SafeMath for uint256; + + string public constant name = "TestToken"; + string public constant symbol = "TTK"; + uint8 public constant decimals = 18; + uint256 private constant MAX_SUPPLY = 1e9 * 1e18; // 1 billion total supply + uint256 private _supply = MAX_SUPPLY; + mapping(address => uint256) balances; + mapping(address => mapping (address => uint256)) allowed; + + event Approval(address indexed tokenOwner, address indexed spender, uint wad); + event Transfer(address indexed from, address indexed to, uint wad); + + constructor() public { + balances[msg.sender] = _supply; + } + + function totalSupply() public view returns (uint256) { + return _supply; + } + + function balanceOf(address tokenOwner) public view returns (uint) { + return balances[tokenOwner]; + } + + function transfer(address receiver, uint wad) public returns (bool) { + require(wad <= balances[msg.sender]); + balances[msg.sender] = balances[msg.sender].sub(wad); + balances[receiver] = balances[receiver].add(wad); + emit Transfer(msg.sender, receiver, wad); + return true; + } + + function approve(address delegate, uint wad) public returns (bool) { + allowed[msg.sender][delegate] = wad; + emit Approval(msg.sender, delegate, wad); + return true; + } + + function allowance(address owner, address delegate) public view returns (uint) { + return allowed[owner][delegate]; + } + + function transferFrom(address owner, address buyer, uint wad) public returns (bool) { + require(wad <= balances[owner]); + require(wad <= allowed[owner][msg.sender]); + if (owner != msg.sender && allowed[owner][msg.sender] != uint(-1)) { + require(allowed[owner][msg.sender] >= wad, "token-insufficient-approval"); + allowed[owner][msg.sender] = allowed[owner][msg.sender].sub(wad); + } + balances[owner] = balances[owner].sub(wad); + balances[buyer] = balances[buyer].add(wad); + emit Transfer(owner, buyer, wad); + return true; + } +} diff --git a/contracts/examples/AskMeAnything.sol b/contracts/examples/AskMeAnything.sol index 7aabbde..7644606 100644 --- a/contracts/examples/AskMeAnything.sol +++ b/contracts/examples/AskMeAnything.sol @@ -1,10 +1,9 @@ -pragma solidity >= 0.4.24; +pragma solidity ^0.5.0; -import "../Ownable.sol"; import "../DOSOnChainSDK.sol"; // A user contract asks anything from off-chain world through a url. -contract AskMeAnything is Ownable, DOSOnChainSDK { +contract AskMeAnything is DOSOnChainSDK { string public response; uint public random; // query_id -> valid_status @@ -15,17 +14,18 @@ contract AskMeAnything is Ownable, DOSOnChainSDK { string public lastQueriedUrl; string public lastQueriedSelector; uint public lastRequestedRandom; + uint8 public lastQueryInternalSerial; event SetTimeout(uint previousTimeout, uint newTimeout); event QueryResponseReady(uint queryId, string result); - event RequestSent(bool succ, uint requestId); - event RandomReady(uint generatedRandom); + event RequestSent(address indexed msgSender, uint8 internalSerial, bool succ, uint requestId); + event RandomReady(uint requestId, uint generatedRandom); - modifier auth(uint id) { - require(msg.sender == fromDOSProxyContract(), - "Unauthenticated response from non-DOS."); - require(_valid[id], "Response with invalid request id!"); - _; + constructor() public { + // @dev: setup and then transfer DOS tokens into deployed contract + // as oracle fees. + // Unused fees can be reclaimed by calling DOSRefund() in the SDK. + super.DOSSetup(); } function setQueryMode(bool newMode) public onlyOwner { @@ -38,50 +38,44 @@ contract AskMeAnything is Ownable, DOSOnChainSDK { } // Ask me anything (AMA) off-chain through an api/url. - function AMA(string memory url, string memory selector) public { + function AMA(uint8 internalSerial, string memory url, string memory selector) public { lastQueriedUrl = url; lastQueriedSelector = selector; + lastQueryInternalSerial = internalSerial; uint id = DOSQuery(timeout, url, selector); if (id != 0x0) { _valid[id] = true; - emit RequestSent(true, id); + emit RequestSent(msg.sender, internalSerial, true, id); } else { revert("Invalid query id."); } } // User-defined callback function handling query response. - function __callback__(uint queryId, bytes memory result) public auth(queryId) { + function __callback__(uint queryId, bytes calldata result) external auth { + require(_valid[queryId], "Response with invalid request id!"); response = string(result); emit QueryResponseReady(queryId, response); delete _valid[queryId]; if (repeatedCall) { - AMA(lastQueriedUrl, lastQueriedSelector); + AMA(lastQueryInternalSerial, lastQueriedUrl, lastQueriedSelector); } } - // Request a fast but insecure random number to use directly. - function requestFastRandom() public { + function requestSafeRandom(uint8 internalSerial) public { lastRequestedRandom = random; - random = DOSRandom(0, now); - } - - function requestSafeRandom() public { - lastRequestedRandom = random; - uint requestId = DOSRandom(1, now); + uint requestId = DOSRandom(now); _valid[requestId] = true; - emit RequestSent(true, requestId); + emit RequestSent(msg.sender, internalSerial, true, requestId); } // User-defined callback function handling newly generated secure // random number. - function __callback__(uint requestId, uint generatedRandom) - public - auth(requestId) - { + function __callback__(uint requestId, uint generatedRandom) external auth { + require(_valid[requestId], "Response with invalid request id!"); random = generatedRandom; - emit RandomReady(generatedRandom); + emit RandomReady(requestId, generatedRandom); delete _valid[requestId]; } } diff --git a/contracts/examples/CoinbaseEthUsd.sol b/contracts/examples/CoinbaseEthUsd.sol index 8a1b2fb..dfa437c 100644 --- a/contracts/examples/CoinbaseEthUsd.sol +++ b/contracts/examples/CoinbaseEthUsd.sol @@ -1,10 +1,12 @@ -pragma solidity >= 0.4.24; +pragma solidity ^0.5.0; -//import "github.com/DOSNetwork/eth-contracts/contracts/DOSOnChainSDK.sol"; +import "../lib/StringUtils.sol"; import "../DOSOnChainSDK.sol"; // An example get latest ETH-USD price from Coinbase contract CoinbaseEthUsd is DOSOnChainSDK { + using StringUtils for *; + // Struct to hold parsed floating string "123.45" struct ethusd { uint integral; @@ -13,27 +15,28 @@ contract CoinbaseEthUsd is DOSOnChainSDK { uint queryId; string public price_str; ethusd public prices; - + event GetPrice(uint integral, uint fractional); - + + constructor() public { + // @dev: setup and then transfer DOS tokens into deployed contract + // as oracle fees. + // Unused fees can be reclaimed by calling DOSRefund() in the SDK. + super.DOSSetup(); + } + function check() public { queryId = DOSQuery(30, "https://api.coinbase.com/v2/prices/ETH-USD/spot", "$.data.amount"); } - - modifier auth { - // Filter out malicious __callback__ callers. - require(msg.sender == fromDOSProxyContract(), "Unauthenticated response"); - _; - } - - function __callback__(uint id, bytes memory result) public auth { + + function __callback__(uint id, bytes calldata result) external auth { require(queryId == id, "Unmatched response"); - + price_str = string(result); prices.integral = price_str.subStr(1).str2Uint(); - int delimit_idx = price_str.indexOf('.'); - if (delimit_idx != -1) { - prices.fractional = price_str.subStr(uint(delimit_idx + 1)).str2Uint(); + uint delimit_idx = price_str.indexOf('.'); + if (delimit_idx != result.length) { + prices.fractional = price_str.subStr(delimit_idx + 1).str2Uint(); } emit GetPrice(prices.integral, prices.fractional); } diff --git a/contracts/examples/SimpleDice.txt b/contracts/examples/SimpleDice.sol similarity index 84% rename from contracts/examples/SimpleDice.txt rename to contracts/examples/SimpleDice.sol index 5428f12..c7654c4 100644 --- a/contracts/examples/SimpleDice.txt +++ b/contracts/examples/SimpleDice.sol @@ -1,15 +1,9 @@ -pragma solidity >= 0.5.0; +pragma solidity ^0.5.0; -// Wait till truffle integrates with latest solc, as currently it's only -// compilable with solc v0.5.x. -// There're many breaking changes between v0.4.x and v0.5.x, see: -// https://solidity.readthedocs.io/en/v0.5.1/050-breaking-changes.html. - -//import "github.com/DOSNetwork/eth-contracts/contracts/DOSOnChainSDK.sol"; import "../DOSOnChainSDK.sol"; contract SimpleDice is DOSOnChainSDK { - address payable public devAddress = 0xe4E18A49c6F1210FFE9a60dBD38071c6ef78d982; + address payable public devAddress; uint public devContributed = 0; // 1% winning payout goes to developer account uint public developCut = 1; @@ -33,17 +27,21 @@ contract SimpleDice is DOSOnChainSDK { event PlayerWin(uint gameId, uint generated, uint betted, uint amountWin); event PlayerLose(uint gameId, uint generated, uint betted); - modifier auth { - // Filter out malicious __callback__ callers. - require(msg.sender == fromDOSProxyContract(), "Unauthenticated response"); - _; - } - modifier onlyDev { require(msg.sender == devAddress); _; } + constructor() public { + // @dev: setup and then transfer DOS tokens into deployed contract + // as oracle fees. + // Unused fees can be reclaimed by calling DOSRefund() in the SDK. + super.DOSSetup(); + + // Convert address to payable address. + devAddress = address(uint160(owner())); + } + function min(uint a, uint b) internal pure returns(uint) { return a < b ? a : b; } @@ -80,14 +78,14 @@ contract SimpleDice is DOSOnChainSDK { // Request a safe, unmanipulatable random number from DOS Network with // optional seed. - uint gameId = DOSRandom(1, now); + uint gameId = DOSRandom(now); games[gameId] = DiceInfo(rollUnder, msg.value, msg.sender); // Emit event to notify Dapp frontend emit ReceivedBet(gameId, rollUnder, msg.value, msg.sender); } - function __callback__(uint requestId, uint generatedRandom) public auth { + function __callback__(uint requestId, uint generatedRandom) external auth { address payable player = games[requestId].player; require(player != address(0x0)); diff --git a/contracts/interfaces/StreamInterface.sol b/contracts/interfaces/StreamInterface.sol new file mode 100644 index 0000000..2159a02 --- /dev/null +++ b/contracts/interfaces/StreamInterface.sol @@ -0,0 +1,31 @@ +pragma solidity ^0.5.0; +pragma experimental ABIEncoderV2; + +interface IStream { + struct Observation { + uint timestamp; + uint price; + } + function description() external view returns (string memory); + function decimal() external view returns (uint); + function windowSize() external view returns (uint); + function source() external view returns (string memory); + function selector() external view returns (string memory); + function deviation() external view returns (uint); + function numPoints() external view returns(uint); + function num24hPoints() external view returns(uint); + function latestResult() external view returns (uint lastPrice, uint lastUpdatedTime); + function result(uint idx) external view returns (uint price, uint timestamp); + function results(uint startIdx, uint lastIdx) external view returns(Observation[] memory); + function last24hResults() external view returns (Observation[] memory); + function shouldUpdate(uint price) external view returns(bool); + function megaUpdate(uint price) external returns(bool); + function TWAP1Hour() external view returns (uint); + function TWAP2Hour() external view returns (uint); + function TWAP4Hour() external view returns (uint); + function TWAP6Hour() external view returns (uint); + function TWAP8Hour() external view returns (uint); + function TWAP12Hour() external view returns (uint); + function TWAP1Day() external view returns (uint); + function TWAP1Week() external view returns (uint); +} diff --git a/contracts/lib/BN256.sol b/contracts/lib/BN256.sol index 5791477..f28a5f7 100644 --- a/contracts/lib/BN256.sol +++ b/contracts/lib/BN256.sol @@ -1,4 +1,4 @@ -pragma solidity >= 0.4.24; +pragma solidity ^0.5.0; library BN256 { struct G1Point { @@ -63,6 +63,10 @@ library BN256 { return scalarMul(P1(), h); } + function G2Equal(G2Point memory p1, G2Point memory p2) internal pure returns (bool) { + return p1.x[0] == p2.x[0] && p1.x[1] == p2.x[1] && p1.y[0] == p2.y[0] && p1.y[1] == p2.y[1]; + } + // @return the result of computing the pairing check // check passes if e(p1[0], p2[0]) * .... * e(p1[n], p2[n]) == 1 // E.g. pairing([p1, p1.negate()], [p2, p2]) should return true. diff --git a/contracts/lib/SafeMath.sol b/contracts/lib/SafeMath.sol new file mode 100644 index 0000000..62ab8a4 --- /dev/null +++ b/contracts/lib/SafeMath.sol @@ -0,0 +1,183 @@ +pragma solidity ^0.5.0; + +library SafeMath { + /** + * @dev Returns the addition of two unsigned integers, reverting on overflow. + * + * Counterpart to Solidity's `+` operator. + * + * Requirements: + * - Addition cannot overflow. + */ + function add(uint256 a, uint256 b) internal pure returns (uint256) { + uint256 c = a + b; + require(c >= a, "SafeMath: addition overflow"); + + return c; + } + + /** + * @dev Returns the addition of two unsigned integers, reverting with custom message on overflow. + * + * Counterpart to Solidity's `+` operator. + * + * Requirements: + * - Addition cannot overflow. + */ + function add(uint256 a, uint256 b, string memory errorMessage) internal pure returns (uint256) { + uint256 c = a + b; + require(c >= a, errorMessage); + + return c; + } + + /** + * @dev Returns the subtraction of two unsigned integers, reverting on underflow (when the result is negative). + * + * Counterpart to Solidity's `-` operator. + * + * Requirements: + * - Subtraction cannot underflow. + */ + function sub(uint256 a, uint256 b) internal pure returns (uint256) { + return sub(a, b, "SafeMath: subtraction underflow"); + } + + /** + * @dev Returns the subtraction of two unsigned integers, reverting with custom message on underflow (when the result is negative). + * + * Counterpart to Solidity's `-` operator. + * + * Requirements: + * - Subtraction cannot underflow. + */ + function sub(uint256 a, uint256 b, string memory errorMessage) internal pure returns (uint256) { + require(b <= a, errorMessage); + uint256 c = a - b; + + return c; + } + + /** + * @dev Returns the multiplication of two unsigned integers, reverting on overflow. + * + * Counterpart to Solidity's `*` operator. + * + * Requirements: + * - Multiplication cannot overflow. + */ + function mul(uint256 a, uint256 b) internal pure returns (uint256) { + // Gas optimization: this is cheaper than requiring 'a' not being zero, but the + // benefit is lost if 'b' is also tested. + // See: https://github.com/OpenZeppelin/openzeppelin-contracts/pull/522 + if (a == 0) { + return 0; + } + + uint256 c = a * b; + require(c / a == b, "SafeMath: multiplication overflow"); + + return c; + } + + /** + * @dev Returns the multiplication of two unsigned integers, reverting on overflow. + * + * Counterpart to Solidity's `*` operator. + * + * Requirements: + * - Multiplication cannot overflow. + */ + function mul(uint256 a, uint256 b, string memory errorMessage) internal pure returns (uint256) { + // Gas optimization: this is cheaper than requiring 'a' not being zero, but the + // benefit is lost if 'b' is also tested. + // See: https://github.com/OpenZeppelin/openzeppelin-contracts/pull/522 + if (a == 0) { + return 0; + } + + uint256 c = a * b; + require(c / a == b, errorMessage); + + return c; + } + + /** + * @dev Returns the integer division of two unsigned integers. + * Reverts on division by zero. The result is rounded towards zero. + * + * Counterpart to Solidity's `/` operator. Note: this function uses a + * `revert` opcode (which leaves remaining gas untouched) while Solidity + * uses an invalid opcode to revert (consuming all remaining gas). + * + * Requirements: + * - The divisor cannot be zero. + */ + function div(uint256 a, uint256 b) internal pure returns (uint256) { + return div(a, b, "SafeMath: division by zero"); + } + + /** + * @dev Returns the integer division of two unsigned integers. + * Reverts with custom message on division by zero. The result is rounded towards zero. + * + * Counterpart to Solidity's `/` operator. Note: this function uses a + * `revert` opcode (which leaves remaining gas untouched) while Solidity + * uses an invalid opcode to revert (consuming all remaining gas). + * + * Requirements: + * - The divisor cannot be zero. + */ + function div(uint256 a, uint256 b, string memory errorMessage) internal pure returns (uint256) { + // Solidity only automatically asserts when dividing by 0 + require(b > 0, errorMessage); + uint256 c = a / b; + // assert(a == b * c + a % b); // There is no case in which this doesn't hold + + return c; + } + + /** + * @dev Returns the remainder of dividing two unsigned integers. (unsigned integer modulo), + * Reverts when dividing by zero. + * + * Counterpart to Solidity's `%` operator. This function uses a `revert` + * opcode (which leaves remaining gas untouched) while Solidity uses an + * invalid opcode to revert (consuming all remaining gas). + * + * Requirements: + * - The divisor cannot be zero. + */ + function mod(uint256 a, uint256 b) internal pure returns (uint256) { + return mod(a, b, "SafeMath: modulo by zero"); + } + + /** + * @dev Returns the remainder of dividing two unsigned integers. (unsigned integer modulo), + * Reverts with custom message when dividing by zero. + * + * Counterpart to Solidity's `%` operator. This function uses a `revert` + * opcode (which leaves remaining gas untouched) while Solidity uses an + * invalid opcode to revert (consuming all remaining gas). + * + * Requirements: + * - The divisor cannot be zero. + */ + function mod(uint256 a, uint256 b, string memory errorMessage) internal pure returns (uint256) { + require(b != 0, errorMessage); + return a % b; + } + + // @dev Returns x^n. + function pow(uint x, uint n) internal pure returns (uint z) { + z = n % 2 != 0 ? x : 1; + + for (n /= 2; n != 0; n /= 2) { + x = mul(x, x); + + if (n % 2 != 0) { + z = mul(z, x); + } + } + } +} diff --git a/contracts/lib/utils.sol b/contracts/lib/StringUtils.sol similarity index 80% rename from contracts/lib/utils.sol rename to contracts/lib/StringUtils.sol index 42f7b8c..61913a2 100644 --- a/contracts/lib/utils.sol +++ b/contracts/lib/StringUtils.sol @@ -1,7 +1,7 @@ -pragma solidity >= 0.4.24; +pragma solidity ^0.5.0; -// Util functions imported in OnChainSDK for caller to use. -library utils { +// Util functions caller to process strings. +library StringUtils { uint constant UINT256MAX = ~uint(0); // A decimal byte to uint. Return value of 10 indicating invalid input. @@ -31,7 +31,11 @@ library utils { // 1. processing stops once encountering character not in charset c. // 2. returns UINT256MAX when overflow. function str2Uint(string memory a) internal pure returns(uint) { - bytes memory b = bytes(a); + return bytes2Uint(bytes(a)); + } + + // A decimal bytes string (charset c in [0-9]) to uint. Like atoi(). + function bytes2Uint(bytes memory b) internal pure returns(uint) { uint res = 0; for (uint i = 0; i < b.length; i++) { uint8 tmp = byte2Uint(b[i]); @@ -208,25 +212,26 @@ library utils { return bytesEqual(aa, bb); } - // Return the index of needle's first occurrance in haystack. Return value - // of -1 indicating no occurrance. + // Return the index of needle's first occurrance in haystack; or return index of the first byte + // after haystack if not found. // Useful in case of parsing float string "123.45". // Example: // indexOf('123', '') => 0 - // indexOf('', '45') => -1 - // indexOf('123', '1234') => -1 + // indexOf('', '45') => 1 + // indexOf('123', '1234') => 3 + // indexOf('12345', '34') => 2 // indexOf('123.45', '.') => 3 - function indexOf(string memory haystack, string memory needle) internal pure returns(int) { + function indexOf(string memory haystack, string memory needle) internal pure returns(uint) { bytes memory b_haystack = bytes(haystack); bytes memory b_needle = bytes(needle); return indexOf(b_haystack, b_needle); } - function indexOf(bytes memory haystack, bytes memory needle) internal pure returns(int) { + function indexOf(bytes memory haystack, bytes memory needle) internal pure returns(uint) { if (needle.length == 0) { return 0; } else if (haystack.length < needle.length) { - return -1; + return haystack.length; } // Instead of O(haystack.length x needle.length), saving gas using KMP: // O(haystack.length + needle.length) @@ -255,18 +260,20 @@ library utils { } // Match if(q == needle.length) { - return int(i - q + 1); + return i - q + 1; } } // No match - return -1; + return haystack.length; } - // subStr("1234567890", 2, 5) => "34567" + // subStr("123456789", 2, 5) => "34567" + // subStr("123456789", 2, 100) => "3456789" // [start, start + len), index starting from 0. function subStr(bytes memory a, uint start, uint len) internal pure returns(bytes memory) { - require(start < a.length && start + len > start && start + len <= a.length, - "Invalid start index or length out of range"); + if (start >= a.length) return ""; + + if (a.length - start < len) len = a.length - start; bytes memory res = new bytes(len); for (uint i = 0; i < len; i++) { res[i] = a[start + i]; @@ -277,8 +284,7 @@ library utils { // string num = "123.4567"; // subStr(num, indexOf(num, '.') + 1) => "4567" function subStr(bytes memory a, uint start) internal pure returns(bytes memory) { - require(start < a.length, "Invalid start index out of range"); - return subStr(a, start, a.length - start); + return subStr(a, start, a.length); } function subStr(string memory a, uint start, uint len) internal pure returns(string memory) { @@ -290,4 +296,42 @@ library utils { bytes memory aa = bytes(a); return string(subStr(aa, start)); } + + function count(bytes memory str, bytes memory delimiter) internal pure returns(uint) { + uint cnt = 0; + while(str.length > 0) { + uint idx = indexOf(str, delimiter); + if (idx != str.length) { + cnt++; + str = subStr(str, idx + delimiter.length); + } else { + return cnt; + } + } + return cnt; + } + + function count(string memory str, string memory delimiter) internal pure returns(uint) { + return count(bytes(str), bytes(delimiter)); + } + + function split(string memory str, string memory delimiter) internal pure returns(string[] memory) { + bytes[] memory r = split(bytes(str), bytes(delimiter)); + string[] memory ret = new string[](r.length); + for (uint i = 0; i < r.length; i++) { + ret[i] = string(r[i]); + } + return ret; + } + + function split(bytes memory str, bytes memory delimiter) internal pure returns(bytes[] memory) { + uint len = count(str, delimiter) + 1; + bytes[] memory ret = new bytes[](len); + for (uint i = 0; i < len; i++) { + uint idx = indexOf(str, delimiter); + ret[i] = subStr(str, 0, idx); + str = subStr(str, idx + delimiter.length); + } + return ret; + } } diff --git a/contracts/lib/math.sol b/contracts/lib/math.sol new file mode 100644 index 0000000..de66218 --- /dev/null +++ b/contracts/lib/math.sol @@ -0,0 +1,74 @@ +pragma solidity >=0.5.0 <0.6.0; + +library DSMath { + function add(uint x, uint y) internal pure returns (uint z) { + require((z = x + y) >= x, "ds-math-add-overflow"); + } + function sub(uint x, uint y) internal pure returns (uint z) { + require((z = x - y) <= x, "ds-math-sub-underflow"); + } + function mul(uint x, uint y) internal pure returns (uint z) { + require(y == 0 || (z = x * y) / y == x, "ds-math-mul-overflow"); + } + function div(uint x, uint y) internal pure returns (uint z) { + // assert(y > 0); // Solidity automatically throws when dividing by 0 + z = x / y; + // assert(x == y * z + x % y); // There is no case in which this doesn't hold + } + + function min(uint x, uint y) internal pure returns (uint z) { + return x <= y ? x : y; + } + function max(uint x, uint y) internal pure returns (uint z) { + return x >= y ? x : y; + } + function imin(int x, int y) internal pure returns (int z) { + return x <= y ? x : y; + } + function imax(int x, int y) internal pure returns (int z) { + return x >= y ? x : y; + } + + uint constant WAD = 10 ** 18; + uint constant RAY = 10 ** 27; + + function wmul(uint x, uint y) internal pure returns (uint z) { + z = add(mul(x, y), WAD / 2) / WAD; + } + function rmul(uint x, uint y) internal pure returns (uint z) { + z = add(mul(x, y), RAY / 2) / RAY; + } + function wdiv(uint x, uint y) internal pure returns (uint z) { + z = add(mul(x, WAD), y / 2) / y; + } + function rdiv(uint x, uint y) internal pure returns (uint z) { + z = add(mul(x, RAY), y / 2) / y; + } + + // This famous algorithm is called "exponentiation by squaring" + // and calculates x^n with x as fixed-point and n as regular unsigned. + // + // It's O(log n), instead of O(n) for naive repeated multiplication. + // + // These facts are why it works: + // + // If n is even, then x^n = (x^2)^(n/2). + // If n is odd, then x^n = x * x^(n-1), + // and applying the equation for even x gives + // x^n = x * (x^2)^((n-1) / 2). + // + // Also, EVM division is flooring and + // floor[(n-1) / 2] = floor[n / 2]. + // + function rpow(uint x, uint n) internal pure returns (uint z) { + z = n % 2 != 0 ? x : RAY; + + for (n /= 2; n != 0; n /= 2) { + x = rmul(x, x); + + if (n % 2 != 0) { + z = rmul(z, x); + } + } + } +} diff --git a/contracts/mocks/BN256Mock.sol b/contracts/mocks/BN256Mock.sol index 916458b..12c84ea 100644 --- a/contracts/mocks/BN256Mock.sol +++ b/contracts/mocks/BN256Mock.sol @@ -1,4 +1,4 @@ -pragma solidity >= 0.4.24; +pragma solidity ^0.5.0; import "../lib/BN256.sol"; diff --git a/contracts/mocks/DOSProxyMock.sol b/contracts/mocks/DOSProxyMock.sol new file mode 100644 index 0000000..395ec1a --- /dev/null +++ b/contracts/mocks/DOSProxyMock.sol @@ -0,0 +1,901 @@ +pragma solidity ^0.5.0; + +import "../lib/BN256.sol"; +import "../Ownable.sol"; + +contract UserContractInterface { + // Query callback. + function __callback__(uint, bytes calldata) external; + // Random number callback. + function __callback__(uint, uint) external; +} + +contract DOSProxyMock is Ownable { + using BN256 for *; + + // Metadata of pending request. + struct PendingRequest { + uint requestId; + BN256.G2Point handledGroupPubKey; + // Calling contract who issues the request. + address callbackAddr; + } + + // Metadata of registered group. + struct Group { + uint groupId; + BN256.G2Point groupPubKey; + uint birthBlkN; + address[] members; + } + + // Metadata of a to-be-registered group whose members are determined already. + struct PendingGroup { + uint groupId; + uint startBlkNum; + mapping(bytes32 => uint) pubKeyCounts; + // 0x1 (HEAD) -> member1 -> member2 -> ... -> memberN -> 0x1 (HEAD) + mapping(address => address) memberList; + } + + uint requestIdSeed; + // calling requestId => PendingQuery metadata + mapping(uint => PendingRequest) PendingRequests; + + uint public refreshSystemRandomHardLimit = 60; // in blocks, ~15min + uint public groupMaturityPeriod = 80; // in blocks, ~2days + // When regrouping, picking @gropToPick working groups, plus one group from pending nodes. + uint public groupToPick = 2; + uint public groupSize = 3; + // decimal 2. + uint public groupingThreshold = 110; + // Bootstrapping related arguments, in blocks. + uint public bootstrapCommitDuration = 10; + uint public bootstrapRevealDuration = 10; + uint public bootstrapStartThreshold = groupSize * (groupToPick + 1); + uint public bootstrapRound = 0; + + uint private constant UINTMAX = uint(-1); + // Dummy head and placeholder used in linkedlists. + uint private constant HEAD_I = 0x1; + address private constant HEAD_A = address(0x1); + + // Linkedlist of newly registered ungrouped nodes, with HEAD points to the earliest and pendingNodeTail points to the latest. + // Initial state: pendingNodeList[HEAD_A] == HEAD_A && pendingNodeTail == HEAD_A. + mapping(address => address) public pendingNodeList; + address public pendingNodeTail; + uint public numPendingNodes; + + // node => a linkedlist of working groupIds the node is in: + // node => (0x1 -> workingGroupId1 -> workingGroupId2 -> ... -> workingGroupIdm -> 0x1) + // Initial state: { nodeAddr : { HEAD_I : HEAD_I } } + mapping(address => mapping(uint => uint)) public nodeToGroupIdList; + + // groupId => Group + mapping(uint => Group) private workingGroups; + // Index:groupId + uint[] public workingGroupIds; + uint[] public expiredWorkingGroupIds; + + // groupId => PendingGroup + mapping(uint => PendingGroup) public pendingGroups; + uint public pendingGroupMaxLife = 40; // in blocks + + // Initial state: pendingGroupList[HEAD_I] == HEAD_I && pendingGroupTail == HEAD_I + mapping(uint => uint) public pendingGroupList; + uint public pendingGroupTail; + uint public numPendingGroups = 0; + + uint public lastUpdatedBlock; + uint public lastRandomness; + Group lastHandledGroup; + + enum TrafficType { + SystemRandom, + UserRandom, + UserQuery + } + + event LogUrl( + uint queryId, + uint timeout, + string dataSource, + string selector, + uint randomness, + uint dispatchedGroupId + ); + event LogRequestUserRandom( + uint requestId, + uint lastSystemRandomness, + uint userSeed, + uint dispatchedGroupId + ); + event LogNonSupportedType(string invalidSelector); + event LogNonContractCall(address from); + event LogCallbackTriggeredFor(address callbackAddr); + event LogRequestFromNonExistentUC(); + event LogUpdateRandom(uint lastRandomness, uint dispatchedGroupId); + event LogValidationResult( + uint8 trafficType, + uint trafficId, + bytes message, + uint[2] signature, + uint[4] pubKey, + uint8 version, + bool pass + ); + event LogInsufficientPendingNode(uint numPendingNodes); + event LogInsufficientWorkingGroup(uint numWorkingGroups, uint numPendingGroups); + event LogGrouping(uint groupId, address[] nodeId); + event LogPublicKeyAccepted(uint groupId, uint[4] pubKey, uint numWorkingGroups); + event LogPublicKeySuggested(uint groupId, uint pubKeyCount); + event LogGroupDissolve(uint groupId); + event LogRegisteredNewPendingNode(address node); + event LogUnRegisteredNewPendingNode(address node,uint unregisterFrom); + event LogGroupingInitiated(uint pendingNodePool, uint groupsize, uint groupingthreshold); + event LogNoPendingGroup(uint groupId); + event LogPendingGroupRemoved(uint groupId); + event LogError(string err); + event UpdateGroupToPick(uint oldNum, uint newNum); + event UpdateGroupSize(uint oldSize, uint newSize); + event UpdateGroupingThreshold(uint oldThreshold, uint newThreshold); + event UpdateGroupMaturityPeriod(uint oldPeriod, uint newPeriod); + event UpdateBootstrapCommitDuration(uint oldDuration, uint newDuration); + event UpdateBootstrapRevealDuration(uint oldDuration, uint newDuration); + event UpdatebootstrapStartThreshold(uint oldThreshold, uint newThreshold); + event UpdatePendingGroupMaxLife(uint oldLifeBlocks, uint newLifeBlocks); + event GuardianReward(uint blkNum, address indexed guardian); + + + modifier fromValidStakingNode { + _; + } + + constructor() public { + pendingNodeList[HEAD_A] = HEAD_A; + pendingNodeTail = HEAD_A; + pendingGroupList[HEAD_I] = HEAD_I; + pendingGroupTail = HEAD_I; + } + + function getLastHandledGroup() public view returns(uint, uint[4] memory, uint, address[] memory) { + return ( + lastHandledGroup.groupId, + getGroupPubKey(lastHandledGroup.groupId), + lastHandledGroup.birthBlkN, + lastHandledGroup.members + ); + } + + function getWorkingGroupById(uint groupId) public view returns(uint, uint[4] memory, uint, address[] memory) { + return ( + workingGroups[groupId].groupId, + getGroupPubKey(groupId), + workingGroups[groupId].birthBlkN, + workingGroups[groupId].members + ); + } + + function workingGroupIdsLength() public view returns(uint256) { + return workingGroupIds.length; + } + + function expiredWorkingGroupIdsLength() public view returns(uint256) { + return expiredWorkingGroupIds.length; + } + + function setGroupToPick(uint newNum) public onlyOwner { + require(newNum != groupToPick && newNum != 0); + emit UpdateGroupToPick(groupToPick, newNum); + groupToPick = newNum; + } + + // groupSize must be an odd number. + function setGroupSize(uint newSize) public onlyOwner { + require(newSize != groupSize && newSize % 2 != 0); + emit UpdateGroupSize(groupSize, newSize); + groupSize = newSize; + } + + function setGroupingThreshold(uint newThreshold) public onlyOwner { + require(newThreshold != groupingThreshold && newThreshold >= 100); + emit UpdateGroupMaturityPeriod(groupingThreshold, newThreshold); + groupingThreshold = newThreshold; + } + + function setGroupMaturityPeriod(uint newPeriod) public onlyOwner { + require(newPeriod != groupMaturityPeriod && newPeriod != 0); + emit UpdateGroupMaturityPeriod(groupMaturityPeriod, newPeriod); + groupMaturityPeriod = newPeriod; + } + + function setBootstrapCommitDuration(uint newCommitDuration) public onlyOwner { + require(newCommitDuration != bootstrapCommitDuration && newCommitDuration != 0); + emit UpdateBootstrapCommitDuration(bootstrapCommitDuration, newCommitDuration); + bootstrapCommitDuration = newCommitDuration; + } + + function setBootstrapRevealDuration(uint newRevealDuration) public onlyOwner { + require(newRevealDuration != bootstrapRevealDuration && newRevealDuration != 0); + emit UpdateBootstrapRevealDuration(bootstrapRevealDuration, newRevealDuration); + bootstrapRevealDuration = newRevealDuration; + } + + function setbootstrapStartThreshold(uint newNum) public onlyOwner { + require(newNum != bootstrapStartThreshold && newNum >= groupSize * (groupToPick + 1)); + emit UpdatebootstrapStartThreshold(bootstrapStartThreshold, newNum); + bootstrapStartThreshold = newNum; + } + + function setPendingGroupMaxLife(uint newLife) public onlyOwner { + require(newLife != pendingGroupMaxLife && newLife != 0); + emit UpdatePendingGroupMaxLife(pendingGroupMaxLife, newLife); + pendingGroupMaxLife = newLife; + } + + function getCodeSize(address addr) private view returns (uint size) { + assembly { + size := extcodesize(addr) + } + } + + function dispatchJobCore(TrafficType trafficType, uint pseudoSeed) private returns(uint idx) { + uint rnd = uint(keccak256(abi.encodePacked(trafficType, pseudoSeed, lastRandomness))); + do { + if (workingGroupIds.length == 0) return UINTMAX; + idx = rnd % workingGroupIds.length; + Group storage group = workingGroups[workingGroupIds[idx]]; + if (groupMaturityPeriod + group.birthBlkN <= block.number) { + // Dissolving expired working groups happens in another phase for gas reasons. + expiredWorkingGroupIds.push(workingGroupIds[idx]); + workingGroupIds[idx] = workingGroupIds[workingGroupIds.length - 1]; + workingGroupIds.length--; + } else { + return idx; + } + } while (true); + } + + function dispatchJob(TrafficType trafficType, uint pseudoSeed) private returns(uint) { + if (refreshSystemRandomHardLimit + lastUpdatedBlock <= block.number) { + kickoffRandom(); + } + return dispatchJobCore(trafficType, pseudoSeed); + } + + function kickoffRandom() private { + uint idx = dispatchJobCore(TrafficType.SystemRandom, uint(blockhash(block.number - 1))); + // TODO: keep id receipt and handle later in v2.0. + if (idx == UINTMAX) { + emit LogError("No live working group, skipped random request"); + return; + } + lastUpdatedBlock = block.number; + lastHandledGroup = workingGroups[workingGroupIds[idx]]; + // Signal off-chain clients + emit LogUpdateRandom(lastRandomness, lastHandledGroup.groupId); + } + + function insertToPendingGroupListTail(uint groupId) private { + pendingGroupList[groupId] = pendingGroupList[pendingGroupTail]; + pendingGroupList[pendingGroupTail] = groupId; + pendingGroupTail = groupId; + numPendingGroups++; + } + + function insertToPendingNodeListTail(address node) private { + pendingNodeList[node] = pendingNodeList[pendingNodeTail]; + pendingNodeList[pendingNodeTail] = node; + pendingNodeTail = node; + numPendingNodes++; + } + + function insertToPendingNodeListHead(address node) private { + pendingNodeList[node] = pendingNodeList[HEAD_A]; + pendingNodeList[HEAD_A] = node; + numPendingNodes++; + } + + function insertToListHead(mapping(uint => uint) storage list, uint id) private { + list[id] = list[HEAD_I]; + list[HEAD_I] = id; + } + + /// Remove Node from a storage linkedlist. Need to check tail after this done + function removeNodeFromList(mapping(address => address) storage list, address node) private returns(bool) { + address prev = HEAD_A; + address curr = list[prev]; + while (curr != HEAD_A && curr != node) { + prev = curr; + curr = list[prev]; + } + if (curr == HEAD_A) { + return false; + } else { + list[prev] = list[curr]; + delete list[curr]; + return true; + } + } + + /// Remove id from a storage linkedlist. Need to check tail after this done + function removeIdFromList(mapping(uint => uint) storage list, uint id) private returns(uint, bool) { + uint prev = HEAD_I; + uint curr = list[prev]; + while (curr != HEAD_I && curr != id) { + prev = curr; + curr = list[prev]; + } + if (curr == HEAD_I) { + return (HEAD_I, false); + } else { + list[prev] = list[curr]; + delete list[curr]; + return (prev, true); + } + } + + /// Remove node from a storage linkedlist. + function removeNodeFromPendingGroup(mapping(uint => uint) storage list, address node) private returns(bool) { + uint prev = HEAD_I; + uint curr = list[prev]; + while (curr != HEAD_I) { + PendingGroup storage pgrp = pendingGroups[curr]; + bool removed = removeNodeFromList(pgrp.memberList, node); + if (removed) { + cleanUpOldestExpiredPendingGroup(curr); + return true; + } + prev = curr; + curr = list[prev]; + } + return false; + } + + /// @notice Caller ensures no index overflow. + function dissolveWorkingGroup(uint groupId, bool backToPendingPool) private { + /// Deregister expired working group and remove metadata. + Group storage grp = workingGroups[groupId]; + for (uint i = 0; i < grp.members.length; i++) { + address member = grp.members[i]; + // Update nodeToGroupIdList[member] and put members back to pendingNodeList's tail if necessary. + // Notice: Guardian may need to signal group formation. + (uint prev, bool removed) = removeIdFromList(nodeToGroupIdList[member], grp.groupId); + if (removed && prev == HEAD_I) { + if (backToPendingPool && pendingNodeList[member] == address(0)) { + insertToPendingNodeListTail(member); + emit LogRegisteredNewPendingNode(member); + } + } + } + delete workingGroups[groupId]; + emit LogGroupDissolve(groupId); + } + + // Returns query id. + // TODO: restrict query from subscribed/paid calling contracts. + function query( + address from, + uint timeout, + string calldata dataSource, + string calldata selector + ) + external + returns (uint) + { + if (getCodeSize(from) > 0) { + bytes memory bs = bytes(selector); + // '': Return whole raw response; + // Starts with '$': response format is parsed as json. + // Starts with '/': response format is parsed as xml/html. + if (bs.length == 0 || bs[0] == '$' || bs[0] == '/') { + uint queryId = uint(keccak256(abi.encodePacked( + ++requestIdSeed, from, timeout, dataSource, selector))); + uint idx = dispatchJob(TrafficType.UserQuery, queryId); + // TODO: keep id receipt and handle later in v2.0. + if (idx == UINTMAX) { + emit LogError("No live working group, skipped query"); + return 0; + } + Group storage grp = workingGroups[workingGroupIds[idx]]; + PendingRequests[queryId] = + PendingRequest(queryId, grp.groupPubKey, from); + emit LogUrl( + queryId, + timeout, + dataSource, + selector, + lastRandomness, + grp.groupId + ); + return queryId; + } else { + emit LogNonSupportedType(selector); + return 0; + } + } else { + // Skip if @from is not contract address. + emit LogNonContractCall(from); + return 0; + } + } + + // Request a new user-level random number. + function requestRandom(address from, uint8 mode, uint userSeed) + public + returns (uint) + { + // fast mode + if (mode == 0) { + return uint(keccak256(abi.encodePacked( + ++requestIdSeed,lastRandomness, userSeed))); + } else if (mode == 1) { + // safe mode + // TODO: restrict request from paid calling contract address. + uint requestId = uint(keccak256(abi.encodePacked( + ++requestIdSeed, from, userSeed))); + uint idx = dispatchJob(TrafficType.UserRandom, requestId); + // TODO: keep id receipt and handle later in v2.0. + if (idx == UINTMAX) { + emit LogError("No live working group, skipped random request"); + return 0; + } + Group storage grp = workingGroups[workingGroupIds[idx]]; + PendingRequests[requestId] = + PendingRequest(requestId, grp.groupPubKey, from); + // sign(requestId ||lastSystemRandomness || userSeed || + // selected sender in group) + emit LogRequestUserRandom( + requestId, + lastRandomness, + userSeed, + grp.groupId + ); + return requestId; + } else { + revert("Non-supported random request"); + } + } + + // Random submitter validation + group signature verification. + function validateAndVerify( + uint8 trafficType, + uint trafficId, + bytes memory data, + BN256.G1Point memory signature, + BN256.G2Point memory grpPubKey, + uint8 version + ) + private + returns (bool) + { + // Validation + // TODO + // 1. Check msg.sender is a member in Group(grpPubKey). + // Clients actually signs (data || addr(selected_submitter)). + bytes memory message = abi.encodePacked(data, msg.sender); + + // Verification + bool passVerify = true; + emit LogValidationResult( + trafficType, + trafficId, + message, + [signature.x, signature.y], + [grpPubKey.x[0], grpPubKey.x[1], grpPubKey.y[0], grpPubKey.y[1]], + version, + passVerify + ); + return passVerify; + } + + function triggerCallback( + uint requestId, + uint8 trafficType, + bytes calldata result, + uint[2] calldata sig, + uint8 version + ) + external + fromValidStakingNode + { + address ucAddr = PendingRequests[requestId].callbackAddr; + if (ucAddr == address(0x0)) { + emit LogRequestFromNonExistentUC(); + return; + } + + if (!validateAndVerify( + trafficType, + requestId, + result, + BN256.G1Point(sig[0], sig[1]), + PendingRequests[requestId].handledGroupPubKey, + version)) + { + return; + } + + emit LogCallbackTriggeredFor(ucAddr); + delete PendingRequests[requestId]; + if (trafficType == uint8(TrafficType.UserQuery)) { + UserContractInterface(ucAddr).__callback__(requestId, result); + } else if (trafficType == uint8(TrafficType.UserRandom)) { + // Safe random number is the collectively signed threshold signature + // of the message (requestId || lastRandomness || userSeed || + // selected sender in group). + UserContractInterface(ucAddr).__callback__( + requestId, uint(keccak256(abi.encodePacked(sig[0], sig[1])))); + } else { + revert("Unsupported traffic type"); + } + } + + function toBytes(uint x) private pure returns (bytes memory b) { + b = new bytes(32); + assembly { mstore(add(b, 32), x) } + } + + // System-level secure distributed random number generator. + function updateRandomness(uint[2] calldata sig, uint8 version) external fromValidStakingNode { + if (!validateAndVerify( + uint8(TrafficType.SystemRandom), + lastRandomness, + toBytes(lastRandomness), + BN256.G1Point(sig[0], sig[1]), + lastHandledGroup.groupPubKey, + version)) + { + return; + } + // Update new randomness = sha3(collectively signed group signature) + // TODO: include and test with blockhash. + lastRandomness = uint(keccak256(abi.encodePacked(sig[0], sig[1]))); + lastUpdatedBlock = block.number; + } + + /// @notice Caller ensures pendingGroupList is not empty and pending group header has indeed expired. + function cleanUpOldestExpiredPendingGroup(uint gid) private { + PendingGroup storage pgrp = pendingGroups[gid]; + address member = pgrp.memberList[HEAD_A]; + while (member != HEAD_A) { + // 1. Put member back to pendingNodeList's head if it's not in any workingGroup. + if (nodeToGroupIdList[member][HEAD_I] == HEAD_I && pendingNodeList[member] == address(0)) { + insertToPendingNodeListTail(member); + } + member = pgrp.memberList[member]; + } + // 2. Update pendingGroupList + (uint prev, bool removed) = removeIdFromList(pendingGroupList, gid); + // Reset pendingGroupTail if necessary. + if (removed && pendingGroupTail == gid) { + pendingGroupTail = prev; + } + + // 3. Update pendingGroup + delete pendingGroups[gid]; + numPendingGroups--; + emit LogPendingGroupRemoved(gid); + } + + /// Guardian node functions + // TODO: Tune guardian signal algorithm. + // TODO: Reward guardian nodes. + /// @dev Guardian signals expiring system randomness and kicks off distributed random engine again. + /// Anyone including but not limited to DOS client node can be a guardian and claim rewards. + function signalRandom() public { + if (lastUpdatedBlock + refreshSystemRandomHardLimit > block.number) { + emit LogError("SystemRandom not expired yet"); + return; + } + + kickoffRandom(); + + emit GuardianReward(block.number, msg.sender); + } + // TODO: Reward guardian nodes. + /// @dev Guardian signals to dissolve expired (workingGroup + pendingGroup) and claim guardian rewards. + function signalGroupDissolve() public { + bool claimed = false; + // Clean up oldest expired working group and related metadata. + if (expiredWorkingGroupIds.length > 0) { + dissolveWorkingGroup(expiredWorkingGroupIds[0], true); + expiredWorkingGroupIds[0] = expiredWorkingGroupIds[expiredWorkingGroupIds.length - 1]; + expiredWorkingGroupIds.length--; + claimed = true; + } else { + emit LogError("No expired working group to clean up"); + } + // Clean up oldest expired PendingGroup and related metadata. Might be due to failed DKG. + uint gid = pendingGroupList[HEAD_I]; + if (gid != HEAD_I && pendingGroups[gid].startBlkNum + pendingGroupMaxLife < block.number) { + cleanUpOldestExpiredPendingGroup(gid); + claimed = true; + } else { + emit LogError("No expired pending group to clean up"); + } + // Claim guardian rewards if work is done. + if (claimed) { + emit GuardianReward(block.number, msg.sender); + } + } + // TODO: Reward guardian nodes. + /// @dev Guardian signals to trigger group formation when there're enough pending nodes. + /// If there aren't enough working groups to choose to dossolve, probably a new bootstrap is needed. + function signalGroupFormation() public { + if (formGroup()) { + emit GuardianReward(block.number, msg.sender); + } + } + // TODO: Reward guardian nodes. + function signalBootstrap(uint _cid) public { + require(bootstrapRound == _cid, "Not in bootstrap phase"); + if (numPendingNodes < bootstrapStartThreshold) { + emit LogError("Not enough nodes to bootstrap"); + return; + } + + // Reset. + bootstrapRound = 0; + uint rndSeed = 1; + lastRandomness = uint(keccak256(abi.encodePacked(lastRandomness, rndSeed))); + lastUpdatedBlock = block.number; + + // TODO: Refine bootstrap algorithm to allow group overlapping. + uint arrSize = bootstrapStartThreshold / groupSize * groupSize; + address[] memory candidates = new address[](arrSize); + + pick(arrSize, 0, candidates); + shuffle(candidates, rndSeed); + regroup(candidates, arrSize / groupSize); + emit GuardianReward(block.number, msg.sender); + } + /// End of Guardian functions + + function unregisterNode() public fromValidStakingNode { + //1) Check if node is in pendingNodeList + if (pendingNodeList[msg.sender] != address(0)) { + // Update pendingNodeList + bool removed = removeNodeFromList(pendingNodeList, msg.sender); + // Reset pendingNodeTail if necessary. + if (removed) { + numPendingNodes--; + emit LogUnRegisteredNewPendingNode(msg.sender,1); + } + return; + } + + //2) Check if node is in workingGroups + uint groupId = nodeToGroupIdList[msg.sender][HEAD_I]; + if (groupId != 0 && groupId != HEAD_I) { + Group storage grp = workingGroups[groupId]; + for (uint i = 0; i < grp.members.length; i++) { + address member = grp.members[i]; + if (member == msg.sender) { + nodeToGroupIdList[msg.sender][HEAD_I] =0; + if (i != (grp.members.length - 1)){ + grp.members[i] = grp.members[grp.members.length - 1]; + } + grp.members.length--; + if (grp.members.length < (groupSize / 2 + 1 )){ + dissolveWorkingGroup(groupId, true); + for (uint idx = 0; idx < workingGroupIds.length; idx++) { + if (workingGroupIds[idx] == groupId) { + if (idx != (workingGroupIds.length - 1)){ + workingGroupIds[idx] = workingGroupIds[workingGroupIds.length - 1]; + } + workingGroupIds.length--; + emit LogUnRegisteredNewPendingNode(msg.sender,2); + return; + } + } + for (uint idx = 0; idx < expiredWorkingGroupIds.length; idx++) { + if (expiredWorkingGroupIds[idx] == groupId) { + if (idx != (workingGroupIds.length - 1)){ + expiredWorkingGroupIds[idx] = expiredWorkingGroupIds[expiredWorkingGroupIds.length - 1]; + } + expiredWorkingGroupIds.length--; + emit LogUnRegisteredNewPendingNode(msg.sender,2); + return; + } + } + } + emit LogUnRegisteredNewPendingNode(msg.sender,2); + return; + } + } + return; + } + //3) Check if node is in pendingGroups + bool removed = removeNodeFromPendingGroup(pendingGroupList,msg.sender); + if (removed) { + emit LogUnRegisteredNewPendingNode(msg.sender,3); + } + } + + // Caller ensures no index overflow. + function getGroupPubKey(uint idx) public view returns (uint[4] memory) { + BN256.G2Point storage pubKey = workingGroups[workingGroupIds[idx]].groupPubKey; + return [pubKey.x[0], pubKey.x[1], pubKey.y[0], pubKey.y[1]]; + } + + function getWorkingGroupSize() public view returns (uint) { + return workingGroupIds.length; + } + + function getExpiredWorkingGroupSize() public view returns (uint) { + return expiredWorkingGroupIds.length; + } + + function registerNewNode() public fromValidStakingNode { + //Duplicated pending node + if (pendingNodeList[msg.sender] != address(0)) { + return; + } + //Already registered in pending or working groups + if (nodeToGroupIdList[msg.sender][HEAD_I] != 0) { + return; + } + nodeToGroupIdList[msg.sender][HEAD_I] = HEAD_I; + insertToPendingNodeListTail(msg.sender); + emit LogRegisteredNewPendingNode(msg.sender); + + formGroup(); + } + + // Form into new working groups or bootstrap if necessary. + // Return true if triggers state change. + function formGroup() private returns(bool) { + if (numPendingNodes < groupSize * groupingThreshold / 100) { + emit LogInsufficientPendingNode(numPendingNodes); + return false; + } + + if (workingGroupIds.length >= groupToPick) { + requestRandom(address(this), 1, block.number); + emit LogGroupingInitiated(numPendingNodes, groupSize, groupingThreshold); + return true; + } else if (workingGroupIds.length + numPendingGroups >= groupToPick) { + emit LogInsufficientWorkingGroup(workingGroupIds.length, numPendingGroups); + return false; + } else if (numPendingNodes < bootstrapStartThreshold) { + emit LogError("Skipped signal, no enough nodes or groups in the network"); + return false; + } else { + // System needs re-bootstrap + if (bootstrapRound == 0) { + bootstrapRound = 1; + return true; + } else { + emit LogError("Skipped group formation, already in bootstrap phase"); + return false; + } + } + } + + // callback to handle re-grouping using generated random number as random seed. + function __callback__(uint requestId, uint rndSeed) external { + require(msg.sender == address(this), "Unauthenticated response"); + require(workingGroupIds.length >= groupToPick, + "No enough working group"); + require(numPendingNodes >= groupSize * groupingThreshold / 100, + "Not enough newly registered nodes"); + + uint arrSize = groupSize * (groupToPick + 1); + address[] memory candidates = new address[](arrSize); + for (uint i = 0; i < groupToPick; i++) { + uint idx = uint(keccak256(abi.encodePacked(rndSeed, requestId, i))) % workingGroupIds.length; + Group storage grpToDissolve = workingGroups[workingGroupIds[idx]]; + for (uint j = 0; j < groupSize; j++) { + candidates[i * groupSize + j] = grpToDissolve.members[j]; + } + // Do not put chosen to-be-dissolved working group back to pending pool. + dissolveWorkingGroup(grpToDissolve.groupId, false); + workingGroupIds[idx] = workingGroupIds[workingGroupIds.length - 1]; + workingGroupIds.length--; + } + + pick(groupSize, groupSize * groupToPick, candidates); + shuffle(candidates, rndSeed); + regroup(candidates, groupToPick + 1); + } + + // Pick @num nodes from pendingNodeList's head and put into the @candidates array from @startIndex. + function pick(uint num, uint startIndex, address[] memory candidates) private { + for (uint i = 0; i < num; i++) { + address curr = pendingNodeList[HEAD_A]; + pendingNodeList[HEAD_A] = pendingNodeList[curr]; + delete pendingNodeList[curr]; + candidates[startIndex + i] = curr; + } + numPendingNodes -= num; + // Reset pendingNodeTail if necessary. + if (numPendingNodes == 0) { + pendingNodeTail = HEAD_A; + } + } + + // Shuffle a memory array using a secure random seed. + function shuffle(address[] memory arr, uint rndSeed) private pure { + for (uint i = arr.length - 1; i > 0; i--) { + uint j = uint(keccak256(abi.encodePacked(rndSeed, i, arr[i]))) % (i + 1); + address tmp = arr[i]; + arr[i] = arr[j]; + arr[j] = tmp; + } + } + + // Regroup a shuffled node array. + function regroup(address[] memory candidates, uint num) private { + require(candidates.length == groupSize * num); + + address[] memory members = new address[](groupSize); + uint groupId; + for (uint i = 0; i < num; i++) { + groupId = 0; + // Generated groupId = sha3(...(sha3(sha3(member 1), member 2), ...), member n) + for (uint j = 0; j < groupSize; j++) { + members[j] = candidates[i * groupSize + j]; + groupId = uint(keccak256(abi.encodePacked(groupId, members[j]))); + } + pendingGroups[groupId] = PendingGroup(groupId, block.number); + mapping(address => address) storage memberList = pendingGroups[groupId].memberList; + memberList[HEAD_A] = HEAD_A; + for (uint j = 0; j < groupSize; j++) { + memberList[members[j]] = memberList[HEAD_A]; + memberList[HEAD_A] = members[j]; + } + insertToPendingGroupListTail(groupId); + emit LogGrouping(groupId, members); + } + } + + function registerGroupPubKey(uint groupId, uint[4] calldata suggestedPubKey) + external + fromValidStakingNode + { + PendingGroup storage pgrp = pendingGroups[groupId]; + if (pgrp.groupId == 0) { + emit LogNoPendingGroup(groupId); + return; + } + + require(pgrp.memberList[msg.sender] != address(0), "Not from authorized group member"); + + bytes32 hashedPubKey = keccak256(abi.encodePacked( + suggestedPubKey[0], suggestedPubKey[1], suggestedPubKey[2], suggestedPubKey[3])); + pgrp.pubKeyCounts[hashedPubKey]++; + emit LogPublicKeySuggested(groupId, pgrp.pubKeyCounts[hashedPubKey]); + if (pgrp.pubKeyCounts[hashedPubKey] > groupSize / 2) { + address[] memory memberArray = new address[](groupSize); + uint idx = 0; + address member = pgrp.memberList[HEAD_A]; + while (member != HEAD_A) { + memberArray[idx++] = member; + // Update nodeToGroupIdList[member] with new group id. + insertToListHead(nodeToGroupIdList[member], groupId); + member = pgrp.memberList[member]; + } + + workingGroupIds.push(groupId); + workingGroups[groupId] = Group( + groupId, + BN256.G2Point([suggestedPubKey[0], suggestedPubKey[1]], [suggestedPubKey[2], suggestedPubKey[3]]), + block.number, + memberArray + ); + + // Update pendingGroupList + (uint prev, bool removed) = removeIdFromList(pendingGroupList, groupId); + // Reset pendingGroupTail if necessary. + if (removed && pendingGroupTail == groupId) { + pendingGroupTail = prev; + } + // Update pendingGroup + delete pendingGroups[groupId]; + numPendingGroups--; + emit LogPendingGroupRemoved(groupId); + emit LogPublicKeyAccepted(groupId, suggestedPubKey, workingGroupIds.length); + } + } +} diff --git a/contracts/mocks/UtilsMock.sol b/contracts/mocks/StringUtilsMock.sol similarity index 63% rename from contracts/mocks/UtilsMock.sol rename to contracts/mocks/StringUtilsMock.sol index c26a79d..c7e4fbc 100644 --- a/contracts/mocks/UtilsMock.sol +++ b/contracts/mocks/StringUtilsMock.sol @@ -1,7 +1,8 @@ -pragma solidity >= 0.4.24; -import "../lib/utils.sol"; +pragma solidity ^0.5.0; -contract UtilsMock { +import "../lib/StringUtils.sol"; + +contract StringUtilsMock { function returnUINT256MAX() public pure returns(uint) { return ~uint(0); } @@ -11,63 +12,63 @@ contract UtilsMock { } function byte2Uint(byte b) public pure returns(uint8) { - return utils.byte2Uint(b); + return StringUtils.byte2Uint(b); } function hexByte2Uint(byte b) public pure returns(uint8) { - return utils.hexByte2Uint(b); + return StringUtils.hexByte2Uint(b); } function str2Uint(string memory a) public pure returns(uint) { - return utils.str2Uint(a); + return StringUtils.str2Uint(a); } function hexStr2Uint(string memory a) public pure returns(uint) { - return utils.hexStr2Uint(a); + return StringUtils.hexStr2Uint(a); } function str2Addr(string memory a) public pure returns(address) { - return utils.str2Addr(a); + return StringUtils.str2Addr(a); } function uint2HexStr(uint x) public pure returns(string memory) { - return utils.uint2HexStr(x); + return StringUtils.uint2HexStr(x); } function uint2Str(uint x) public pure returns(string memory) { - return utils.uint2Str(x); + return StringUtils.uint2Str(x); } function addr2Str(string memory a) public pure returns(string memory) { - address x = utils.str2Addr(a); - return utils.addr2Str(x); + address x = StringUtils.str2Addr(a); + return StringUtils.addr2Str(x); } function bytesConcat(bytes memory a, bytes memory b) public pure returns(bytes memory) { - return utils.bytesConcat(a,b); + return StringUtils.bytesConcat(a,b); } function strConcat(string memory a, string memory b) public pure returns(string memory) { - return utils.strConcat(a,b); + return StringUtils.strConcat(a,b); } function strCompare(string memory a, string memory b) public pure returns(int) { - return utils.strCompare(a, b); + return StringUtils.strCompare(a, b); } function strEqual(string memory a, string memory b) public pure returns(bool) { - return utils.strEqual(a, b); + return StringUtils.strEqual(a, b); } - function indexOf(string memory haystack, string memory needle) public pure returns(int) { - return utils.indexOf(haystack, needle); + function indexOf(string memory haystack, string memory needle) public pure returns(uint) { + return StringUtils.indexOf(haystack, needle); } function subStr(string memory a, uint start, uint len) public pure returns(string memory) { - return utils.subStr(a, start, len); + return StringUtils.subStr(a, start, len); } function subStr1(string memory a, uint start) public pure returns(string memory) { - return utils.subStr(a, start); + return StringUtils.subStr(a, start); } -} \ No newline at end of file +} diff --git a/deployed.json b/deployed.json new file mode 100644 index 0000000..09c4df8 --- /dev/null +++ b/deployed.json @@ -0,0 +1,106 @@ +{ + "mainnet":{ + "DOSToken":"0x0A913beaD80F321E7Ac35285Ee10d9d922659cB7", + "DBToken":"0x9456d6a22c8bdFF613366d51e3d60402cB8cFd8F", + "DOSAddressBridge":"0x98a0e7026778840aacd28b9c03137d32e06f5ff1", + "Commit Reveal":"0x144ed0555269628049f76da2adbdcdf3aa488e0e", + "DOSProxy":"0x557B3CE8891D4ef5D6ad2A66445993a035FEdb5c", + "DOSPayment Gateway":"0x7B8D5a37008382B2C7e8e15EcF3C2727e38A6aC6", + "DOSPayment Implementation":"0x24286C5a340bF99EDB2d7e7D114477987d34816F", + "Staking Gateway":"0x5DBeF8E9e83A17D4D1D4c65a1E26133EDAE851Dc", + "Staking Implementation":"0x6a829E0EB032FA39D0444D29DFd80Bd3AE91C5B9" + }, + "rinkeby":{ + "DOSToken":"0x214e79c85744cd2ebbc64ddc0047131496871bee", + "DBToken":"0x9bfe8f5749d90eb4049ad94cc4de9b6c4c31f822", + "DOSAddressBridge":"0xeE2e9f35c9F91571535173902E7e7B4E67deE32b", + "Commit Reveal":"0x044D8D7028eC8Fc98247d072603F5316656EcfDe", + "DOSProxy":"0xAb09D3A9998c918Ffa796F6449D8515e5C7DB8a2", + "DOSPayment Gateway":"0x306d78A9Cf1116513220C908C5D950914D797682", + "DOSPayment Implementation":"0x6b89f9C6bD11B14ae17DAfba4C578DdA527E7EF3", + "Staking Gateway":"0x064fa6a739580a9bA8cfeFDc271fa5585BC274e3", + "Staking Implementation":"0x9FAAebE59eaf3132c3cf42a947bAb11408D12296" + }, + "hecoTestnet":{ + "DOSToken":"0x3bca354b33e0a0ca6487fb51d1150f6e9c0e0e5e", + "DBToken":"0x84c6be700f2db040ed1455ac980538003cda90dd", + "DOSAddressBridge":"0x797D0f474dDcAa8F4066A263684B540C074801b3", + "Commit Reveal":"0x9DC5A7FE9cE5136Cfd2c4B2FfCAe38c7d2b1819A", + "DOSProxy":"0x56e315c15506d4fdfc4bfcd895802c35f9dfd903", + "DOSPayment Gateway":"0x4eCECeCDCFC068643252b46F86bA1Dc30dccB1dD", + "DOSPayment Implementation":"0x7e6a95eb1d5f2f9c89b3e6eb78afd08770cc18d8", + "Staking Gateway":"0xFd9B8A33756A9De4E2bBd9cc066dB912bb5c5499", + "Staking Implementation":"0xAA06934e959efa9F8E41B8c6D3CA49a8Da0Ca37e", + "CoingeckoParserV2" : "0xBF8295AF9c26618Fb48c4fEF38571268413147F0", + "CoingeckoMegaStream": "0x8d2cf53d3c9635DC0f73B4Ca4cbf3191DBeC29b8", + "CoingeckoStreamsManager": "0x51D657f6000190Ba785e30344E9987028c1CF025", + "CoingeckoBTCUSDStream" : "0x2022737ddC95b15d55E452C9E8418899063fc196", + "CoingeckoETHUSDStream" : "0x9E39eF90EfE2eF833a9bB1F149be17477cdFA4d0", + "CoingeckoDOTUSDStream" : "0x4bBe16963C98553416114846e77696680F7cB812", + "CoingeckoHTUSDStream" : "0x438A5CC6A2b5E14A81e196fa32356a3705db10Fa", + "CoingeckoDOSUSDStream" : "0xfBc42FA54b3dc107f76978436b46542E3876229F" + }, + "heco":{ + "DOSToken":"0xF50821F0A136A4514D476dC4Cc2a731e7728aFaF", + "DBToken":"0x1B7BEaa5107Ac5Fb2E8ADCAE2B64B0Ba1997EFd9", + "DOSAddressBridge":"0x9Ee7F642d3955ecf17D7223705DCb285dbA679fc", + "Commit Reveal":"0x2a15a2Bc8F0bEc8316977178A72DFDB533565b74", + "DOSProxy":"0x142fE126773Df5dE10148028D516A9DA8a1d71AD", + "DOSPayment Gateway":"0xC3ffA80C80AcdA7a12F452df5dcd3afaf5Ebeed8", + "DOSPayment Implementation":"0xCfE9F9230796ed9532FA790EF70d845585bc8caf", + "Staking Gateway":"0xc1Ce1C11b485c7E227Cb066C75B6280533194Ad2", + "Staking Implementation":"0xA3F8Cf8F4bEE4b0CD983653201300C8A29336720", + "CoingeckoParserV2": "0xE1Ff4ebc4ECa883Bb615a8986aB0543E475E70e1", + "CoingeckoMegaStream": "0xF0236DfB582B43fF2db7f390A6829cF22ABf9bB9", + "CoingeckoStreamsManager": "0xc02DDAeb7644b9D2d92b96371f79A92FB6d306fe", + "CoingeckoBTCUSDStream" : "0xEE12758Ea54F0Afa4268cc1Fc5BB70b53E24E8A5", + "CoingeckoETHUSDStream" : "0x7ceDd198017b030F9009D800fa8e3DfEB48e098f", + "CoingeckoDOTUSDStream" : "0xB01c89Effe80c29782d50CBE09160F20BA9Bc4F7", + "CoingeckoHTUSDStream" : "0xB6D103f142A3f493f1d00478F64159591d82c92a", + "CoingeckoDOSUSDStream" : "0xdB2831118407367d9116E509bC7AeED325c21B59", + "CoingeckoFILUSDStream" : "0x0bC3E19138F8B0CaB31F369565e4fd5A90bD79f8", + "CoingeckoHPTUSDStream" : "0x27CF3f3C05188Fb61696d0a6Aad1a1013126cA89" + }, + "okchainTest":{ + "DOSToken":"0x51147d0bc5be0a9d487a412e59ece23bb699461a", + "DBToken":"0x7c013b34d07ab263233372a2f385460fdedd902a", + "DOSAddressBridge":"0xD1aFEa6D7745c9d168A77Abd80124A0592B0D48e", + "Commit Reveal":"0x6510aA8EF75e409f8139084B5ec1D0Ef39759A91", + "DOSProxy":"0x365b9F766a54d161f260bB806e6E97043Ee8668c", + "DOSPayment Gateway":"0x7e6A95EB1D5F2f9c89B3E6eb78AFD08770cc18D8", + "DOSPayment Implementation":"0x6863D706861d7ce7ADB1e1AD5AB54E1784bB670d", + "Staking Gateway":"0xAA06934e959efa9F8E41B8c6D3CA49a8Da0Ca37e", + "Staking Implementation":"0x9aEB6F0BD24962C44FdAD317DF9f5C6FD0d46C9E" + }, + "bscTestnet":{ + "DOSToken":"0x4eCECeCDCFC068643252b46F86bA1Dc30dccB1dD", + "DBToken":"0xCEF1EE1049903B727cc60d6990cd48567AA7D983", + "DOSAddressBridge":"0xb20BE4f55Aca452a60b8812F051c39C302161BE7", + "Commit Reveal":"0x686a79ff2054A5Edc632295A7278980138E6a134", + "DOSProxy":"0x1A4936Ee97EaBc4E7B18201AAeF2971f77ab4617", + "DOSPayment Gateway":"0x9B21770b41DD007f1C5131380286a6364D685912", + "DOSPayment Implementation":"0x1fC4553CebE6841BFe63dB00382E3822Cd6AEf4a", + "Staking Gateway":"0xC706701Fbd0eaFeBFD279d2bF4be61EACbeFfF8e", + "Staking Implementation":"0xCd79875835039Fd4367d6807994af6Bc95681984", + "CoingeckoParserV2": "0x47011aD8d19e445e82D2B2a42604C3eaAC1D262D", + "CoingeckoMegaStream": "0xB65eAd4D23E4A7a407FACf02Aed3EB5A94b0A774", + "CoingeckoStreamsManager": "0x7a61d1Ab09B69C61B25d8D113a963453A0f996D2", + "CoingeckoBTCUSDStream" : "0x2086eB68cE992c8A53EB0bBe28E2C0E4A7D254B9", + "CoingeckoETHUSDStream" : "0x1CA4AF463713974123093f593D5c0CC1668933E0", + "CoingeckoBNBUSDStream" : "0xF4D5436175c5d81174395c4158981bCdb22e3055", + "CoingeckoDOTUSDStream" : "0x7D433CB0ceF7f99F3051a99A2a2Be6A3D183Dd4F", + "CoingeckoDOSUSDStream" : "0x1eE4Ba6e48E2adf834F41a8Fe51455D6A05B013f", + "CoingeckoFILUSDStream" : "0x23464572923B24Ee8CEd6a304bb28D10a2e3919f" + }, + "bsc":{ + "DOSToken":"0xDc0f0a5719c39764b011eDd02811BD228296887C", + "DBToken":"0x4250A5022C4372e3f16cfa47Ac6449C48eC719b6", + "DOSAddressBridge":"0x70157cf10404170EEc183043354D0a886Fa51d73", + "Commit Reveal":"0xD5135970D1663FfD3cf96b69Dc390C10680768b1", + "DOSProxy":"0x940EA430fE756d309B776349CB68EA6028B613d1", + "DOSPayment Gateway":"0x27A09BA4c194C39A3898775BDEF15F444801F048", + "DOSPayment Implementation":"0x98A0E7026778840Aacd28B9c03137D32e06F5ff1", + "Staking Gateway":"0x8Aa8c0d911cf703C516210994De77812024497B6", + "Staking Implementation":"0x4dd79f907f4D5d8952FEf1eFA0B5d0467c612Cb3" + } +} diff --git a/migrations/2_deploy_dos_contracts.js b/migrations/2_deploy_dos_contracts.js index 064a6ec..dcb0ac1 100644 --- a/migrations/2_deploy_dos_contracts.js +++ b/migrations/2_deploy_dos_contracts.js @@ -1,11 +1,107 @@ -var DOSAddressBridge = artifacts.require("./DOSAddressBridge.sol"); -var DOSOnChainSDK = artifacts.require("./DOSOnChainSDK.sol"); -var DOSProxy = artifacts.require("./DOSProxy.sol"); - -module.exports = function(deployer, network) { - if (network === "development") { - deployer.deploy(DOSAddressBridge); - deployer.deploy(DOSOnChainSDK); - deployer.deploy(DOSProxy); - } +const DOSAddressBridge = artifacts.require("./DOSAddressBridge.sol"); +const CommitReveal = artifacts.require("./CommitReveal.sol"); +const DOSProxy = artifacts.require("./DOSProxy.sol"); +const DOSPayment = artifacts.require("./DOSPayment.sol"); +const Staking = artifacts.require("./Staking.sol"); +const ContractGateway = artifacts.require("./ContractGateway.sol"); + +const configs = { + rinkeby: { + DOSToken: '0x214e79c85744cd2ebbc64ddc0047131496871bee', + DBToken: '0x9bfe8f5749d90eb4049ad94cc4de9b6c4c31f822', + RewardsVault: '0xE222f441cb42bCFE8E46Fdecad0e633C70246BD3', + GatewayAdmin: '0xebef930796883E0A1D2f8964AEd7a59FE64e68E6', + BootstrapList: 'https://dashboard.dos.network/api/bootStrapRinkeby', + }, + mainnet: { + DOSToken: '0x0A913beaD80F321E7Ac35285Ee10d9d922659cB7', + DBToken: '0x9456d6a22c8bdFF613366d51e3d60402cB8cFd8F', + RewardsVault: '0x76cEc0b88FD0F109C04F0475EBdF1648DF1c60B4', + GatewayAdmin: '0x250f871e3ccafde7b5053f321241fd8bb67a54f8', + BootstrapList: 'https://dashboard.dos.network/api/bootStrap', + }, + hecoTestnet: { + DOSToken: '0x3bca354b33e0a0ca6487fb51d1150f6e9c0e0e5e', + DBToken: '0x84c6be700f2db040ed1455ac980538003cda90dd', + RewardsVault: '0xE222f441cb42bCFE8E46Fdecad0e633C70246BD3', + GatewayAdmin: '0xebef930796883E0A1D2f8964AEd7a59FE64e68E6', + BootstrapList: 'https://dashboard.dos.network/api/bootStrapHeco', + }, + heco: { + DOSToken: '0xF50821F0A136A4514D476dC4Cc2a731e7728aFaF', + DBToken: '0x1B7BEaa5107Ac5Fb2E8ADCAE2B64B0Ba1997EFd9', + RewardsVault: '0xC25079a8A14FCA9a588616ebACD7b68745a3f709', + GatewayAdmin: '0x78DBae2489CD0E961893788272AF2C85Fc03d418', + BootstrapList: 'https://dashboard.dos.network/api/bootStrapHeco', + }, + okchainTest: { + DOSToken: '0x51147d0bc5be0a9d487a412e59ece23bb699461a', + DBToken: '0x7c013b34d07ab263233372a2f385460fdedd902a', + RewardsVault: '0xE222f441cb42bCFE8E46Fdecad0e633C70246BD3', + GatewayAdmin: '0xebef930796883E0A1D2f8964AEd7a59FE64e68E6', + BootstrapList: 'https://dashboard.dos.network/api/bootStrapOkchain', + }, + bscTestnet: { + DOSToken: '0x4eCECeCDCFC068643252b46F86bA1Dc30dccB1dD', + DBToken: '0xCEF1EE1049903B727cc60d6990cd48567AA7D983', + RewardsVault: '0xE222f441cb42bCFE8E46Fdecad0e633C70246BD3', + GatewayAdmin: '0xebef930796883E0A1D2f8964AEd7a59FE64e68E6', + BootstrapList: 'https://dashboard.dos.network/api/bootStrapBSC', + }, + bsc: { + DOSToken: '0xDc0f0a5719c39764b011eDd02811BD228296887C', + DBToken: '0x4250A5022C4372e3f16cfa47Ac6449C48eC719b6', + RewardsVault: '0x76cEc0b88FD0F109C04F0475EBdF1648DF1c60B4', + GatewayAdmin: '0x250f871e3ccafde7b5053f321241fd8bb67a54f8', + BootstrapList: 'https://dashboard.dos.network/api/bootStrapBSC', + }, +} + +module.exports = function(deployer, network, accounts) { + deployer.then(async () => { + await deployer.deploy(DOSAddressBridge); + let bridgeInstance = await DOSAddressBridge.deployed(); + + if (network === 'rinkeby' || network === 'live' || network === 'hecoTestnet' || + network === 'heco' || network === 'okchainTest' || network === 'bscTestnet' || network === 'bsc') { + await bridgeInstance.setBootStrapUrl(configs[network].BootstrapList); + // Deploying CommitReveal contracts. + await deployer.deploy(CommitReveal, DOSAddressBridge.address); + await bridgeInstance.setCommitRevealAddress(CommitReveal.address); + + + // Deploying DOSPayment implementation & proxy contracts. + await deployer.deploy(DOSPayment, DOSAddressBridge.address, configs[network].RewardsVault, configs[network].DOSToken); + await deployer.deploy(ContractGateway, DOSPayment.address); + await bridgeInstance.setPaymentAddress(ContractGateway.address); + let PaymentGateway = await ContractGateway.deployed(); + await PaymentGateway.changeAdmin(configs[network].GatewayAdmin); + // Pretend the proxy address is a Payment impl. This is ok as proxy will forward + // all the calls to the Payment impl. + PaymentGateway = await DOSPayment.at(ContractGateway.address); + await PaymentGateway.initialize(DOSAddressBridge.address, configs[network].RewardsVault, configs[network].DOSToken); + + + // Note: guardianFundsAddr to call approve(PaymentGateway.address) as part of initialization. + + // Deploying DOSProxy contract. + await deployer.deploy(DOSProxy, DOSAddressBridge.address, configs[network].RewardsVault, configs[network].DOSToken); + await bridgeInstance.setProxyAddress(DOSProxy.address); + + + // Deploying Staking implementation & proxy contracts. + await deployer.deploy(Staking, configs[network].DOSToken, configs[network].DBToken, configs[network].RewardsVault, DOSAddressBridge.address); + await deployer.deploy(ContractGateway, Staking.address); + await bridgeInstance.setStakingAddress(ContractGateway.address); + let StakingGateway = await ContractGateway.deployed(); + await StakingGateway.changeAdmin(configs[network].GatewayAdmin); + // Pretend the proxy address is a Staking impl. This is ok as proxy will forward + // all the calls to the Staking impl. + StakingGateway = await Staking.at(ContractGateway.address); + await StakingGateway.initialize(configs[network].DOSToken, configs[network].DBToken, configs[network].RewardsVault, DOSAddressBridge.address); + + + // Note: stakingRewardsValut to call approve(StakingGateway.address) as part of initialization. + } + }); } diff --git a/package-lock.json b/package-lock.json deleted file mode 100644 index 72bd788..0000000 --- a/package-lock.json +++ /dev/null @@ -1,11577 +0,0 @@ -{ - "name": "contracts", - "version": "1.0.0", - "lockfileVersion": 1, - "requires": true, - "dependencies": { - "abstract-leveldown": { - "version": "2.6.3", - "resolved": "https://registry.npmjs.org/abstract-leveldown/-/abstract-leveldown-2.6.3.tgz", - "integrity": "sha512-2++wDf/DYqkPR3o5tbfdhF96EfMApo1GpPfzOsR/ZYXdkSmELlvOOEAl9iKkRsktMPHdGjO4rtkBpf2I7TiTeA==", - "requires": { - "xtend": "~4.0.0" - } - }, - "aes-js": { - "version": "0.2.4", - "resolved": "http://registry.npmjs.org/aes-js/-/aes-js-0.2.4.tgz", - "integrity": "sha1-lLiBq3FyhtAV+iGeCPtmcJ3aWj0=" - }, - "ajv": { - "version": "6.6.2", - "resolved": "https://registry.npmjs.org/ajv/-/ajv-6.6.2.tgz", - "integrity": "sha512-FBHEW6Jf5TB9MGBgUUA9XHkTbjXYfAUjY43ACMfmdMRHniyoMHjHjzD50OK8LGDWQwp4rWEsIq5kEqq7rvIM1g==", - "requires": { - "fast-deep-equal": "^2.0.1", - "fast-json-stable-stringify": "^2.0.0", - "json-schema-traverse": "^0.4.1", - "uri-js": "^4.2.2" - } - }, - "ansi-regex": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-2.1.1.tgz", - "integrity": "sha1-w7M6te42DYbg5ijwRorn7yfWVN8=" - }, - "ansi-styles": { - "version": "2.2.1", - "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-2.2.1.tgz", - "integrity": "sha1-tDLdM1i2NM914eRmQ2gkBTPB3b4=" - }, - "asn1": { - "version": "0.2.4", - "resolved": "https://registry.npmjs.org/asn1/-/asn1-0.2.4.tgz", - "integrity": "sha512-jxwzQpLQjSmWXgwaCZE9Nz+glAG01yF1QnWgbhGwHI5A6FRIEY6IVqtHhIepHqI7/kyEyQEagBC5mBEFlIYvdg==", - "requires": { - "safer-buffer": "~2.1.0" - } - }, - "assert-plus": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/assert-plus/-/assert-plus-1.0.0.tgz", - "integrity": "sha1-8S4PPF13sLHN2RRpQuTpbB5N1SU=" - }, - "async": { - "version": "2.6.1", - "resolved": "https://registry.npmjs.org/async/-/async-2.6.1.tgz", - "integrity": "sha512-fNEiL2+AZt6AlAw/29Cr0UDe4sRAHCpEHh54WMz+Bb7QfNcFw4h3loofyJpLeQs4Yx7yuqu/2dLgM5hKOs6HlQ==", - "requires": { - "lodash": "^4.17.10" - } - }, - "async-eventemitter": { - "version": "0.2.4", - "resolved": "https://registry.npmjs.org/async-eventemitter/-/async-eventemitter-0.2.4.tgz", - "integrity": "sha512-pd20BwL7Yt1zwDFy+8MX8F1+WCT8aQeKj0kQnTrH9WaeRETlRamVhD0JtRPmrV4GfOJ2F9CvdQkZeZhnh2TuHw==", - "requires": { - "async": "^2.4.0" - } - }, - "async-limiter": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/async-limiter/-/async-limiter-1.0.0.tgz", - "integrity": "sha512-jp/uFnooOiO+L211eZOoSyzpOITMXx1rBITauYykG3BRYPu8h0UcxsPNB04RR5vo4Tyz3+ay17tR6JVf9qzYWg==" - }, - "asynckit": { - "version": "0.4.0", - "resolved": "https://registry.npmjs.org/asynckit/-/asynckit-0.4.0.tgz", - "integrity": "sha1-x57Zf380y48robyXkLzDZkdLS3k=" - }, - "aws-sign2": { - "version": "0.7.0", - "resolved": "https://registry.npmjs.org/aws-sign2/-/aws-sign2-0.7.0.tgz", - "integrity": "sha1-tG6JCTSpWR8tL2+G1+ap8bP+dqg=" - }, - "aws4": { - "version": "1.8.0", - "resolved": "https://registry.npmjs.org/aws4/-/aws4-1.8.0.tgz", - "integrity": "sha512-ReZxvNHIOv88FlT7rxcXIIC0fPt4KZqZbOlivyWtXLt8ESx84zd3kMC6iK5jVeS2qt+g7ftS7ye4fi06X5rtRQ==" - }, - "babel-code-frame": { - "version": "6.26.0", - "resolved": "https://registry.npmjs.org/babel-code-frame/-/babel-code-frame-6.26.0.tgz", - "integrity": "sha1-Y/1D99weO7fONZR9uP42mj9Yx0s=", - "requires": { - "chalk": "^1.1.3", - "esutils": "^2.0.2", - "js-tokens": "^3.0.2" - } - }, - "babel-core": { - "version": "6.26.3", - "resolved": "https://registry.npmjs.org/babel-core/-/babel-core-6.26.3.tgz", - "integrity": "sha512-6jyFLuDmeidKmUEb3NM+/yawG0M2bDZ9Z1qbZP59cyHLz8kYGKYwpJP0UwUKKUiTRNvxfLesJnTedqczP7cTDA==", - "requires": { - "babel-code-frame": "^6.26.0", - "babel-generator": "^6.26.0", - "babel-helpers": "^6.24.1", - "babel-messages": "^6.23.0", - "babel-register": "^6.26.0", - "babel-runtime": "^6.26.0", - "babel-template": "^6.26.0", - "babel-traverse": "^6.26.0", - "babel-types": "^6.26.0", - "babylon": "^6.18.0", - "convert-source-map": "^1.5.1", - "debug": "^2.6.9", - "json5": "^0.5.1", - "lodash": "^4.17.4", - "minimatch": "^3.0.4", - "path-is-absolute": "^1.0.1", - "private": "^0.1.8", - "slash": "^1.0.0", - "source-map": "^0.5.7" - } - }, - "babel-generator": { - "version": "6.26.1", - "resolved": "https://registry.npmjs.org/babel-generator/-/babel-generator-6.26.1.tgz", - "integrity": "sha512-HyfwY6ApZj7BYTcJURpM5tznulaBvyio7/0d4zFOeMPUmfxkCjHocCuoLa2SAGzBI8AREcH3eP3758F672DppA==", - "requires": { - "babel-messages": "^6.23.0", - "babel-runtime": "^6.26.0", - "babel-types": "^6.26.0", - "detect-indent": "^4.0.0", - "jsesc": "^1.3.0", - "lodash": "^4.17.4", - "source-map": "^0.5.7", - "trim-right": "^1.0.1" - }, - "dependencies": { - "jsesc": { - "version": "1.3.0", - "resolved": "http://registry.npmjs.org/jsesc/-/jsesc-1.3.0.tgz", - "integrity": "sha1-RsP+yMGJKxKwgz25vHYiF226s0s=" - } - } - }, - "babel-helper-builder-binary-assignment-operator-visitor": { - "version": "6.24.1", - "resolved": "https://registry.npmjs.org/babel-helper-builder-binary-assignment-operator-visitor/-/babel-helper-builder-binary-assignment-operator-visitor-6.24.1.tgz", - "integrity": "sha1-zORReto1b0IgvK6KAsKzRvmlZmQ=", - "requires": { - "babel-helper-explode-assignable-expression": "^6.24.1", - "babel-runtime": "^6.22.0", - "babel-types": "^6.24.1" - } - }, - "babel-helper-call-delegate": { - "version": "6.24.1", - "resolved": "https://registry.npmjs.org/babel-helper-call-delegate/-/babel-helper-call-delegate-6.24.1.tgz", - "integrity": "sha1-7Oaqzdx25Bw0YfiL/Fdb0Nqi340=", - "requires": { - "babel-helper-hoist-variables": "^6.24.1", - "babel-runtime": "^6.22.0", - "babel-traverse": "^6.24.1", - "babel-types": "^6.24.1" - } - }, - "babel-helper-define-map": { - "version": "6.26.0", - "resolved": "https://registry.npmjs.org/babel-helper-define-map/-/babel-helper-define-map-6.26.0.tgz", - "integrity": "sha1-pfVtq0GiX5fstJjH66ypgZ+Vvl8=", - "requires": { - "babel-helper-function-name": "^6.24.1", - "babel-runtime": "^6.26.0", - "babel-types": "^6.26.0", - "lodash": "^4.17.4" - } - }, - "babel-helper-explode-assignable-expression": { - "version": "6.24.1", - "resolved": "https://registry.npmjs.org/babel-helper-explode-assignable-expression/-/babel-helper-explode-assignable-expression-6.24.1.tgz", - "integrity": "sha1-8luCz33BBDPFX3BZLVdGQArCLKo=", - "requires": { - "babel-runtime": "^6.22.0", - "babel-traverse": "^6.24.1", - "babel-types": "^6.24.1" - } - }, - "babel-helper-function-name": { - "version": "6.24.1", - "resolved": "https://registry.npmjs.org/babel-helper-function-name/-/babel-helper-function-name-6.24.1.tgz", - "integrity": "sha1-00dbjAPtmCQqJbSDUasYOZ01gKk=", - "requires": { - "babel-helper-get-function-arity": "^6.24.1", - "babel-runtime": "^6.22.0", - "babel-template": "^6.24.1", - "babel-traverse": "^6.24.1", - "babel-types": "^6.24.1" - } - }, - "babel-helper-get-function-arity": { - "version": "6.24.1", - "resolved": "https://registry.npmjs.org/babel-helper-get-function-arity/-/babel-helper-get-function-arity-6.24.1.tgz", - "integrity": "sha1-j3eCqpNAfEHTqlCQj4mwMbG2hT0=", - "requires": { - "babel-runtime": "^6.22.0", - "babel-types": "^6.24.1" - } - }, - "babel-helper-hoist-variables": { - "version": "6.24.1", - "resolved": "https://registry.npmjs.org/babel-helper-hoist-variables/-/babel-helper-hoist-variables-6.24.1.tgz", - "integrity": "sha1-HssnaJydJVE+rbyZFKc/VAi+enY=", - "requires": { - "babel-runtime": "^6.22.0", - "babel-types": "^6.24.1" - } - }, - "babel-helper-optimise-call-expression": { - "version": "6.24.1", - "resolved": "https://registry.npmjs.org/babel-helper-optimise-call-expression/-/babel-helper-optimise-call-expression-6.24.1.tgz", - "integrity": "sha1-96E0J7qfc/j0+pk8VKl4gtEkQlc=", - "requires": { - "babel-runtime": "^6.22.0", - "babel-types": "^6.24.1" - } - }, - "babel-helper-regex": { - "version": "6.26.0", - "resolved": "https://registry.npmjs.org/babel-helper-regex/-/babel-helper-regex-6.26.0.tgz", - "integrity": "sha1-MlxZ+QL4LyS3T6zu0DY5VPZJXnI=", - "requires": { - "babel-runtime": "^6.26.0", - "babel-types": "^6.26.0", - "lodash": "^4.17.4" - } - }, - "babel-helper-remap-async-to-generator": { - "version": "6.24.1", - "resolved": "https://registry.npmjs.org/babel-helper-remap-async-to-generator/-/babel-helper-remap-async-to-generator-6.24.1.tgz", - "integrity": "sha1-XsWBgnrXI/7N04HxySg5BnbkVRs=", - "requires": { - "babel-helper-function-name": "^6.24.1", - "babel-runtime": "^6.22.0", - "babel-template": "^6.24.1", - "babel-traverse": "^6.24.1", - "babel-types": "^6.24.1" - } - }, - "babel-helper-replace-supers": { - "version": "6.24.1", - "resolved": "https://registry.npmjs.org/babel-helper-replace-supers/-/babel-helper-replace-supers-6.24.1.tgz", - "integrity": "sha1-v22/5Dk40XNpohPKiov3S2qQqxo=", - "requires": { - "babel-helper-optimise-call-expression": "^6.24.1", - "babel-messages": "^6.23.0", - "babel-runtime": "^6.22.0", - "babel-template": "^6.24.1", - "babel-traverse": "^6.24.1", - "babel-types": "^6.24.1" - } - }, - "babel-helpers": { - "version": "6.24.1", - "resolved": "https://registry.npmjs.org/babel-helpers/-/babel-helpers-6.24.1.tgz", - "integrity": "sha1-NHHenK7DiOXIUOWX5Yom3fN2ArI=", - "requires": { - "babel-runtime": "^6.22.0", - "babel-template": "^6.24.1" - } - }, - "babel-messages": { - "version": "6.23.0", - "resolved": "https://registry.npmjs.org/babel-messages/-/babel-messages-6.23.0.tgz", - "integrity": "sha1-8830cDhYA1sqKVHG7F7fbGLyYw4=", - "requires": { - "babel-runtime": "^6.22.0" - } - }, - "babel-plugin-check-es2015-constants": { - "version": "6.22.0", - "resolved": "https://registry.npmjs.org/babel-plugin-check-es2015-constants/-/babel-plugin-check-es2015-constants-6.22.0.tgz", - "integrity": "sha1-NRV7EBQm/S/9PaP3XH0ekYNbv4o=", - "requires": { - "babel-runtime": "^6.22.0" - } - }, - "babel-plugin-syntax-async-functions": { - "version": "6.13.0", - "resolved": "http://registry.npmjs.org/babel-plugin-syntax-async-functions/-/babel-plugin-syntax-async-functions-6.13.0.tgz", - "integrity": "sha1-ytnK0RkbWtY0vzCuCHI5HgZHvpU=" - }, - "babel-plugin-syntax-exponentiation-operator": { - "version": "6.13.0", - "resolved": "http://registry.npmjs.org/babel-plugin-syntax-exponentiation-operator/-/babel-plugin-syntax-exponentiation-operator-6.13.0.tgz", - "integrity": "sha1-nufoM3KQ2pUoggGmpX9BcDF4MN4=" - }, - "babel-plugin-syntax-trailing-function-commas": { - "version": "6.22.0", - "resolved": "https://registry.npmjs.org/babel-plugin-syntax-trailing-function-commas/-/babel-plugin-syntax-trailing-function-commas-6.22.0.tgz", - "integrity": "sha1-ugNgk3+NBuQBgKQ/4NVhb/9TLPM=" - }, - "babel-plugin-transform-async-to-generator": { - "version": "6.24.1", - "resolved": "https://registry.npmjs.org/babel-plugin-transform-async-to-generator/-/babel-plugin-transform-async-to-generator-6.24.1.tgz", - "integrity": "sha1-ZTbjeK/2yx1VF6wOQOs+n8jQh2E=", - "requires": { - "babel-helper-remap-async-to-generator": "^6.24.1", - "babel-plugin-syntax-async-functions": "^6.8.0", - "babel-runtime": "^6.22.0" - } - }, - "babel-plugin-transform-es2015-arrow-functions": { - "version": "6.22.0", - "resolved": "https://registry.npmjs.org/babel-plugin-transform-es2015-arrow-functions/-/babel-plugin-transform-es2015-arrow-functions-6.22.0.tgz", - "integrity": "sha1-RSaSy3EdX3ncf4XkQM5BufJE0iE=", - "requires": { - "babel-runtime": "^6.22.0" - } - }, - "babel-plugin-transform-es2015-block-scoped-functions": { - "version": "6.22.0", - "resolved": "https://registry.npmjs.org/babel-plugin-transform-es2015-block-scoped-functions/-/babel-plugin-transform-es2015-block-scoped-functions-6.22.0.tgz", - "integrity": "sha1-u8UbSflk1wy42OC5ToICRs46YUE=", - "requires": { - "babel-runtime": "^6.22.0" - } - }, - "babel-plugin-transform-es2015-block-scoping": { - "version": "6.26.0", - "resolved": "https://registry.npmjs.org/babel-plugin-transform-es2015-block-scoping/-/babel-plugin-transform-es2015-block-scoping-6.26.0.tgz", - "integrity": "sha1-1w9SmcEwjQXBL0Y4E7CgnnOxiV8=", - "requires": { - "babel-runtime": "^6.26.0", - "babel-template": "^6.26.0", - "babel-traverse": "^6.26.0", - "babel-types": "^6.26.0", - "lodash": "^4.17.4" - } - }, - "babel-plugin-transform-es2015-classes": { - "version": "6.24.1", - "resolved": "https://registry.npmjs.org/babel-plugin-transform-es2015-classes/-/babel-plugin-transform-es2015-classes-6.24.1.tgz", - "integrity": "sha1-WkxYpQyclGHlZLSyo7+ryXolhNs=", - "requires": { - "babel-helper-define-map": "^6.24.1", - "babel-helper-function-name": "^6.24.1", - "babel-helper-optimise-call-expression": "^6.24.1", - "babel-helper-replace-supers": "^6.24.1", - "babel-messages": "^6.23.0", - "babel-runtime": "^6.22.0", - "babel-template": "^6.24.1", - "babel-traverse": "^6.24.1", - "babel-types": "^6.24.1" - } - }, - "babel-plugin-transform-es2015-computed-properties": { - "version": "6.24.1", - "resolved": "https://registry.npmjs.org/babel-plugin-transform-es2015-computed-properties/-/babel-plugin-transform-es2015-computed-properties-6.24.1.tgz", - "integrity": "sha1-b+Ko0WiV1WNPTNmZttNICjCBWbM=", - "requires": { - "babel-runtime": "^6.22.0", - "babel-template": "^6.24.1" - } - }, - "babel-plugin-transform-es2015-destructuring": { - "version": "6.23.0", - "resolved": "https://registry.npmjs.org/babel-plugin-transform-es2015-destructuring/-/babel-plugin-transform-es2015-destructuring-6.23.0.tgz", - "integrity": "sha1-mXux8auWf2gtKwh2/jWNYOdlxW0=", - "requires": { - "babel-runtime": "^6.22.0" - } - }, - "babel-plugin-transform-es2015-duplicate-keys": { - "version": "6.24.1", - "resolved": "https://registry.npmjs.org/babel-plugin-transform-es2015-duplicate-keys/-/babel-plugin-transform-es2015-duplicate-keys-6.24.1.tgz", - "integrity": "sha1-c+s9MQypaePvnskcU3QabxV2Qj4=", - "requires": { - "babel-runtime": "^6.22.0", - "babel-types": "^6.24.1" - } - }, - "babel-plugin-transform-es2015-for-of": { - "version": "6.23.0", - "resolved": "https://registry.npmjs.org/babel-plugin-transform-es2015-for-of/-/babel-plugin-transform-es2015-for-of-6.23.0.tgz", - "integrity": "sha1-9HyVsrYT3x0+zC/bdXNiPHUkhpE=", - "requires": { - "babel-runtime": "^6.22.0" - } - }, - "babel-plugin-transform-es2015-function-name": { - "version": "6.24.1", - "resolved": "https://registry.npmjs.org/babel-plugin-transform-es2015-function-name/-/babel-plugin-transform-es2015-function-name-6.24.1.tgz", - "integrity": "sha1-g0yJhTvDaxrw86TF26qU/Y6sqos=", - "requires": { - "babel-helper-function-name": "^6.24.1", - "babel-runtime": "^6.22.0", - "babel-types": "^6.24.1" - } - }, - "babel-plugin-transform-es2015-literals": { - "version": "6.22.0", - "resolved": "https://registry.npmjs.org/babel-plugin-transform-es2015-literals/-/babel-plugin-transform-es2015-literals-6.22.0.tgz", - "integrity": "sha1-T1SgLWzWbPkVKAAZox0xklN3yi4=", - "requires": { - "babel-runtime": "^6.22.0" - } - }, - "babel-plugin-transform-es2015-modules-amd": { - "version": "6.24.1", - "resolved": "https://registry.npmjs.org/babel-plugin-transform-es2015-modules-amd/-/babel-plugin-transform-es2015-modules-amd-6.24.1.tgz", - "integrity": "sha1-Oz5UAXI5hC1tGcMBHEvS8AoA0VQ=", - "requires": { - "babel-plugin-transform-es2015-modules-commonjs": "^6.24.1", - "babel-runtime": "^6.22.0", - "babel-template": "^6.24.1" - } - }, - "babel-plugin-transform-es2015-modules-commonjs": { - "version": "6.26.2", - "resolved": "https://registry.npmjs.org/babel-plugin-transform-es2015-modules-commonjs/-/babel-plugin-transform-es2015-modules-commonjs-6.26.2.tgz", - "integrity": "sha512-CV9ROOHEdrjcwhIaJNBGMBCodN+1cfkwtM1SbUHmvyy35KGT7fohbpOxkE2uLz1o6odKK2Ck/tz47z+VqQfi9Q==", - "requires": { - "babel-plugin-transform-strict-mode": "^6.24.1", - "babel-runtime": "^6.26.0", - "babel-template": "^6.26.0", - "babel-types": "^6.26.0" - } - }, - "babel-plugin-transform-es2015-modules-systemjs": { - "version": "6.24.1", - "resolved": "https://registry.npmjs.org/babel-plugin-transform-es2015-modules-systemjs/-/babel-plugin-transform-es2015-modules-systemjs-6.24.1.tgz", - "integrity": "sha1-/4mhQrkRmpBhlfXxBuzzBdlAfSM=", - "requires": { - "babel-helper-hoist-variables": "^6.24.1", - "babel-runtime": "^6.22.0", - "babel-template": "^6.24.1" - } - }, - "babel-plugin-transform-es2015-modules-umd": { - "version": "6.24.1", - "resolved": "https://registry.npmjs.org/babel-plugin-transform-es2015-modules-umd/-/babel-plugin-transform-es2015-modules-umd-6.24.1.tgz", - "integrity": "sha1-rJl+YoXNGO1hdq22B9YCNErThGg=", - "requires": { - "babel-plugin-transform-es2015-modules-amd": "^6.24.1", - "babel-runtime": "^6.22.0", - "babel-template": "^6.24.1" - } - }, - "babel-plugin-transform-es2015-object-super": { - "version": "6.24.1", - "resolved": "https://registry.npmjs.org/babel-plugin-transform-es2015-object-super/-/babel-plugin-transform-es2015-object-super-6.24.1.tgz", - "integrity": "sha1-JM72muIcuDp/hgPa0CH1cusnj40=", - "requires": { - "babel-helper-replace-supers": "^6.24.1", - "babel-runtime": "^6.22.0" - } - }, - "babel-plugin-transform-es2015-parameters": { - "version": "6.24.1", - "resolved": "https://registry.npmjs.org/babel-plugin-transform-es2015-parameters/-/babel-plugin-transform-es2015-parameters-6.24.1.tgz", - "integrity": "sha1-V6w1GrScrxSpfNE7CfZv3wpiXys=", - "requires": { - "babel-helper-call-delegate": "^6.24.1", - "babel-helper-get-function-arity": "^6.24.1", - "babel-runtime": "^6.22.0", - "babel-template": "^6.24.1", - "babel-traverse": "^6.24.1", - "babel-types": "^6.24.1" - } - }, - "babel-plugin-transform-es2015-shorthand-properties": { - "version": "6.24.1", - "resolved": "https://registry.npmjs.org/babel-plugin-transform-es2015-shorthand-properties/-/babel-plugin-transform-es2015-shorthand-properties-6.24.1.tgz", - "integrity": "sha1-JPh11nIch2YbvZmkYi5R8U3jiqA=", - "requires": { - "babel-runtime": "^6.22.0", - "babel-types": "^6.24.1" - } - }, - "babel-plugin-transform-es2015-spread": { - "version": "6.22.0", - "resolved": "https://registry.npmjs.org/babel-plugin-transform-es2015-spread/-/babel-plugin-transform-es2015-spread-6.22.0.tgz", - "integrity": "sha1-1taKmfia7cRTbIGlQujdnxdG+NE=", - "requires": { - "babel-runtime": "^6.22.0" - } - }, - "babel-plugin-transform-es2015-sticky-regex": { - "version": "6.24.1", - "resolved": "https://registry.npmjs.org/babel-plugin-transform-es2015-sticky-regex/-/babel-plugin-transform-es2015-sticky-regex-6.24.1.tgz", - "integrity": "sha1-AMHNsaynERLN8M9hJsLta0V8zbw=", - "requires": { - "babel-helper-regex": "^6.24.1", - "babel-runtime": "^6.22.0", - "babel-types": "^6.24.1" - } - }, - "babel-plugin-transform-es2015-template-literals": { - "version": "6.22.0", - "resolved": "https://registry.npmjs.org/babel-plugin-transform-es2015-template-literals/-/babel-plugin-transform-es2015-template-literals-6.22.0.tgz", - "integrity": "sha1-qEs0UPfp+PH2g51taH2oS7EjbY0=", - "requires": { - "babel-runtime": "^6.22.0" - } - }, - "babel-plugin-transform-es2015-typeof-symbol": { - "version": "6.23.0", - "resolved": "https://registry.npmjs.org/babel-plugin-transform-es2015-typeof-symbol/-/babel-plugin-transform-es2015-typeof-symbol-6.23.0.tgz", - "integrity": "sha1-3sCfHN3/lLUqxz1QXITfWdzOs3I=", - "requires": { - "babel-runtime": "^6.22.0" - } - }, - "babel-plugin-transform-es2015-unicode-regex": { - "version": "6.24.1", - "resolved": "https://registry.npmjs.org/babel-plugin-transform-es2015-unicode-regex/-/babel-plugin-transform-es2015-unicode-regex-6.24.1.tgz", - "integrity": "sha1-04sS9C6nMj9yk4fxinxa4frrNek=", - "requires": { - "babel-helper-regex": "^6.24.1", - "babel-runtime": "^6.22.0", - "regexpu-core": "^2.0.0" - } - }, - "babel-plugin-transform-exponentiation-operator": { - "version": "6.24.1", - "resolved": "https://registry.npmjs.org/babel-plugin-transform-exponentiation-operator/-/babel-plugin-transform-exponentiation-operator-6.24.1.tgz", - "integrity": "sha1-KrDJx/MJj6SJB3cruBP+QejeOg4=", - "requires": { - "babel-helper-builder-binary-assignment-operator-visitor": "^6.24.1", - "babel-plugin-syntax-exponentiation-operator": "^6.8.0", - "babel-runtime": "^6.22.0" - } - }, - "babel-plugin-transform-regenerator": { - "version": "6.26.0", - "resolved": "https://registry.npmjs.org/babel-plugin-transform-regenerator/-/babel-plugin-transform-regenerator-6.26.0.tgz", - "integrity": "sha1-4HA2lvveJ/Cj78rPi03KL3s6jy8=", - "requires": { - "regenerator-transform": "^0.10.0" - } - }, - "babel-plugin-transform-strict-mode": { - "version": "6.24.1", - "resolved": "https://registry.npmjs.org/babel-plugin-transform-strict-mode/-/babel-plugin-transform-strict-mode-6.24.1.tgz", - "integrity": "sha1-1fr3qleKZbvlkc9e2uBKDGcCB1g=", - "requires": { - "babel-runtime": "^6.22.0", - "babel-types": "^6.24.1" - } - }, - "babel-preset-env": { - "version": "1.7.0", - "resolved": "https://registry.npmjs.org/babel-preset-env/-/babel-preset-env-1.7.0.tgz", - "integrity": "sha512-9OR2afuKDneX2/q2EurSftUYM0xGu4O2D9adAhVfADDhrYDaxXV0rBbevVYoY9n6nyX1PmQW/0jtpJvUNr9CHg==", - "requires": { - "babel-plugin-check-es2015-constants": "^6.22.0", - "babel-plugin-syntax-trailing-function-commas": "^6.22.0", - "babel-plugin-transform-async-to-generator": "^6.22.0", - "babel-plugin-transform-es2015-arrow-functions": "^6.22.0", - "babel-plugin-transform-es2015-block-scoped-functions": "^6.22.0", - "babel-plugin-transform-es2015-block-scoping": "^6.23.0", - "babel-plugin-transform-es2015-classes": "^6.23.0", - "babel-plugin-transform-es2015-computed-properties": "^6.22.0", - "babel-plugin-transform-es2015-destructuring": "^6.23.0", - "babel-plugin-transform-es2015-duplicate-keys": "^6.22.0", - "babel-plugin-transform-es2015-for-of": "^6.23.0", - "babel-plugin-transform-es2015-function-name": "^6.22.0", - "babel-plugin-transform-es2015-literals": "^6.22.0", - "babel-plugin-transform-es2015-modules-amd": "^6.22.0", - "babel-plugin-transform-es2015-modules-commonjs": "^6.23.0", - "babel-plugin-transform-es2015-modules-systemjs": "^6.23.0", - "babel-plugin-transform-es2015-modules-umd": "^6.23.0", - "babel-plugin-transform-es2015-object-super": "^6.22.0", - "babel-plugin-transform-es2015-parameters": "^6.23.0", - "babel-plugin-transform-es2015-shorthand-properties": "^6.22.0", - "babel-plugin-transform-es2015-spread": "^6.22.0", - "babel-plugin-transform-es2015-sticky-regex": "^6.22.0", - "babel-plugin-transform-es2015-template-literals": "^6.22.0", - "babel-plugin-transform-es2015-typeof-symbol": "^6.23.0", - "babel-plugin-transform-es2015-unicode-regex": "^6.22.0", - "babel-plugin-transform-exponentiation-operator": "^6.22.0", - "babel-plugin-transform-regenerator": "^6.22.0", - "browserslist": "^3.2.6", - "invariant": "^2.2.2", - "semver": "^5.3.0" - } - }, - "babel-register": { - "version": "6.26.0", - "resolved": "https://registry.npmjs.org/babel-register/-/babel-register-6.26.0.tgz", - "integrity": "sha1-btAhFz4vy0htestFxgCahW9kcHE=", - "requires": { - "babel-core": "^6.26.0", - "babel-runtime": "^6.26.0", - "core-js": "^2.5.0", - "home-or-tmp": "^2.0.0", - "lodash": "^4.17.4", - "mkdirp": "^0.5.1", - "source-map-support": "^0.4.15" - } - }, - "babel-runtime": { - "version": "6.26.0", - "resolved": "https://registry.npmjs.org/babel-runtime/-/babel-runtime-6.26.0.tgz", - "integrity": "sha1-llxwWGaOgrVde/4E/yM3vItWR/4=", - "requires": { - "core-js": "^2.4.0", - "regenerator-runtime": "^0.11.0" - } - }, - "babel-template": { - "version": "6.26.0", - "resolved": "https://registry.npmjs.org/babel-template/-/babel-template-6.26.0.tgz", - "integrity": "sha1-3gPi0WOWsGn0bdn/+FIfsaDjXgI=", - "requires": { - "babel-runtime": "^6.26.0", - "babel-traverse": "^6.26.0", - "babel-types": "^6.26.0", - "babylon": "^6.18.0", - "lodash": "^4.17.4" - } - }, - "babel-traverse": { - "version": "6.26.0", - "resolved": "https://registry.npmjs.org/babel-traverse/-/babel-traverse-6.26.0.tgz", - "integrity": "sha1-RqnL1+3MYsjlwGTi0tjQ9ANXZu4=", - "requires": { - "babel-code-frame": "^6.26.0", - "babel-messages": "^6.23.0", - "babel-runtime": "^6.26.0", - "babel-types": "^6.26.0", - "babylon": "^6.18.0", - "debug": "^2.6.8", - "globals": "^9.18.0", - "invariant": "^2.2.2", - "lodash": "^4.17.4" - } - }, - "babel-types": { - "version": "6.26.0", - "resolved": "https://registry.npmjs.org/babel-types/-/babel-types-6.26.0.tgz", - "integrity": "sha1-o7Bz+Uq0nrb6Vc1lInozQ4BjJJc=", - "requires": { - "babel-runtime": "^6.26.0", - "esutils": "^2.0.2", - "lodash": "^4.17.4", - "to-fast-properties": "^1.0.3" - } - }, - "babelify": { - "version": "7.3.0", - "resolved": "http://registry.npmjs.org/babelify/-/babelify-7.3.0.tgz", - "integrity": "sha1-qlau3nBn/XvVSWZu4W3ChQh+iOU=", - "requires": { - "babel-core": "^6.0.14", - "object-assign": "^4.0.0" - } - }, - "babylon": { - "version": "6.18.0", - "resolved": "https://registry.npmjs.org/babylon/-/babylon-6.18.0.tgz", - "integrity": "sha512-q/UEjfGJ2Cm3oKV71DJz9d25TPnq5rhBVL2Q4fA5wcC3jcrdn7+SssEybFIxwAvvP+YCsCYNKughoF33GxgycQ==" - }, - "backoff": { - "version": "2.5.0", - "resolved": "https://registry.npmjs.org/backoff/-/backoff-2.5.0.tgz", - "integrity": "sha1-9hbtqdPktmuMp/ynn2lXIsX44m8=", - "requires": { - "precond": "0.2" - } - }, - "balanced-match": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.0.tgz", - "integrity": "sha1-ibTRmasr7kneFk6gK4nORi1xt2c=" - }, - "base-x": { - "version": "1.1.0", - "resolved": "http://registry.npmjs.org/base-x/-/base-x-1.1.0.tgz", - "integrity": "sha1-QtPXF0dPnqAiB/bRqh9CaRPut6w=" - }, - "bcrypt-pbkdf": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/bcrypt-pbkdf/-/bcrypt-pbkdf-1.0.2.tgz", - "integrity": "sha1-pDAdOJtqQ/m2f/PKEaP2Y342Dp4=", - "requires": { - "tweetnacl": "^0.14.3" - } - }, - "bignumber.js": { - "version": "git+https://github.com/debris/bignumber.js.git#94d7146671b9719e00a09c29b01a691bc85048c2", - "from": "git+https://github.com/debris/bignumber.js.git#94d7146671b9719e00a09c29b01a691bc85048c2" - }, - "bindings": { - "version": "1.3.1", - "resolved": "https://registry.npmjs.org/bindings/-/bindings-1.3.1.tgz", - "integrity": "sha512-i47mqjF9UbjxJhxGf+pZ6kSxrnI3wBLlnGI2ArWJ4r0VrvDS7ZYXkprq/pLaBWYq4GM0r4zdHY+NNRqEMU7uew==" - }, - "bip39": { - "version": "2.5.0", - "resolved": "https://registry.npmjs.org/bip39/-/bip39-2.5.0.tgz", - "integrity": "sha512-xwIx/8JKoT2+IPJpFEfXoWdYwP7UVAoUxxLNfGCfVowaJE7yg1Y5B1BVPqlUNsBq5/nGwmFkwRJ8xDW4sX8OdA==", - "requires": { - "create-hash": "^1.1.0", - "pbkdf2": "^3.0.9", - "randombytes": "^2.0.1", - "safe-buffer": "^5.0.1", - "unorm": "^1.3.3" - } - }, - "bip66": { - "version": "1.1.5", - "resolved": "https://registry.npmjs.org/bip66/-/bip66-1.1.5.tgz", - "integrity": "sha1-AfqHSHhcpwlV1QESF9GzE5lpyiI=", - "requires": { - "safe-buffer": "^5.0.1" - } - }, - "bn.js": { - "version": "4.11.8", - "resolved": "https://registry.npmjs.org/bn.js/-/bn.js-4.11.8.tgz", - "integrity": "sha512-ItfYfPLkWHUjckQCk8xC+LwxgK8NYcXywGigJgSwOP8Y2iyWT4f2vsZnoOXTTbo+o5yXmIUJ4gn5538SO5S3gA==" - }, - "brace-expansion": { - "version": "1.1.11", - "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz", - "integrity": "sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==", - "requires": { - "balanced-match": "^1.0.0", - "concat-map": "0.0.1" - } - }, - "brorand": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/brorand/-/brorand-1.1.0.tgz", - "integrity": "sha1-EsJe/kCkXjwyPrhnWgoM5XsiNx8=" - }, - "browserify-aes": { - "version": "1.2.0", - "resolved": "http://registry.npmjs.org/browserify-aes/-/browserify-aes-1.2.0.tgz", - "integrity": "sha512-+7CHXqGuspUn/Sl5aO7Ea0xWGAtETPXNSAjHo48JfLdPWcMng33Xe4znFvQweqc/uzk5zSOI3H52CYnjCfb5hA==", - "requires": { - "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-sha3": { - "version": "0.0.4", - "resolved": "https://registry.npmjs.org/browserify-sha3/-/browserify-sha3-0.0.4.tgz", - "integrity": "sha1-CGxHuMgjFsnUcCLCYYWVRXbdjiY=", - "requires": { - "js-sha3": "^0.6.1", - "safe-buffer": "^5.1.1" - } - }, - "browserslist": { - "version": "3.2.8", - "resolved": "https://registry.npmjs.org/browserslist/-/browserslist-3.2.8.tgz", - "integrity": "sha512-WHVocJYavUwVgVViC0ORikPHQquXwVh939TaelZ4WDqpWgTX/FsGhl/+P4qBUAGcRvtOgDgC+xftNWWp2RUTAQ==", - "requires": { - "caniuse-lite": "^1.0.30000844", - "electron-to-chromium": "^1.3.47" - } - }, - "bs58": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/bs58/-/bs58-3.1.0.tgz", - "integrity": "sha1-1MJjiL9IBMrHFBQbGUWqR+XrJI4=", - "requires": { - "base-x": "^1.1.0" - } - }, - "bs58check": { - "version": "1.3.4", - "resolved": "https://registry.npmjs.org/bs58check/-/bs58check-1.3.4.tgz", - "integrity": "sha1-xSVABzdJEXcU+gQsMEfrj5FRy/g=", - "requires": { - "bs58": "^3.1.0", - "create-hash": "^1.1.0" - } - }, - "buffer-from": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/buffer-from/-/buffer-from-1.1.1.tgz", - "integrity": "sha512-MQcXEUbCKtEo7bhqEs6560Hyd4XaovZlO/k9V3hjVUF/zwW7KBVdSK4gIt/bzwS9MbR5qob+F5jusZsb0YQK2A==" - }, - "buffer-xor": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/buffer-xor/-/buffer-xor-1.0.3.tgz", - "integrity": "sha1-JuYe0UIvtw3ULm42cp7VHYVf6Nk=" - }, - "builtin-modules": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/builtin-modules/-/builtin-modules-1.1.1.tgz", - "integrity": "sha1-Jw8HbFpywC9bZaR9+Uxf46J4iS8=" - }, - "camelcase": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-3.0.0.tgz", - "integrity": "sha1-MvxLn82vhF/N9+c7uXysImHwqwo=" - }, - "caniuse-lite": { -<<<<<<< 0e7904660e90ddcf44e1194b7aa8c00703fc95cb - "version": "1.0.30000918", - "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30000918.tgz", - "integrity": "sha512-CAZ9QXGViBvhHnmIHhsTPSWFBujDaelKnUj7wwImbyQRxmXynYqKGi3UaZTSz9MoVh+1EVxOS/DFIkrJYgR3aw==" -======= - "version": "1.0.30000923", - "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30000923.tgz", - "integrity": "sha512-j5ur7eeluOFjjPUkydtXP4KFAsmH3XaQNch5tvWSO+dLHYt5PE+VgJZLWtbVOodfWij6m6zas28T4gB/cLYq1w==" ->>>>>>> complete dosproxy_test - }, - "caseless": { - "version": "0.12.0", - "resolved": "https://registry.npmjs.org/caseless/-/caseless-0.12.0.tgz", - "integrity": "sha1-G2gcIf+EAzyCZUMJBolCDRhxUdw=" - }, - "chalk": { - "version": "1.1.3", - "resolved": "http://registry.npmjs.org/chalk/-/chalk-1.1.3.tgz", - "integrity": "sha1-qBFcVeSnAv5NFQq9OHKCKn4J/Jg=", - "requires": { - "ansi-styles": "^2.2.1", - "escape-string-regexp": "^1.0.2", - "has-ansi": "^2.0.0", - "strip-ansi": "^3.0.0", - "supports-color": "^2.0.0" - } - }, - "checkpoint-store": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/checkpoint-store/-/checkpoint-store-1.1.0.tgz", - "integrity": "sha1-BOTLUWuRQziTWB5tRgGnjpVS6gY=", - "requires": { - "functional-red-black-tree": "^1.0.1" - } - }, - "cipher-base": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/cipher-base/-/cipher-base-1.0.4.tgz", - "integrity": "sha512-Kkht5ye6ZGmwv40uUDZztayT2ThLQGfnj/T71N/XzeZeo3nf8foyW7zGTsPYkEya3m5f3cAypH+qe7YOrM1U2Q==", - "requires": { - "inherits": "^2.0.1", - "safe-buffer": "^5.0.1" - } - }, - "cliui": { - "version": "3.2.0", - "resolved": "https://registry.npmjs.org/cliui/-/cliui-3.2.0.tgz", - "integrity": "sha1-EgYBU3qRbSmUD5NNo7SNWFo5IT0=", - "requires": { - "string-width": "^1.0.1", - "strip-ansi": "^3.0.1", - "wrap-ansi": "^2.0.0" - } - }, - "clone": { - "version": "2.1.2", - "resolved": "https://registry.npmjs.org/clone/-/clone-2.1.2.tgz", - "integrity": "sha1-G39Ln1kfHo+DZwQBYANFoCiHQ18=" - }, - "code-point-at": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/code-point-at/-/code-point-at-1.1.0.tgz", - "integrity": "sha1-DQcLTQQ6W+ozovGkDi7bPZpMz3c=" - }, - "coinstring": { - "version": "2.3.0", - "resolved": "https://registry.npmjs.org/coinstring/-/coinstring-2.3.0.tgz", - "integrity": "sha1-zbYzY6lhUCQEolr7gsLibV/2J6Q=", - "requires": { - "bs58": "^2.0.1", - "create-hash": "^1.1.1" - }, - "dependencies": { - "bs58": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/bs58/-/bs58-2.0.1.tgz", - "integrity": "sha1-VZCNWPGYKrogCPob7Y+RmYopv40=" - } - } - }, - "combined-stream": { - "version": "1.0.7", - "resolved": "https://registry.npmjs.org/combined-stream/-/combined-stream-1.0.7.tgz", - "integrity": "sha512-brWl9y6vOB1xYPZcpZde3N9zDByXTosAeMDo4p1wzo6UMOX4vumB+TP1RZ76sfE6Md68Q0NJSrE/gbezd4Ul+w==", - "requires": { - "delayed-stream": "~1.0.0" - } - }, - "concat-map": { - "version": "0.0.1", - "resolved": "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz", - "integrity": "sha1-2Klr13/Wjfd5OnMDajug1UBdR3s=" - }, - "concat-stream": { - "version": "1.6.2", - "resolved": "https://registry.npmjs.org/concat-stream/-/concat-stream-1.6.2.tgz", - "integrity": "sha512-27HBghJxjiZtIk3Ycvn/4kbJk/1uZuJFfuPEns6LaEvpvG1f0hTea8lilrouyo9mVc2GWdcEZ8OLoGmSADlrCw==", - "requires": { - "buffer-from": "^1.0.0", - "inherits": "^2.0.3", - "readable-stream": "^2.2.2", - "typedarray": "^0.0.6" - } - }, - "convert-source-map": { - "version": "1.6.0", - "resolved": "https://registry.npmjs.org/convert-source-map/-/convert-source-map-1.6.0.tgz", - "integrity": "sha512-eFu7XigvxdZ1ETfbgPBohgyQ/Z++C0eEhTor0qRwBw9unw+L0/6V8wkSuGgzdThkiS5lSpdptOQPD8Ak40a+7A==", - "requires": { - "safe-buffer": "~5.1.1" - } - }, - "core-js": { -<<<<<<< 0e7904660e90ddcf44e1194b7aa8c00703fc95cb - "version": "2.6.0", - "resolved": "https://registry.npmjs.org/core-js/-/core-js-2.6.0.tgz", - "integrity": "sha512-kLRC6ncVpuEW/1kwrOXYX6KQASCVtrh1gQr/UiaVgFlf9WE5Vp+lNe5+h3LuMr5PAucWnnEXwH0nQHRH/gpGtw==" -======= - "version": "2.6.1", - "resolved": "https://registry.npmjs.org/core-js/-/core-js-2.6.1.tgz", - "integrity": "sha512-L72mmmEayPJBejKIWe2pYtGis5r0tQ5NaJekdhyXgeMQTpJoBsH0NL4ElY2LfSoV15xeQWKQ+XTTOZdyero5Xg==" ->>>>>>> complete dosproxy_test - }, - "core-util-is": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/core-util-is/-/core-util-is-1.0.2.tgz", - "integrity": "sha1-tf1UIgqivFq1eqtxQMlAdUUDwac=" - }, - "create-hash": { - "version": "1.2.0", - "resolved": "http://registry.npmjs.org/create-hash/-/create-hash-1.2.0.tgz", - "integrity": "sha512-z00bCGNHDG8mHAkP7CtT1qVu+bFQUPjYq/4Iv3C3kWjTFV10zIjfSoeqXo9Asws8gwSHDGj/hl2u4OGIjapeCg==", - "requires": { - "cipher-base": "^1.0.1", - "inherits": "^2.0.1", - "md5.js": "^1.3.4", - "ripemd160": "^2.0.1", - "sha.js": "^2.4.0" - } - }, - "create-hmac": { - "version": "1.1.7", - "resolved": "http://registry.npmjs.org/create-hmac/-/create-hmac-1.1.7.tgz", - "integrity": "sha512-MJG9liiZ+ogc4TzUwuvbER1JRdgvUFSB5+VR/g5h82fGaIRWMWddtKBHi7/sVhfjQZ6SehlyhvQYrcYkaUIpLg==", - "requires": { - "cipher-base": "^1.0.3", - "create-hash": "^1.1.0", - "inherits": "^2.0.1", - "ripemd160": "^2.0.0", - "safe-buffer": "^5.0.1", - "sha.js": "^2.4.8" - } - }, - "cross-fetch": { - "version": "2.2.3", - "resolved": "https://registry.npmjs.org/cross-fetch/-/cross-fetch-2.2.3.tgz", - "integrity": "sha512-PrWWNH3yL2NYIb/7WF/5vFG3DCQiXDOVf8k3ijatbrtnwNuhMWLC7YF7uqf53tbTFDzHIUD8oITw4Bxt8ST3Nw==", - "requires": { - "node-fetch": "2.1.2", - "whatwg-fetch": "2.0.4" - } - }, - "crypto-js": { - "version": "3.1.8", - "resolved": "https://registry.npmjs.org/crypto-js/-/crypto-js-3.1.8.tgz", - "integrity": "sha1-cV8HC/YBTyrpkqmLOSkli3E/CNU=" - }, - "dashdash": { - "version": "1.14.1", - "resolved": "https://registry.npmjs.org/dashdash/-/dashdash-1.14.1.tgz", - "integrity": "sha1-hTz6D3y+L+1d4gMmuN1YEDX24vA=", - "requires": { - "assert-plus": "^1.0.0" - } - }, - "debug": { - "version": "2.6.9", - "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", - "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", - "requires": { - "ms": "2.0.0" - } - }, - "decamelize": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/decamelize/-/decamelize-1.2.0.tgz", - "integrity": "sha1-9lNNFRSCabIDUue+4m9QH5oZEpA=" - }, - "deep-equal": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/deep-equal/-/deep-equal-1.0.1.tgz", - "integrity": "sha1-9dJgKStmDghO/0zbyfCK0yR0SLU=" - }, - "deferred-leveldown": { - "version": "1.2.2", - "resolved": "https://registry.npmjs.org/deferred-leveldown/-/deferred-leveldown-1.2.2.tgz", - "integrity": "sha512-uukrWD2bguRtXilKt6cAWKyoXrTSMo5m7crUdLfWQmu8kIm88w3QZoUL+6nhpfKVmhHANER6Re3sKoNoZ3IKMA==", - "requires": { - "abstract-leveldown": "~2.6.0" - } - }, - "define-properties": { - "version": "1.1.3", - "resolved": "https://registry.npmjs.org/define-properties/-/define-properties-1.1.3.tgz", - "integrity": "sha512-3MqfYKj2lLzdMSf8ZIZE/V+Zuy+BgD6f164e8K2w7dgnpKArBDerGYpM46IYYcjnkdPNMjPk9A6VFB8+3SKlXQ==", - "requires": { - "object-keys": "^1.0.12" - } - }, - "defined": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/defined/-/defined-1.0.0.tgz", - "integrity": "sha1-yY2bzvdWdBiOEQlpFRGZ45sfppM=" - }, - "delayed-stream": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/delayed-stream/-/delayed-stream-1.0.0.tgz", - "integrity": "sha1-3zrhmayt+31ECqrgsp4icrJOxhk=" - }, - "detect-indent": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/detect-indent/-/detect-indent-4.0.0.tgz", - "integrity": "sha1-920GQ1LN9Docts5hnE7jqUdd4gg=", - "requires": { - "repeating": "^2.0.0" - } - }, - "dom-walk": { - "version": "0.1.1", - "resolved": "https://registry.npmjs.org/dom-walk/-/dom-walk-0.1.1.tgz", - "integrity": "sha1-ZyIm3HTI95mtNTB9+TaroRrNYBg=" - }, - "drbg.js": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/drbg.js/-/drbg.js-1.0.1.tgz", - "integrity": "sha1-Pja2xCs3BDgjzbwzLVjzHiRFSAs=", - "requires": { - "browserify-aes": "^1.0.6", - "create-hash": "^1.1.2", - "create-hmac": "^1.1.4" - } - }, - "ecc-jsbn": { - "version": "0.1.2", - "resolved": "https://registry.npmjs.org/ecc-jsbn/-/ecc-jsbn-0.1.2.tgz", - "integrity": "sha1-OoOpBOVDUyh4dMVkt1SThoSamMk=", - "requires": { - "jsbn": "~0.1.0", - "safer-buffer": "^2.1.0" - } - }, - "electron-to-chromium": { -<<<<<<< 0e7904660e90ddcf44e1194b7aa8c00703fc95cb - "version": "1.3.89", - "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.3.89.tgz", - "integrity": "sha512-Vb6lmZZdqMX4+v2G5SCTgy/cYtACuG5pAlFrC6AoyOpQaXBft32Vv9ejjPW7+rYWA/ww1iGKMDUCpnmqab6XBg==" -======= - "version": "1.3.95", - "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.3.95.tgz", - "integrity": "sha512-0JZEDKOQAE05EO/4rk3vLAE+PYFI9OLCVLAS4QAq1y+Bb2y1N6MyQJz62ynzHN/y0Ka/nO5jVJcahbCEdfiXLQ==" ->>>>>>> complete dosproxy_test - }, - "elliptic": { - "version": "6.4.1", - "resolved": "https://registry.npmjs.org/elliptic/-/elliptic-6.4.1.tgz", - "integrity": "sha512-BsXLz5sqX8OHcsh7CqBMztyXARmGQ3LWPtGjJi6DiJHq5C/qvi9P3OqgswKSDftbu8+IoI/QDTAm2fFnQ9SZSQ==", - "requires": { - "bn.js": "^4.4.0", - "brorand": "^1.0.1", - "hash.js": "^1.0.0", - "hmac-drbg": "^1.0.0", - "inherits": "^2.0.1", - "minimalistic-assert": "^1.0.0", - "minimalistic-crypto-utils": "^1.0.0" - } - }, - "encoding": { - "version": "0.1.12", - "resolved": "https://registry.npmjs.org/encoding/-/encoding-0.1.12.tgz", - "integrity": "sha1-U4tm8+5izRq1HsMjgp0flIDHS+s=", - "requires": { - "iconv-lite": "~0.4.13" - } - }, - "end-of-stream": { - "version": "1.4.1", - "resolved": "https://registry.npmjs.org/end-of-stream/-/end-of-stream-1.4.1.tgz", - "integrity": "sha512-1MkrZNvWTKCaigbn+W15elq2BB/L22nqrSY5DKlo3X6+vclJm8Bb5djXJBmEX6fS3+zCh/F4VBK5Z2KxJt4s2Q==", - "requires": { - "once": "^1.4.0" - } - }, - "errno": { - "version": "0.1.7", - "resolved": "https://registry.npmjs.org/errno/-/errno-0.1.7.tgz", - "integrity": "sha512-MfrRBDWzIWifgq6tJj60gkAwtLNb6sQPlcFrSOflcP1aFmmruKQ2wRnze/8V6kgyz7H3FF8Npzv78mZ7XLLflg==", - "requires": { - "prr": "~1.0.1" - } - }, - "error-ex": { - "version": "1.3.2", - "resolved": "https://registry.npmjs.org/error-ex/-/error-ex-1.3.2.tgz", - "integrity": "sha512-7dFHNmqeFSEt2ZBsCriorKnn3Z2pj+fd9kmI6QoWw4//DL+icEBfc0U7qJCisqrTsKTjw4fNFy2pW9OqStD84g==", - "requires": { - "is-arrayish": "^0.2.1" - } - }, - "es-abstract": { - "version": "1.12.0", - "resolved": "https://registry.npmjs.org/es-abstract/-/es-abstract-1.12.0.tgz", - "integrity": "sha512-C8Fx/0jFmV5IPoMOFPA9P9G5NtqW+4cOPit3MIuvR2t7Ag2K15EJTpxnHAYTzL+aYQJIESYeXZmDBfOBE1HcpA==", - "requires": { - "es-to-primitive": "^1.1.1", - "function-bind": "^1.1.1", - "has": "^1.0.1", - "is-callable": "^1.1.3", - "is-regex": "^1.0.4" - } - }, - "es-to-primitive": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/es-to-primitive/-/es-to-primitive-1.2.0.tgz", - "integrity": "sha512-qZryBOJjV//LaxLTV6UC//WewneB3LcXOL9NP++ozKVXsIIIpm/2c13UDiD9Jp2eThsecw9m3jPqDwTyobcdbg==", - "requires": { - "is-callable": "^1.1.4", - "is-date-object": "^1.0.1", - "is-symbol": "^1.0.2" - } - }, - "escape-string-regexp": { - "version": "1.0.5", - "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz", - "integrity": "sha1-G2HAViGQqN/2rjuyzwIAyhMLhtQ=" - }, - "esutils": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/esutils/-/esutils-2.0.2.tgz", - "integrity": "sha1-Cr9PHKpbyx96nYrMbepPqqBLrJs=" - }, - "eth-block-tracker": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/eth-block-tracker/-/eth-block-tracker-3.0.1.tgz", - "integrity": "sha512-WUVxWLuhMmsfenfZvFO5sbl1qFY2IqUlw/FPVmjjdElpqLsZtSG+wPe9Dz7W/sB6e80HgFKknOmKk2eNlznHug==", - "requires": { - "eth-query": "^2.1.0", - "ethereumjs-tx": "^1.3.3", - "ethereumjs-util": "^5.1.3", - "ethjs-util": "^0.1.3", - "json-rpc-engine": "^3.6.0", - "pify": "^2.3.0", - "tape": "^4.6.3" - }, - "dependencies": { - "ethereumjs-util": { - "version": "5.2.0", - "resolved": "https://registry.npmjs.org/ethereumjs-util/-/ethereumjs-util-5.2.0.tgz", - "integrity": "sha512-CJAKdI0wgMbQFLlLRtZKGcy/L6pzVRgelIZqRqNbuVFM3K9VEnyfbcvz0ncWMRNCe4kaHWjwRYQcYMucmwsnWA==", - "requires": { - "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" - } - } - } - }, - "eth-json-rpc-infura": { - "version": "3.1.2", - "resolved": "https://registry.npmjs.org/eth-json-rpc-infura/-/eth-json-rpc-infura-3.1.2.tgz", - "integrity": "sha512-IuK5Iowfs6taluA/3Okmu6EfZcFMq6MQuyrUL1PrCoJstuuBr3TvVeSy3keDyxfbrjFB34nCo538I8G+qMtsbw==", - "requires": { - "cross-fetch": "^2.1.1", - "eth-json-rpc-middleware": "^1.5.0", - "json-rpc-engine": "^3.4.0", - "json-rpc-error": "^2.0.0", - "tape": "^4.8.0" - } - }, - "eth-json-rpc-middleware": { - "version": "1.6.0", - "resolved": "http://registry.npmjs.org/eth-json-rpc-middleware/-/eth-json-rpc-middleware-1.6.0.tgz", - "integrity": "sha512-tDVCTlrUvdqHKqivYMjtFZsdD7TtpNLBCfKAcOpaVs7orBMS/A8HWro6dIzNtTZIR05FAbJ3bioFOnZpuCew9Q==", - "requires": { - "async": "^2.5.0", - "eth-query": "^2.1.2", - "eth-tx-summary": "^3.1.2", - "ethereumjs-block": "^1.6.0", - "ethereumjs-tx": "^1.3.3", - "ethereumjs-util": "^5.1.2", - "ethereumjs-vm": "^2.1.0", - "fetch-ponyfill": "^4.0.0", - "json-rpc-engine": "^3.6.0", - "json-rpc-error": "^2.0.0", - "json-stable-stringify": "^1.0.1", - "promise-to-callback": "^1.0.0", - "tape": "^4.6.3" - }, - "dependencies": { - "ethereumjs-util": { - "version": "5.2.0", - "resolved": "https://registry.npmjs.org/ethereumjs-util/-/ethereumjs-util-5.2.0.tgz", - "integrity": "sha512-CJAKdI0wgMbQFLlLRtZKGcy/L6pzVRgelIZqRqNbuVFM3K9VEnyfbcvz0ncWMRNCe4kaHWjwRYQcYMucmwsnWA==", - "requires": { - "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" - } - } - } - }, - "eth-query": { - "version": "2.1.2", - "resolved": "https://registry.npmjs.org/eth-query/-/eth-query-2.1.2.tgz", - "integrity": "sha1-1nQdkAAQa1FRDHLbktY2VFam2l4=", - "requires": { - "json-rpc-random-id": "^1.0.0", - "xtend": "^4.0.1" - } - }, - "eth-sig-util": { - "version": "1.4.2", - "resolved": "https://registry.npmjs.org/eth-sig-util/-/eth-sig-util-1.4.2.tgz", - "integrity": "sha1-jZWCAsftuq6Dlwf7pvCf8ydgYhA=", - "requires": { - "ethereumjs-abi": "git+https://github.com/ethereumjs/ethereumjs-abi.git#2863c40e0982acfc0b7163f0285d4c56427c7799", - "ethereumjs-util": "^5.1.1" - }, - "dependencies": { - "ethereumjs-util": { - "version": "5.2.0", - "resolved": "https://registry.npmjs.org/ethereumjs-util/-/ethereumjs-util-5.2.0.tgz", - "integrity": "sha512-CJAKdI0wgMbQFLlLRtZKGcy/L6pzVRgelIZqRqNbuVFM3K9VEnyfbcvz0ncWMRNCe4kaHWjwRYQcYMucmwsnWA==", - "requires": { - "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" - } - } - } - }, - "eth-tx-summary": { - "version": "3.2.3", - "resolved": "https://registry.npmjs.org/eth-tx-summary/-/eth-tx-summary-3.2.3.tgz", - "integrity": "sha512-1gZpA5fKarJOVSb5OUlPnhDQuIazqAkI61zlVvf5LdG47nEgw+/qhyZnuj3CUdE/TLTKuRzPLeyXLjaB4qWTRQ==", - "requires": { - "async": "^2.1.2", - "bn.js": "^4.11.8", - "clone": "^2.0.0", - "concat-stream": "^1.5.1", - "end-of-stream": "^1.1.0", - "eth-query": "^2.0.2", - "ethereumjs-block": "^1.4.1", - "ethereumjs-tx": "^1.1.1", - "ethereumjs-util": "^5.0.1", - "ethereumjs-vm": "2.3.4", - "through2": "^2.0.3", - "treeify": "^1.0.1", - "web3-provider-engine": "^13.3.2" - }, - "dependencies": { - "eth-block-tracker": { - "version": "2.3.1", - "resolved": "https://registry.npmjs.org/eth-block-tracker/-/eth-block-tracker-2.3.1.tgz", - "integrity": "sha512-NamWuMBIl8kmkJFVj8WzGatySTzQPQag4Xr677yFxdVtIxACFbL/dQowk0MzEqIKk93U1TwY3MjVU6mOcwZnKA==", - "requires": { - "async-eventemitter": "github:ahultgren/async-eventemitter#fa06e39e56786ba541c180061dbf2c0a5bbf951c", - "eth-query": "^2.1.0", - "ethereumjs-tx": "^1.3.3", - "ethereumjs-util": "^5.1.3", - "ethjs-util": "^0.1.3", - "json-rpc-engine": "^3.6.0", - "pify": "^2.3.0", - "tape": "^4.6.3" - }, - "dependencies": { - "async-eventemitter": { - "version": "github:ahultgren/async-eventemitter#fa06e39e56786ba541c180061dbf2c0a5bbf951c", - "from": "github:ahultgren/async-eventemitter#fa06e39e56786ba541c180061dbf2c0a5bbf951c", - "requires": { - "async": "^2.4.0" - } - } - } - }, - "ethereum-common": { - "version": "0.2.0", - "resolved": "https://registry.npmjs.org/ethereum-common/-/ethereum-common-0.2.0.tgz", - "integrity": "sha512-XOnAR/3rntJgbCdGhqdaLIxDLWKLmsZOGhHdBKadEr6gEnJLH52k93Ou+TUdFaPN3hJc3isBZBal3U/XZ15abA==" - }, - "ethereumjs-util": { - "version": "5.2.0", - "resolved": "https://registry.npmjs.org/ethereumjs-util/-/ethereumjs-util-5.2.0.tgz", - "integrity": "sha512-CJAKdI0wgMbQFLlLRtZKGcy/L6pzVRgelIZqRqNbuVFM3K9VEnyfbcvz0ncWMRNCe4kaHWjwRYQcYMucmwsnWA==", - "requires": { - "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" - } - }, - "ethereumjs-vm": { - "version": "2.3.4", - "resolved": "http://registry.npmjs.org/ethereumjs-vm/-/ethereumjs-vm-2.3.4.tgz", - "integrity": "sha512-Y4SlzNDqxrCO58jhp98HdnZVdjOqB+HC0hoU+N/DEp1aU+hFkRX/nru5F7/HkQRPIlA6aJlQp/xIA6xZs1kspw==", - "requires": { - "async": "^2.1.2", - "async-eventemitter": "^0.2.2", - "ethereum-common": "0.2.0", - "ethereumjs-account": "^2.0.3", - "ethereumjs-block": "~1.7.0", - "ethereumjs-util": "^5.1.3", - "fake-merkle-patricia-tree": "^1.0.1", - "functional-red-black-tree": "^1.0.1", - "merkle-patricia-tree": "^2.1.2", - "rustbn.js": "~0.1.1", - "safe-buffer": "^5.1.1" - } - }, - "web3-provider-engine": { - "version": "13.8.0", - "resolved": "http://registry.npmjs.org/web3-provider-engine/-/web3-provider-engine-13.8.0.tgz", - "integrity": "sha512-fZXhX5VWwWpoFfrfocslyg6P7cN3YWPG/ASaevNfeO80R+nzgoPUBXcWQekSGSsNDkeRTis4aMmpmofYf1TNtQ==", - "requires": { - "async": "^2.5.0", - "clone": "^2.0.0", - "eth-block-tracker": "^2.2.2", - "eth-sig-util": "^1.4.2", - "ethereumjs-block": "^1.2.2", - "ethereumjs-tx": "^1.2.0", - "ethereumjs-util": "^5.1.1", - "ethereumjs-vm": "^2.0.2", - "fetch-ponyfill": "^4.0.0", - "json-rpc-error": "^2.0.0", - "json-stable-stringify": "^1.0.1", - "promise-to-callback": "^1.0.0", - "readable-stream": "^2.2.9", - "request": "^2.67.0", - "semaphore": "^1.0.3", - "solc": "^0.4.2", - "tape": "^4.4.0", - "xhr": "^2.2.0", - "xtend": "^4.0.1" - } - } - } - }, - "ethereum-common": { - "version": "0.0.18", - "resolved": "https://registry.npmjs.org/ethereum-common/-/ethereum-common-0.0.18.tgz", - "integrity": "sha1-L9w1dvIykDNYl26znaeDIT/5Uj8=" - }, - "ethereumjs-abi": { - "version": "git+https://github.com/ethereumjs/ethereumjs-abi.git#2863c40e0982acfc0b7163f0285d4c56427c7799", - "from": "git+https://github.com/ethereumjs/ethereumjs-abi.git", - "requires": { - "bn.js": "^4.10.0", - "ethereumjs-util": "^5.0.0" - }, - "dependencies": { - "ethereumjs-util": { - "version": "5.2.0", - "resolved": "https://registry.npmjs.org/ethereumjs-util/-/ethereumjs-util-5.2.0.tgz", - "integrity": "sha512-CJAKdI0wgMbQFLlLRtZKGcy/L6pzVRgelIZqRqNbuVFM3K9VEnyfbcvz0ncWMRNCe4kaHWjwRYQcYMucmwsnWA==", - "requires": { - "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" - } - } - } - }, - "ethereumjs-account": { - "version": "2.0.5", - "resolved": "https://registry.npmjs.org/ethereumjs-account/-/ethereumjs-account-2.0.5.tgz", - "integrity": "sha512-bgDojnXGjhMwo6eXQC0bY6UK2liSFUSMwwylOmQvZbSl/D7NXQ3+vrGO46ZeOgjGfxXmgIeVNDIiHw7fNZM4VA==", - "requires": { - "ethereumjs-util": "^5.0.0", - "rlp": "^2.0.0", - "safe-buffer": "^5.1.1" - }, - "dependencies": { - "ethereumjs-util": { - "version": "5.2.0", - "resolved": "https://registry.npmjs.org/ethereumjs-util/-/ethereumjs-util-5.2.0.tgz", - "integrity": "sha512-CJAKdI0wgMbQFLlLRtZKGcy/L6pzVRgelIZqRqNbuVFM3K9VEnyfbcvz0ncWMRNCe4kaHWjwRYQcYMucmwsnWA==", - "requires": { - "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" - } - } - } - }, - "ethereumjs-block": { - "version": "1.7.1", - "resolved": "http://registry.npmjs.org/ethereumjs-block/-/ethereumjs-block-1.7.1.tgz", - "integrity": "sha512-B+sSdtqm78fmKkBq78/QLKJbu/4Ts4P2KFISdgcuZUPDm9x+N7qgBPIIFUGbaakQh8bzuquiRVbdmvPKqbILRg==", - "requires": { - "async": "^2.0.1", - "ethereum-common": "0.2.0", - "ethereumjs-tx": "^1.2.2", - "ethereumjs-util": "^5.0.0", - "merkle-patricia-tree": "^2.1.2" - }, - "dependencies": { - "ethereum-common": { - "version": "0.2.0", - "resolved": "https://registry.npmjs.org/ethereum-common/-/ethereum-common-0.2.0.tgz", - "integrity": "sha512-XOnAR/3rntJgbCdGhqdaLIxDLWKLmsZOGhHdBKadEr6gEnJLH52k93Ou+TUdFaPN3hJc3isBZBal3U/XZ15abA==" - }, - "ethereumjs-util": { - "version": "5.2.0", - "resolved": "https://registry.npmjs.org/ethereumjs-util/-/ethereumjs-util-5.2.0.tgz", - "integrity": "sha512-CJAKdI0wgMbQFLlLRtZKGcy/L6pzVRgelIZqRqNbuVFM3K9VEnyfbcvz0ncWMRNCe4kaHWjwRYQcYMucmwsnWA==", - "requires": { - "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" - } - } - } - }, - "ethereumjs-common": { - "version": "0.6.1", - "resolved": "https://registry.npmjs.org/ethereumjs-common/-/ethereumjs-common-0.6.1.tgz", - "integrity": "sha512-4jOrfDu9qOBTTGGb3zrfT1tE1Hyc6a8LJpEk0Vk9AYlLkBY7crjVICyJpRvjNI+KLDMpMITMw3eWVZOLMtZdhw==" - }, - "ethereumjs-tx": { - "version": "1.3.7", - "resolved": "https://registry.npmjs.org/ethereumjs-tx/-/ethereumjs-tx-1.3.7.tgz", - "integrity": "sha512-wvLMxzt1RPhAQ9Yi3/HKZTn0FZYpnsmQdbKYfUUpi4j1SEIcbkd9tndVjcPrufY3V7j2IebOpC00Zp2P/Ay2kA==", - "requires": { - "ethereum-common": "^0.0.18", - "ethereumjs-util": "^5.0.0" - }, - "dependencies": { - "ethereumjs-util": { - "version": "5.2.0", - "resolved": "https://registry.npmjs.org/ethereumjs-util/-/ethereumjs-util-5.2.0.tgz", - "integrity": "sha512-CJAKdI0wgMbQFLlLRtZKGcy/L6pzVRgelIZqRqNbuVFM3K9VEnyfbcvz0ncWMRNCe4kaHWjwRYQcYMucmwsnWA==", - "requires": { - "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" - } - } - } - }, - "ethereumjs-util": { - "version": "4.5.0", - "resolved": "http://registry.npmjs.org/ethereumjs-util/-/ethereumjs-util-4.5.0.tgz", - "integrity": "sha1-PpQosxfuvaPXJg2FT93alUsfG8Y=", - "requires": { - "bn.js": "^4.8.0", - "create-hash": "^1.1.2", - "keccakjs": "^0.2.0", - "rlp": "^2.0.0", - "secp256k1": "^3.0.1" - } - }, - "ethereumjs-vm": { - "version": "2.5.0", - "resolved": "https://registry.npmjs.org/ethereumjs-vm/-/ethereumjs-vm-2.5.0.tgz", - "integrity": "sha512-Cp1do4J2FIJFnbofqLsKb/aoZKG+Q8NBIbTa1qwZPQkQxzeR3DZVpFk/VbE1EUO6Ha0kSClJ1jzfj07z3cScSQ==", - "requires": { - "async": "^2.1.2", - "async-eventemitter": "^0.2.2", - "ethereumjs-account": "^2.0.3", - "ethereumjs-block": "~2.1.0", - "ethereumjs-common": "^0.6.0", - "ethereumjs-util": "^6.0.0", - "fake-merkle-patricia-tree": "^1.0.1", - "functional-red-black-tree": "^1.0.1", - "merkle-patricia-tree": "^2.1.2", - "rustbn.js": "~0.2.0", - "safe-buffer": "^5.1.1" - }, - "dependencies": { - "ethereumjs-block": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/ethereumjs-block/-/ethereumjs-block-2.1.0.tgz", - "integrity": "sha512-ip+x4/7hUInX+TQfhEKsQh9MJK1Dbjp4AuPjf1UdX3udAV4beYD4EMCNIPzBLCsGS8WQZYXLpo83tVTISYNpow==", - "requires": { - "async": "^2.0.1", - "ethereumjs-common": "^0.6.0", - "ethereumjs-tx": "^1.2.2", - "ethereumjs-util": "^5.0.0", - "merkle-patricia-tree": "^2.1.2" - }, - "dependencies": { - "ethereumjs-util": { - "version": "5.2.0", - "resolved": "https://registry.npmjs.org/ethereumjs-util/-/ethereumjs-util-5.2.0.tgz", - "integrity": "sha512-CJAKdI0wgMbQFLlLRtZKGcy/L6pzVRgelIZqRqNbuVFM3K9VEnyfbcvz0ncWMRNCe4kaHWjwRYQcYMucmwsnWA==", - "requires": { - "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" - } - } - } - }, - "ethereumjs-util": { - "version": "6.0.0", - "resolved": "https://registry.npmjs.org/ethereumjs-util/-/ethereumjs-util-6.0.0.tgz", - "integrity": "sha512-E3yKUyl0Fs95nvTFQZe/ZSNcofhDzUsDlA5y2uoRmf1+Ec7gpGhNCsgKkZBRh7Br5op8mJcYF/jFbmjj909+nQ==", - "requires": { - "bn.js": "^4.11.0", - "create-hash": "^1.1.2", - "ethjs-util": "^0.1.6", - "keccak": "^1.0.2", - "rlp": "^2.0.0", - "safe-buffer": "^5.1.1", - "secp256k1": "^3.0.1" - } - }, - "rustbn.js": { - "version": "0.2.0", - "resolved": "https://registry.npmjs.org/rustbn.js/-/rustbn.js-0.2.0.tgz", - "integrity": "sha512-4VlvkRUuCJvr2J6Y0ImW7NvTCriMi7ErOAqWk1y69vAdoNIzCF3yPmgeNzx+RQTLEDFq5sHfscn1MwHxP9hNfA==" - } - } - }, - "ethereumjs-wallet": { - "version": "0.6.0", - "resolved": "https://registry.npmjs.org/ethereumjs-wallet/-/ethereumjs-wallet-0.6.0.tgz", - "integrity": "sha1-gnY7Fpfuenlr5xVdqd+0my+Yz9s=", - "requires": { - "aes-js": "^0.2.3", - "bs58check": "^1.0.8", - "ethereumjs-util": "^4.4.0", - "hdkey": "^0.7.0", - "scrypt.js": "^0.2.0", - "utf8": "^2.1.1", - "uuid": "^2.0.1" - } - }, - "ethjs-util": { - "version": "0.1.6", - "resolved": "https://registry.npmjs.org/ethjs-util/-/ethjs-util-0.1.6.tgz", - "integrity": "sha512-CUnVOQq7gSpDHZVVrQW8ExxUETWrnrvXYvYz55wOU8Uj4VCgw56XC2B/fVqQN+f7gmrnRHSLVnFAwsCuNwji8w==", - "requires": { - "is-hex-prefixed": "1.0.0", - "strip-hex-prefix": "1.0.0" - } - }, - "events": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/events/-/events-3.0.0.tgz", - "integrity": "sha512-Dc381HFWJzEOhQ+d8pkNon++bk9h6cdAoAj4iE6Q4y6xgTzySWXlKn05/TVNpjnfRqi/X0EpJEJohPjNI3zpVA==" - }, - "evp_bytestokey": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/evp_bytestokey/-/evp_bytestokey-1.0.3.tgz", - "integrity": "sha512-/f2Go4TognH/KvCISP7OUsHn85hT9nUkxxA9BEWxFn+Oj9o8ZNLm/40hdlgSLyuOimsrTKLUMEorQexp/aPQeA==", - "requires": { - "md5.js": "^1.3.4", - "safe-buffer": "^5.1.1" - } - }, - "extend": { - "version": "3.0.2", - "resolved": "https://registry.npmjs.org/extend/-/extend-3.0.2.tgz", - "integrity": "sha512-fjquC59cD7CyW6urNXK0FBufkZcoiGG80wTuPujX590cB5Ttln20E2UB4S/WARVqhXffZl2LNgS+gQdPIIim/g==" - }, - "extsprintf": { - "version": "1.3.0", - "resolved": "https://registry.npmjs.org/extsprintf/-/extsprintf-1.3.0.tgz", - "integrity": "sha1-lpGEQOMEGnpBT4xS48V06zw+HgU=" - }, - "fake-merkle-patricia-tree": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/fake-merkle-patricia-tree/-/fake-merkle-patricia-tree-1.0.1.tgz", - "integrity": "sha1-S4w6z7Ugr635hgsfFM2M40As3dM=", - "requires": { - "checkpoint-store": "^1.1.0" - } - }, - "fast-deep-equal": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/fast-deep-equal/-/fast-deep-equal-2.0.1.tgz", - "integrity": "sha1-ewUhjd+WZ79/Nwv3/bLLFf3Qqkk=" - }, - "fast-json-stable-stringify": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/fast-json-stable-stringify/-/fast-json-stable-stringify-2.0.0.tgz", - "integrity": "sha1-1RQsDK7msRifh9OnYREGT4bIu/I=" - }, - "fetch-ponyfill": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/fetch-ponyfill/-/fetch-ponyfill-4.1.0.tgz", - "integrity": "sha1-rjzl9zLGReq4fkroeTQUcJsjmJM=", - "requires": { - "node-fetch": "~1.7.1" - }, - "dependencies": { - "node-fetch": { - "version": "1.7.3", - "resolved": "https://registry.npmjs.org/node-fetch/-/node-fetch-1.7.3.tgz", - "integrity": "sha512-NhZ4CsKx7cYm2vSrBAr2PvFOe6sWDf0UYLRqA6svUYg7+/TSfVAu49jYC4BvQ4Sms9SZgdqGBgroqfDhJdTyKQ==", - "requires": { - "encoding": "^0.1.11", - "is-stream": "^1.0.1" - } - } - } - }, - "find-up": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/find-up/-/find-up-1.1.2.tgz", - "integrity": "sha1-ay6YIrGizgpgq2TWEOzK1TyyTQ8=", - "requires": { - "path-exists": "^2.0.0", - "pinkie-promise": "^2.0.0" - } - }, - "for-each": { - "version": "0.3.3", - "resolved": "https://registry.npmjs.org/for-each/-/for-each-0.3.3.tgz", - "integrity": "sha512-jqYfLp7mo9vIyQf8ykW2v7A+2N4QjeCeI5+Dz9XraiO1ign81wjiH7Fb9vSOWvQfNtmSa4H2RoQTrrXivdUZmw==", - "requires": { - "is-callable": "^1.1.3" - } - }, - "forever-agent": { - "version": "0.6.1", - "resolved": "https://registry.npmjs.org/forever-agent/-/forever-agent-0.6.1.tgz", - "integrity": "sha1-+8cfDEGt6zf5bFd60e1C2P2sypE=" - }, - "form-data": { - "version": "2.3.3", - "resolved": "https://registry.npmjs.org/form-data/-/form-data-2.3.3.tgz", - "integrity": "sha512-1lLKB2Mu3aGP1Q/2eCOx0fNbRMe7XdwktwOruhfqqd0rIJWwN4Dh+E3hrPSlDCXnSR7UtZ1N38rVXm+6+MEhJQ==", - "requires": { - "asynckit": "^0.4.0", - "combined-stream": "^1.0.6", - "mime-types": "^2.1.12" - } - }, - "fs-extra": { - "version": "0.30.0", - "resolved": "http://registry.npmjs.org/fs-extra/-/fs-extra-0.30.0.tgz", - "integrity": "sha1-8jP/zAjU2n1DLapEl3aYnbHfk/A=", - "requires": { - "graceful-fs": "^4.1.2", - "jsonfile": "^2.1.0", - "klaw": "^1.0.0", - "path-is-absolute": "^1.0.0", - "rimraf": "^2.2.8" - } - }, - "fs.realpath": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/fs.realpath/-/fs.realpath-1.0.0.tgz", - "integrity": "sha1-FQStJSMVjKpA20onh8sBQRmU6k8=" - }, - "function-bind": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/function-bind/-/function-bind-1.1.1.tgz", - "integrity": "sha512-yIovAzMX49sF8Yl58fSCWJ5svSLuaibPxXQJFLmBObTuCr0Mf1KiPopGM9NiFjiYBCbfaa2Fh6breQ6ANVTI0A==" - }, - "functional-red-black-tree": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/functional-red-black-tree/-/functional-red-black-tree-1.0.1.tgz", - "integrity": "sha1-GwqzvVU7Kg1jmdKcDj6gslIHgyc=" - }, - "ganache-cli": { - "version": "6.2.3", - "resolved": "https://registry.npmjs.org/ganache-cli/-/ganache-cli-6.2.3.tgz", - "integrity": "sha512-+FYzINouw+yHHG6bT8m6O5xCw5NP6rpSL2keChKlcwgRRFz8SrZS6Q26iJ7ixBp6bk+UMMua8IPZgNFizbdZlQ==", - "requires": { - "bn.js": "4.11.8", - "ganache-core": "^2.3.1", - "source-map-support": "^0.5.3", - "yargs": "^11.0.0" - }, - "dependencies": { - "ansi-regex": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-3.0.0.tgz", - "integrity": "sha1-7QMXwyIGT3lGbAKWa922Bas32Zg=" - }, - "bn.js": { - "version": "4.11.8", - "resolved": "https://registry.npmjs.org/bn.js/-/bn.js-4.11.8.tgz", - "integrity": "sha512-ItfYfPLkWHUjckQCk8xC+LwxgK8NYcXywGigJgSwOP8Y2iyWT4f2vsZnoOXTTbo+o5yXmIUJ4gn5538SO5S3gA==" - }, - "buffer-from": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/buffer-from/-/buffer-from-1.1.1.tgz", - "integrity": "sha512-MQcXEUbCKtEo7bhqEs6560Hyd4XaovZlO/k9V3hjVUF/zwW7KBVdSK4gIt/bzwS9MbR5qob+F5jusZsb0YQK2A==" - }, - "camelcase": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-4.1.0.tgz", - "integrity": "sha1-1UVjW+HjPFQmScaRc+Xeas+uNN0=" - }, - "cliui": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/cliui/-/cliui-4.1.0.tgz", - "integrity": "sha512-4FG+RSG9DL7uEwRUZXZn3SS34DiDPfzP0VOiEwtUWlE+AR2EIg+hSyvrIgUUfhdgR/UkAeW2QHgeP+hWrXs7jQ==", - "requires": { - "string-width": "^2.1.1", - "strip-ansi": "^4.0.0", - "wrap-ansi": "^2.0.0" - } - }, - "code-point-at": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/code-point-at/-/code-point-at-1.1.0.tgz", - "integrity": "sha1-DQcLTQQ6W+ozovGkDi7bPZpMz3c=" - }, - "cross-spawn": { - "version": "5.1.0", - "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-5.1.0.tgz", - "integrity": "sha1-6L0O/uWPz/b4+UUQoKVUu/ojVEk=", - "requires": { - "lru-cache": "^4.0.1", - "shebang-command": "^1.2.0", - "which": "^1.2.9" - } - }, - "decamelize": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/decamelize/-/decamelize-1.2.0.tgz", - "integrity": "sha1-9lNNFRSCabIDUue+4m9QH5oZEpA=" - }, - "execa": { - "version": "0.7.0", - "resolved": "https://registry.npmjs.org/execa/-/execa-0.7.0.tgz", - "integrity": "sha1-lEvs00zEHuMqY6n68nrVpl/Fl3c=", - "requires": { - "cross-spawn": "^5.0.1", - "get-stream": "^3.0.0", - "is-stream": "^1.1.0", - "npm-run-path": "^2.0.0", - "p-finally": "^1.0.0", - "signal-exit": "^3.0.0", - "strip-eof": "^1.0.0" - } - }, - "find-up": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/find-up/-/find-up-2.1.0.tgz", - "integrity": "sha1-RdG35QbHF93UgndaK3eSCjwMV6c=", - "requires": { - "locate-path": "^2.0.0" - } - }, - "ganache-core": { - "version": "2.3.1", - "resolved": "https://registry.npmjs.org/ganache-core/-/ganache-core-2.3.1.tgz", - "integrity": "sha512-I4t4P+LYUZRnGbxDseqSa5vIJ8C5e35vw5Fr7f2iMMN6jmO5TVjWWgNib60G2iL+XTbYUFmou040hHxrTaNtnA==", - "requires": { - "abstract-leveldown": "3.0.0", - "async": "2.6.1", - "bip39": "2.5.0", - "bn.js": "4.11.8", - "cachedown": "1.0.0", - "clone": "2.1.2", - "debug": "3.1.0", - "encoding-down": "5.0.4", - "eth-sig-util": "2.0.2", - "ethereumjs-abi": "0.6.5", - "ethereumjs-account": "2.0.5", - "ethereumjs-block": "1.2.2", - "ethereumjs-tx": "1.3.7", - "ethereumjs-util": "5.2.0", - "ethereumjs-vm": "2.4.0", - "ethereumjs-wallet": "0.6.2", - "heap": "0.2.6", - "level-sublevel": "6.6.4", - "levelup": "3.1.1", - "lodash": "4.17.10", - "merkle-patricia-tree": "2.3.1", - "seedrandom": "2.4.4", - "tmp": "0.0.33", - "web3": "1.0.0-beta.35", - "web3-provider-engine": "14.1.0", - "websocket": "1.0.26" - }, - "dependencies": { - "abstract-leveldown": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/abstract-leveldown/-/abstract-leveldown-3.0.0.tgz", - "integrity": "sha512-KUWx9UWGQD12zsmLNj64/pndaz4iJh/Pj7nopgkfDG6RlCcbMZvT6+9l7dchK4idog2Is8VdC/PvNbFuFmalIQ==", - "requires": { - "xtend": "~4.0.0" - } - }, - "accepts": { - "version": "1.3.5", - "resolved": "https://registry.npmjs.org/accepts/-/accepts-1.3.5.tgz", - "integrity": "sha1-63d99gEXI6OxTopywIBcjoZ0a9I=", - "requires": { - "mime-types": "~2.1.18", - "negotiator": "0.6.1" - } - }, - "aes-js": { - "version": "3.1.2", - "resolved": "https://registry.npmjs.org/aes-js/-/aes-js-3.1.2.tgz", - "integrity": "sha512-e5pEa2kBnBOgR4Y/p20pskXI74UEz7de8ZGVo58asOtvSVG5YAbJeELPZxOmt+Bnz3rX753YKhfIn4X4l1PPRQ==", - "optional": true - }, - "ajv": { - "version": "6.5.5", - "resolved": "https://registry.npmjs.org/ajv/-/ajv-6.5.5.tgz", - "integrity": "sha512-7q7gtRQDJSyuEHjuVgHoUa2VuemFiCMrfQc9Tc08XTAc4Zj/5U1buQJ0HU6i7fKjXU09SVgSmxa4sLvuvS8Iyg==", - "requires": { - "fast-deep-equal": "^2.0.1", - "fast-json-stable-stringify": "^2.0.0", - "json-schema-traverse": "^0.4.1", - "uri-js": "^4.2.2" - } - }, - "ansi-regex": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-2.1.1.tgz", - "integrity": "sha1-w7M6te42DYbg5ijwRorn7yfWVN8=" - }, - "ansi-styles": { - "version": "2.2.1", - "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-2.2.1.tgz", - "integrity": "sha1-tDLdM1i2NM914eRmQ2gkBTPB3b4=" - }, - "any-promise": { - "version": "1.3.0", - "resolved": "https://registry.npmjs.org/any-promise/-/any-promise-1.3.0.tgz", - "integrity": "sha1-q8av7tzqUugJzcA3au0845Y10X8=" - }, - "array-flatten": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/array-flatten/-/array-flatten-1.1.1.tgz", - "integrity": "sha1-ml9pkFGx5wczKPKgCJaLZOopVdI=" - }, - "asn1": { - "version": "0.2.4", - "resolved": "https://registry.npmjs.org/asn1/-/asn1-0.2.4.tgz", - "integrity": "sha512-jxwzQpLQjSmWXgwaCZE9Nz+glAG01yF1QnWgbhGwHI5A6FRIEY6IVqtHhIepHqI7/kyEyQEagBC5mBEFlIYvdg==", - "requires": { - "safer-buffer": "~2.1.0" - } - }, - "asn1.js": { - "version": "4.10.1", - "resolved": "https://registry.npmjs.org/asn1.js/-/asn1.js-4.10.1.tgz", - "integrity": "sha512-p32cOF5q0Zqs9uBiONKYLm6BClCoBCM5O9JfeUSlnQLBTxYdTK+pW+nXflm8UkKd2UYlEbYz5qEi0JuZR9ckSw==", - "requires": { - "bn.js": "^4.0.0", - "inherits": "^2.0.1", - "minimalistic-assert": "^1.0.0" - } - }, - "assert-plus": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/assert-plus/-/assert-plus-1.0.0.tgz", - "integrity": "sha1-8S4PPF13sLHN2RRpQuTpbB5N1SU=" - }, - "async": { - "version": "2.6.1", - "resolved": "https://registry.npmjs.org/async/-/async-2.6.1.tgz", - "integrity": "sha512-fNEiL2+AZt6AlAw/29Cr0UDe4sRAHCpEHh54WMz+Bb7QfNcFw4h3loofyJpLeQs4Yx7yuqu/2dLgM5hKOs6HlQ==", - "requires": { - "lodash": "^4.17.10" - } - }, - "async-eventemitter": { - "version": "0.2.4", - "resolved": "https://registry.npmjs.org/async-eventemitter/-/async-eventemitter-0.2.4.tgz", - "integrity": "sha512-pd20BwL7Yt1zwDFy+8MX8F1+WCT8aQeKj0kQnTrH9WaeRETlRamVhD0JtRPmrV4GfOJ2F9CvdQkZeZhnh2TuHw==", - "requires": { - "async": "^2.4.0" - } - }, - "async-limiter": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/async-limiter/-/async-limiter-1.0.0.tgz", - "integrity": "sha512-jp/uFnooOiO+L211eZOoSyzpOITMXx1rBITauYykG3BRYPu8h0UcxsPNB04RR5vo4Tyz3+ay17tR6JVf9qzYWg==" - }, - "asynckit": { - "version": "0.4.0", - "resolved": "https://registry.npmjs.org/asynckit/-/asynckit-0.4.0.tgz", - "integrity": "sha1-x57Zf380y48robyXkLzDZkdLS3k=" - }, - "aws-sign2": { - "version": "0.7.0", - "resolved": "https://registry.npmjs.org/aws-sign2/-/aws-sign2-0.7.0.tgz", - "integrity": "sha1-tG6JCTSpWR8tL2+G1+ap8bP+dqg=" - }, - "aws4": { - "version": "1.8.0", - "resolved": "https://registry.npmjs.org/aws4/-/aws4-1.8.0.tgz", - "integrity": "sha512-ReZxvNHIOv88FlT7rxcXIIC0fPt4KZqZbOlivyWtXLt8ESx84zd3kMC6iK5jVeS2qt+g7ftS7ye4fi06X5rtRQ==" - }, - "babel-code-frame": { - "version": "6.26.0", - "resolved": "https://registry.npmjs.org/babel-code-frame/-/babel-code-frame-6.26.0.tgz", - "integrity": "sha1-Y/1D99weO7fONZR9uP42mj9Yx0s=", - "requires": { - "chalk": "^1.1.3", - "esutils": "^2.0.2", - "js-tokens": "^3.0.2" - } - }, - "babel-core": { - "version": "6.26.3", - "resolved": "https://registry.npmjs.org/babel-core/-/babel-core-6.26.3.tgz", - "integrity": "sha512-6jyFLuDmeidKmUEb3NM+/yawG0M2bDZ9Z1qbZP59cyHLz8kYGKYwpJP0UwUKKUiTRNvxfLesJnTedqczP7cTDA==", - "requires": { - "babel-code-frame": "^6.26.0", - "babel-generator": "^6.26.0", - "babel-helpers": "^6.24.1", - "babel-messages": "^6.23.0", - "babel-register": "^6.26.0", - "babel-runtime": "^6.26.0", - "babel-template": "^6.26.0", - "babel-traverse": "^6.26.0", - "babel-types": "^6.26.0", - "babylon": "^6.18.0", - "convert-source-map": "^1.5.1", - "debug": "^2.6.9", - "json5": "^0.5.1", - "lodash": "^4.17.4", - "minimatch": "^3.0.4", - "path-is-absolute": "^1.0.1", - "private": "^0.1.8", - "slash": "^1.0.0", - "source-map": "^0.5.7" - }, - "dependencies": { - "debug": { - "version": "2.6.9", - "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", - "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", - "requires": { - "ms": "2.0.0" - } - } - } - }, - "babel-generator": { - "version": "6.26.1", - "resolved": "https://registry.npmjs.org/babel-generator/-/babel-generator-6.26.1.tgz", - "integrity": "sha512-HyfwY6ApZj7BYTcJURpM5tznulaBvyio7/0d4zFOeMPUmfxkCjHocCuoLa2SAGzBI8AREcH3eP3758F672DppA==", - "requires": { - "babel-messages": "^6.23.0", - "babel-runtime": "^6.26.0", - "babel-types": "^6.26.0", - "detect-indent": "^4.0.0", - "jsesc": "^1.3.0", - "lodash": "^4.17.4", - "source-map": "^0.5.7", - "trim-right": "^1.0.1" - }, - "dependencies": { - "jsesc": { - "version": "1.3.0", - "resolved": "http://registry.npmjs.org/jsesc/-/jsesc-1.3.0.tgz", - "integrity": "sha1-RsP+yMGJKxKwgz25vHYiF226s0s=" - } - } - }, - "babel-helper-builder-binary-assignment-operator-visitor": { - "version": "6.24.1", - "resolved": "https://registry.npmjs.org/babel-helper-builder-binary-assignment-operator-visitor/-/babel-helper-builder-binary-assignment-operator-visitor-6.24.1.tgz", - "integrity": "sha1-zORReto1b0IgvK6KAsKzRvmlZmQ=", - "requires": { - "babel-helper-explode-assignable-expression": "^6.24.1", - "babel-runtime": "^6.22.0", - "babel-types": "^6.24.1" - } - }, - "babel-helper-call-delegate": { - "version": "6.24.1", - "resolved": "https://registry.npmjs.org/babel-helper-call-delegate/-/babel-helper-call-delegate-6.24.1.tgz", - "integrity": "sha1-7Oaqzdx25Bw0YfiL/Fdb0Nqi340=", - "requires": { - "babel-helper-hoist-variables": "^6.24.1", - "babel-runtime": "^6.22.0", - "babel-traverse": "^6.24.1", - "babel-types": "^6.24.1" - } - }, - "babel-helper-define-map": { - "version": "6.26.0", - "resolved": "https://registry.npmjs.org/babel-helper-define-map/-/babel-helper-define-map-6.26.0.tgz", - "integrity": "sha1-pfVtq0GiX5fstJjH66ypgZ+Vvl8=", - "requires": { - "babel-helper-function-name": "^6.24.1", - "babel-runtime": "^6.26.0", - "babel-types": "^6.26.0", - "lodash": "^4.17.4" - } - }, - "babel-helper-explode-assignable-expression": { - "version": "6.24.1", - "resolved": "https://registry.npmjs.org/babel-helper-explode-assignable-expression/-/babel-helper-explode-assignable-expression-6.24.1.tgz", - "integrity": "sha1-8luCz33BBDPFX3BZLVdGQArCLKo=", - "requires": { - "babel-runtime": "^6.22.0", - "babel-traverse": "^6.24.1", - "babel-types": "^6.24.1" - } - }, - "babel-helper-function-name": { - "version": "6.24.1", - "resolved": "https://registry.npmjs.org/babel-helper-function-name/-/babel-helper-function-name-6.24.1.tgz", - "integrity": "sha1-00dbjAPtmCQqJbSDUasYOZ01gKk=", - "requires": { - "babel-helper-get-function-arity": "^6.24.1", - "babel-runtime": "^6.22.0", - "babel-template": "^6.24.1", - "babel-traverse": "^6.24.1", - "babel-types": "^6.24.1" - } - }, - "babel-helper-get-function-arity": { - "version": "6.24.1", - "resolved": "https://registry.npmjs.org/babel-helper-get-function-arity/-/babel-helper-get-function-arity-6.24.1.tgz", - "integrity": "sha1-j3eCqpNAfEHTqlCQj4mwMbG2hT0=", - "requires": { - "babel-runtime": "^6.22.0", - "babel-types": "^6.24.1" - } - }, - "babel-helper-hoist-variables": { - "version": "6.24.1", - "resolved": "https://registry.npmjs.org/babel-helper-hoist-variables/-/babel-helper-hoist-variables-6.24.1.tgz", - "integrity": "sha1-HssnaJydJVE+rbyZFKc/VAi+enY=", - "requires": { - "babel-runtime": "^6.22.0", - "babel-types": "^6.24.1" - } - }, - "babel-helper-optimise-call-expression": { - "version": "6.24.1", - "resolved": "https://registry.npmjs.org/babel-helper-optimise-call-expression/-/babel-helper-optimise-call-expression-6.24.1.tgz", - "integrity": "sha1-96E0J7qfc/j0+pk8VKl4gtEkQlc=", - "requires": { - "babel-runtime": "^6.22.0", - "babel-types": "^6.24.1" - } - }, - "babel-helper-regex": { - "version": "6.26.0", - "resolved": "https://registry.npmjs.org/babel-helper-regex/-/babel-helper-regex-6.26.0.tgz", - "integrity": "sha1-MlxZ+QL4LyS3T6zu0DY5VPZJXnI=", - "requires": { - "babel-runtime": "^6.26.0", - "babel-types": "^6.26.0", - "lodash": "^4.17.4" - } - }, - "babel-helper-remap-async-to-generator": { - "version": "6.24.1", - "resolved": "https://registry.npmjs.org/babel-helper-remap-async-to-generator/-/babel-helper-remap-async-to-generator-6.24.1.tgz", - "integrity": "sha1-XsWBgnrXI/7N04HxySg5BnbkVRs=", - "requires": { - "babel-helper-function-name": "^6.24.1", - "babel-runtime": "^6.22.0", - "babel-template": "^6.24.1", - "babel-traverse": "^6.24.1", - "babel-types": "^6.24.1" - } - }, - "babel-helper-replace-supers": { - "version": "6.24.1", - "resolved": "https://registry.npmjs.org/babel-helper-replace-supers/-/babel-helper-replace-supers-6.24.1.tgz", - "integrity": "sha1-v22/5Dk40XNpohPKiov3S2qQqxo=", - "requires": { - "babel-helper-optimise-call-expression": "^6.24.1", - "babel-messages": "^6.23.0", - "babel-runtime": "^6.22.0", - "babel-template": "^6.24.1", - "babel-traverse": "^6.24.1", - "babel-types": "^6.24.1" - } - }, - "babel-helpers": { - "version": "6.24.1", - "resolved": "https://registry.npmjs.org/babel-helpers/-/babel-helpers-6.24.1.tgz", - "integrity": "sha1-NHHenK7DiOXIUOWX5Yom3fN2ArI=", - "requires": { - "babel-runtime": "^6.22.0", - "babel-template": "^6.24.1" - } - }, - "babel-messages": { - "version": "6.23.0", - "resolved": "https://registry.npmjs.org/babel-messages/-/babel-messages-6.23.0.tgz", - "integrity": "sha1-8830cDhYA1sqKVHG7F7fbGLyYw4=", - "requires": { - "babel-runtime": "^6.22.0" - } - }, - "babel-plugin-check-es2015-constants": { - "version": "6.22.0", - "resolved": "https://registry.npmjs.org/babel-plugin-check-es2015-constants/-/babel-plugin-check-es2015-constants-6.22.0.tgz", - "integrity": "sha1-NRV7EBQm/S/9PaP3XH0ekYNbv4o=", - "requires": { - "babel-runtime": "^6.22.0" - } - }, - "babel-plugin-syntax-async-functions": { - "version": "6.13.0", - "resolved": "http://registry.npmjs.org/babel-plugin-syntax-async-functions/-/babel-plugin-syntax-async-functions-6.13.0.tgz", - "integrity": "sha1-ytnK0RkbWtY0vzCuCHI5HgZHvpU=" - }, - "babel-plugin-syntax-exponentiation-operator": { - "version": "6.13.0", - "resolved": "http://registry.npmjs.org/babel-plugin-syntax-exponentiation-operator/-/babel-plugin-syntax-exponentiation-operator-6.13.0.tgz", - "integrity": "sha1-nufoM3KQ2pUoggGmpX9BcDF4MN4=" - }, - "babel-plugin-syntax-trailing-function-commas": { - "version": "6.22.0", - "resolved": "https://registry.npmjs.org/babel-plugin-syntax-trailing-function-commas/-/babel-plugin-syntax-trailing-function-commas-6.22.0.tgz", - "integrity": "sha1-ugNgk3+NBuQBgKQ/4NVhb/9TLPM=" - }, - "babel-plugin-transform-async-to-generator": { - "version": "6.24.1", - "resolved": "https://registry.npmjs.org/babel-plugin-transform-async-to-generator/-/babel-plugin-transform-async-to-generator-6.24.1.tgz", - "integrity": "sha1-ZTbjeK/2yx1VF6wOQOs+n8jQh2E=", - "requires": { - "babel-helper-remap-async-to-generator": "^6.24.1", - "babel-plugin-syntax-async-functions": "^6.8.0", - "babel-runtime": "^6.22.0" - } - }, - "babel-plugin-transform-es2015-arrow-functions": { - "version": "6.22.0", - "resolved": "https://registry.npmjs.org/babel-plugin-transform-es2015-arrow-functions/-/babel-plugin-transform-es2015-arrow-functions-6.22.0.tgz", - "integrity": "sha1-RSaSy3EdX3ncf4XkQM5BufJE0iE=", - "requires": { - "babel-runtime": "^6.22.0" - } - }, - "babel-plugin-transform-es2015-block-scoped-functions": { - "version": "6.22.0", - "resolved": "https://registry.npmjs.org/babel-plugin-transform-es2015-block-scoped-functions/-/babel-plugin-transform-es2015-block-scoped-functions-6.22.0.tgz", - "integrity": "sha1-u8UbSflk1wy42OC5ToICRs46YUE=", - "requires": { - "babel-runtime": "^6.22.0" - } - }, - "babel-plugin-transform-es2015-block-scoping": { - "version": "6.26.0", - "resolved": "https://registry.npmjs.org/babel-plugin-transform-es2015-block-scoping/-/babel-plugin-transform-es2015-block-scoping-6.26.0.tgz", - "integrity": "sha1-1w9SmcEwjQXBL0Y4E7CgnnOxiV8=", - "requires": { - "babel-runtime": "^6.26.0", - "babel-template": "^6.26.0", - "babel-traverse": "^6.26.0", - "babel-types": "^6.26.0", - "lodash": "^4.17.4" - } - }, - "babel-plugin-transform-es2015-classes": { - "version": "6.24.1", - "resolved": "https://registry.npmjs.org/babel-plugin-transform-es2015-classes/-/babel-plugin-transform-es2015-classes-6.24.1.tgz", - "integrity": "sha1-WkxYpQyclGHlZLSyo7+ryXolhNs=", - "requires": { - "babel-helper-define-map": "^6.24.1", - "babel-helper-function-name": "^6.24.1", - "babel-helper-optimise-call-expression": "^6.24.1", - "babel-helper-replace-supers": "^6.24.1", - "babel-messages": "^6.23.0", - "babel-runtime": "^6.22.0", - "babel-template": "^6.24.1", - "babel-traverse": "^6.24.1", - "babel-types": "^6.24.1" - } - }, - "babel-plugin-transform-es2015-computed-properties": { - "version": "6.24.1", - "resolved": "https://registry.npmjs.org/babel-plugin-transform-es2015-computed-properties/-/babel-plugin-transform-es2015-computed-properties-6.24.1.tgz", - "integrity": "sha1-b+Ko0WiV1WNPTNmZttNICjCBWbM=", - "requires": { - "babel-runtime": "^6.22.0", - "babel-template": "^6.24.1" - } - }, - "babel-plugin-transform-es2015-destructuring": { - "version": "6.23.0", - "resolved": "https://registry.npmjs.org/babel-plugin-transform-es2015-destructuring/-/babel-plugin-transform-es2015-destructuring-6.23.0.tgz", - "integrity": "sha1-mXux8auWf2gtKwh2/jWNYOdlxW0=", - "requires": { - "babel-runtime": "^6.22.0" - } - }, - "babel-plugin-transform-es2015-duplicate-keys": { - "version": "6.24.1", - "resolved": "https://registry.npmjs.org/babel-plugin-transform-es2015-duplicate-keys/-/babel-plugin-transform-es2015-duplicate-keys-6.24.1.tgz", - "integrity": "sha1-c+s9MQypaePvnskcU3QabxV2Qj4=", - "requires": { - "babel-runtime": "^6.22.0", - "babel-types": "^6.24.1" - } - }, - "babel-plugin-transform-es2015-for-of": { - "version": "6.23.0", - "resolved": "https://registry.npmjs.org/babel-plugin-transform-es2015-for-of/-/babel-plugin-transform-es2015-for-of-6.23.0.tgz", - "integrity": "sha1-9HyVsrYT3x0+zC/bdXNiPHUkhpE=", - "requires": { - "babel-runtime": "^6.22.0" - } - }, - "babel-plugin-transform-es2015-function-name": { - "version": "6.24.1", - "resolved": "https://registry.npmjs.org/babel-plugin-transform-es2015-function-name/-/babel-plugin-transform-es2015-function-name-6.24.1.tgz", - "integrity": "sha1-g0yJhTvDaxrw86TF26qU/Y6sqos=", - "requires": { - "babel-helper-function-name": "^6.24.1", - "babel-runtime": "^6.22.0", - "babel-types": "^6.24.1" - } - }, - "babel-plugin-transform-es2015-literals": { - "version": "6.22.0", - "resolved": "https://registry.npmjs.org/babel-plugin-transform-es2015-literals/-/babel-plugin-transform-es2015-literals-6.22.0.tgz", - "integrity": "sha1-T1SgLWzWbPkVKAAZox0xklN3yi4=", - "requires": { - "babel-runtime": "^6.22.0" - } - }, - "babel-plugin-transform-es2015-modules-amd": { - "version": "6.24.1", - "resolved": "https://registry.npmjs.org/babel-plugin-transform-es2015-modules-amd/-/babel-plugin-transform-es2015-modules-amd-6.24.1.tgz", - "integrity": "sha1-Oz5UAXI5hC1tGcMBHEvS8AoA0VQ=", - "requires": { - "babel-plugin-transform-es2015-modules-commonjs": "^6.24.1", - "babel-runtime": "^6.22.0", - "babel-template": "^6.24.1" - } - }, - "babel-plugin-transform-es2015-modules-commonjs": { - "version": "6.26.2", - "resolved": "https://registry.npmjs.org/babel-plugin-transform-es2015-modules-commonjs/-/babel-plugin-transform-es2015-modules-commonjs-6.26.2.tgz", - "integrity": "sha512-CV9ROOHEdrjcwhIaJNBGMBCodN+1cfkwtM1SbUHmvyy35KGT7fohbpOxkE2uLz1o6odKK2Ck/tz47z+VqQfi9Q==", - "requires": { - "babel-plugin-transform-strict-mode": "^6.24.1", - "babel-runtime": "^6.26.0", - "babel-template": "^6.26.0", - "babel-types": "^6.26.0" - } - }, - "babel-plugin-transform-es2015-modules-systemjs": { - "version": "6.24.1", - "resolved": "https://registry.npmjs.org/babel-plugin-transform-es2015-modules-systemjs/-/babel-plugin-transform-es2015-modules-systemjs-6.24.1.tgz", - "integrity": "sha1-/4mhQrkRmpBhlfXxBuzzBdlAfSM=", - "requires": { - "babel-helper-hoist-variables": "^6.24.1", - "babel-runtime": "^6.22.0", - "babel-template": "^6.24.1" - } - }, - "babel-plugin-transform-es2015-modules-umd": { - "version": "6.24.1", - "resolved": "https://registry.npmjs.org/babel-plugin-transform-es2015-modules-umd/-/babel-plugin-transform-es2015-modules-umd-6.24.1.tgz", - "integrity": "sha1-rJl+YoXNGO1hdq22B9YCNErThGg=", - "requires": { - "babel-plugin-transform-es2015-modules-amd": "^6.24.1", - "babel-runtime": "^6.22.0", - "babel-template": "^6.24.1" - } - }, - "babel-plugin-transform-es2015-object-super": { - "version": "6.24.1", - "resolved": "https://registry.npmjs.org/babel-plugin-transform-es2015-object-super/-/babel-plugin-transform-es2015-object-super-6.24.1.tgz", - "integrity": "sha1-JM72muIcuDp/hgPa0CH1cusnj40=", - "requires": { - "babel-helper-replace-supers": "^6.24.1", - "babel-runtime": "^6.22.0" - } - }, - "babel-plugin-transform-es2015-parameters": { - "version": "6.24.1", - "resolved": "https://registry.npmjs.org/babel-plugin-transform-es2015-parameters/-/babel-plugin-transform-es2015-parameters-6.24.1.tgz", - "integrity": "sha1-V6w1GrScrxSpfNE7CfZv3wpiXys=", - "requires": { - "babel-helper-call-delegate": "^6.24.1", - "babel-helper-get-function-arity": "^6.24.1", - "babel-runtime": "^6.22.0", - "babel-template": "^6.24.1", - "babel-traverse": "^6.24.1", - "babel-types": "^6.24.1" - } - }, - "babel-plugin-transform-es2015-shorthand-properties": { - "version": "6.24.1", - "resolved": "https://registry.npmjs.org/babel-plugin-transform-es2015-shorthand-properties/-/babel-plugin-transform-es2015-shorthand-properties-6.24.1.tgz", - "integrity": "sha1-JPh11nIch2YbvZmkYi5R8U3jiqA=", - "requires": { - "babel-runtime": "^6.22.0", - "babel-types": "^6.24.1" - } - }, - "babel-plugin-transform-es2015-spread": { - "version": "6.22.0", - "resolved": "https://registry.npmjs.org/babel-plugin-transform-es2015-spread/-/babel-plugin-transform-es2015-spread-6.22.0.tgz", - "integrity": "sha1-1taKmfia7cRTbIGlQujdnxdG+NE=", - "requires": { - "babel-runtime": "^6.22.0" - } - }, - "babel-plugin-transform-es2015-sticky-regex": { - "version": "6.24.1", - "resolved": "https://registry.npmjs.org/babel-plugin-transform-es2015-sticky-regex/-/babel-plugin-transform-es2015-sticky-regex-6.24.1.tgz", - "integrity": "sha1-AMHNsaynERLN8M9hJsLta0V8zbw=", - "requires": { - "babel-helper-regex": "^6.24.1", - "babel-runtime": "^6.22.0", - "babel-types": "^6.24.1" - } - }, - "babel-plugin-transform-es2015-template-literals": { - "version": "6.22.0", - "resolved": "https://registry.npmjs.org/babel-plugin-transform-es2015-template-literals/-/babel-plugin-transform-es2015-template-literals-6.22.0.tgz", - "integrity": "sha1-qEs0UPfp+PH2g51taH2oS7EjbY0=", - "requires": { - "babel-runtime": "^6.22.0" - } - }, - "babel-plugin-transform-es2015-typeof-symbol": { - "version": "6.23.0", - "resolved": "https://registry.npmjs.org/babel-plugin-transform-es2015-typeof-symbol/-/babel-plugin-transform-es2015-typeof-symbol-6.23.0.tgz", - "integrity": "sha1-3sCfHN3/lLUqxz1QXITfWdzOs3I=", - "requires": { - "babel-runtime": "^6.22.0" - } - }, - "babel-plugin-transform-es2015-unicode-regex": { - "version": "6.24.1", - "resolved": "https://registry.npmjs.org/babel-plugin-transform-es2015-unicode-regex/-/babel-plugin-transform-es2015-unicode-regex-6.24.1.tgz", - "integrity": "sha1-04sS9C6nMj9yk4fxinxa4frrNek=", - "requires": { - "babel-helper-regex": "^6.24.1", - "babel-runtime": "^6.22.0", - "regexpu-core": "^2.0.0" - } - }, - "babel-plugin-transform-exponentiation-operator": { - "version": "6.24.1", - "resolved": "https://registry.npmjs.org/babel-plugin-transform-exponentiation-operator/-/babel-plugin-transform-exponentiation-operator-6.24.1.tgz", - "integrity": "sha1-KrDJx/MJj6SJB3cruBP+QejeOg4=", - "requires": { - "babel-helper-builder-binary-assignment-operator-visitor": "^6.24.1", - "babel-plugin-syntax-exponentiation-operator": "^6.8.0", - "babel-runtime": "^6.22.0" - } - }, - "babel-plugin-transform-regenerator": { - "version": "6.26.0", - "resolved": "https://registry.npmjs.org/babel-plugin-transform-regenerator/-/babel-plugin-transform-regenerator-6.26.0.tgz", - "integrity": "sha1-4HA2lvveJ/Cj78rPi03KL3s6jy8=", - "requires": { - "regenerator-transform": "^0.10.0" - } - }, - "babel-plugin-transform-strict-mode": { - "version": "6.24.1", - "resolved": "https://registry.npmjs.org/babel-plugin-transform-strict-mode/-/babel-plugin-transform-strict-mode-6.24.1.tgz", - "integrity": "sha1-1fr3qleKZbvlkc9e2uBKDGcCB1g=", - "requires": { - "babel-runtime": "^6.22.0", - "babel-types": "^6.24.1" - } - }, - "babel-preset-env": { - "version": "1.7.0", - "resolved": "https://registry.npmjs.org/babel-preset-env/-/babel-preset-env-1.7.0.tgz", - "integrity": "sha512-9OR2afuKDneX2/q2EurSftUYM0xGu4O2D9adAhVfADDhrYDaxXV0rBbevVYoY9n6nyX1PmQW/0jtpJvUNr9CHg==", - "requires": { - "babel-plugin-check-es2015-constants": "^6.22.0", - "babel-plugin-syntax-trailing-function-commas": "^6.22.0", - "babel-plugin-transform-async-to-generator": "^6.22.0", - "babel-plugin-transform-es2015-arrow-functions": "^6.22.0", - "babel-plugin-transform-es2015-block-scoped-functions": "^6.22.0", - "babel-plugin-transform-es2015-block-scoping": "^6.23.0", - "babel-plugin-transform-es2015-classes": "^6.23.0", - "babel-plugin-transform-es2015-computed-properties": "^6.22.0", - "babel-plugin-transform-es2015-destructuring": "^6.23.0", - "babel-plugin-transform-es2015-duplicate-keys": "^6.22.0", - "babel-plugin-transform-es2015-for-of": "^6.23.0", - "babel-plugin-transform-es2015-function-name": "^6.22.0", - "babel-plugin-transform-es2015-literals": "^6.22.0", - "babel-plugin-transform-es2015-modules-amd": "^6.22.0", - "babel-plugin-transform-es2015-modules-commonjs": "^6.23.0", - "babel-plugin-transform-es2015-modules-systemjs": "^6.23.0", - "babel-plugin-transform-es2015-modules-umd": "^6.23.0", - "babel-plugin-transform-es2015-object-super": "^6.22.0", - "babel-plugin-transform-es2015-parameters": "^6.23.0", - "babel-plugin-transform-es2015-shorthand-properties": "^6.22.0", - "babel-plugin-transform-es2015-spread": "^6.22.0", - "babel-plugin-transform-es2015-sticky-regex": "^6.22.0", - "babel-plugin-transform-es2015-template-literals": "^6.22.0", - "babel-plugin-transform-es2015-typeof-symbol": "^6.23.0", - "babel-plugin-transform-es2015-unicode-regex": "^6.22.0", - "babel-plugin-transform-exponentiation-operator": "^6.22.0", - "babel-plugin-transform-regenerator": "^6.22.0", - "browserslist": "^3.2.6", - "invariant": "^2.2.2", - "semver": "^5.3.0" - } - }, - "babel-register": { - "version": "6.26.0", - "resolved": "https://registry.npmjs.org/babel-register/-/babel-register-6.26.0.tgz", - "integrity": "sha1-btAhFz4vy0htestFxgCahW9kcHE=", - "requires": { - "babel-core": "^6.26.0", - "babel-runtime": "^6.26.0", - "core-js": "^2.5.0", - "home-or-tmp": "^2.0.0", - "lodash": "^4.17.4", - "mkdirp": "^0.5.1", - "source-map-support": "^0.4.15" - }, - "dependencies": { - "source-map-support": { - "version": "0.4.18", - "resolved": "https://registry.npmjs.org/source-map-support/-/source-map-support-0.4.18.tgz", - "integrity": "sha512-try0/JqxPLF9nOjvSta7tVondkP5dwgyLDjVoyMDlmjugT2lRZ1OfsrYTkCd2hkDnJTKRbO/Rl3orm8vlsUzbA==", - "requires": { - "source-map": "^0.5.6" - } - } - } - }, - "babel-runtime": { - "version": "6.26.0", - "resolved": "https://registry.npmjs.org/babel-runtime/-/babel-runtime-6.26.0.tgz", - "integrity": "sha1-llxwWGaOgrVde/4E/yM3vItWR/4=", - "requires": { - "core-js": "^2.4.0", - "regenerator-runtime": "^0.11.0" - } - }, - "babel-template": { - "version": "6.26.0", - "resolved": "https://registry.npmjs.org/babel-template/-/babel-template-6.26.0.tgz", - "integrity": "sha1-3gPi0WOWsGn0bdn/+FIfsaDjXgI=", - "requires": { - "babel-runtime": "^6.26.0", - "babel-traverse": "^6.26.0", - "babel-types": "^6.26.0", - "babylon": "^6.18.0", - "lodash": "^4.17.4" - } - }, - "babel-traverse": { - "version": "6.26.0", - "resolved": "https://registry.npmjs.org/babel-traverse/-/babel-traverse-6.26.0.tgz", - "integrity": "sha1-RqnL1+3MYsjlwGTi0tjQ9ANXZu4=", - "requires": { - "babel-code-frame": "^6.26.0", - "babel-messages": "^6.23.0", - "babel-runtime": "^6.26.0", - "babel-types": "^6.26.0", - "babylon": "^6.18.0", - "debug": "^2.6.8", - "globals": "^9.18.0", - "invariant": "^2.2.2", - "lodash": "^4.17.4" - }, - "dependencies": { - "debug": { - "version": "2.6.9", - "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", - "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", - "requires": { - "ms": "2.0.0" - } - } - } - }, - "babel-types": { - "version": "6.26.0", - "resolved": "https://registry.npmjs.org/babel-types/-/babel-types-6.26.0.tgz", - "integrity": "sha1-o7Bz+Uq0nrb6Vc1lInozQ4BjJJc=", - "requires": { - "babel-runtime": "^6.26.0", - "esutils": "^2.0.2", - "lodash": "^4.17.4", - "to-fast-properties": "^1.0.3" - } - }, - "babelify": { - "version": "7.3.0", - "resolved": "http://registry.npmjs.org/babelify/-/babelify-7.3.0.tgz", - "integrity": "sha1-qlau3nBn/XvVSWZu4W3ChQh+iOU=", - "requires": { - "babel-core": "^6.0.14", - "object-assign": "^4.0.0" - } - }, - "babylon": { - "version": "6.18.0", - "resolved": "https://registry.npmjs.org/babylon/-/babylon-6.18.0.tgz", - "integrity": "sha512-q/UEjfGJ2Cm3oKV71DJz9d25TPnq5rhBVL2Q4fA5wcC3jcrdn7+SssEybFIxwAvvP+YCsCYNKughoF33GxgycQ==" - }, - "backoff": { - "version": "2.5.0", - "resolved": "https://registry.npmjs.org/backoff/-/backoff-2.5.0.tgz", - "integrity": "sha1-9hbtqdPktmuMp/ynn2lXIsX44m8=", - "requires": { - "precond": "0.2" - } - }, - "balanced-match": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.0.tgz", - "integrity": "sha1-ibTRmasr7kneFk6gK4nORi1xt2c=" - }, - "base-x": { - "version": "3.0.5", - "resolved": "https://registry.npmjs.org/base-x/-/base-x-3.0.5.tgz", - "integrity": "sha512-C3picSgzPSLE+jW3tcBzJoGwitOtazb5B+5YmAxZm2ybmTi9LNgAtDO/jjVEBZwHoXmDBZ9m/IELj3elJVRBcA==", - "optional": true, - "requires": { - "safe-buffer": "^5.0.1" - } - }, - "base64-js": { - "version": "1.3.0", - "resolved": "https://registry.npmjs.org/base64-js/-/base64-js-1.3.0.tgz", - "integrity": "sha512-ccav/yGvoa80BQDljCxsmmQ3Xvx60/UpBIij5QN21W3wBi/hhIC9OoO+KLpu9IJTS9j4DRVJ3aDDF9cMSoa2lw==", - "optional": true - }, - "bcrypt-pbkdf": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/bcrypt-pbkdf/-/bcrypt-pbkdf-1.0.2.tgz", - "integrity": "sha1-pDAdOJtqQ/m2f/PKEaP2Y342Dp4=", - "requires": { - "tweetnacl": "^0.14.3" - } - }, - "bindings": { - "version": "1.3.0", - "resolved": "https://registry.npmjs.org/bindings/-/bindings-1.3.0.tgz", - "integrity": "sha512-DpLh5EzMR2kzvX1KIlVC0VkC3iZtHKTgdtZ0a3pglBZdaQFjt5S9g9xd1lE+YvXyfd6mtCeRnrUfOLYiTMlNSw==" - }, - "bip39": { - "version": "2.5.0", - "resolved": "https://registry.npmjs.org/bip39/-/bip39-2.5.0.tgz", - "integrity": "sha512-xwIx/8JKoT2+IPJpFEfXoWdYwP7UVAoUxxLNfGCfVowaJE7yg1Y5B1BVPqlUNsBq5/nGwmFkwRJ8xDW4sX8OdA==", - "requires": { - "create-hash": "^1.1.0", - "pbkdf2": "^3.0.9", - "randombytes": "^2.0.1", - "safe-buffer": "^5.0.1", - "unorm": "^1.3.3" - } - }, - "bip66": { - "version": "1.1.5", - "resolved": "https://registry.npmjs.org/bip66/-/bip66-1.1.5.tgz", - "integrity": "sha1-AfqHSHhcpwlV1QESF9GzE5lpyiI=", - "requires": { - "safe-buffer": "^5.0.1" - } - }, - "bl": { - "version": "1.2.2", - "resolved": "http://registry.npmjs.org/bl/-/bl-1.2.2.tgz", - "integrity": "sha512-e8tQYnZodmebYDWGH7KMRvtzKXaJHx3BbilrgZCfvyLUYdKpK1t5PSPmpkny/SgiTSCnjfLW7v5rlONXVFkQEA==", - "requires": { - "readable-stream": "^2.3.5", - "safe-buffer": "^5.1.1" - } - }, - "block-stream": { - "version": "0.0.9", - "resolved": "https://registry.npmjs.org/block-stream/-/block-stream-0.0.9.tgz", - "integrity": "sha1-E+v+d4oDIFz+A3UUgeu0szAMEmo=", - "optional": true, - "requires": { - "inherits": "~2.0.0" - } - }, - "bluebird": { - "version": "3.5.3", - "resolved": "https://registry.npmjs.org/bluebird/-/bluebird-3.5.3.tgz", - "integrity": "sha512-/qKPUQlaW1OyR51WeCPBvRnAlnZFUJkCSG5HzGnuIqhgyJtF+T94lFnn33eiazjRm2LAHVy2guNnaq48X9SJuw==", - "optional": true - }, - "bn.js": { - "version": "4.11.8", - "resolved": "https://registry.npmjs.org/bn.js/-/bn.js-4.11.8.tgz", - "integrity": "sha512-ItfYfPLkWHUjckQCk8xC+LwxgK8NYcXywGigJgSwOP8Y2iyWT4f2vsZnoOXTTbo+o5yXmIUJ4gn5538SO5S3gA==" - }, - "body-parser": { - "version": "1.18.3", - "resolved": "https://registry.npmjs.org/body-parser/-/body-parser-1.18.3.tgz", - "integrity": "sha1-WykhmP/dVTs6DyDe0FkrlWlVyLQ=", - "requires": { - "bytes": "3.0.0", - "content-type": "~1.0.4", - "debug": "2.6.9", - "depd": "~1.1.2", - "http-errors": "~1.6.3", - "iconv-lite": "0.4.23", - "on-finished": "~2.3.0", - "qs": "6.5.2", - "raw-body": "2.3.3", - "type-is": "~1.6.16" - }, - "dependencies": { - "debug": { - "version": "2.6.9", - "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", - "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", - "requires": { - "ms": "2.0.0" - } - } - } - }, - "brace-expansion": { - "version": "1.1.11", - "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz", - "integrity": "sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==", - "requires": { - "balanced-match": "^1.0.0", - "concat-map": "0.0.1" - } - }, - "brorand": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/brorand/-/brorand-1.1.0.tgz", - "integrity": "sha1-EsJe/kCkXjwyPrhnWgoM5XsiNx8=" - }, - "browserify-aes": { - "version": "1.2.0", - "resolved": "http://registry.npmjs.org/browserify-aes/-/browserify-aes-1.2.0.tgz", - "integrity": "sha512-+7CHXqGuspUn/Sl5aO7Ea0xWGAtETPXNSAjHo48JfLdPWcMng33Xe4znFvQweqc/uzk5zSOI3H52CYnjCfb5hA==", - "requires": { - "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": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/browserify-cipher/-/browserify-cipher-1.0.1.tgz", - "integrity": "sha512-sPhkz0ARKbf4rRQt2hTpAHqn47X3llLkUGn+xEJzLjwY8LRs2p0v7ljvI5EyoRO/mexrNunNECisZs+gw2zz1w==", - "optional": true, - "requires": { - "browserify-aes": "^1.0.4", - "browserify-des": "^1.0.0", - "evp_bytestokey": "^1.0.0" - } - }, - "browserify-des": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/browserify-des/-/browserify-des-1.0.2.tgz", - "integrity": "sha512-BioO1xf3hFwz4kc6iBhI3ieDFompMhrMlnDFC4/0/vd5MokpuAc3R+LYbwTA9A5Yc9pq9UYPqffKpW2ObuwX5A==", - "optional": true, - "requires": { - "cipher-base": "^1.0.1", - "des.js": "^1.0.0", - "inherits": "^2.0.1", - "safe-buffer": "^5.1.2" - } - }, - "browserify-rsa": { - "version": "4.0.1", - "resolved": "http://registry.npmjs.org/browserify-rsa/-/browserify-rsa-4.0.1.tgz", - "integrity": "sha1-IeCr+vbyApzy+vsTNWenAdQTVSQ=", - "requires": { - "bn.js": "^4.1.0", - "randombytes": "^2.0.1" - } - }, - "browserify-sha3": { - "version": "0.0.1", - "resolved": "https://registry.npmjs.org/browserify-sha3/-/browserify-sha3-0.0.1.tgz", - "integrity": "sha1-P/NKMAbvFcD7NWflQbkaI0ASPRE=", - "requires": { - "js-sha3": "^0.3.1" - } - }, - "browserify-sign": { - "version": "4.0.4", - "resolved": "https://registry.npmjs.org/browserify-sign/-/browserify-sign-4.0.4.tgz", - "integrity": "sha1-qk62jl17ZYuqa/alfmMMvXqT0pg=", - "optional": true, - "requires": { - "bn.js": "^4.1.1", - "browserify-rsa": "^4.0.0", - "create-hash": "^1.1.0", - "create-hmac": "^1.1.2", - "elliptic": "^6.0.0", - "inherits": "^2.0.1", - "parse-asn1": "^5.0.0" - } - }, - "browserslist": { - "version": "3.2.8", - "resolved": "https://registry.npmjs.org/browserslist/-/browserslist-3.2.8.tgz", - "integrity": "sha512-WHVocJYavUwVgVViC0ORikPHQquXwVh939TaelZ4WDqpWgTX/FsGhl/+P4qBUAGcRvtOgDgC+xftNWWp2RUTAQ==", - "requires": { - "caniuse-lite": "^1.0.30000844", - "electron-to-chromium": "^1.3.47" - } - }, - "bs58": { - "version": "4.0.1", - "resolved": "https://registry.npmjs.org/bs58/-/bs58-4.0.1.tgz", - "integrity": "sha1-vhYedsNU9veIrkBx9j806MTwpCo=", - "optional": true, - "requires": { - "base-x": "^3.0.2" - } - }, - "bs58check": { - "version": "2.1.2", - "resolved": "https://registry.npmjs.org/bs58check/-/bs58check-2.1.2.tgz", - "integrity": "sha512-0TS1jicxdU09dwJMNZtVAfzPi6Q6QeN0pM1Fkzrjn+XYHvzMKPU3pHVpva+769iNVSfIYWf7LJ6WR+BuuMf8cA==", - "optional": true, - "requires": { - "bs58": "^4.0.0", - "create-hash": "^1.1.0", - "safe-buffer": "^5.1.2" - } - }, - "buffer": { - "version": "5.2.1", - "resolved": "https://registry.npmjs.org/buffer/-/buffer-5.2.1.tgz", - "integrity": "sha512-c+Ko0loDaFfuPWiL02ls9Xd3GO3cPVmUobQ6t3rXNUk304u6hGq+8N/kFi+QEIKhzK3uwolVhLzszmfLmMLnqg==", - "optional": true, - "requires": { - "base64-js": "^1.0.2", - "ieee754": "^1.1.4" - } - }, - "buffer-alloc": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/buffer-alloc/-/buffer-alloc-1.2.0.tgz", - "integrity": "sha512-CFsHQgjtW1UChdXgbyJGtnm+O/uLQeZdtbDo8mfUgYXCHSM1wgrVxXm6bSyrUuErEb+4sYVGCzASBRot7zyrow==", - "requires": { - "buffer-alloc-unsafe": "^1.1.0", - "buffer-fill": "^1.0.0" - } - }, - "buffer-alloc-unsafe": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/buffer-alloc-unsafe/-/buffer-alloc-unsafe-1.1.0.tgz", - "integrity": "sha512-TEM2iMIEQdJ2yjPJoSIsldnleVaAk1oW3DBVUykyOLsEsFmEc9kn+SFFPz+gl54KQNxlDnAwCXosOS9Okx2xAg==" - }, - "buffer-crc32": { - "version": "0.2.13", - "resolved": "https://registry.npmjs.org/buffer-crc32/-/buffer-crc32-0.2.13.tgz", - "integrity": "sha1-DTM+PwDqxQqhRUq9MO+MKl2ackI=", - "optional": true - }, - "buffer-fill": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/buffer-fill/-/buffer-fill-1.0.0.tgz", - "integrity": "sha1-+PeLdniYiO858gXNY39o5wISKyw=" - }, - "buffer-from": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/buffer-from/-/buffer-from-1.1.1.tgz", - "integrity": "sha512-MQcXEUbCKtEo7bhqEs6560Hyd4XaovZlO/k9V3hjVUF/zwW7KBVdSK4gIt/bzwS9MbR5qob+F5jusZsb0YQK2A==" - }, - "buffer-to-arraybuffer": { - "version": "0.0.5", - "resolved": "https://registry.npmjs.org/buffer-to-arraybuffer/-/buffer-to-arraybuffer-0.0.5.tgz", - "integrity": "sha1-YGSkD6dutDxyOrqe+PbhIW0QURo=" - }, - "buffer-xor": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/buffer-xor/-/buffer-xor-1.0.3.tgz", - "integrity": "sha1-JuYe0UIvtw3ULm42cp7VHYVf6Nk=" - }, - "builtin-modules": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/builtin-modules/-/builtin-modules-1.1.1.tgz", - "integrity": "sha1-Jw8HbFpywC9bZaR9+Uxf46J4iS8=" - }, - "bytes": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/bytes/-/bytes-3.0.0.tgz", - "integrity": "sha1-0ygVQE1olpn4Wk6k+odV3ROpYEg=" - }, - "bytewise": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/bytewise/-/bytewise-1.1.0.tgz", - "integrity": "sha1-HRPL/3F65xWAlKqIGzXQgbOHJT4=", - "requires": { - "bytewise-core": "^1.2.2", - "typewise": "^1.0.3" - } - }, - "bytewise-core": { - "version": "1.2.3", - "resolved": "https://registry.npmjs.org/bytewise-core/-/bytewise-core-1.2.3.tgz", - "integrity": "sha1-P7QQx+kVWOsasiqCg0V3qmvWHUI=", - "requires": { - "typewise-core": "^1.2" - } - }, - "cachedown": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/cachedown/-/cachedown-1.0.0.tgz", - "integrity": "sha1-1D8DbkUQaWsxJG19sx6/D3rDLRU=", - "requires": { - "abstract-leveldown": "^2.4.1", - "lru-cache": "^3.2.0" - }, - "dependencies": { - "abstract-leveldown": { - "version": "2.7.2", - "resolved": "https://registry.npmjs.org/abstract-leveldown/-/abstract-leveldown-2.7.2.tgz", - "integrity": "sha512-+OVvxH2rHVEhWLdbudP6p0+dNMXu8JA1CbhP19T8paTYAcX7oJ4OVjT+ZUVpv7mITxXHqDMej+GdqXBmXkw09w==", - "requires": { - "xtend": "~4.0.0" - } - } - } - }, - "camelcase": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-3.0.0.tgz", - "integrity": "sha1-MvxLn82vhF/N9+c7uXysImHwqwo=" - }, - "caniuse-lite": { - "version": "1.0.30000907", - "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30000907.tgz", - "integrity": "sha512-No5sQ/OB2Nmka8MNOOM6nJx+Hxt6MQ6h7t7kgJFu9oTuwjykyKRSBP/+i/QAyFHxeHB+ddE0Da1CG5ihx9oehQ==" - }, - "caseless": { - "version": "0.12.0", - "resolved": "https://registry.npmjs.org/caseless/-/caseless-0.12.0.tgz", - "integrity": "sha1-G2gcIf+EAzyCZUMJBolCDRhxUdw=" - }, - "chalk": { - "version": "1.1.3", - "resolved": "http://registry.npmjs.org/chalk/-/chalk-1.1.3.tgz", - "integrity": "sha1-qBFcVeSnAv5NFQq9OHKCKn4J/Jg=", - "requires": { - "ansi-styles": "^2.2.1", - "escape-string-regexp": "^1.0.2", - "has-ansi": "^2.0.0", - "strip-ansi": "^3.0.0", - "supports-color": "^2.0.0" - } - }, - "checkpoint-store": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/checkpoint-store/-/checkpoint-store-1.1.0.tgz", - "integrity": "sha1-BOTLUWuRQziTWB5tRgGnjpVS6gY=", - "requires": { - "functional-red-black-tree": "^1.0.1" - } - }, - "cipher-base": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/cipher-base/-/cipher-base-1.0.4.tgz", - "integrity": "sha512-Kkht5ye6ZGmwv40uUDZztayT2ThLQGfnj/T71N/XzeZeo3nf8foyW7zGTsPYkEya3m5f3cAypH+qe7YOrM1U2Q==", - "requires": { - "inherits": "^2.0.1", - "safe-buffer": "^5.0.1" - } - }, - "cliui": { - "version": "3.2.0", - "resolved": "https://registry.npmjs.org/cliui/-/cliui-3.2.0.tgz", - "integrity": "sha1-EgYBU3qRbSmUD5NNo7SNWFo5IT0=", - "requires": { - "string-width": "^1.0.1", - "strip-ansi": "^3.0.1", - "wrap-ansi": "^2.0.0" - } - }, - "clone": { - "version": "2.1.2", - "resolved": "https://registry.npmjs.org/clone/-/clone-2.1.2.tgz", - "integrity": "sha1-G39Ln1kfHo+DZwQBYANFoCiHQ18=" - }, - "code-point-at": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/code-point-at/-/code-point-at-1.1.0.tgz", - "integrity": "sha1-DQcLTQQ6W+ozovGkDi7bPZpMz3c=" - }, - "coinstring": { - "version": "2.3.0", - "resolved": "https://registry.npmjs.org/coinstring/-/coinstring-2.3.0.tgz", - "integrity": "sha1-zbYzY6lhUCQEolr7gsLibV/2J6Q=", - "optional": true, - "requires": { - "bs58": "^2.0.1", - "create-hash": "^1.1.1" - }, - "dependencies": { - "bs58": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/bs58/-/bs58-2.0.1.tgz", - "integrity": "sha1-VZCNWPGYKrogCPob7Y+RmYopv40=", - "optional": true - } - } - }, - "combined-stream": { - "version": "1.0.7", - "resolved": "https://registry.npmjs.org/combined-stream/-/combined-stream-1.0.7.tgz", - "integrity": "sha512-brWl9y6vOB1xYPZcpZde3N9zDByXTosAeMDo4p1wzo6UMOX4vumB+TP1RZ76sfE6Md68Q0NJSrE/gbezd4Ul+w==", - "requires": { - "delayed-stream": "~1.0.0" - } - }, - "commander": { - "version": "2.8.1", - "resolved": "http://registry.npmjs.org/commander/-/commander-2.8.1.tgz", - "integrity": "sha1-Br42f+v9oMMwqh4qBy09yXYkJdQ=", - "requires": { - "graceful-readlink": ">= 1.0.0" - } - }, - "concat-map": { - "version": "0.0.1", - "resolved": "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz", - "integrity": "sha1-2Klr13/Wjfd5OnMDajug1UBdR3s=" - }, - "concat-stream": { - "version": "1.6.2", - "resolved": "https://registry.npmjs.org/concat-stream/-/concat-stream-1.6.2.tgz", - "integrity": "sha512-27HBghJxjiZtIk3Ycvn/4kbJk/1uZuJFfuPEns6LaEvpvG1f0hTea8lilrouyo9mVc2GWdcEZ8OLoGmSADlrCw==", - "requires": { - "buffer-from": "^1.0.0", - "inherits": "^2.0.3", - "readable-stream": "^2.2.2", - "typedarray": "^0.0.6" - } - }, - "content-disposition": { - "version": "0.5.2", - "resolved": "https://registry.npmjs.org/content-disposition/-/content-disposition-0.5.2.tgz", - "integrity": "sha1-DPaLud318r55YcOoUXjLhdunjLQ=" - }, - "content-type": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/content-type/-/content-type-1.0.4.tgz", - "integrity": "sha512-hIP3EEPs8tB9AT1L+NUqtwOAps4mk2Zob89MWXMHjHWg9milF/j4osnnQLXBCBFBk/tvIG/tUc9mOUJiPBhPXA==" - }, - "convert-source-map": { - "version": "1.6.0", - "resolved": "https://registry.npmjs.org/convert-source-map/-/convert-source-map-1.6.0.tgz", - "integrity": "sha512-eFu7XigvxdZ1ETfbgPBohgyQ/Z++C0eEhTor0qRwBw9unw+L0/6V8wkSuGgzdThkiS5lSpdptOQPD8Ak40a+7A==", - "requires": { - "safe-buffer": "~5.1.1" - } - }, - "cookie": { - "version": "0.3.1", - "resolved": "https://registry.npmjs.org/cookie/-/cookie-0.3.1.tgz", - "integrity": "sha1-5+Ch+e9DtMi6klxcWpboBtFoc7s=" - }, - "cookie-signature": { - "version": "1.0.6", - "resolved": "https://registry.npmjs.org/cookie-signature/-/cookie-signature-1.0.6.tgz", - "integrity": "sha1-4wOogrNCzD7oylE6eZmXNNqzriw=" - }, - "cookiejar": { - "version": "2.1.2", - "resolved": "https://registry.npmjs.org/cookiejar/-/cookiejar-2.1.2.tgz", - "integrity": "sha512-Mw+adcfzPxcPeI+0WlvRrr/3lGVO0bD75SxX6811cxSh1Wbxx7xZBGK1eVtDf6si8rg2lhnUjsVLMFMfbRIuwA==" - }, - "core-js": { - "version": "2.5.7", - "resolved": "https://registry.npmjs.org/core-js/-/core-js-2.5.7.tgz", - "integrity": "sha512-RszJCAxg/PP6uzXVXL6BsxSXx/B05oJAQ2vkJRjyjrEcNVycaqOmNb5OTxZPE3xa5gwZduqza6L9JOCenh/Ecw==" - }, - "core-util-is": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/core-util-is/-/core-util-is-1.0.2.tgz", - "integrity": "sha1-tf1UIgqivFq1eqtxQMlAdUUDwac=" - }, - "cors": { - "version": "2.8.5", - "resolved": "https://registry.npmjs.org/cors/-/cors-2.8.5.tgz", - "integrity": "sha512-KIHbLJqu73RGr/hnbrO9uBeixNGuvSQjul/jdFvS/KFSIH1hWVd1ng7zOHx+YrEfInLG7q4n6GHQ9cDtxv/P6g==", - "requires": { - "object-assign": "^4", - "vary": "^1" - } - }, - "create-ecdh": { - "version": "4.0.3", - "resolved": "https://registry.npmjs.org/create-ecdh/-/create-ecdh-4.0.3.tgz", - "integrity": "sha512-GbEHQPMOswGpKXM9kCWVrremUcBmjteUaQ01T9rkKCPDXfUHX0IoP9LpHYo2NPFampa4e+/pFDc3jQdxrxQLaw==", - "optional": true, - "requires": { - "bn.js": "^4.1.0", - "elliptic": "^6.0.0" - } - }, - "create-hash": { - "version": "1.2.0", - "resolved": "http://registry.npmjs.org/create-hash/-/create-hash-1.2.0.tgz", - "integrity": "sha512-z00bCGNHDG8mHAkP7CtT1qVu+bFQUPjYq/4Iv3C3kWjTFV10zIjfSoeqXo9Asws8gwSHDGj/hl2u4OGIjapeCg==", - "requires": { - "cipher-base": "^1.0.1", - "inherits": "^2.0.1", - "md5.js": "^1.3.4", - "ripemd160": "^2.0.1", - "sha.js": "^2.4.0" - } - }, - "create-hmac": { - "version": "1.1.7", - "resolved": "http://registry.npmjs.org/create-hmac/-/create-hmac-1.1.7.tgz", - "integrity": "sha512-MJG9liiZ+ogc4TzUwuvbER1JRdgvUFSB5+VR/g5h82fGaIRWMWddtKBHi7/sVhfjQZ6SehlyhvQYrcYkaUIpLg==", - "requires": { - "cipher-base": "^1.0.3", - "create-hash": "^1.1.0", - "inherits": "^2.0.1", - "ripemd160": "^2.0.0", - "safe-buffer": "^5.0.1", - "sha.js": "^2.4.8" - } - }, - "cross-fetch": { - "version": "2.2.3", - "resolved": "https://registry.npmjs.org/cross-fetch/-/cross-fetch-2.2.3.tgz", - "integrity": "sha512-PrWWNH3yL2NYIb/7WF/5vFG3DCQiXDOVf8k3ijatbrtnwNuhMWLC7YF7uqf53tbTFDzHIUD8oITw4Bxt8ST3Nw==", - "requires": { - "node-fetch": "2.1.2", - "whatwg-fetch": "2.0.4" - } - }, - "crypto-browserify": { - "version": "3.12.0", - "resolved": "https://registry.npmjs.org/crypto-browserify/-/crypto-browserify-3.12.0.tgz", - "integrity": "sha512-fz4spIh+znjO2VjL+IdhEpRJ3YN6sMzITSBijk6FK2UvTqruSQW+/cCZTSNsMiZNvUeq0CqurF+dAbyiGOY6Wg==", - "optional": true, - "requires": { - "browserify-cipher": "^1.0.0", - "browserify-sign": "^4.0.0", - "create-ecdh": "^4.0.0", - "create-hash": "^1.1.0", - "create-hmac": "^1.1.0", - "diffie-hellman": "^5.0.0", - "inherits": "^2.0.1", - "pbkdf2": "^3.0.3", - "public-encrypt": "^4.0.0", - "randombytes": "^2.0.0", - "randomfill": "^1.0.3" - } - }, - "dashdash": { - "version": "1.14.1", - "resolved": "https://registry.npmjs.org/dashdash/-/dashdash-1.14.1.tgz", - "integrity": "sha1-hTz6D3y+L+1d4gMmuN1YEDX24vA=", - "requires": { - "assert-plus": "^1.0.0" - } - }, - "debug": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/debug/-/debug-3.1.0.tgz", - "integrity": "sha512-OX8XqP7/1a9cqkxYw2yXss15f26NKWBpDXQd0/uK/KPqdQhxbPa994hnzjcE2VqQpDslf55723cKPUOGSmMY3g==", - "requires": { - "ms": "2.0.0" - } - }, - "decamelize": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/decamelize/-/decamelize-1.2.0.tgz", - "integrity": "sha1-9lNNFRSCabIDUue+4m9QH5oZEpA=" - }, - "decode-uri-component": { - "version": "0.2.0", - "resolved": "https://registry.npmjs.org/decode-uri-component/-/decode-uri-component-0.2.0.tgz", - "integrity": "sha1-6zkTMzRYd1y4TNGh+uBiEGu4dUU=" - }, - "decompress": { - "version": "4.2.0", - "resolved": "https://registry.npmjs.org/decompress/-/decompress-4.2.0.tgz", - "integrity": "sha1-eu3YVCflqS2s/lVnSnxQXpbQH50=", - "optional": true, - "requires": { - "decompress-tar": "^4.0.0", - "decompress-tarbz2": "^4.0.0", - "decompress-targz": "^4.0.0", - "decompress-unzip": "^4.0.1", - "graceful-fs": "^4.1.10", - "make-dir": "^1.0.0", - "pify": "^2.3.0", - "strip-dirs": "^2.0.0" - }, - "dependencies": { - "pify": { - "version": "2.3.0", - "resolved": "http://registry.npmjs.org/pify/-/pify-2.3.0.tgz", - "integrity": "sha1-7RQaasBDqEnqWISY59yosVMw6Qw=", - "optional": true - } - } - }, - "decompress-response": { - "version": "3.3.0", - "resolved": "https://registry.npmjs.org/decompress-response/-/decompress-response-3.3.0.tgz", - "integrity": "sha1-gKTdMjdIOEv6JICDYirt7Jgq3/M=", - "requires": { - "mimic-response": "^1.0.0" - } - }, - "decompress-tar": { - "version": "4.1.1", - "resolved": "https://registry.npmjs.org/decompress-tar/-/decompress-tar-4.1.1.tgz", - "integrity": "sha512-JdJMaCrGpB5fESVyxwpCx4Jdj2AagLmv3y58Qy4GE6HMVjWz1FeVQk1Ct4Kye7PftcdOo/7U7UKzYBJgqnGeUQ==", - "requires": { - "file-type": "^5.2.0", - "is-stream": "^1.1.0", - "tar-stream": "^1.5.2" - } - }, - "decompress-tarbz2": { - "version": "4.1.1", - "resolved": "https://registry.npmjs.org/decompress-tarbz2/-/decompress-tarbz2-4.1.1.tgz", - "integrity": "sha512-s88xLzf1r81ICXLAVQVzaN6ZmX4A6U4z2nMbOwobxkLoIIfjVMBg7TeguTUXkKeXni795B6y5rnvDw7rxhAq9A==", - "optional": true, - "requires": { - "decompress-tar": "^4.1.0", - "file-type": "^6.1.0", - "is-stream": "^1.1.0", - "seek-bzip": "^1.0.5", - "unbzip2-stream": "^1.0.9" - }, - "dependencies": { - "file-type": { - "version": "6.2.0", - "resolved": "https://registry.npmjs.org/file-type/-/file-type-6.2.0.tgz", - "integrity": "sha512-YPcTBDV+2Tm0VqjybVd32MHdlEGAtuxS3VAYsumFokDSMG+ROT5wawGlnHDoz7bfMcMDt9hxuXvXwoKUx2fkOg==", - "optional": true - } - } - }, - "decompress-targz": { - "version": "4.1.1", - "resolved": "https://registry.npmjs.org/decompress-targz/-/decompress-targz-4.1.1.tgz", - "integrity": "sha512-4z81Znfr6chWnRDNfFNqLwPvm4db3WuZkqV+UgXQzSngG3CEKdBkw5jrv3axjjL96glyiiKjsxJG3X6WBZwX3w==", - "optional": true, - "requires": { - "decompress-tar": "^4.1.1", - "file-type": "^5.2.0", - "is-stream": "^1.1.0" - } - }, - "decompress-unzip": { - "version": "4.0.1", - "resolved": "https://registry.npmjs.org/decompress-unzip/-/decompress-unzip-4.0.1.tgz", - "integrity": "sha1-3qrM39FK6vhVePczroIQ+bSEj2k=", - "optional": true, - "requires": { - "file-type": "^3.8.0", - "get-stream": "^2.2.0", - "pify": "^2.3.0", - "yauzl": "^2.4.2" - }, - "dependencies": { - "file-type": { - "version": "3.9.0", - "resolved": "http://registry.npmjs.org/file-type/-/file-type-3.9.0.tgz", - "integrity": "sha1-JXoHg4TR24CHvESdEH1SpSZyuek=", - "optional": true - }, - "get-stream": { - "version": "2.3.1", - "resolved": "http://registry.npmjs.org/get-stream/-/get-stream-2.3.1.tgz", - "integrity": "sha1-Xzj5PzRgCWZu4BUKBUFn+Rvdld4=", - "optional": true, - "requires": { - "object-assign": "^4.0.1", - "pinkie-promise": "^2.0.0" - } - }, - "pify": { - "version": "2.3.0", - "resolved": "http://registry.npmjs.org/pify/-/pify-2.3.0.tgz", - "integrity": "sha1-7RQaasBDqEnqWISY59yosVMw6Qw=", - "optional": true - } - } - }, - "deep-equal": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/deep-equal/-/deep-equal-1.0.1.tgz", - "integrity": "sha1-9dJgKStmDghO/0zbyfCK0yR0SLU=" - }, - "deferred-leveldown": { - "version": "1.2.2", - "resolved": "https://registry.npmjs.org/deferred-leveldown/-/deferred-leveldown-1.2.2.tgz", - "integrity": "sha512-uukrWD2bguRtXilKt6cAWKyoXrTSMo5m7crUdLfWQmu8kIm88w3QZoUL+6nhpfKVmhHANER6Re3sKoNoZ3IKMA==", - "requires": { - "abstract-leveldown": "~2.6.0" - }, - "dependencies": { - "abstract-leveldown": { - "version": "2.6.3", - "resolved": "https://registry.npmjs.org/abstract-leveldown/-/abstract-leveldown-2.6.3.tgz", - "integrity": "sha512-2++wDf/DYqkPR3o5tbfdhF96EfMApo1GpPfzOsR/ZYXdkSmELlvOOEAl9iKkRsktMPHdGjO4rtkBpf2I7TiTeA==", - "requires": { - "xtend": "~4.0.0" - } - } - } - }, - "define-properties": { - "version": "1.1.3", - "resolved": "https://registry.npmjs.org/define-properties/-/define-properties-1.1.3.tgz", - "integrity": "sha512-3MqfYKj2lLzdMSf8ZIZE/V+Zuy+BgD6f164e8K2w7dgnpKArBDerGYpM46IYYcjnkdPNMjPk9A6VFB8+3SKlXQ==", - "requires": { - "object-keys": "^1.0.12" - }, - "dependencies": { - "object-keys": { - "version": "1.0.12", - "resolved": "https://registry.npmjs.org/object-keys/-/object-keys-1.0.12.tgz", - "integrity": "sha512-FTMyFUm2wBcGHnH2eXmz7tC6IwlqQZ6mVZ+6dm6vZ4IQIHjs6FdNsQBuKGPuUUUY6NfJw2PshC08Tn6LzLDOag==" - } - } - }, - "defined": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/defined/-/defined-1.0.0.tgz", - "integrity": "sha1-yY2bzvdWdBiOEQlpFRGZ45sfppM=" - }, - "delayed-stream": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/delayed-stream/-/delayed-stream-1.0.0.tgz", - "integrity": "sha1-3zrhmayt+31ECqrgsp4icrJOxhk=" - }, - "depd": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/depd/-/depd-1.1.2.tgz", - "integrity": "sha1-m81S4UwJd2PnSbJ0xDRu0uVgtak=" - }, - "des.js": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/des.js/-/des.js-1.0.0.tgz", - "integrity": "sha1-wHTS4qpqipoH29YfmhXCzYPsjsw=", - "optional": true, - "requires": { - "inherits": "^2.0.1", - "minimalistic-assert": "^1.0.0" - } - }, - "destroy": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/destroy/-/destroy-1.0.4.tgz", - "integrity": "sha1-l4hXRCxEdJ5CBmE+N5RiBYJqvYA=" - }, - "detect-indent": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/detect-indent/-/detect-indent-4.0.0.tgz", - "integrity": "sha1-920GQ1LN9Docts5hnE7jqUdd4gg=", - "requires": { - "repeating": "^2.0.0" - } - }, - "diffie-hellman": { - "version": "5.0.3", - "resolved": "http://registry.npmjs.org/diffie-hellman/-/diffie-hellman-5.0.3.tgz", - "integrity": "sha512-kqag/Nl+f3GwyK25fhUMYj81BUOrZ9IuJsjIcDE5icNM9FJHAVm3VcUDxdLPoQtTuUylWm6ZIknYJwwaPxsUzg==", - "optional": true, - "requires": { - "bn.js": "^4.1.0", - "miller-rabin": "^4.0.0", - "randombytes": "^2.0.0" - } - }, - "dom-walk": { - "version": "0.1.1", - "resolved": "https://registry.npmjs.org/dom-walk/-/dom-walk-0.1.1.tgz", - "integrity": "sha1-ZyIm3HTI95mtNTB9+TaroRrNYBg=" - }, - "drbg.js": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/drbg.js/-/drbg.js-1.0.1.tgz", - "integrity": "sha1-Pja2xCs3BDgjzbwzLVjzHiRFSAs=", - "requires": { - "browserify-aes": "^1.0.6", - "create-hash": "^1.1.2", - "create-hmac": "^1.1.4" - } - }, - "duplexer3": { - "version": "0.1.4", - "resolved": "https://registry.npmjs.org/duplexer3/-/duplexer3-0.1.4.tgz", - "integrity": "sha1-7gHdHKwO08vH/b6jfcCo8c4ALOI=" - }, - "ecc-jsbn": { - "version": "0.1.2", - "resolved": "https://registry.npmjs.org/ecc-jsbn/-/ecc-jsbn-0.1.2.tgz", - "integrity": "sha1-OoOpBOVDUyh4dMVkt1SThoSamMk=", - "requires": { - "jsbn": "~0.1.0", - "safer-buffer": "^2.1.0" - } - }, - "ee-first": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/ee-first/-/ee-first-1.1.1.tgz", - "integrity": "sha1-WQxhFWsK4vTwJVcyoViyZrxWsh0=" - }, - "electron-to-chromium": { - "version": "1.3.84", - "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.3.84.tgz", - "integrity": "sha512-IYhbzJYOopiTaNWMBp7RjbecUBsbnbDneOP86f3qvS0G0xfzwNSvMJpTrvi5/Y1gU7tg2NAgeg8a8rCYvW9Whw==" - }, - "elliptic": { - "version": "6.4.1", - "resolved": "https://registry.npmjs.org/elliptic/-/elliptic-6.4.1.tgz", - "integrity": "sha512-BsXLz5sqX8OHcsh7CqBMztyXARmGQ3LWPtGjJi6DiJHq5C/qvi9P3OqgswKSDftbu8+IoI/QDTAm2fFnQ9SZSQ==", - "requires": { - "bn.js": "^4.4.0", - "brorand": "^1.0.1", - "hash.js": "^1.0.0", - "hmac-drbg": "^1.0.0", - "inherits": "^2.0.1", - "minimalistic-assert": "^1.0.0", - "minimalistic-crypto-utils": "^1.0.0" - } - }, - "encodeurl": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/encodeurl/-/encodeurl-1.0.2.tgz", - "integrity": "sha1-rT/0yG7C0CkyL1oCw6mmBslbP1k=" - }, - "encoding": { - "version": "0.1.12", - "resolved": "https://registry.npmjs.org/encoding/-/encoding-0.1.12.tgz", - "integrity": "sha1-U4tm8+5izRq1HsMjgp0flIDHS+s=", - "requires": { - "iconv-lite": "~0.4.13" - } - }, - "encoding-down": { - "version": "5.0.4", - "resolved": "https://registry.npmjs.org/encoding-down/-/encoding-down-5.0.4.tgz", - "integrity": "sha512-8CIZLDcSKxgzT+zX8ZVfgNbu8Md2wq/iqa1Y7zyVR18QBEAc0Nmzuvj/N5ykSKpfGzjM8qxbaFntLPwnVoUhZw==", - "requires": { - "abstract-leveldown": "^5.0.0", - "inherits": "^2.0.3", - "level-codec": "^9.0.0", - "level-errors": "^2.0.0", - "xtend": "^4.0.1" - }, - "dependencies": { - "abstract-leveldown": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/abstract-leveldown/-/abstract-leveldown-5.0.0.tgz", - "integrity": "sha512-5mU5P1gXtsMIXg65/rsYGsi93+MlogXZ9FA8JnwKurHQg64bfXwGYVdVdijNTVNOlAsuIiOwHdvFFD5JqCJQ7A==", - "requires": { - "xtend": "~4.0.0" - } - } - } - }, - "end-of-stream": { - "version": "1.4.1", - "resolved": "https://registry.npmjs.org/end-of-stream/-/end-of-stream-1.4.1.tgz", - "integrity": "sha512-1MkrZNvWTKCaigbn+W15elq2BB/L22nqrSY5DKlo3X6+vclJm8Bb5djXJBmEX6fS3+zCh/F4VBK5Z2KxJt4s2Q==", - "requires": { - "once": "^1.4.0" - } - }, - "errno": { - "version": "0.1.7", - "resolved": "https://registry.npmjs.org/errno/-/errno-0.1.7.tgz", - "integrity": "sha512-MfrRBDWzIWifgq6tJj60gkAwtLNb6sQPlcFrSOflcP1aFmmruKQ2wRnze/8V6kgyz7H3FF8Npzv78mZ7XLLflg==", - "requires": { - "prr": "~1.0.1" - } - }, - "error-ex": { - "version": "1.3.2", - "resolved": "https://registry.npmjs.org/error-ex/-/error-ex-1.3.2.tgz", - "integrity": "sha512-7dFHNmqeFSEt2ZBsCriorKnn3Z2pj+fd9kmI6QoWw4//DL+icEBfc0U7qJCisqrTsKTjw4fNFy2pW9OqStD84g==", - "requires": { - "is-arrayish": "^0.2.1" - } - }, - "es-abstract": { - "version": "1.12.0", - "resolved": "https://registry.npmjs.org/es-abstract/-/es-abstract-1.12.0.tgz", - "integrity": "sha512-C8Fx/0jFmV5IPoMOFPA9P9G5NtqW+4cOPit3MIuvR2t7Ag2K15EJTpxnHAYTzL+aYQJIESYeXZmDBfOBE1HcpA==", - "requires": { - "es-to-primitive": "^1.1.1", - "function-bind": "^1.1.1", - "has": "^1.0.1", - "is-callable": "^1.1.3", - "is-regex": "^1.0.4" - } - }, - "es-to-primitive": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/es-to-primitive/-/es-to-primitive-1.2.0.tgz", - "integrity": "sha512-qZryBOJjV//LaxLTV6UC//WewneB3LcXOL9NP++ozKVXsIIIpm/2c13UDiD9Jp2eThsecw9m3jPqDwTyobcdbg==", - "requires": { - "is-callable": "^1.1.4", - "is-date-object": "^1.0.1", - "is-symbol": "^1.0.2" - } - }, - "escape-html": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/escape-html/-/escape-html-1.0.3.tgz", - "integrity": "sha1-Aljq5NPQwJdN4cFpGI7wBR0dGYg=" - }, - "escape-string-regexp": { - "version": "1.0.5", - "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz", - "integrity": "sha1-G2HAViGQqN/2rjuyzwIAyhMLhtQ=" - }, - "esutils": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/esutils/-/esutils-2.0.2.tgz", - "integrity": "sha1-Cr9PHKpbyx96nYrMbepPqqBLrJs=" - }, - "etag": { - "version": "1.8.1", - "resolved": "https://registry.npmjs.org/etag/-/etag-1.8.1.tgz", - "integrity": "sha1-Qa4u62XvpiJorr/qg6x9eSmbCIc=" - }, - "eth-block-tracker": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/eth-block-tracker/-/eth-block-tracker-3.0.1.tgz", - "integrity": "sha512-WUVxWLuhMmsfenfZvFO5sbl1qFY2IqUlw/FPVmjjdElpqLsZtSG+wPe9Dz7W/sB6e80HgFKknOmKk2eNlznHug==", - "requires": { - "eth-query": "^2.1.0", - "ethereumjs-tx": "^1.3.3", - "ethereumjs-util": "^5.1.3", - "ethjs-util": "^0.1.3", - "json-rpc-engine": "^3.6.0", - "pify": "^2.3.0", - "tape": "^4.6.3" - }, - "dependencies": { - "pify": { - "version": "2.3.0", - "resolved": "http://registry.npmjs.org/pify/-/pify-2.3.0.tgz", - "integrity": "sha1-7RQaasBDqEnqWISY59yosVMw6Qw=" - } - } - }, - "eth-json-rpc-infura": { - "version": "3.1.2", - "resolved": "https://registry.npmjs.org/eth-json-rpc-infura/-/eth-json-rpc-infura-3.1.2.tgz", - "integrity": "sha512-IuK5Iowfs6taluA/3Okmu6EfZcFMq6MQuyrUL1PrCoJstuuBr3TvVeSy3keDyxfbrjFB34nCo538I8G+qMtsbw==", - "requires": { - "cross-fetch": "^2.1.1", - "eth-json-rpc-middleware": "^1.5.0", - "json-rpc-engine": "^3.4.0", - "json-rpc-error": "^2.0.0", - "tape": "^4.8.0" - } - }, - "eth-json-rpc-middleware": { - "version": "1.6.0", - "resolved": "http://registry.npmjs.org/eth-json-rpc-middleware/-/eth-json-rpc-middleware-1.6.0.tgz", - "integrity": "sha512-tDVCTlrUvdqHKqivYMjtFZsdD7TtpNLBCfKAcOpaVs7orBMS/A8HWro6dIzNtTZIR05FAbJ3bioFOnZpuCew9Q==", - "requires": { - "async": "^2.5.0", - "eth-query": "^2.1.2", - "eth-tx-summary": "^3.1.2", - "ethereumjs-block": "^1.6.0", - "ethereumjs-tx": "^1.3.3", - "ethereumjs-util": "^5.1.2", - "ethereumjs-vm": "^2.1.0", - "fetch-ponyfill": "^4.0.0", - "json-rpc-engine": "^3.6.0", - "json-rpc-error": "^2.0.0", - "json-stable-stringify": "^1.0.1", - "promise-to-callback": "^1.0.0", - "tape": "^4.6.3" - }, - "dependencies": { - "ethereum-common": { - "version": "0.2.0", - "resolved": "https://registry.npmjs.org/ethereum-common/-/ethereum-common-0.2.0.tgz", - "integrity": "sha512-XOnAR/3rntJgbCdGhqdaLIxDLWKLmsZOGhHdBKadEr6gEnJLH52k93Ou+TUdFaPN3hJc3isBZBal3U/XZ15abA==" - }, - "ethereumjs-block": { - "version": "1.7.1", - "resolved": "http://registry.npmjs.org/ethereumjs-block/-/ethereumjs-block-1.7.1.tgz", - "integrity": "sha512-B+sSdtqm78fmKkBq78/QLKJbu/4Ts4P2KFISdgcuZUPDm9x+N7qgBPIIFUGbaakQh8bzuquiRVbdmvPKqbILRg==", - "requires": { - "async": "^2.0.1", - "ethereum-common": "0.2.0", - "ethereumjs-tx": "^1.2.2", - "ethereumjs-util": "^5.0.0", - "merkle-patricia-tree": "^2.1.2" - } - } - } - }, - "eth-lib": { - "version": "0.1.27", - "resolved": "https://registry.npmjs.org/eth-lib/-/eth-lib-0.1.27.tgz", - "integrity": "sha512-B8czsfkJYzn2UIEMwjc7Mbj+Cy72V+/OXH/tb44LV8jhrjizQJJ325xMOMyk3+ETa6r6oi0jsUY14+om8mQMWA==", - "requires": { - "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-query": { - "version": "2.1.2", - "resolved": "https://registry.npmjs.org/eth-query/-/eth-query-2.1.2.tgz", - "integrity": "sha1-1nQdkAAQa1FRDHLbktY2VFam2l4=", - "requires": { - "json-rpc-random-id": "^1.0.0", - "xtend": "^4.0.1" - } - }, - "eth-sig-util": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/eth-sig-util/-/eth-sig-util-2.0.2.tgz", - "integrity": "sha512-tB6E8jf/aZQ943bo3+iojl8xRe3Jzcl+9OT6v8K7kWis6PdIX19SB2vYvN849cB9G9m/XLjYFK381SgdbsnpTA==", - "requires": { - "ethereumjs-abi": "0.6.5", - "ethereumjs-util": "^5.1.1" - } - }, - "eth-tx-summary": { - "version": "3.2.3", - "resolved": "https://registry.npmjs.org/eth-tx-summary/-/eth-tx-summary-3.2.3.tgz", - "integrity": "sha512-1gZpA5fKarJOVSb5OUlPnhDQuIazqAkI61zlVvf5LdG47nEgw+/qhyZnuj3CUdE/TLTKuRzPLeyXLjaB4qWTRQ==", - "requires": { - "async": "^2.1.2", - "bn.js": "^4.11.8", - "clone": "^2.0.0", - "concat-stream": "^1.5.1", - "end-of-stream": "^1.1.0", - "eth-query": "^2.0.2", - "ethereumjs-block": "^1.4.1", - "ethereumjs-tx": "^1.1.1", - "ethereumjs-util": "^5.0.1", - "ethereumjs-vm": "2.3.4", - "through2": "^2.0.3", - "treeify": "^1.0.1", - "web3-provider-engine": "^13.3.2" - }, - "dependencies": { - "eth-block-tracker": { - "version": "2.3.1", - "resolved": "https://registry.npmjs.org/eth-block-tracker/-/eth-block-tracker-2.3.1.tgz", - "integrity": "sha512-NamWuMBIl8kmkJFVj8WzGatySTzQPQag4Xr677yFxdVtIxACFbL/dQowk0MzEqIKk93U1TwY3MjVU6mOcwZnKA==", - "requires": { - "async-eventemitter": "github:ahultgren/async-eventemitter#fa06e39e56786ba541c180061dbf2c0a5bbf951c", - "eth-query": "^2.1.0", - "ethereumjs-tx": "^1.3.3", - "ethereumjs-util": "^5.1.3", - "ethjs-util": "^0.1.3", - "json-rpc-engine": "^3.6.0", - "pify": "^2.3.0", - "tape": "^4.6.3" - }, - "dependencies": { - "async-eventemitter": { - "version": "github:ahultgren/async-eventemitter#fa06e39e56786ba541c180061dbf2c0a5bbf951c", - "from": "github:ahultgren/async-eventemitter#fa06e39e56786ba541c180061dbf2c0a5bbf951c", - "requires": { - "async": "^2.4.0" - } - } - } - }, - "eth-sig-util": { - "version": "1.4.2", - "resolved": "https://registry.npmjs.org/eth-sig-util/-/eth-sig-util-1.4.2.tgz", - "integrity": "sha1-jZWCAsftuq6Dlwf7pvCf8ydgYhA=", - "requires": { - "ethereumjs-abi": "git+https://github.com/ethereumjs/ethereumjs-abi.git#2863c40e0982acfc0b7163f0285d4c56427c7799", - "ethereumjs-util": "^5.1.1" - } - }, - "ethereum-common": { - "version": "0.2.0", - "resolved": "https://registry.npmjs.org/ethereum-common/-/ethereum-common-0.2.0.tgz", - "integrity": "sha512-XOnAR/3rntJgbCdGhqdaLIxDLWKLmsZOGhHdBKadEr6gEnJLH52k93Ou+TUdFaPN3hJc3isBZBal3U/XZ15abA==" - }, - "ethereumjs-abi": { - "version": "git+https://github.com/ethereumjs/ethereumjs-abi.git#2863c40e0982acfc0b7163f0285d4c56427c7799", - "from": "git+https://github.com/ethereumjs/ethereumjs-abi.git", - "requires": { - "bn.js": "^4.10.0", - "ethereumjs-util": "^5.0.0" - } - }, - "ethereumjs-block": { - "version": "1.7.1", - "resolved": "http://registry.npmjs.org/ethereumjs-block/-/ethereumjs-block-1.7.1.tgz", - "integrity": "sha512-B+sSdtqm78fmKkBq78/QLKJbu/4Ts4P2KFISdgcuZUPDm9x+N7qgBPIIFUGbaakQh8bzuquiRVbdmvPKqbILRg==", - "requires": { - "async": "^2.0.1", - "ethereum-common": "0.2.0", - "ethereumjs-tx": "^1.2.2", - "ethereumjs-util": "^5.0.0", - "merkle-patricia-tree": "^2.1.2" - } - }, - "ethereumjs-vm": { - "version": "2.3.4", - "resolved": "https://registry.npmjs.org/ethereumjs-vm/-/ethereumjs-vm-2.3.4.tgz", - "integrity": "sha512-Y4SlzNDqxrCO58jhp98HdnZVdjOqB+HC0hoU+N/DEp1aU+hFkRX/nru5F7/HkQRPIlA6aJlQp/xIA6xZs1kspw==", - "requires": { - "async": "^2.1.2", - "async-eventemitter": "^0.2.2", - "ethereum-common": "0.2.0", - "ethereumjs-account": "^2.0.3", - "ethereumjs-block": "~1.7.0", - "ethereumjs-util": "^5.1.3", - "fake-merkle-patricia-tree": "^1.0.1", - "functional-red-black-tree": "^1.0.1", - "merkle-patricia-tree": "^2.1.2", - "rustbn.js": "~0.1.1", - "safe-buffer": "^5.1.1" - } - }, - "fs-extra": { - "version": "0.30.0", - "resolved": "http://registry.npmjs.org/fs-extra/-/fs-extra-0.30.0.tgz", - "integrity": "sha1-8jP/zAjU2n1DLapEl3aYnbHfk/A=", - "requires": { - "graceful-fs": "^4.1.2", - "jsonfile": "^2.1.0", - "klaw": "^1.0.0", - "path-is-absolute": "^1.0.0", - "rimraf": "^2.2.8" - } - }, - "pify": { - "version": "2.3.0", - "resolved": "http://registry.npmjs.org/pify/-/pify-2.3.0.tgz", - "integrity": "sha1-7RQaasBDqEnqWISY59yosVMw6Qw=" - }, - "rustbn.js": { - "version": "0.1.2", - "resolved": "https://registry.npmjs.org/rustbn.js/-/rustbn.js-0.1.2.tgz", - "integrity": "sha512-bAkNqSHYdJdFsBC7Z11JgzYktL31HIpB2o70jZcGiL1U1TVtPyvaVhDrGWwS8uZtaqwW2k6NOPGZCqW/Dgh5Lg==" - }, - "web3-provider-engine": { - "version": "13.8.0", - "resolved": "http://registry.npmjs.org/web3-provider-engine/-/web3-provider-engine-13.8.0.tgz", - "integrity": "sha512-fZXhX5VWwWpoFfrfocslyg6P7cN3YWPG/ASaevNfeO80R+nzgoPUBXcWQekSGSsNDkeRTis4aMmpmofYf1TNtQ==", - "requires": { - "async": "^2.5.0", - "clone": "^2.0.0", - "eth-block-tracker": "^2.2.2", - "eth-sig-util": "^1.4.2", - "ethereumjs-block": "^1.2.2", - "ethereumjs-tx": "^1.2.0", - "ethereumjs-util": "^5.1.1", - "ethereumjs-vm": "^2.0.2", - "fetch-ponyfill": "^4.0.0", - "json-rpc-error": "^2.0.0", - "json-stable-stringify": "^1.0.1", - "promise-to-callback": "^1.0.0", - "readable-stream": "^2.2.9", - "request": "^2.67.0", - "semaphore": "^1.0.3", - "solc": "^0.4.2", - "tape": "^4.4.0", - "xhr": "^2.2.0", - "xtend": "^4.0.1" - } - } - } - }, - "ethereum-common": { - "version": "0.0.16", - "resolved": "https://registry.npmjs.org/ethereum-common/-/ethereum-common-0.0.16.tgz", - "integrity": "sha1-mh4Wnq00q3XgifUMpRK/0PvRJlU=" - }, - "ethereumjs-abi": { - "version": "0.6.5", - "resolved": "https://registry.npmjs.org/ethereumjs-abi/-/ethereumjs-abi-0.6.5.tgz", - "integrity": "sha1-WmN+8Wq0NHP6cqKa2QhxQFs/UkE=", - "requires": { - "bn.js": "^4.10.0", - "ethereumjs-util": "^4.3.0" - }, - "dependencies": { - "ethereumjs-util": { - "version": "4.5.0", - "resolved": "http://registry.npmjs.org/ethereumjs-util/-/ethereumjs-util-4.5.0.tgz", - "integrity": "sha1-PpQosxfuvaPXJg2FT93alUsfG8Y=", - "requires": { - "bn.js": "^4.8.0", - "create-hash": "^1.1.2", - "keccakjs": "^0.2.0", - "rlp": "^2.0.0", - "secp256k1": "^3.0.1" - } - } - } - }, - "ethereumjs-account": { - "version": "2.0.5", - "resolved": "https://registry.npmjs.org/ethereumjs-account/-/ethereumjs-account-2.0.5.tgz", - "integrity": "sha512-bgDojnXGjhMwo6eXQC0bY6UK2liSFUSMwwylOmQvZbSl/D7NXQ3+vrGO46ZeOgjGfxXmgIeVNDIiHw7fNZM4VA==", - "requires": { - "ethereumjs-util": "^5.0.0", - "rlp": "^2.0.0", - "safe-buffer": "^5.1.1" - } - }, - "ethereumjs-block": { - "version": "1.2.2", - "resolved": "http://registry.npmjs.org/ethereumjs-block/-/ethereumjs-block-1.2.2.tgz", - "integrity": "sha1-LsdTSlkCG47JuDww5JaQxuuu3aE=", - "requires": { - "async": "^1.5.2", - "ethereum-common": "0.0.16", - "ethereumjs-tx": "^1.0.0", - "ethereumjs-util": "^4.0.1", - "merkle-patricia-tree": "^2.1.2" - }, - "dependencies": { - "async": { - "version": "1.5.2", - "resolved": "http://registry.npmjs.org/async/-/async-1.5.2.tgz", - "integrity": "sha1-7GphrlZIDAw8skHJVhjiCJL5Zyo=" - }, - "ethereumjs-util": { - "version": "4.5.0", - "resolved": "http://registry.npmjs.org/ethereumjs-util/-/ethereumjs-util-4.5.0.tgz", - "integrity": "sha1-PpQosxfuvaPXJg2FT93alUsfG8Y=", - "requires": { - "bn.js": "^4.8.0", - "create-hash": "^1.1.2", - "keccakjs": "^0.2.0", - "rlp": "^2.0.0", - "secp256k1": "^3.0.1" - } - } - } - }, - "ethereumjs-common": { - "version": "0.4.1", - "resolved": "https://registry.npmjs.org/ethereumjs-common/-/ethereumjs-common-0.4.1.tgz", - "integrity": "sha512-ywYGsOeGCsMNWso5Y4GhjWI24FJv9FK7+VyVKiQgXg8ZRDPXJ7F/kJ1CnjtkjTvDF4e0yqU+FWswlqR3bmZQ9Q==" - }, - "ethereumjs-tx": { - "version": "1.3.7", - "resolved": "https://registry.npmjs.org/ethereumjs-tx/-/ethereumjs-tx-1.3.7.tgz", - "integrity": "sha512-wvLMxzt1RPhAQ9Yi3/HKZTn0FZYpnsmQdbKYfUUpi4j1SEIcbkd9tndVjcPrufY3V7j2IebOpC00Zp2P/Ay2kA==", - "requires": { - "ethereum-common": "^0.0.18", - "ethereumjs-util": "^5.0.0" - }, - "dependencies": { - "ethereum-common": { - "version": "0.0.18", - "resolved": "https://registry.npmjs.org/ethereum-common/-/ethereum-common-0.0.18.tgz", - "integrity": "sha1-L9w1dvIykDNYl26znaeDIT/5Uj8=" - } - } - }, - "ethereumjs-util": { - "version": "5.2.0", - "resolved": "https://registry.npmjs.org/ethereumjs-util/-/ethereumjs-util-5.2.0.tgz", - "integrity": "sha512-CJAKdI0wgMbQFLlLRtZKGcy/L6pzVRgelIZqRqNbuVFM3K9VEnyfbcvz0ncWMRNCe4kaHWjwRYQcYMucmwsnWA==", - "requires": { - "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" - } - }, - "ethereumjs-vm": { - "version": "2.4.0", - "resolved": "https://registry.npmjs.org/ethereumjs-vm/-/ethereumjs-vm-2.4.0.tgz", - "integrity": "sha512-MJ4lCWa5c6LhahhhvoDKW+YGjK00ZQn0RHHLh4L+WaH1k6Qv7/q3uTluew6sJGNCZdlO0yYMDXYW9qyxLHKlgQ==", - "requires": { - "async": "^2.1.2", - "async-eventemitter": "^0.2.2", - "ethereumjs-account": "^2.0.3", - "ethereumjs-block": "~1.7.0", - "ethereumjs-common": "~0.4.0", - "ethereumjs-util": "^5.2.0", - "fake-merkle-patricia-tree": "^1.0.1", - "functional-red-black-tree": "^1.0.1", - "merkle-patricia-tree": "^2.1.2", - "rustbn.js": "~0.2.0", - "safe-buffer": "^5.1.1" - }, - "dependencies": { - "ethereum-common": { - "version": "0.2.0", - "resolved": "https://registry.npmjs.org/ethereum-common/-/ethereum-common-0.2.0.tgz", - "integrity": "sha512-XOnAR/3rntJgbCdGhqdaLIxDLWKLmsZOGhHdBKadEr6gEnJLH52k93Ou+TUdFaPN3hJc3isBZBal3U/XZ15abA==" - }, - "ethereumjs-block": { - "version": "1.7.1", - "resolved": "http://registry.npmjs.org/ethereumjs-block/-/ethereumjs-block-1.7.1.tgz", - "integrity": "sha512-B+sSdtqm78fmKkBq78/QLKJbu/4Ts4P2KFISdgcuZUPDm9x+N7qgBPIIFUGbaakQh8bzuquiRVbdmvPKqbILRg==", - "requires": { - "async": "^2.0.1", - "ethereum-common": "0.2.0", - "ethereumjs-tx": "^1.2.2", - "ethereumjs-util": "^5.0.0", - "merkle-patricia-tree": "^2.1.2" - } - } - } - }, - "ethereumjs-wallet": { - "version": "0.6.2", - "resolved": "https://registry.npmjs.org/ethereumjs-wallet/-/ethereumjs-wallet-0.6.2.tgz", - "integrity": "sha512-DHEKPV9lYORM7dL8602dkb+AgdfzCYz2lxpdYQoD3OwG355LLDuivW9rGuLpDMCry/ORyBYV6n+QCo/71SwACg==", - "optional": true, - "requires": { - "aes-js": "^3.1.1", - "bs58check": "^2.1.2", - "ethereumjs-util": "^5.2.0", - "hdkey": "^1.0.0", - "safe-buffer": "^5.1.2", - "scrypt.js": "^0.2.0", - "utf8": "^3.0.0", - "uuid": "^3.3.2" - } - }, - "ethjs-unit": { - "version": "0.1.6", - "resolved": "https://registry.npmjs.org/ethjs-unit/-/ethjs-unit-0.1.6.tgz", - "integrity": "sha1-xmWSHkduh7ziqdWIpv4EBbLEFpk=", - "requires": { - "bn.js": "4.11.6", - "number-to-bn": "1.7.0" - }, - "dependencies": { - "bn.js": { - "version": "4.11.6", - "resolved": "https://registry.npmjs.org/bn.js/-/bn.js-4.11.6.tgz", - "integrity": "sha1-UzRK2xRhehP26N0s4okF0cC6MhU=" - } - } - }, - "ethjs-util": { - "version": "0.1.6", - "resolved": "https://registry.npmjs.org/ethjs-util/-/ethjs-util-0.1.6.tgz", - "integrity": "sha512-CUnVOQq7gSpDHZVVrQW8ExxUETWrnrvXYvYz55wOU8Uj4VCgw56XC2B/fVqQN+f7gmrnRHSLVnFAwsCuNwji8w==", - "requires": { - "is-hex-prefixed": "1.0.0", - "strip-hex-prefix": "1.0.0" - } - }, - "eventemitter3": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/eventemitter3/-/eventemitter3-1.1.1.tgz", - "integrity": "sha1-R3hr2qCHyvext15zq8XH1UAVjNA=" - }, - "events": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/events/-/events-3.0.0.tgz", - "integrity": "sha512-Dc381HFWJzEOhQ+d8pkNon++bk9h6cdAoAj4iE6Q4y6xgTzySWXlKn05/TVNpjnfRqi/X0EpJEJohPjNI3zpVA==" - }, - "evp_bytestokey": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/evp_bytestokey/-/evp_bytestokey-1.0.3.tgz", - "integrity": "sha512-/f2Go4TognH/KvCISP7OUsHn85hT9nUkxxA9BEWxFn+Oj9o8ZNLm/40hdlgSLyuOimsrTKLUMEorQexp/aPQeA==", - "requires": { - "md5.js": "^1.3.4", - "safe-buffer": "^5.1.1" - } - }, - "express": { - "version": "4.16.4", - "resolved": "https://registry.npmjs.org/express/-/express-4.16.4.tgz", - "integrity": "sha512-j12Uuyb4FMrd/qQAm6uCHAkPtO8FDTRJZBDd5D2KOL2eLaz1yUNdUB/NOIyq0iU4q4cFarsUCrnFDPBcnksuOg==", - "requires": { - "accepts": "~1.3.5", - "array-flatten": "1.1.1", - "body-parser": "1.18.3", - "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.4", - "qs": "6.5.2", - "range-parser": "~1.2.0", - "safe-buffer": "5.1.2", - "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" - }, - "dependencies": { - "debug": { - "version": "2.6.9", - "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", - "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", - "requires": { - "ms": "2.0.0" - } - }, - "statuses": { - "version": "1.4.0", - "resolved": "https://registry.npmjs.org/statuses/-/statuses-1.4.0.tgz", - "integrity": "sha512-zhSCtt8v2NDrRlPQpCNtw/heZLtfUDqxBM1udqikb/Hbk52LK4nQSwr10u77iopCW5LsyHpuXS0GnEc48mLeew==" - } - } - }, - "extend": { - "version": "3.0.2", - "resolved": "https://registry.npmjs.org/extend/-/extend-3.0.2.tgz", - "integrity": "sha512-fjquC59cD7CyW6urNXK0FBufkZcoiGG80wTuPujX590cB5Ttln20E2UB4S/WARVqhXffZl2LNgS+gQdPIIim/g==" - }, - "extsprintf": { - "version": "1.3.0", - "resolved": "https://registry.npmjs.org/extsprintf/-/extsprintf-1.3.0.tgz", - "integrity": "sha1-lpGEQOMEGnpBT4xS48V06zw+HgU=" - }, - "fake-merkle-patricia-tree": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/fake-merkle-patricia-tree/-/fake-merkle-patricia-tree-1.0.1.tgz", - "integrity": "sha1-S4w6z7Ugr635hgsfFM2M40As3dM=", - "requires": { - "checkpoint-store": "^1.1.0" - } - }, - "fast-deep-equal": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/fast-deep-equal/-/fast-deep-equal-2.0.1.tgz", - "integrity": "sha1-ewUhjd+WZ79/Nwv3/bLLFf3Qqkk=" - }, - "fast-json-stable-stringify": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/fast-json-stable-stringify/-/fast-json-stable-stringify-2.0.0.tgz", - "integrity": "sha1-1RQsDK7msRifh9OnYREGT4bIu/I=" - }, - "fd-slicer": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/fd-slicer/-/fd-slicer-1.1.0.tgz", - "integrity": "sha1-JcfInLH5B3+IkbvmHY85Dq4lbx4=", - "optional": true, - "requires": { - "pend": "~1.2.0" - } - }, - "fetch-ponyfill": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/fetch-ponyfill/-/fetch-ponyfill-4.1.0.tgz", - "integrity": "sha1-rjzl9zLGReq4fkroeTQUcJsjmJM=", - "requires": { - "node-fetch": "~1.7.1" - }, - "dependencies": { - "node-fetch": { - "version": "1.7.3", - "resolved": "https://registry.npmjs.org/node-fetch/-/node-fetch-1.7.3.tgz", - "integrity": "sha512-NhZ4CsKx7cYm2vSrBAr2PvFOe6sWDf0UYLRqA6svUYg7+/TSfVAu49jYC4BvQ4Sms9SZgdqGBgroqfDhJdTyKQ==", - "requires": { - "encoding": "^0.1.11", - "is-stream": "^1.0.1" - } - } - } - }, - "file-type": { - "version": "5.2.0", - "resolved": "https://registry.npmjs.org/file-type/-/file-type-5.2.0.tgz", - "integrity": "sha1-LdvqfHP/42No365J3DOMBYwritY=" - }, - "finalhandler": { - "version": "1.1.1", - "resolved": "http://registry.npmjs.org/finalhandler/-/finalhandler-1.1.1.tgz", - "integrity": "sha512-Y1GUDo39ez4aHAw7MysnUD5JzYX+WaIj8I57kO3aEPT1fFRL4sr7mjei97FgnwhAyyzRYmQZaTHb2+9uZ1dPtg==", - "requires": { - "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" - }, - "dependencies": { - "debug": { - "version": "2.6.9", - "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", - "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", - "requires": { - "ms": "2.0.0" - } - }, - "statuses": { - "version": "1.4.0", - "resolved": "https://registry.npmjs.org/statuses/-/statuses-1.4.0.tgz", - "integrity": "sha512-zhSCtt8v2NDrRlPQpCNtw/heZLtfUDqxBM1udqikb/Hbk52LK4nQSwr10u77iopCW5LsyHpuXS0GnEc48mLeew==" - } - } - }, - "find-up": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/find-up/-/find-up-1.1.2.tgz", - "integrity": "sha1-ay6YIrGizgpgq2TWEOzK1TyyTQ8=", - "requires": { - "path-exists": "^2.0.0", - "pinkie-promise": "^2.0.0" - } - }, - "for-each": { - "version": "0.3.3", - "resolved": "https://registry.npmjs.org/for-each/-/for-each-0.3.3.tgz", - "integrity": "sha512-jqYfLp7mo9vIyQf8ykW2v7A+2N4QjeCeI5+Dz9XraiO1ign81wjiH7Fb9vSOWvQfNtmSa4H2RoQTrrXivdUZmw==", - "requires": { - "is-callable": "^1.1.3" - } - }, - "forever-agent": { - "version": "0.6.1", - "resolved": "https://registry.npmjs.org/forever-agent/-/forever-agent-0.6.1.tgz", - "integrity": "sha1-+8cfDEGt6zf5bFd60e1C2P2sypE=" - }, - "form-data": { - "version": "2.3.3", - "resolved": "https://registry.npmjs.org/form-data/-/form-data-2.3.3.tgz", - "integrity": "sha512-1lLKB2Mu3aGP1Q/2eCOx0fNbRMe7XdwktwOruhfqqd0rIJWwN4Dh+E3hrPSlDCXnSR7UtZ1N38rVXm+6+MEhJQ==", - "requires": { - "asynckit": "^0.4.0", - "combined-stream": "^1.0.6", - "mime-types": "^2.1.12" - } - }, - "forwarded": { - "version": "0.1.2", - "resolved": "https://registry.npmjs.org/forwarded/-/forwarded-0.1.2.tgz", - "integrity": "sha1-mMI9qxF1ZXuMBXPozszZGw/xjIQ=" - }, - "fresh": { - "version": "0.5.2", - "resolved": "https://registry.npmjs.org/fresh/-/fresh-0.5.2.tgz", - "integrity": "sha1-PYyt2Q2XZWn6g1qx+OSyOhBWBac=" - }, - "fs-constants": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/fs-constants/-/fs-constants-1.0.0.tgz", - "integrity": "sha512-y6OAwoSIf7FyjMIv94u+b5rdheZEjzR63GTyZJm5qh4Bi+2YgwLCcI/fPFZkL5PSixOt6ZNKm+w+Hfp/Bciwow==" - }, - "fs-extra": { - "version": "2.1.2", - "resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-2.1.2.tgz", - "integrity": "sha1-BGxwFjzvmq1GsOSn+kZ/si1x3jU=", - "requires": { - "graceful-fs": "^4.1.2", - "jsonfile": "^2.1.0" - } - }, - "fs-promise": { - "version": "2.0.3", - "resolved": "https://registry.npmjs.org/fs-promise/-/fs-promise-2.0.3.tgz", - "integrity": "sha1-9k5PhUvPaJqovdy6JokW2z20aFQ=", - "optional": true, - "requires": { - "any-promise": "^1.3.0", - "fs-extra": "^2.0.0", - "mz": "^2.6.0", - "thenify-all": "^1.6.0" - } - }, - "fs.realpath": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/fs.realpath/-/fs.realpath-1.0.0.tgz", - "integrity": "sha1-FQStJSMVjKpA20onh8sBQRmU6k8=" - }, - "fstream": { - "version": "1.0.11", - "resolved": "https://registry.npmjs.org/fstream/-/fstream-1.0.11.tgz", - "integrity": "sha1-XB+x8RdHcRTwYyoOtLcbPLD9MXE=", - "requires": { - "graceful-fs": "^4.1.2", - "inherits": "~2.0.0", - "mkdirp": ">=0.5 0", - "rimraf": "2" - } - }, - "function-bind": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/function-bind/-/function-bind-1.1.1.tgz", - "integrity": "sha512-yIovAzMX49sF8Yl58fSCWJ5svSLuaibPxXQJFLmBObTuCr0Mf1KiPopGM9NiFjiYBCbfaa2Fh6breQ6ANVTI0A==" - }, - "functional-red-black-tree": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/functional-red-black-tree/-/functional-red-black-tree-1.0.1.tgz", - "integrity": "sha1-GwqzvVU7Kg1jmdKcDj6gslIHgyc=" - }, - "get-caller-file": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/get-caller-file/-/get-caller-file-1.0.3.tgz", - "integrity": "sha512-3t6rVToeoZfYSGd8YoLFR2DJkiQrIiUrGcjvFX2mDw3bn6k2OtwHN0TNCLbBO+w8qTvimhDkv+LSscbJY1vE6w==" - }, - "get-stream": { - "version": "3.0.0", - "resolved": "http://registry.npmjs.org/get-stream/-/get-stream-3.0.0.tgz", - "integrity": "sha1-jpQ9E1jcN1VQVOy+LtsFqhdO3hQ=" - }, - "getpass": { - "version": "0.1.7", - "resolved": "https://registry.npmjs.org/getpass/-/getpass-0.1.7.tgz", - "integrity": "sha1-Xv+OPmhNVprkyysSgmBOi6YhSfo=", - "requires": { - "assert-plus": "^1.0.0" - } - }, - "glob": { - "version": "7.1.3", - "resolved": "https://registry.npmjs.org/glob/-/glob-7.1.3.tgz", - "integrity": "sha512-vcfuiIxogLV4DlGBHIUOwI0IbrJ8HWPc4MU7HzviGeNho/UJDfi6B5p3sHeWIQ0KGIU0Jpxi5ZHxemQfLkkAwQ==", - "requires": { - "fs.realpath": "^1.0.0", - "inflight": "^1.0.4", - "inherits": "2", - "minimatch": "^3.0.4", - "once": "^1.3.0", - "path-is-absolute": "^1.0.0" - } - }, - "global": { - "version": "4.3.2", - "resolved": "https://registry.npmjs.org/global/-/global-4.3.2.tgz", - "integrity": "sha1-52mJJopsdMOJCLEwWxD8DjlOnQ8=", - "requires": { - "min-document": "^2.19.0", - "process": "~0.5.1" - } - }, - "globals": { - "version": "9.18.0", - "resolved": "https://registry.npmjs.org/globals/-/globals-9.18.0.tgz", - "integrity": "sha512-S0nG3CLEQiY/ILxqtztTWH/3iRRdyBLw6KMDxnKMchrtbj2OFmehVh0WUCfW3DUrIgx/qFrJPICrq4Z4sTR9UQ==" - }, - "got": { - "version": "7.1.0", - "resolved": "https://registry.npmjs.org/got/-/got-7.1.0.tgz", - "integrity": "sha512-Y5WMo7xKKq1muPsxD+KmrR8DH5auG7fBdDVueZwETwV6VytKyU9OX/ddpq2/1hp1vIPvVb4T81dKQz3BivkNLw==", - "requires": { - "decompress-response": "^3.2.0", - "duplexer3": "^0.1.4", - "get-stream": "^3.0.0", - "is-plain-obj": "^1.1.0", - "is-retry-allowed": "^1.0.0", - "is-stream": "^1.0.0", - "isurl": "^1.0.0-alpha5", - "lowercase-keys": "^1.0.0", - "p-cancelable": "^0.3.0", - "p-timeout": "^1.1.1", - "safe-buffer": "^5.0.1", - "timed-out": "^4.0.0", - "url-parse-lax": "^1.0.0", - "url-to-options": "^1.0.1" - } - }, - "graceful-fs": { - "version": "4.1.15", - "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.1.15.tgz", - "integrity": "sha512-6uHUhOPEBgQ24HM+r6b/QwWfZq+yiFcipKFrOFiBEnWdy5sdzYoi+pJeQaPI5qOLRFqWmAXUPQNsielzdLoecA==" - }, - "graceful-readlink": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/graceful-readlink/-/graceful-readlink-1.0.1.tgz", - "integrity": "sha1-TK+tdrxi8C+gObL5Tpo906ORpyU=" - }, - "har-schema": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/har-schema/-/har-schema-2.0.0.tgz", - "integrity": "sha1-qUwiJOvKwEeCoNkDVSHyRzW37JI=" - }, - "har-validator": { - "version": "5.1.3", - "resolved": "https://registry.npmjs.org/har-validator/-/har-validator-5.1.3.tgz", - "integrity": "sha512-sNvOCzEQNr/qrvJgc3UG/kD4QtlHycrzwS+6mfTrrSq97BvaYcPZZI1ZSqGSPR73Cxn4LKTD4PttRwfU7jWq5g==", - "requires": { - "ajv": "^6.5.5", - "har-schema": "^2.0.0" - } - }, - "has": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/has/-/has-1.0.3.tgz", - "integrity": "sha512-f2dvO0VU6Oej7RkWJGrehjbzMAjFp5/VKPp5tTpWIV4JHHZK1/BxbFRtf/siA2SWTe09caDmVtYYzWEIbBS4zw==", - "requires": { - "function-bind": "^1.1.1" - } - }, - "has-ansi": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/has-ansi/-/has-ansi-2.0.0.tgz", - "integrity": "sha1-NPUEnOHs3ysGSa8+8k5F7TVBbZE=", - "requires": { - "ansi-regex": "^2.0.0" - } - }, - "has-symbol-support-x": { - "version": "1.4.2", - "resolved": "https://registry.npmjs.org/has-symbol-support-x/-/has-symbol-support-x-1.4.2.tgz", - "integrity": "sha512-3ToOva++HaW+eCpgqZrCfN51IPB+7bJNVT6CUATzueB5Heb8o6Nam0V3HG5dlDvZU1Gn5QLcbahiKw/XVk5JJw==" - }, - "has-symbols": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/has-symbols/-/has-symbols-1.0.0.tgz", - "integrity": "sha1-uhqPGvKg/DllD1yFA2dwQSIGO0Q=" - }, - "has-to-string-tag-x": { - "version": "1.4.1", - "resolved": "https://registry.npmjs.org/has-to-string-tag-x/-/has-to-string-tag-x-1.4.1.tgz", - "integrity": "sha512-vdbKfmw+3LoOYVr+mtxHaX5a96+0f3DljYd8JOqvOLsf5mw2Otda2qCDT9qRqLAhrjyQ0h7ual5nOiASpsGNFw==", - "requires": { - "has-symbol-support-x": "^1.4.1" - } - }, - "hash-base": { - "version": "3.0.4", - "resolved": "https://registry.npmjs.org/hash-base/-/hash-base-3.0.4.tgz", - "integrity": "sha1-X8hoaEfs1zSZQDMZprCj8/auSRg=", - "requires": { - "inherits": "^2.0.1", - "safe-buffer": "^5.0.1" - } - }, - "hash.js": { - "version": "1.1.5", - "resolved": "https://registry.npmjs.org/hash.js/-/hash.js-1.1.5.tgz", - "integrity": "sha512-eWI5HG9Np+eHV1KQhisXWwM+4EPPYe5dFX1UZZH7k/E3JzDEazVH+VGlZi6R94ZqImq+A3D1mCEtrFIfg/E7sA==", - "requires": { - "inherits": "^2.0.3", - "minimalistic-assert": "^1.0.1" - } - }, - "hdkey": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/hdkey/-/hdkey-1.1.0.tgz", - "integrity": "sha512-E7aU8pNlWUJbXGjTz/+lKf1LkMcA3hUrC5ZleeizrmLSd++kvf8mSOe3q8CmBDA9j4hdfXO5iY6hGiTUCOV2jQ==", - "optional": true, - "requires": { - "coinstring": "^2.0.0", - "safe-buffer": "^5.1.1", - "secp256k1": "^3.0.1" - } - }, - "heap": { - "version": "0.2.6", - "resolved": "https://registry.npmjs.org/heap/-/heap-0.2.6.tgz", - "integrity": "sha1-CH4fELBGky/IWU3Z5tN4r8nR5aw=" - }, - "hmac-drbg": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/hmac-drbg/-/hmac-drbg-1.0.1.tgz", - "integrity": "sha1-0nRXAQJabHdabFRXk+1QL8DGSaE=", - "requires": { - "hash.js": "^1.0.3", - "minimalistic-assert": "^1.0.0", - "minimalistic-crypto-utils": "^1.0.1" - } - }, - "home-or-tmp": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/home-or-tmp/-/home-or-tmp-2.0.0.tgz", - "integrity": "sha1-42w/LSyufXRqhX440Y1fMqeILbg=", - "requires": { - "os-homedir": "^1.0.0", - "os-tmpdir": "^1.0.1" - } - }, - "hosted-git-info": { - "version": "2.7.1", - "resolved": "https://registry.npmjs.org/hosted-git-info/-/hosted-git-info-2.7.1.tgz", - "integrity": "sha512-7T/BxH19zbcCTa8XkMlbK5lTo1WtgkFi3GvdWEyNuc4Vex7/9Dqbnpsf4JMydcfj9HCg4zUWFTL3Za6lapg5/w==" - }, - "http-errors": { - "version": "1.6.3", - "resolved": "http://registry.npmjs.org/http-errors/-/http-errors-1.6.3.tgz", - "integrity": "sha1-i1VoC7S+KDoLW/TqLjhYC+HZMg0=", - "requires": { - "depd": "~1.1.2", - "inherits": "2.0.3", - "setprototypeof": "1.1.0", - "statuses": ">= 1.4.0 < 2" - } - }, - "http-https": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/http-https/-/http-https-1.0.0.tgz", - "integrity": "sha1-L5CN1fHbQGjAWM1ubUzjkskTOJs=" - }, - "http-signature": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/http-signature/-/http-signature-1.2.0.tgz", - "integrity": "sha1-muzZJRFHcvPZW2WmCruPfBj7rOE=", - "requires": { - "assert-plus": "^1.0.0", - "jsprim": "^1.2.2", - "sshpk": "^1.7.0" - } - }, - "iconv-lite": { - "version": "0.4.23", - "resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.4.23.tgz", - "integrity": "sha512-neyTUVFtahjf0mB3dZT77u+8O0QB89jFdnBkd5P1JgYPbPaia3gXXOVL2fq8VyU2gMMD7SaN7QukTB/pmXYvDA==", - "requires": { - "safer-buffer": ">= 2.1.2 < 3" - } - }, - "ieee754": { - "version": "1.1.12", - "resolved": "https://registry.npmjs.org/ieee754/-/ieee754-1.1.12.tgz", - "integrity": "sha512-GguP+DRY+pJ3soyIiGPTvdiVXjZ+DbXOxGpXn3eMvNW4x4irjqXm4wHKscC+TfxSJ0yw/S1F24tqdMNsMZTiLA==" - }, - "immediate": { - "version": "3.2.3", - "resolved": "https://registry.npmjs.org/immediate/-/immediate-3.2.3.tgz", - "integrity": "sha1-0UD6j2FGWb1lQSMwl92qwlzdmRw=" - }, - "inflight": { - "version": "1.0.6", - "resolved": "https://registry.npmjs.org/inflight/-/inflight-1.0.6.tgz", - "integrity": "sha1-Sb1jMdfQLQwJvJEKEHW6gWW1bfk=", - "requires": { - "once": "^1.3.0", - "wrappy": "1" - } - }, - "inherits": { - "version": "2.0.3", - "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.3.tgz", - "integrity": "sha1-Yzwsg+PaQqUC9SRmAiSA9CCCYd4=" - }, - "invariant": { - "version": "2.2.4", - "resolved": "https://registry.npmjs.org/invariant/-/invariant-2.2.4.tgz", - "integrity": "sha512-phJfQVBuaJM5raOpJjSfkiD6BpbCE4Ns//LaXl6wGYtUBY83nWS6Rf9tXm2e8VaK60JEjYldbPif/A2B1C2gNA==", - "requires": { - "loose-envify": "^1.0.0" - } - }, - "invert-kv": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/invert-kv/-/invert-kv-1.0.0.tgz", - "integrity": "sha1-EEqOSqym09jNFXqO+L+rLXo//bY=" - }, - "ipaddr.js": { - "version": "1.8.0", - "resolved": "https://registry.npmjs.org/ipaddr.js/-/ipaddr.js-1.8.0.tgz", - "integrity": "sha1-6qM9bd16zo9/b+DJygRA5wZzix4=" - }, - "is-arrayish": { - "version": "0.2.1", - "resolved": "https://registry.npmjs.org/is-arrayish/-/is-arrayish-0.2.1.tgz", - "integrity": "sha1-d8mYQFJ6qOyxqLppe4BkWnqSap0=" - }, - "is-builtin-module": { - "version": "1.0.0", - "resolved": "http://registry.npmjs.org/is-builtin-module/-/is-builtin-module-1.0.0.tgz", - "integrity": "sha1-VAVy0096wxGfj3bDDLwbHgN6/74=", - "requires": { - "builtin-modules": "^1.0.0" - } - }, - "is-callable": { - "version": "1.1.4", - "resolved": "https://registry.npmjs.org/is-callable/-/is-callable-1.1.4.tgz", - "integrity": "sha512-r5p9sxJjYnArLjObpjA4xu5EKI3CuKHkJXMhT7kwbpUyIFD1n5PMAsoPvWnvtZiNz7LjkYDRZhd7FlI0eMijEA==" - }, - "is-date-object": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/is-date-object/-/is-date-object-1.0.1.tgz", - "integrity": "sha1-mqIOtq7rv/d/vTPnTKAbM1gdOhY=" - }, - "is-finite": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/is-finite/-/is-finite-1.0.2.tgz", - "integrity": "sha1-zGZ3aVYCvlUO8R6LSqYwU0K20Ko=", - "requires": { - "number-is-nan": "^1.0.0" - } - }, - "is-fn": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/is-fn/-/is-fn-1.0.0.tgz", - "integrity": "sha1-lUPV3nvPWwiiLsiiC65uKG1RDYw=" - }, - "is-fullwidth-code-point": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-1.0.0.tgz", - "integrity": "sha1-754xOG8DGn8NZDr4L95QxFfvAMs=", - "requires": { - "number-is-nan": "^1.0.0" - } - }, - "is-function": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/is-function/-/is-function-1.0.1.tgz", - "integrity": "sha1-Es+5i2W1fdPRk6MSH19uL0N2ArU=" - }, - "is-hex-prefixed": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/is-hex-prefixed/-/is-hex-prefixed-1.0.0.tgz", - "integrity": "sha1-fY035q135dEnFIkTxXPggtd39VQ=" - }, - "is-natural-number": { - "version": "4.0.1", - "resolved": "https://registry.npmjs.org/is-natural-number/-/is-natural-number-4.0.1.tgz", - "integrity": "sha1-q5124dtM7VHjXeDHLr7PCfc0zeg=", - "optional": true - }, - "is-object": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/is-object/-/is-object-1.0.1.tgz", - "integrity": "sha1-iVJojF7C/9awPsyF52ngKQMINHA=" - }, - "is-plain-obj": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/is-plain-obj/-/is-plain-obj-1.1.0.tgz", - "integrity": "sha1-caUMhCnfync8kqOQpKA7OfzVHT4=" - }, - "is-regex": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/is-regex/-/is-regex-1.0.4.tgz", - "integrity": "sha1-VRdIm1RwkbCTDglWVM7SXul+lJE=", - "requires": { - "has": "^1.0.1" - } - }, - "is-retry-allowed": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/is-retry-allowed/-/is-retry-allowed-1.1.0.tgz", - "integrity": "sha1-EaBgVotnM5REAz0BJaYaINVk+zQ=" - }, - "is-stream": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/is-stream/-/is-stream-1.1.0.tgz", - "integrity": "sha1-EtSj3U5o4Lec6428hBc66A2RykQ=" - }, - "is-symbol": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/is-symbol/-/is-symbol-1.0.2.tgz", - "integrity": "sha512-HS8bZ9ox60yCJLH9snBpIwv9pYUAkcuLhSA1oero1UB5y9aiQpRA8y2ex945AOtCZL1lJDeIk3G5LthswI46Lw==", - "requires": { - "has-symbols": "^1.0.0" - } - }, - "is-typedarray": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/is-typedarray/-/is-typedarray-1.0.0.tgz", - "integrity": "sha1-5HnICFjfDBsR3dppQPlgEfzaSpo=" - }, - "is-utf8": { - "version": "0.2.1", - "resolved": "https://registry.npmjs.org/is-utf8/-/is-utf8-0.2.1.tgz", - "integrity": "sha1-Sw2hRCEE0bM2NA6AeX6GXPOffXI=" - }, - "isarray": { - "version": "0.0.1", - "resolved": "https://registry.npmjs.org/isarray/-/isarray-0.0.1.tgz", - "integrity": "sha1-ihis/Kmo9Bd+Cav8YDiTmwXR7t8=" - }, - "isstream": { - "version": "0.1.2", - "resolved": "https://registry.npmjs.org/isstream/-/isstream-0.1.2.tgz", - "integrity": "sha1-R+Y/evVa+m+S4VAOaQ64uFKcCZo=" - }, - "isurl": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/isurl/-/isurl-1.0.0.tgz", - "integrity": "sha512-1P/yWsxPlDtn7QeRD+ULKQPaIaN6yF368GZ2vDfv0AL0NwpStafjWCDDdn0k8wgFMWpVAqG7oJhxHnlud42i9w==", - "requires": { - "has-to-string-tag-x": "^1.2.0", - "is-object": "^1.0.1" - } - }, - "js-sha3": { - "version": "0.3.1", - "resolved": "https://registry.npmjs.org/js-sha3/-/js-sha3-0.3.1.tgz", - "integrity": "sha1-hhIoAhQvCChQKg0d7h2V4lO7AkM=" - }, - "js-tokens": { - "version": "3.0.2", - "resolved": "https://registry.npmjs.org/js-tokens/-/js-tokens-3.0.2.tgz", - "integrity": "sha1-mGbfOVECEw449/mWvOtlRDIJwls=" - }, - "jsbn": { - "version": "0.1.1", - "resolved": "https://registry.npmjs.org/jsbn/-/jsbn-0.1.1.tgz", - "integrity": "sha1-peZUwuWi3rXyAdls77yoDA7y9RM=" - }, - "jsesc": { - "version": "0.5.0", - "resolved": "http://registry.npmjs.org/jsesc/-/jsesc-0.5.0.tgz", - "integrity": "sha1-597mbjXW/Bb3EP6R1c9p9w8IkR0=" - }, - "json-rpc-engine": { - "version": "3.8.0", - "resolved": "https://registry.npmjs.org/json-rpc-engine/-/json-rpc-engine-3.8.0.tgz", - "integrity": "sha512-6QNcvm2gFuuK4TKU1uwfH0Qd/cOSb9c1lls0gbnIhciktIUQJwz6NQNAW4B1KiGPenv7IKu97V222Yo1bNhGuA==", - "requires": { - "async": "^2.0.1", - "babel-preset-env": "^1.7.0", - "babelify": "^7.3.0", - "json-rpc-error": "^2.0.0", - "promise-to-callback": "^1.0.0", - "safe-event-emitter": "^1.0.1" - } - }, - "json-rpc-error": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/json-rpc-error/-/json-rpc-error-2.0.0.tgz", - "integrity": "sha1-p6+cICg4tekFxyUOVH8a/3cligI=", - "requires": { - "inherits": "^2.0.1" - } - }, - "json-rpc-random-id": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/json-rpc-random-id/-/json-rpc-random-id-1.0.1.tgz", - "integrity": "sha1-uknZat7RRE27jaPSA3SKy7zeyMg=" - }, - "json-schema": { - "version": "0.2.3", - "resolved": "https://registry.npmjs.org/json-schema/-/json-schema-0.2.3.tgz", - "integrity": "sha1-tIDIkuWaLwWVTOcnvT8qTogvnhM=" - }, - "json-schema-traverse": { - "version": "0.4.1", - "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-0.4.1.tgz", - "integrity": "sha512-xbbCH5dCYU5T8LcEhhuh7HJ88HXuW3qsI3Y0zOZFKfZEHcpWiHU/Jxzk629Brsab/mMiHQti9wMP+845RPe3Vg==" - }, - "json-stable-stringify": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/json-stable-stringify/-/json-stable-stringify-1.0.1.tgz", - "integrity": "sha1-mnWdOcXy/1A/1TAGRu1EX4jE+a8=", - "requires": { - "jsonify": "~0.0.0" - } - }, - "json-stringify-safe": { - "version": "5.0.1", - "resolved": "https://registry.npmjs.org/json-stringify-safe/-/json-stringify-safe-5.0.1.tgz", - "integrity": "sha1-Epai1Y/UXxmg9s4B1lcB4sc1tus=" - }, - "json5": { - "version": "0.5.1", - "resolved": "http://registry.npmjs.org/json5/-/json5-0.5.1.tgz", - "integrity": "sha1-Hq3nrMASA0rYTiOWdn6tn6VJWCE=" - }, - "jsonfile": { - "version": "2.4.0", - "resolved": "http://registry.npmjs.org/jsonfile/-/jsonfile-2.4.0.tgz", - "integrity": "sha1-NzaitCi4e72gzIO1P6PWM6NcKug=", - "requires": { - "graceful-fs": "^4.1.6" - } - }, - "jsonify": { - "version": "0.0.0", - "resolved": "https://registry.npmjs.org/jsonify/-/jsonify-0.0.0.tgz", - "integrity": "sha1-LHS27kHZPKUbe1qu6PUDYx0lKnM=" - }, - "jsprim": { - "version": "1.4.1", - "resolved": "https://registry.npmjs.org/jsprim/-/jsprim-1.4.1.tgz", - "integrity": "sha1-MT5mvB5cwG5Di8G3SZwuXFastqI=", - "requires": { - "assert-plus": "1.0.0", - "extsprintf": "1.3.0", - "json-schema": "0.2.3", - "verror": "1.10.0" - } - }, - "keccak": { - "version": "1.4.0", - "resolved": "https://registry.npmjs.org/keccak/-/keccak-1.4.0.tgz", - "integrity": "sha512-eZVaCpblK5formjPjeTBik7TAg+pqnDrMHIffSvi9Lh7PQgM1+hSzakUeZFCk9DVVG0dacZJuaz2ntwlzZUIBw==", - "requires": { - "bindings": "^1.2.1", - "inherits": "^2.0.3", - "nan": "^2.2.1", - "safe-buffer": "^5.1.0" - } - }, - "keccakjs": { - "version": "0.2.1", - "resolved": "https://registry.npmjs.org/keccakjs/-/keccakjs-0.2.1.tgz", - "integrity": "sha1-HWM6+QfvMFu/ny+mFtVsRFYd+k0=", - "requires": { - "browserify-sha3": "^0.0.1", - "sha3": "^1.1.0" - } - }, - "klaw": { - "version": "1.3.1", - "resolved": "https://registry.npmjs.org/klaw/-/klaw-1.3.1.tgz", - "integrity": "sha1-QIhDO0azsbolnXh4XY6W9zugJDk=", - "requires": { - "graceful-fs": "^4.1.9" - } - }, - "lcid": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/lcid/-/lcid-1.0.0.tgz", - "integrity": "sha1-MIrMr6C8SDo4Z7S28rlQYlHRuDU=", - "requires": { - "invert-kv": "^1.0.0" - } - }, - "level-codec": { - "version": "9.0.0", - "resolved": "https://registry.npmjs.org/level-codec/-/level-codec-9.0.0.tgz", - "integrity": "sha512-OIpVvjCcZNP5SdhcNupnsI1zo5Y9Vpm+k/F1gfG5kXrtctlrwanisakweJtE0uA0OpLukRfOQae+Fg0M5Debhg==" - }, - "level-errors": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/level-errors/-/level-errors-2.0.0.tgz", - "integrity": "sha512-AmY4HCp9h3OiU19uG+3YWkdELgy05OTP/r23aNHaQKWv8DO787yZgsEuGVkoph40uwN+YdUKnANlrxSsoOaaxg==", - "requires": { - "errno": "~0.1.1" - } - }, - "level-iterator-stream": { - "version": "1.3.1", - "resolved": "http://registry.npmjs.org/level-iterator-stream/-/level-iterator-stream-1.3.1.tgz", - "integrity": "sha1-5Dt4sagUPm+pek9IXrjqUwNS8u0=", - "requires": { - "inherits": "^2.0.1", - "level-errors": "^1.0.3", - "readable-stream": "^1.0.33", - "xtend": "^4.0.0" - }, - "dependencies": { - "level-errors": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/level-errors/-/level-errors-1.1.2.tgz", - "integrity": "sha512-Sw/IJwWbPKF5Ai4Wz60B52yj0zYeqzObLh8k1Tk88jVmD51cJSKWSYpRyhVIvFzZdvsPqlH5wfhp/yxdsaQH4w==", - "requires": { - "errno": "~0.1.1" - } - }, - "readable-stream": { - "version": "1.1.14", - "resolved": "http://registry.npmjs.org/readable-stream/-/readable-stream-1.1.14.tgz", - "integrity": "sha1-fPTFTvZI44EwhMY23SB54WbAgdk=", - "requires": { - "core-util-is": "~1.0.0", - "inherits": "~2.0.1", - "isarray": "0.0.1", - "string_decoder": "~0.10.x" - } - } - } - }, - "level-post": { - "version": "1.0.7", - "resolved": "https://registry.npmjs.org/level-post/-/level-post-1.0.7.tgz", - "integrity": "sha512-PWYqG4Q00asOrLhX7BejSajByB4EmG2GaKHfj3h5UmmZ2duciXLPGYWIjBzLECFWUGOZWlm5B20h/n3Gs3HKew==", - "requires": { - "ltgt": "^2.1.2" - } - }, - "level-sublevel": { - "version": "6.6.4", - "resolved": "https://registry.npmjs.org/level-sublevel/-/level-sublevel-6.6.4.tgz", - "integrity": "sha512-pcCrTUOiO48+Kp6F1+UAzF/OtWqLcQVTVF39HLdZ3RO8XBoXt+XVPKZO1vVr1aUoxHZA9OtD2e1v7G+3S5KFDA==", - "requires": { - "bytewise": "~1.1.0", - "level-codec": "^9.0.0", - "level-errors": "^2.0.0", - "level-iterator-stream": "^2.0.3", - "ltgt": "~2.1.1", - "pull-defer": "^0.2.2", - "pull-level": "^2.0.3", - "pull-stream": "^3.6.8", - "typewiselite": "~1.0.0", - "xtend": "~4.0.0" - }, - "dependencies": { - "level-iterator-stream": { - "version": "2.0.3", - "resolved": "https://registry.npmjs.org/level-iterator-stream/-/level-iterator-stream-2.0.3.tgz", - "integrity": "sha512-I6Heg70nfF+e5Y3/qfthJFexhRw/Gi3bIymCoXAlijZdAcLaPuWSJs3KXyTYf23ID6g0o2QF62Yh+grOXY3Rig==", - "requires": { - "inherits": "^2.0.1", - "readable-stream": "^2.0.5", - "xtend": "^4.0.0" - } - }, - "ltgt": { - "version": "2.1.3", - "resolved": "https://registry.npmjs.org/ltgt/-/ltgt-2.1.3.tgz", - "integrity": "sha1-EIUaBtmWS5cReEQcI8nlJpjuzjQ=" - } - } - }, - "level-ws": { - "version": "0.0.0", - "resolved": "https://registry.npmjs.org/level-ws/-/level-ws-0.0.0.tgz", - "integrity": "sha1-Ny5RIXeSSgBCSwtDrvK7QkltIos=", - "requires": { - "readable-stream": "~1.0.15", - "xtend": "~2.1.1" - }, - "dependencies": { - "readable-stream": { - "version": "1.0.34", - "resolved": "http://registry.npmjs.org/readable-stream/-/readable-stream-1.0.34.tgz", - "integrity": "sha1-Elgg40vIQtLyqq+v5MKRbuMsFXw=", - "requires": { - "core-util-is": "~1.0.0", - "inherits": "~2.0.1", - "isarray": "0.0.1", - "string_decoder": "~0.10.x" - } - }, - "xtend": { - "version": "2.1.2", - "resolved": "https://registry.npmjs.org/xtend/-/xtend-2.1.2.tgz", - "integrity": "sha1-bv7MKk2tjmlixJAbM3znuoe10os=", - "requires": { - "object-keys": "~0.4.0" - } - } - } - }, - "levelup": { - "version": "3.1.1", - "resolved": "https://registry.npmjs.org/levelup/-/levelup-3.1.1.tgz", - "integrity": "sha512-9N10xRkUU4dShSRRFTBdNaBxofz+PGaIZO962ckboJZiNmLuhVT6FZ6ZKAsICKfUBO76ySaYU6fJWX/jnj3Lcg==", - "requires": { - "deferred-leveldown": "~4.0.0", - "level-errors": "~2.0.0", - "level-iterator-stream": "~3.0.0", - "xtend": "~4.0.0" - }, - "dependencies": { - "abstract-leveldown": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/abstract-leveldown/-/abstract-leveldown-5.0.0.tgz", - "integrity": "sha512-5mU5P1gXtsMIXg65/rsYGsi93+MlogXZ9FA8JnwKurHQg64bfXwGYVdVdijNTVNOlAsuIiOwHdvFFD5JqCJQ7A==", - "requires": { - "xtend": "~4.0.0" - } - }, - "deferred-leveldown": { - "version": "4.0.2", - "resolved": "https://registry.npmjs.org/deferred-leveldown/-/deferred-leveldown-4.0.2.tgz", - "integrity": "sha512-5fMC8ek8alH16QiV0lTCis610D1Zt1+LA4MS4d63JgS32lrCjTFDUFz2ao09/j2I4Bqb5jL4FZYwu7Jz0XO1ww==", - "requires": { - "abstract-leveldown": "~5.0.0", - "inherits": "^2.0.3" - } - }, - "level-iterator-stream": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/level-iterator-stream/-/level-iterator-stream-3.0.1.tgz", - "integrity": "sha512-nEIQvxEED9yRThxvOrq8Aqziy4EGzrxSZK+QzEFAVuJvQ8glfyZ96GB6BoI4sBbLfjMXm2w4vu3Tkcm9obcY0g==", - "requires": { - "inherits": "^2.0.1", - "readable-stream": "^2.3.6", - "xtend": "^4.0.0" - } - } - } - }, - "load-json-file": { - "version": "1.1.0", - "resolved": "http://registry.npmjs.org/load-json-file/-/load-json-file-1.1.0.tgz", - "integrity": "sha1-lWkFcI1YtLq0wiYbBPWfMcmTdMA=", - "requires": { - "graceful-fs": "^4.1.2", - "parse-json": "^2.2.0", - "pify": "^2.0.0", - "pinkie-promise": "^2.0.0", - "strip-bom": "^2.0.0" - }, - "dependencies": { - "pify": { - "version": "2.3.0", - "resolved": "http://registry.npmjs.org/pify/-/pify-2.3.0.tgz", - "integrity": "sha1-7RQaasBDqEnqWISY59yosVMw6Qw=" - } - } - }, - "lodash": { - "version": "4.17.10", - "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.10.tgz", - "integrity": "sha512-UejweD1pDoXu+AD825lWwp4ZGtSwgnpZxb3JDViD7StjQz+Nb/6l093lx4OQ0foGWNRoc19mWy7BzL+UAK2iVg==" - }, - "lodash.assign": { - "version": "4.2.0", - "resolved": "https://registry.npmjs.org/lodash.assign/-/lodash.assign-4.2.0.tgz", - "integrity": "sha1-DZnzzNem0mHRm9rrkkUAXShYCOc=" - }, - "looper": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/looper/-/looper-2.0.0.tgz", - "integrity": "sha1-Zs0Md0rz1P7axTeU90LbVtqPCew=" - }, - "loose-envify": { - "version": "1.4.0", - "resolved": "https://registry.npmjs.org/loose-envify/-/loose-envify-1.4.0.tgz", - "integrity": "sha512-lyuxPGr/Wfhrlem2CL/UcnUc1zcqKAImBDzukY7Y5F/yQiNdko6+fRLevlw1HgMySw7f611UIY408EtxRSoK3Q==", - "requires": { - "js-tokens": "^3.0.0 || ^4.0.0" - } - }, - "lowercase-keys": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/lowercase-keys/-/lowercase-keys-1.0.1.tgz", - "integrity": "sha512-G2Lj61tXDnVFFOi8VZds+SoQjtQC3dgokKdDG2mTm1tx4m50NUHBOZSBwQQHyy0V12A0JTG4icfZQH+xPyh8VA==" - }, - "lru-cache": { - "version": "3.2.0", - "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-3.2.0.tgz", - "integrity": "sha1-cXibO39Tmb7IVl3aOKow0qCX7+4=", - "requires": { - "pseudomap": "^1.0.1" - } - }, - "ltgt": { - "version": "2.2.1", - "resolved": "https://registry.npmjs.org/ltgt/-/ltgt-2.2.1.tgz", - "integrity": "sha1-81ypHEk/e3PaDgdJUwTxezH4fuU=" - }, - "make-dir": { - "version": "1.3.0", - "resolved": "https://registry.npmjs.org/make-dir/-/make-dir-1.3.0.tgz", - "integrity": "sha512-2w31R7SJtieJJnQtGc7RVL2StM2vGYVfqUOvUDxH6bC6aJTxPxTF0GnIgCyu7tjockiUWAYQRbxa7vKn34s5sQ==", - "optional": true, - "requires": { - "pify": "^3.0.0" - }, - "dependencies": { - "pify": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/pify/-/pify-3.0.0.tgz", - "integrity": "sha1-5aSs0sEB/fPZpNB/DbxNtJ3SgXY=", - "optional": true - } - } - }, - "md5.js": { - "version": "1.3.5", - "resolved": "https://registry.npmjs.org/md5.js/-/md5.js-1.3.5.tgz", - "integrity": "sha512-xitP+WxNPcTTOgnTJcrhM0xvdPepipPSf3I8EIpGKeFLjt3PlJLIDG3u8EX53ZIubkb+5U2+3rELYpEhHhzdkg==", - "requires": { - "hash-base": "^3.0.0", - "inherits": "^2.0.1", - "safe-buffer": "^5.1.2" - } - }, - "media-typer": { - "version": "0.3.0", - "resolved": "http://registry.npmjs.org/media-typer/-/media-typer-0.3.0.tgz", - "integrity": "sha1-hxDXrwqmJvj/+hzgAWhUUmMlV0g=" - }, - "memdown": { - "version": "1.4.1", - "resolved": "https://registry.npmjs.org/memdown/-/memdown-1.4.1.tgz", - "integrity": "sha1-tOThkhdGZP+65BNhqlAPMRnv4hU=", - "requires": { - "abstract-leveldown": "~2.7.1", - "functional-red-black-tree": "^1.0.1", - "immediate": "^3.2.3", - "inherits": "~2.0.1", - "ltgt": "~2.2.0", - "safe-buffer": "~5.1.1" - }, - "dependencies": { - "abstract-leveldown": { - "version": "2.7.2", - "resolved": "https://registry.npmjs.org/abstract-leveldown/-/abstract-leveldown-2.7.2.tgz", - "integrity": "sha512-+OVvxH2rHVEhWLdbudP6p0+dNMXu8JA1CbhP19T8paTYAcX7oJ4OVjT+ZUVpv7mITxXHqDMej+GdqXBmXkw09w==", - "requires": { - "xtend": "~4.0.0" - } - } - } - }, - "memorystream": { - "version": "0.3.1", - "resolved": "https://registry.npmjs.org/memorystream/-/memorystream-0.3.1.tgz", - "integrity": "sha1-htcJCzDORV1j+64S3aUaR93K+bI=" - }, - "merge-descriptors": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/merge-descriptors/-/merge-descriptors-1.0.1.tgz", - "integrity": "sha1-sAqqVW3YtEVoFQ7J0blT8/kMu2E=" - }, - "merkle-patricia-tree": { - "version": "2.3.1", - "resolved": "http://registry.npmjs.org/merkle-patricia-tree/-/merkle-patricia-tree-2.3.1.tgz", - "integrity": "sha512-Qp9Mpb3xazznXzzGQBqHbqCpT2AR9joUOHYYPiQjYCarrdCPCnLWXo4BFv77y4xN26KR224xoU1n/qYY7RYYgw==", - "requires": { - "async": "^1.4.2", - "ethereumjs-util": "^5.0.0", - "level-ws": "0.0.0", - "levelup": "^1.2.1", - "memdown": "^1.0.0", - "readable-stream": "^2.0.0", - "rlp": "^2.0.0", - "semaphore": ">=1.0.1" - }, - "dependencies": { - "async": { - "version": "1.5.2", - "resolved": "http://registry.npmjs.org/async/-/async-1.5.2.tgz", - "integrity": "sha1-7GphrlZIDAw8skHJVhjiCJL5Zyo=" - }, - "level-codec": { - "version": "7.0.1", - "resolved": "https://registry.npmjs.org/level-codec/-/level-codec-7.0.1.tgz", - "integrity": "sha512-Ua/R9B9r3RasXdRmOtd+t9TCOEIIlts+TN/7XTT2unhDaL6sJn83S3rUyljbr6lVtw49N3/yA0HHjpV6Kzb2aQ==" - }, - "level-errors": { - "version": "1.0.5", - "resolved": "https://registry.npmjs.org/level-errors/-/level-errors-1.0.5.tgz", - "integrity": "sha512-/cLUpQduF6bNrWuAC4pwtUKA5t669pCsCi2XbmojG2tFeOr9j6ShtdDCtFFQO1DRt+EVZhx9gPzP9G2bUaG4ig==", - "requires": { - "errno": "~0.1.1" - } - }, - "levelup": { - "version": "1.3.9", - "resolved": "https://registry.npmjs.org/levelup/-/levelup-1.3.9.tgz", - "integrity": "sha512-VVGHfKIlmw8w1XqpGOAGwq6sZm2WwWLmlDcULkKWQXEA5EopA8OBNJ2Ck2v6bdk8HeEZSbCSEgzXadyQFm76sQ==", - "requires": { - "deferred-leveldown": "~1.2.1", - "level-codec": "~7.0.0", - "level-errors": "~1.0.3", - "level-iterator-stream": "~1.3.0", - "prr": "~1.0.1", - "semver": "~5.4.1", - "xtend": "~4.0.0" - } - } - } - }, - "methods": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/methods/-/methods-1.1.2.tgz", - "integrity": "sha1-VSmk1nZUE07cxSZmVoNbD4Ua/O4=" - }, - "miller-rabin": { - "version": "4.0.1", - "resolved": "https://registry.npmjs.org/miller-rabin/-/miller-rabin-4.0.1.tgz", - "integrity": "sha512-115fLhvZVqWwHPbClyntxEVfVDfl9DLLTuJvq3g2O/Oxi8AiNouAHvDSzHS0viUJc+V5vm3eq91Xwqn9dp4jRA==", - "optional": true, - "requires": { - "bn.js": "^4.0.0", - "brorand": "^1.0.1" - } - }, - "mime": { - "version": "1.4.1", - "resolved": "https://registry.npmjs.org/mime/-/mime-1.4.1.tgz", - "integrity": "sha512-KI1+qOZu5DcW6wayYHSzR/tXKCDC5Om4s1z2QJjDULzLcmf3DvzS7oluY4HCTrc+9FiKmWUgeNLg7W3uIQvxtQ==" - }, - "mime-db": { - "version": "1.37.0", - "resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.37.0.tgz", - "integrity": "sha512-R3C4db6bgQhlIhPU48fUtdVmKnflq+hRdad7IyKhtFj06VPNVdk2RhiYL3UjQIlso8L+YxAtFkobT0VK+S/ybg==" - }, - "mime-types": { - "version": "2.1.21", - "resolved": "https://registry.npmjs.org/mime-types/-/mime-types-2.1.21.tgz", - "integrity": "sha512-3iL6DbwpyLzjR3xHSFNFeb9Nz/M8WDkX33t1GFQnFOllWk8pOrh/LSrB5OXlnlW5P9LH73X6loW/eogc+F5lJg==", - "requires": { - "mime-db": "~1.37.0" - } - }, - "mimic-response": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/mimic-response/-/mimic-response-1.0.1.tgz", - "integrity": "sha512-j5EctnkH7amfV/q5Hgmoal1g2QHFJRraOtmx0JpIqkxhBhI/lJSl1nMpQ45hVarwNETOoWEimndZ4QK0RHxuxQ==" - }, - "min-document": { - "version": "2.19.0", - "resolved": "https://registry.npmjs.org/min-document/-/min-document-2.19.0.tgz", - "integrity": "sha1-e9KC4/WELtKVu3SM3Z8f+iyCRoU=", - "requires": { - "dom-walk": "^0.1.0" - } - }, - "minimalistic-assert": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/minimalistic-assert/-/minimalistic-assert-1.0.1.tgz", - "integrity": "sha512-UtJcAD4yEaGtjPezWuO9wC4nwUnVH/8/Im3yEHQP4b67cXlD/Qr9hdITCU1xDbSEXg2XKNaP8jsReV7vQd00/A==" - }, - "minimalistic-crypto-utils": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/minimalistic-crypto-utils/-/minimalistic-crypto-utils-1.0.1.tgz", - "integrity": "sha1-9sAMHAsIIkblxNmd+4x8CDsrWCo=" - }, - "minimatch": { - "version": "3.0.4", - "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.0.4.tgz", - "integrity": "sha512-yJHVQEhyqPLUTgt9B83PXu6W3rx4MvvHvSUvToogpwoGDOUQ+yDrR0HRot+yOCdCO7u4hX3pWft6kWBBcqh0UA==", - "requires": { - "brace-expansion": "^1.1.7" - } - }, - "minimist": { - "version": "0.0.8", - "resolved": "http://registry.npmjs.org/minimist/-/minimist-0.0.8.tgz", - "integrity": "sha1-hX/Kv8M5fSYluCKCYuhqp6ARsF0=" - }, - "mkdirp": { - "version": "0.5.1", - "resolved": "http://registry.npmjs.org/mkdirp/-/mkdirp-0.5.1.tgz", - "integrity": "sha1-MAV0OOrGz3+MR2fzhkjWaX11yQM=", - "requires": { - "minimist": "0.0.8" - } - }, - "mkdirp-promise": { - "version": "5.0.1", - "resolved": "https://registry.npmjs.org/mkdirp-promise/-/mkdirp-promise-5.0.1.tgz", - "integrity": "sha1-6bj2jlUsaKnBcTuEiD96HdA5uKE=", - "optional": true, - "requires": { - "mkdirp": "*" - } - }, - "mock-fs": { - "version": "4.7.0", - "resolved": "https://registry.npmjs.org/mock-fs/-/mock-fs-4.7.0.tgz", - "integrity": "sha512-WlQNtUlzMRpvLHf8dqeUmNqfdPjGY29KrJF50Ldb4AcL+vQeR8QH3wQcFMgrhTwb1gHjZn9xggho+84tBskLgA==", - "optional": true - }, - "mout": { - "version": "0.11.1", - "resolved": "https://registry.npmjs.org/mout/-/mout-0.11.1.tgz", - "integrity": "sha1-ujYR318OWx/7/QEWa48C0fX6K5k=", - "optional": true - }, - "ms": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", - "integrity": "sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g=" - }, - "mz": { - "version": "2.7.0", - "resolved": "https://registry.npmjs.org/mz/-/mz-2.7.0.tgz", - "integrity": "sha512-z81GNO7nnYMEhrGh9LeymoE4+Yr0Wn5McHIZMK5cfQCl+NDX08sCZgUc9/6MHni9IWuFLm1Z3HTCXu2z9fN62Q==", - "optional": true, - "requires": { - "any-promise": "^1.0.0", - "object-assign": "^4.0.1", - "thenify-all": "^1.0.0" - } - }, - "nan": { - "version": "2.10.0", - "resolved": "http://registry.npmjs.org/nan/-/nan-2.10.0.tgz", - "integrity": "sha512-bAdJv7fBLhWC+/Bls0Oza+mvTaNQtP+1RyhhhvD95pgUJz6XM5IzgmxOkItJ9tkoCiplvAnXI1tNmmUD/eScyA==" - }, - "nano-json-stream-parser": { - "version": "0.1.2", - "resolved": "https://registry.npmjs.org/nano-json-stream-parser/-/nano-json-stream-parser-0.1.2.tgz", - "integrity": "sha1-DMj20OK2IrR5xA1JnEbWS3Vcb18=" - }, - "negotiator": { - "version": "0.6.1", - "resolved": "https://registry.npmjs.org/negotiator/-/negotiator-0.6.1.tgz", - "integrity": "sha1-KzJxhOiZIQEXeyhWP7XnECrNDKk=" - }, - "node-fetch": { - "version": "2.1.2", - "resolved": "http://registry.npmjs.org/node-fetch/-/node-fetch-2.1.2.tgz", - "integrity": "sha1-q4hOjn5X44qUR1POxwb3iNF2i7U=" - }, - "normalize-package-data": { - "version": "2.4.0", - "resolved": "https://registry.npmjs.org/normalize-package-data/-/normalize-package-data-2.4.0.tgz", - "integrity": "sha512-9jjUFbTPfEy3R/ad/2oNbKtW9Hgovl5O1FvFWKkKblNXoN/Oou6+9+KKohPK13Yc3/TyunyWhJp6gvRNR/PPAw==", - "requires": { - "hosted-git-info": "^2.1.4", - "is-builtin-module": "^1.0.0", - "semver": "2 || 3 || 4 || 5", - "validate-npm-package-license": "^3.0.1" - } - }, - "number-is-nan": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/number-is-nan/-/number-is-nan-1.0.1.tgz", - "integrity": "sha1-CXtgK1NCKlIsGvuHkDGDNpQaAR0=" - }, - "number-to-bn": { - "version": "1.7.0", - "resolved": "https://registry.npmjs.org/number-to-bn/-/number-to-bn-1.7.0.tgz", - "integrity": "sha1-uzYjWS9+X54AMLGXe9QaDFP+HqA=", - "requires": { - "bn.js": "4.11.6", - "strip-hex-prefix": "1.0.0" - }, - "dependencies": { - "bn.js": { - "version": "4.11.6", - "resolved": "https://registry.npmjs.org/bn.js/-/bn.js-4.11.6.tgz", - "integrity": "sha1-UzRK2xRhehP26N0s4okF0cC6MhU=" - } - } - }, - "oauth-sign": { - "version": "0.9.0", - "resolved": "https://registry.npmjs.org/oauth-sign/-/oauth-sign-0.9.0.tgz", - "integrity": "sha512-fexhUFFPTGV8ybAtSIGbV6gOkSv8UtRbDBnAyLQw4QPKkgNlsH2ByPGtMUqdWkos6YCRmAqViwgZrJc/mRDzZQ==" - }, - "object-assign": { - "version": "4.1.1", - "resolved": "https://registry.npmjs.org/object-assign/-/object-assign-4.1.1.tgz", - "integrity": "sha1-IQmtx5ZYh8/AXLvUQsrIv7s2CGM=" - }, - "object-inspect": { - "version": "1.6.0", - "resolved": "https://registry.npmjs.org/object-inspect/-/object-inspect-1.6.0.tgz", - "integrity": "sha512-GJzfBZ6DgDAmnuaM3104jR4s1Myxr3Y3zfIyN4z3UdqN69oSRacNK8UhnobDdC+7J2AHCjGwxQubNJfE70SXXQ==" - }, - "object-keys": { - "version": "0.4.0", - "resolved": "https://registry.npmjs.org/object-keys/-/object-keys-0.4.0.tgz", - "integrity": "sha1-KKaq50KN0sOpLz2V8hM13SBOAzY=" - }, - "oboe": { - "version": "2.1.3", - "resolved": "https://registry.npmjs.org/oboe/-/oboe-2.1.3.tgz", - "integrity": "sha1-K0hl29Rr6BIlcT9Om/5Lz09oCk8=", - "requires": { - "http-https": "^1.0.0" - } - }, - "on-finished": { - "version": "2.3.0", - "resolved": "https://registry.npmjs.org/on-finished/-/on-finished-2.3.0.tgz", - "integrity": "sha1-IPEzZIGwg811M3mSoWlxqi2QaUc=", - "requires": { - "ee-first": "1.1.1" - } - }, - "once": { - "version": "1.4.0", - "resolved": "https://registry.npmjs.org/once/-/once-1.4.0.tgz", - "integrity": "sha1-WDsap3WWHUsROsF9nFC6753Xa9E=", - "requires": { - "wrappy": "1" - } - }, - "os-homedir": { - "version": "1.0.2", - "resolved": "http://registry.npmjs.org/os-homedir/-/os-homedir-1.0.2.tgz", - "integrity": "sha1-/7xJiDNuDoM94MFox+8VISGqf7M=" - }, - "os-locale": { - "version": "1.4.0", - "resolved": "http://registry.npmjs.org/os-locale/-/os-locale-1.4.0.tgz", - "integrity": "sha1-IPnxeuKe00XoveWDsT0gCYA8FNk=", - "requires": { - "lcid": "^1.0.0" - } - }, - "os-tmpdir": { - "version": "1.0.2", - "resolved": "http://registry.npmjs.org/os-tmpdir/-/os-tmpdir-1.0.2.tgz", - "integrity": "sha1-u+Z0BseaqFxc/sdm/lc0VV36EnQ=" - }, - "p-cancelable": { - "version": "0.3.0", - "resolved": "https://registry.npmjs.org/p-cancelable/-/p-cancelable-0.3.0.tgz", - "integrity": "sha512-RVbZPLso8+jFeq1MfNvgXtCRED2raz/dKpacfTNxsx6pLEpEomM7gah6VeHSYV3+vo0OAi4MkArtQcWWXuQoyw==" - }, - "p-finally": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/p-finally/-/p-finally-1.0.0.tgz", - "integrity": "sha1-P7z7FbiZpEEjs0ttzBi3JDNqLK4=" - }, - "p-timeout": { - "version": "1.2.1", - "resolved": "https://registry.npmjs.org/p-timeout/-/p-timeout-1.2.1.tgz", - "integrity": "sha1-XrOzU7f86Z8QGhA4iAuwVOu+o4Y=", - "requires": { - "p-finally": "^1.0.0" - } - }, - "parse-asn1": { - "version": "5.1.1", - "resolved": "http://registry.npmjs.org/parse-asn1/-/parse-asn1-5.1.1.tgz", - "integrity": "sha512-KPx7flKXg775zZpnp9SxJlz00gTd4BmJ2yJufSc44gMCRrRQ7NSzAcSJQfifuOLgW6bEi+ftrALtsgALeB2Adw==", - "requires": { - "asn1.js": "^4.0.0", - "browserify-aes": "^1.0.0", - "create-hash": "^1.1.0", - "evp_bytestokey": "^1.0.0", - "pbkdf2": "^3.0.3" - } - }, - "parse-headers": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/parse-headers/-/parse-headers-2.0.1.tgz", - "integrity": "sha1-aug6eqJanZtwCswoaYzR8e1+lTY=", - "requires": { - "for-each": "^0.3.2", - "trim": "0.0.1" - } - }, - "parse-json": { - "version": "2.2.0", - "resolved": "https://registry.npmjs.org/parse-json/-/parse-json-2.2.0.tgz", - "integrity": "sha1-9ID0BDTvgHQfhGkJn43qGPVaTck=", - "requires": { - "error-ex": "^1.2.0" - } - }, - "parseurl": { - "version": "1.3.2", - "resolved": "https://registry.npmjs.org/parseurl/-/parseurl-1.3.2.tgz", - "integrity": "sha1-/CidTtiZMRlGDBViUyYs3I3mW/M=" - }, - "path-exists": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-2.1.0.tgz", - "integrity": "sha1-D+tsZPD8UY2adU3V77YscCJ2H0s=", - "requires": { - "pinkie-promise": "^2.0.0" - } - }, - "path-is-absolute": { - "version": "1.0.1", - "resolved": "http://registry.npmjs.org/path-is-absolute/-/path-is-absolute-1.0.1.tgz", - "integrity": "sha1-F0uSaHNVNP+8es5r9TpanhtcX18=" - }, - "path-parse": { - "version": "1.0.6", - "resolved": "https://registry.npmjs.org/path-parse/-/path-parse-1.0.6.tgz", - "integrity": "sha512-GSmOT2EbHrINBf9SR7CDELwlJ8AENk3Qn7OikK4nFYAu3Ote2+JYNVvkpAEQm3/TLNEJFD/xZJjzyxg3KBWOzw==" - }, - "path-to-regexp": { - "version": "0.1.7", - "resolved": "https://registry.npmjs.org/path-to-regexp/-/path-to-regexp-0.1.7.tgz", - "integrity": "sha1-32BBeABfUi8V60SQ5yR6G/qmf4w=" - }, - "path-type": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/path-type/-/path-type-1.1.0.tgz", - "integrity": "sha1-WcRPfuSR2nBNpBXaWkBwuk+P5EE=", - "requires": { - "graceful-fs": "^4.1.2", - "pify": "^2.0.0", - "pinkie-promise": "^2.0.0" - }, - "dependencies": { - "pify": { - "version": "2.3.0", - "resolved": "http://registry.npmjs.org/pify/-/pify-2.3.0.tgz", - "integrity": "sha1-7RQaasBDqEnqWISY59yosVMw6Qw=" - } - } - }, - "pbkdf2": { - "version": "3.0.17", - "resolved": "https://registry.npmjs.org/pbkdf2/-/pbkdf2-3.0.17.tgz", - "integrity": "sha512-U/il5MsrZp7mGg3mSQfn742na2T+1/vHDCG5/iTI3X9MKUuYUZVLQhyRsg06mCgDBTd57TxzgZt7P+fYfjRLtA==", - "requires": { - "create-hash": "^1.1.2", - "create-hmac": "^1.1.4", - "ripemd160": "^2.0.1", - "safe-buffer": "^5.0.1", - "sha.js": "^2.4.8" - } - }, - "pend": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/pend/-/pend-1.2.0.tgz", - "integrity": "sha1-elfrVQpng/kRUzH89GY9XI4AelA=", - "optional": true - }, - "performance-now": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/performance-now/-/performance-now-2.1.0.tgz", - "integrity": "sha1-Ywn04OX6kT7BxpMHrjZLSzd8nns=" - }, - "pinkie": { - "version": "2.0.4", - "resolved": "https://registry.npmjs.org/pinkie/-/pinkie-2.0.4.tgz", - "integrity": "sha1-clVrgM+g1IqXToDnckjoDtT3+HA=" - }, - "pinkie-promise": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/pinkie-promise/-/pinkie-promise-2.0.1.tgz", - "integrity": "sha1-ITXW36ejWMBprJsXh3YogihFD/o=", - "requires": { - "pinkie": "^2.0.0" - } - }, - "precond": { - "version": "0.2.3", - "resolved": "https://registry.npmjs.org/precond/-/precond-0.2.3.tgz", - "integrity": "sha1-qpWRvKokkj8eD0hJ0kD0fvwQdaw=" - }, - "prepend-http": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/prepend-http/-/prepend-http-1.0.4.tgz", - "integrity": "sha1-1PRWKwzjaW5BrFLQ4ALlemNdxtw=" - }, - "private": { - "version": "0.1.8", - "resolved": "https://registry.npmjs.org/private/-/private-0.1.8.tgz", - "integrity": "sha512-VvivMrbvd2nKkiG38qjULzlc+4Vx4wm/whI9pQD35YrARNnhxeiRktSOhSukRLFNlzg6Br/cJPet5J/u19r/mg==" - }, - "process": { - "version": "0.5.2", - "resolved": "https://registry.npmjs.org/process/-/process-0.5.2.tgz", - "integrity": "sha1-FjjYqONML0QKkduVq5rrZ3/Bhc8=" - }, - "process-nextick-args": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/process-nextick-args/-/process-nextick-args-2.0.0.tgz", - "integrity": "sha512-MtEC1TqN0EU5nephaJ4rAtThHtC86dNN9qCuEhtshvpVBkAW5ZO7BASN9REnF9eoXGcRub+pFuKEpOHE+HbEMw==" - }, - "promise-to-callback": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/promise-to-callback/-/promise-to-callback-1.0.0.tgz", - "integrity": "sha1-XSp0kBC/tn2WNZj805YHRqaP7vc=", - "requires": { - "is-fn": "^1.0.0", - "set-immediate-shim": "^1.0.1" - } - }, - "proxy-addr": { - "version": "2.0.4", - "resolved": "https://registry.npmjs.org/proxy-addr/-/proxy-addr-2.0.4.tgz", - "integrity": "sha512-5erio2h9jp5CHGwcybmxmVqHmnCBZeewlfJ0pex+UW7Qny7OOZXTtH56TGNyBizkgiOwhJtMKrVzDTeKcySZwA==", - "requires": { - "forwarded": "~0.1.2", - "ipaddr.js": "1.8.0" - } - }, - "prr": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/prr/-/prr-1.0.1.tgz", - "integrity": "sha1-0/wRS6BplaRexok/SEzrHXj19HY=" - }, - "pseudomap": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/pseudomap/-/pseudomap-1.0.2.tgz", - "integrity": "sha1-8FKijacOYYkX7wqKw0wa5aaChrM=" - }, - "psl": { - "version": "1.1.29", - "resolved": "https://registry.npmjs.org/psl/-/psl-1.1.29.tgz", - "integrity": "sha512-AeUmQ0oLN02flVHXWh9sSJF7mcdFq0ppid/JkErufc3hGIV/AMa8Fo9VgDo/cT2jFdOWoFvHp90qqBH54W+gjQ==" - }, - "public-encrypt": { - "version": "4.0.3", - "resolved": "https://registry.npmjs.org/public-encrypt/-/public-encrypt-4.0.3.tgz", - "integrity": "sha512-zVpa8oKZSz5bTMTFClc1fQOnyyEzpl5ozpi1B5YcvBrdohMjH2rfsBtyXcuNuwjsDIXmBYlF2N5FlJYhR29t8Q==", - "optional": true, - "requires": { - "bn.js": "^4.1.0", - "browserify-rsa": "^4.0.0", - "create-hash": "^1.1.0", - "parse-asn1": "^5.0.0", - "randombytes": "^2.0.1", - "safe-buffer": "^5.1.2" - } - }, - "pull-cat": { - "version": "1.1.11", - "resolved": "https://registry.npmjs.org/pull-cat/-/pull-cat-1.1.11.tgz", - "integrity": "sha1-tkLdElXaN2pwa220+pYvX9t0wxs=" - }, - "pull-defer": { - "version": "0.2.3", - "resolved": "https://registry.npmjs.org/pull-defer/-/pull-defer-0.2.3.tgz", - "integrity": "sha512-/An3KE7mVjZCqNhZsr22k1Tx8MACnUnHZZNPSJ0S62td8JtYr/AiRG42Vz7Syu31SoTLUzVIe61jtT/pNdjVYA==" - }, - "pull-level": { - "version": "2.0.4", - "resolved": "https://registry.npmjs.org/pull-level/-/pull-level-2.0.4.tgz", - "integrity": "sha512-fW6pljDeUThpq5KXwKbRG3X7Ogk3vc75d5OQU/TvXXui65ykm+Bn+fiktg+MOx2jJ85cd+sheufPL+rw9QSVZg==", - "requires": { - "level-post": "^1.0.7", - "pull-cat": "^1.1.9", - "pull-live": "^1.0.1", - "pull-pushable": "^2.0.0", - "pull-stream": "^3.4.0", - "pull-window": "^2.1.4", - "stream-to-pull-stream": "^1.7.1" - } - }, - "pull-live": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/pull-live/-/pull-live-1.0.1.tgz", - "integrity": "sha1-pOzuAeMwFV6RJLu89HYfIbOPUfU=", - "requires": { - "pull-cat": "^1.1.9", - "pull-stream": "^3.4.0" - } - }, - "pull-pushable": { - "version": "2.2.0", - "resolved": "https://registry.npmjs.org/pull-pushable/-/pull-pushable-2.2.0.tgz", - "integrity": "sha1-Xy867UethpGfAbEqLpnW8b13ZYE=" - }, - "pull-stream": { - "version": "3.6.9", - "resolved": "https://registry.npmjs.org/pull-stream/-/pull-stream-3.6.9.tgz", - "integrity": "sha512-hJn4POeBrkttshdNl0AoSCVjMVSuBwuHocMerUdoZ2+oIUzrWHFTwJMlbHND7OiKLVgvz6TFj8ZUVywUMXccbw==" - }, - "pull-window": { - "version": "2.1.4", - "resolved": "https://registry.npmjs.org/pull-window/-/pull-window-2.1.4.tgz", - "integrity": "sha1-/DuG/uvRkgx64pdpHiP3BfiFUvA=", - "requires": { - "looper": "^2.0.0" - } - }, - "punycode": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/punycode/-/punycode-2.1.1.tgz", - "integrity": "sha512-XRsRjdf+j5ml+y/6GKHPZbrF/8p2Yga0JPtdqTIY2Xe5ohJPD9saDJJLPvp9+NSBprVvevdXZybnj2cv8OEd0A==" - }, - "qs": { - "version": "6.5.2", - "resolved": "https://registry.npmjs.org/qs/-/qs-6.5.2.tgz", - "integrity": "sha512-N5ZAX4/LxJmF+7wN74pUD6qAh9/wnvdQcjq9TZjevvXzSUo7bfmw91saqMjzGS2xq91/odN2dW/WOl7qQHNDGA==" - }, - "query-string": { - "version": "5.1.1", - "resolved": "http://registry.npmjs.org/query-string/-/query-string-5.1.1.tgz", - "integrity": "sha512-gjWOsm2SoGlgLEdAGt7a6slVOk9mGiXmPFMqrEhLQ68rhQuBnpfs3+EmlvqKyxnCo9/PPlF+9MtY02S1aFg+Jw==", - "requires": { - "decode-uri-component": "^0.2.0", - "object-assign": "^4.1.0", - "strict-uri-encode": "^1.0.0" - } - }, - "randombytes": { - "version": "2.0.6", - "resolved": "https://registry.npmjs.org/randombytes/-/randombytes-2.0.6.tgz", - "integrity": "sha512-CIQ5OFxf4Jou6uOKe9t1AOgqpeU5fd70A8NPdHSGeYXqXsPe6peOwI0cUl88RWZ6sP1vPMV3avd/R6cZ5/sP1A==", - "requires": { - "safe-buffer": "^5.1.0" - } - }, - "randomfill": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/randomfill/-/randomfill-1.0.4.tgz", - "integrity": "sha512-87lcbR8+MhcWcUiQ+9e+Rwx8MyR2P7qnt15ynUlbm3TU/fjbgz4GsvfSUDTemtCCtVCqb4ZcEFlyPNTh9bBTLw==", - "optional": true, - "requires": { - "randombytes": "^2.0.5", - "safe-buffer": "^5.1.0" - } - }, - "randomhex": { - "version": "0.1.5", - "resolved": "https://registry.npmjs.org/randomhex/-/randomhex-0.1.5.tgz", - "integrity": "sha1-us7vmCMpCRQA8qKRLGzQLxCU9YU=" - }, - "range-parser": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/range-parser/-/range-parser-1.2.0.tgz", - "integrity": "sha1-9JvmtIeJTdxA3MlKMi9hEJLgDV4=" - }, - "raw-body": { - "version": "2.3.3", - "resolved": "https://registry.npmjs.org/raw-body/-/raw-body-2.3.3.tgz", - "integrity": "sha512-9esiElv1BrZoI3rCDuOuKCBRbuApGGaDPQfjSflGxdy4oyzqghxu6klEkkVIvBje+FF0BX9coEv8KqW6X/7njw==", - "requires": { - "bytes": "3.0.0", - "http-errors": "1.6.3", - "iconv-lite": "0.4.23", - "unpipe": "1.0.0" - } - }, - "read-pkg": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/read-pkg/-/read-pkg-1.1.0.tgz", - "integrity": "sha1-9f+qXs0pyzHAR0vKfXVra7KePyg=", - "requires": { - "load-json-file": "^1.0.0", - "normalize-package-data": "^2.3.2", - "path-type": "^1.0.0" - } - }, - "read-pkg-up": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/read-pkg-up/-/read-pkg-up-1.0.1.tgz", - "integrity": "sha1-nWPBMnbAZZGNV/ACpX9AobZD+wI=", - "requires": { - "find-up": "^1.0.0", - "read-pkg": "^1.0.0" - } - }, - "readable-stream": { - "version": "2.3.6", - "resolved": "http://registry.npmjs.org/readable-stream/-/readable-stream-2.3.6.tgz", - "integrity": "sha512-tQtKA9WIAhBF3+VLAseyMqZeBjW0AHJoxOtYqSUZNJxauErmLbVm2FW1y+J/YA9dUrAC39ITejlZWhVIwawkKw==", - "requires": { - "core-util-is": "~1.0.0", - "inherits": "~2.0.3", - "isarray": "~1.0.0", - "process-nextick-args": "~2.0.0", - "safe-buffer": "~5.1.1", - "string_decoder": "~1.1.1", - "util-deprecate": "~1.0.1" - }, - "dependencies": { - "isarray": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/isarray/-/isarray-1.0.0.tgz", - "integrity": "sha1-u5NdSFgsuhaMBoNJV6VKPgcSTxE=" - }, - "string_decoder": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.1.1.tgz", - "integrity": "sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg==", - "requires": { - "safe-buffer": "~5.1.0" - } - } - } - }, - "regenerate": { - "version": "1.4.0", - "resolved": "https://registry.npmjs.org/regenerate/-/regenerate-1.4.0.tgz", - "integrity": "sha512-1G6jJVDWrt0rK99kBjvEtziZNCICAuvIPkSiUFIQxVP06RCVpq3dmDo2oi6ABpYaDYaTRr67BEhL8r1wgEZZKg==" - }, - "regenerator-runtime": { - "version": "0.11.1", - "resolved": "https://registry.npmjs.org/regenerator-runtime/-/regenerator-runtime-0.11.1.tgz", - "integrity": "sha512-MguG95oij0fC3QV3URf4V2SDYGJhJnJGqvIIgdECeODCT98wSWDAJ94SSuVpYQUoTcGUIL6L4yNB7j1DFFHSBg==" - }, - "regenerator-transform": { - "version": "0.10.1", - "resolved": "https://registry.npmjs.org/regenerator-transform/-/regenerator-transform-0.10.1.tgz", - "integrity": "sha512-PJepbvDbuK1xgIgnau7Y90cwaAmO/LCLMI2mPvaXq2heGMR3aWW5/BQvYrhJ8jgmQjXewXvBjzfqKcVOmhjZ6Q==", - "requires": { - "babel-runtime": "^6.18.0", - "babel-types": "^6.19.0", - "private": "^0.1.6" - } - }, - "regexpu-core": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/regexpu-core/-/regexpu-core-2.0.0.tgz", - "integrity": "sha1-SdA4g3uNz4v6W5pCE5k45uoq4kA=", - "requires": { - "regenerate": "^1.2.1", - "regjsgen": "^0.2.0", - "regjsparser": "^0.1.4" - } - }, - "regjsgen": { - "version": "0.2.0", - "resolved": "http://registry.npmjs.org/regjsgen/-/regjsgen-0.2.0.tgz", - "integrity": "sha1-bAFq3qxVT3WCP+N6wFuS1aTtsfc=" - }, - "regjsparser": { - "version": "0.1.5", - "resolved": "https://registry.npmjs.org/regjsparser/-/regjsparser-0.1.5.tgz", - "integrity": "sha1-fuj4Tcb6eS0/0K4ijSS9lJ6tIFw=", - "requires": { - "jsesc": "~0.5.0" - } - }, - "repeating": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/repeating/-/repeating-2.0.1.tgz", - "integrity": "sha1-UhTFOpJtNVJwdSf7q0FdvAjQbdo=", - "requires": { - "is-finite": "^1.0.0" - } - }, - "request": { - "version": "2.88.0", - "resolved": "https://registry.npmjs.org/request/-/request-2.88.0.tgz", - "integrity": "sha512-NAqBSrijGLZdM0WZNsInLJpkJokL72XYjUpnB0iwsRgxh7dB6COrHnTBNwN0E+lHDAJzu7kLAkDeY08z2/A0hg==", - "requires": { - "aws-sign2": "~0.7.0", - "aws4": "^1.8.0", - "caseless": "~0.12.0", - "combined-stream": "~1.0.6", - "extend": "~3.0.2", - "forever-agent": "~0.6.1", - "form-data": "~2.3.2", - "har-validator": "~5.1.0", - "http-signature": "~1.2.0", - "is-typedarray": "~1.0.0", - "isstream": "~0.1.2", - "json-stringify-safe": "~5.0.1", - "mime-types": "~2.1.19", - "oauth-sign": "~0.9.0", - "performance-now": "^2.1.0", - "qs": "~6.5.2", - "safe-buffer": "^5.1.2", - "tough-cookie": "~2.4.3", - "tunnel-agent": "^0.6.0", - "uuid": "^3.3.2" - } - }, - "require-directory": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/require-directory/-/require-directory-2.1.1.tgz", - "integrity": "sha1-jGStX9MNqxyXbiNE/+f3kqam30I=" - }, - "require-from-string": { - "version": "1.2.1", - "resolved": "https://registry.npmjs.org/require-from-string/-/require-from-string-1.2.1.tgz", - "integrity": "sha1-UpyczvJzgK3+yaL5ZbZJu+5jZBg=" - }, - "require-main-filename": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/require-main-filename/-/require-main-filename-1.0.1.tgz", - "integrity": "sha1-l/cXtp1IeE9fUmpsWqj/3aBVpNE=" - }, - "resolve": { - "version": "1.7.1", - "resolved": "https://registry.npmjs.org/resolve/-/resolve-1.7.1.tgz", - "integrity": "sha512-c7rwLofp8g1U+h1KNyHL/jicrKg1Ek4q+Lr33AL65uZTinUZHe30D5HlyN5V9NW0JX1D5dXQ4jqW5l7Sy/kGfw==", - "requires": { - "path-parse": "^1.0.5" - } - }, - "resumer": { - "version": "0.0.0", - "resolved": "https://registry.npmjs.org/resumer/-/resumer-0.0.0.tgz", - "integrity": "sha1-8ej0YeQGS6Oegq883CqMiT0HZ1k=", - "requires": { - "through": "~2.3.4" - } - }, - "rimraf": { - "version": "2.6.2", - "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-2.6.2.tgz", - "integrity": "sha512-lreewLK/BlghmxtfH36YYVg1i8IAce4TI7oao75I1g245+6BctqTVQiBP3YUJ9C6DQOXJmkYR9X9fCLtCOJc5w==", - "requires": { - "glob": "^7.0.5" - } - }, - "ripemd160": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/ripemd160/-/ripemd160-2.0.2.tgz", - "integrity": "sha512-ii4iagi25WusVoiC4B4lq7pbXfAp3D9v5CwfkY33vffw2+pkDjY1D8GaN7spsxvCSx8dkPqOZCEZyfxcmJG2IA==", - "requires": { - "hash-base": "^3.0.0", - "inherits": "^2.0.1" - } - }, - "rlp": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/rlp/-/rlp-2.1.0.tgz", - "integrity": "sha512-93U7IKH5j7nmXFVg19MeNBGzQW5uXW1pmCuKY8veeKIhYTE32C2d0mOegfiIAfXcHOKJjjPlJisn8iHDF5AezA==", - "requires": { - "safe-buffer": "^5.1.1" - } - }, - "rustbn.js": { - "version": "0.2.0", - "resolved": "https://registry.npmjs.org/rustbn.js/-/rustbn.js-0.2.0.tgz", - "integrity": "sha512-4VlvkRUuCJvr2J6Y0ImW7NvTCriMi7ErOAqWk1y69vAdoNIzCF3yPmgeNzx+RQTLEDFq5sHfscn1MwHxP9hNfA==" - }, - "safe-buffer": { - "version": "5.1.2", - "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz", - "integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==" - }, - "safe-event-emitter": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/safe-event-emitter/-/safe-event-emitter-1.0.1.tgz", - "integrity": "sha512-e1wFe99A91XYYxoQbcq2ZJUWurxEyP8vfz7A7vuUe1s95q8r5ebraVaA1BukYJcpM6V16ugWoD9vngi8Ccu5fg==", - "requires": { - "events": "^3.0.0" - } - }, - "safer-buffer": { - "version": "2.1.2", - "resolved": "https://registry.npmjs.org/safer-buffer/-/safer-buffer-2.1.2.tgz", - "integrity": "sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg==" - }, - "scrypt": { - "version": "6.0.3", - "resolved": "https://registry.npmjs.org/scrypt/-/scrypt-6.0.3.tgz", - "integrity": "sha1-BOAUpWgrU/pQwtXM4WfXGcBthw0=", - "optional": true, - "requires": { - "nan": "^2.0.8" - } - }, - "scrypt.js": { - "version": "0.2.0", - "resolved": "https://registry.npmjs.org/scrypt.js/-/scrypt.js-0.2.0.tgz", - "integrity": "sha1-r40UZbcemZARC+38WTuUeeA6ito=", - "optional": true, - "requires": { - "scrypt": "^6.0.2", - "scryptsy": "^1.2.1" - } - }, - "scryptsy": { - "version": "1.2.1", - "resolved": "https://registry.npmjs.org/scryptsy/-/scryptsy-1.2.1.tgz", - "integrity": "sha1-oyJfpLJST4AnAHYeKFW987LZIWM=", - "optional": true, - "requires": { - "pbkdf2": "^3.0.3" - } - }, - "secp256k1": { - "version": "3.5.2", - "resolved": "https://registry.npmjs.org/secp256k1/-/secp256k1-3.5.2.tgz", - "integrity": "sha512-iin3kojdybY6NArd+UFsoTuapOF7bnJNf2UbcWXaY3z+E1sJDipl60vtzB5hbO/uquBu7z0fd4VC4Irp+xoFVQ==", - "requires": { - "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" - } - }, - "seedrandom": { - "version": "2.4.4", - "resolved": "https://registry.npmjs.org/seedrandom/-/seedrandom-2.4.4.tgz", - "integrity": "sha512-9A+PDmgm+2du77B5i0Ip2cxOqqHjgNxnBgglxLcX78A2D6c2rTo61z4jnVABpF4cKeDMDG+cmXXvdnqse2VqMA==" - }, - "seek-bzip": { - "version": "1.0.5", - "resolved": "https://registry.npmjs.org/seek-bzip/-/seek-bzip-1.0.5.tgz", - "integrity": "sha1-z+kXyz0nS8/6x5J1ivUxc+sfq9w=", - "optional": true, - "requires": { - "commander": "~2.8.1" - } - }, - "semaphore": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/semaphore/-/semaphore-1.1.0.tgz", - "integrity": "sha512-O4OZEaNtkMd/K0i6js9SL+gqy0ZCBMgUvlSqHKi4IBdjhe7wB8pwztUk1BbZ1fmrvpwFrPbHzqd2w5pTcJH6LA==" - }, - "semver": { - "version": "5.4.1", - "resolved": "https://registry.npmjs.org/semver/-/semver-5.4.1.tgz", - "integrity": "sha512-WfG/X9+oATh81XtllIo/I8gOiY9EXRdv1cQdyykeXK17YcUW3EXUAi2To4pcH6nZtJPr7ZOpM5OMyWJZm+8Rsg==" - }, - "send": { - "version": "0.16.2", - "resolved": "https://registry.npmjs.org/send/-/send-0.16.2.tgz", - "integrity": "sha512-E64YFPUssFHEFBvpbbjr44NCLtI1AohxQ8ZSiJjQLskAdKuriYEP6VyGEsRDH8ScozGpkaX1BGvhanqCwkcEZw==", - "requires": { - "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" - }, - "dependencies": { - "debug": { - "version": "2.6.9", - "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", - "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", - "requires": { - "ms": "2.0.0" - } - }, - "statuses": { - "version": "1.4.0", - "resolved": "https://registry.npmjs.org/statuses/-/statuses-1.4.0.tgz", - "integrity": "sha512-zhSCtt8v2NDrRlPQpCNtw/heZLtfUDqxBM1udqikb/Hbk52LK4nQSwr10u77iopCW5LsyHpuXS0GnEc48mLeew==" - } - } - }, - "serve-static": { - "version": "1.13.2", - "resolved": "https://registry.npmjs.org/serve-static/-/serve-static-1.13.2.tgz", - "integrity": "sha512-p/tdJrO4U387R9oMjb1oj7qSMaMfmOyd4j9hOFoxZe2baQszgHcSWjuya/CiT5kgZZKRudHNOA0pYXOl8rQ5nw==", - "requires": { - "encodeurl": "~1.0.2", - "escape-html": "~1.0.3", - "parseurl": "~1.3.2", - "send": "0.16.2" - } - }, - "servify": { - "version": "0.1.12", - "resolved": "https://registry.npmjs.org/servify/-/servify-0.1.12.tgz", - "integrity": "sha512-/xE6GvsKKqyo1BAY+KxOWXcLpPsUUyji7Qg3bVD7hh1eRze5bR1uYiuDA/k3Gof1s9BTzQZEJK8sNcNGFIzeWw==", - "requires": { - "body-parser": "^1.16.0", - "cors": "^2.8.1", - "express": "^4.14.0", - "request": "^2.79.0", - "xhr": "^2.3.3" - } - }, - "set-blocking": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/set-blocking/-/set-blocking-2.0.0.tgz", - "integrity": "sha1-BF+XgtARrppoA93TgrJDkrPYkPc=" - }, - "set-immediate-shim": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/set-immediate-shim/-/set-immediate-shim-1.0.1.tgz", - "integrity": "sha1-SysbJ+uAip+NzEgaWOXlb1mfP2E=" - }, - "setimmediate": { - "version": "1.0.5", - "resolved": "https://registry.npmjs.org/setimmediate/-/setimmediate-1.0.5.tgz", - "integrity": "sha1-KQy7Iy4waULX1+qbg3Mqt4VvgoU=", - "optional": true - }, - "setprototypeof": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/setprototypeof/-/setprototypeof-1.1.0.tgz", - "integrity": "sha512-BvE/TwpZX4FXExxOxZyRGQQv651MSwmWKZGqvmPcRIjDqWub67kTKuIMx43cZZrS/cBBzwBcNDWoFxt2XEFIpQ==" - }, - "sha.js": { - "version": "2.4.11", - "resolved": "http://registry.npmjs.org/sha.js/-/sha.js-2.4.11.tgz", - "integrity": "sha512-QMEp5B7cftE7APOjk5Y6xgrbWu+WkLVQwk8JNjZ8nKRciZaByEW6MubieAiToS7+dwvrjGhH8jRXz3MVd0AYqQ==", - "requires": { - "inherits": "^2.0.1", - "safe-buffer": "^5.0.1" - } - }, - "sha3": { - "version": "1.2.2", - "resolved": "https://registry.npmjs.org/sha3/-/sha3-1.2.2.tgz", - "integrity": "sha1-pmxQmN5MJbyIM27ItIF9AFvKe6k=", - "requires": { - "nan": "2.10.0" - } - }, - "simple-concat": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/simple-concat/-/simple-concat-1.0.0.tgz", - "integrity": "sha1-c0TLuLbib7J9ZrL8hvn21Zl1IcY=" - }, - "simple-get": { - "version": "2.8.1", - "resolved": "https://registry.npmjs.org/simple-get/-/simple-get-2.8.1.tgz", - "integrity": "sha512-lSSHRSw3mQNUGPAYRqo7xy9dhKmxFXIjLjp4KHpf99GEH2VH7C3AM+Qfx6du6jhfUi6Vm7XnbEVEf7Wb6N8jRw==", - "requires": { - "decompress-response": "^3.3.0", - "once": "^1.3.1", - "simple-concat": "^1.0.0" - } - }, - "slash": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/slash/-/slash-1.0.0.tgz", - "integrity": "sha1-xB8vbDn8FtHNF61LXYlhFK5HDVU=" - }, - "solc": { - "version": "0.4.24", - "resolved": "https://registry.npmjs.org/solc/-/solc-0.4.24.tgz", - "integrity": "sha512-2xd7Cf1HeVwrIb6Bu1cwY2/TaLRodrppCq3l7rhLimFQgmxptXhTC3+/wesVLpB09F1A2kZgvbMOgH7wvhFnBQ==", - "requires": { - "fs-extra": "^0.30.0", - "memorystream": "^0.3.1", - "require-from-string": "^1.1.0", - "semver": "^5.3.0", - "yargs": "^4.7.1" - }, - "dependencies": { - "fs-extra": { - "version": "0.30.0", - "resolved": "http://registry.npmjs.org/fs-extra/-/fs-extra-0.30.0.tgz", - "integrity": "sha1-8jP/zAjU2n1DLapEl3aYnbHfk/A=", - "requires": { - "graceful-fs": "^4.1.2", - "jsonfile": "^2.1.0", - "klaw": "^1.0.0", - "path-is-absolute": "^1.0.0", - "rimraf": "^2.2.8" - } - } - } - }, - "source-map": { - "version": "0.5.7", - "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.5.7.tgz", - "integrity": "sha1-igOdLRAh0i0eoUyA2OpGi6LvP8w=" - }, - "spdx-correct": { - "version": "3.0.2", - "resolved": "https://registry.npmjs.org/spdx-correct/-/spdx-correct-3.0.2.tgz", - "integrity": "sha512-q9hedtzyXHr5S0A1vEPoK/7l8NpfkFYTq6iCY+Pno2ZbdZR6WexZFtqeVGkGxW3TEJMN914Z55EnAGMmenlIQQ==", - "requires": { - "spdx-expression-parse": "^3.0.0", - "spdx-license-ids": "^3.0.0" - } - }, - "spdx-exceptions": { - "version": "2.2.0", - "resolved": "https://registry.npmjs.org/spdx-exceptions/-/spdx-exceptions-2.2.0.tgz", - "integrity": "sha512-2XQACfElKi9SlVb1CYadKDXvoajPgBVPn/gOQLrTvHdElaVhr7ZEbqJaRnJLVNeaI4cMEAgVCeBMKF6MWRDCRA==" - }, - "spdx-expression-parse": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/spdx-expression-parse/-/spdx-expression-parse-3.0.0.tgz", - "integrity": "sha512-Yg6D3XpRD4kkOmTpdgbUiEJFKghJH03fiC1OPll5h/0sO6neh2jqRDVHOQ4o/LMea0tgCkbMgea5ip/e+MkWyg==", - "requires": { - "spdx-exceptions": "^2.1.0", - "spdx-license-ids": "^3.0.0" - } - }, - "spdx-license-ids": { - "version": "3.0.2", - "resolved": "https://registry.npmjs.org/spdx-license-ids/-/spdx-license-ids-3.0.2.tgz", - "integrity": "sha512-qky9CVt0lVIECkEsYbNILVnPvycuEBkXoMFLRWsREkomQLevYhtRKC+R91a5TOAQ3bCMjikRwhyaRqj1VYatYg==" - }, - "sshpk": { - "version": "1.15.2", - "resolved": "https://registry.npmjs.org/sshpk/-/sshpk-1.15.2.tgz", - "integrity": "sha512-Ra/OXQtuh0/enyl4ETZAfTaeksa6BXks5ZcjpSUNrjBr0DvrJKX+1fsKDPpT9TBXgHAFsa4510aNVgI8g/+SzA==", - "requires": { - "asn1": "~0.2.3", - "assert-plus": "^1.0.0", - "bcrypt-pbkdf": "^1.0.0", - "dashdash": "^1.12.0", - "ecc-jsbn": "~0.1.1", - "getpass": "^0.1.1", - "jsbn": "~0.1.0", - "safer-buffer": "^2.0.2", - "tweetnacl": "~0.14.0" - } - }, - "statuses": { - "version": "1.5.0", - "resolved": "https://registry.npmjs.org/statuses/-/statuses-1.5.0.tgz", - "integrity": "sha1-Fhx9rBd2Wf2YEfQ3cfqZOBR4Yow=" - }, - "stream-to-pull-stream": { - "version": "1.7.2", - "resolved": "https://registry.npmjs.org/stream-to-pull-stream/-/stream-to-pull-stream-1.7.2.tgz", - "integrity": "sha1-dXYJrhzr0zx0MtSvvjH/eGULnd4=", - "requires": { - "looper": "^3.0.0", - "pull-stream": "^3.2.3" - }, - "dependencies": { - "looper": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/looper/-/looper-3.0.0.tgz", - "integrity": "sha1-LvpUw7HLq6m5Su4uWRSwvlf7t0k=" - } - } - }, - "strict-uri-encode": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/strict-uri-encode/-/strict-uri-encode-1.1.0.tgz", - "integrity": "sha1-J5siXfHVgrH1TmWt3UNS4Y+qBxM=" - }, - "string-width": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/string-width/-/string-width-1.0.2.tgz", - "integrity": "sha1-EYvfW4zcUaKn5w0hHgfisLmxB9M=", - "requires": { - "code-point-at": "^1.0.0", - "is-fullwidth-code-point": "^1.0.0", - "strip-ansi": "^3.0.0" - } - }, - "string.prototype.trim": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/string.prototype.trim/-/string.prototype.trim-1.1.2.tgz", - "integrity": "sha1-0E3iyJ4Tf019IG8Ia17S+ua+jOo=", - "requires": { - "define-properties": "^1.1.2", - "es-abstract": "^1.5.0", - "function-bind": "^1.0.2" - } - }, - "string_decoder": { - "version": "0.10.31", - "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-0.10.31.tgz", - "integrity": "sha1-YuIDvEF2bGwoyfyEMB2rHFMQ+pQ=" - }, - "strip-ansi": { - "version": "3.0.1", - "resolved": "http://registry.npmjs.org/strip-ansi/-/strip-ansi-3.0.1.tgz", - "integrity": "sha1-ajhfuIU9lS1f8F0Oiq+UJ43GPc8=", - "requires": { - "ansi-regex": "^2.0.0" - } - }, - "strip-bom": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/strip-bom/-/strip-bom-2.0.0.tgz", - "integrity": "sha1-YhmoVhZSBJHzV4i9vxRHqZx+aw4=", - "requires": { - "is-utf8": "^0.2.0" - } - }, - "strip-dirs": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/strip-dirs/-/strip-dirs-2.1.0.tgz", - "integrity": "sha512-JOCxOeKLm2CAS73y/U4ZeZPTkE+gNVCzKt7Eox84Iej1LT/2pTWYpZKJuxwQpvX1LiZb1xokNR7RLfuBAa7T3g==", - "optional": true, - "requires": { - "is-natural-number": "^4.0.1" - } - }, - "strip-hex-prefix": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/strip-hex-prefix/-/strip-hex-prefix-1.0.0.tgz", - "integrity": "sha1-DF8VX+8RUTczd96du1iNoFUA428=", - "requires": { - "is-hex-prefixed": "1.0.0" - } - }, - "supports-color": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-2.0.0.tgz", - "integrity": "sha1-U10EXOa2Nj+kARcIRimZXp3zJMc=" - }, - "swarm-js": { - "version": "0.1.37", - "resolved": "https://registry.npmjs.org/swarm-js/-/swarm-js-0.1.37.tgz", - "integrity": "sha512-G8gi5fcXP/2upwiuOShJ258sIufBVztekgobr3cVgYXObZwJ5AXLqZn52AI+/ffft29pJexF9WNdUxjlkVehoQ==", - "optional": true, - "requires": { - "bluebird": "^3.5.0", - "buffer": "^5.0.5", - "decompress": "^4.0.0", - "eth-lib": "^0.1.26", - "fs-extra": "^2.1.2", - "fs-promise": "^2.0.0", - "got": "^7.1.0", - "mime-types": "^2.1.16", - "mkdirp-promise": "^5.0.1", - "mock-fs": "^4.1.0", - "setimmediate": "^1.0.5", - "tar.gz": "^1.0.5", - "xhr-request-promise": "^0.1.2" - } - }, - "tape": { - "version": "4.9.1", - "resolved": "https://registry.npmjs.org/tape/-/tape-4.9.1.tgz", - "integrity": "sha512-6fKIXknLpoe/Jp4rzHKFPpJUHDHDqn8jus99IfPnHIjyz78HYlefTGD3b5EkbQzuLfaEvmfPK3IolLgq2xT3kw==", - "requires": { - "deep-equal": "~1.0.1", - "defined": "~1.0.0", - "for-each": "~0.3.3", - "function-bind": "~1.1.1", - "glob": "~7.1.2", - "has": "~1.0.3", - "inherits": "~2.0.3", - "minimist": "~1.2.0", - "object-inspect": "~1.6.0", - "resolve": "~1.7.1", - "resumer": "~0.0.0", - "string.prototype.trim": "~1.1.2", - "through": "~2.3.8" - }, - "dependencies": { - "minimist": { - "version": "1.2.0", - "resolved": "http://registry.npmjs.org/minimist/-/minimist-1.2.0.tgz", - "integrity": "sha1-o1AIsg9BOD7sH7kU9M1d95omQoQ=" - } - } - }, - "tar": { - "version": "2.2.1", - "resolved": "http://registry.npmjs.org/tar/-/tar-2.2.1.tgz", - "integrity": "sha1-jk0qJWwOIYXGsYrWlK7JaLg8sdE=", - "optional": true, - "requires": { - "block-stream": "*", - "fstream": "^1.0.2", - "inherits": "2" - } - }, - "tar-stream": { - "version": "1.6.2", - "resolved": "https://registry.npmjs.org/tar-stream/-/tar-stream-1.6.2.tgz", - "integrity": "sha512-rzS0heiNf8Xn7/mpdSVVSMAWAoy9bfb1WOTYC78Z0UQKeKa/CWS8FOq0lKGNa8DWKAn9gxjCvMLYc5PGXYlK2A==", - "requires": { - "bl": "^1.0.0", - "buffer-alloc": "^1.2.0", - "end-of-stream": "^1.0.0", - "fs-constants": "^1.0.0", - "readable-stream": "^2.3.0", - "to-buffer": "^1.1.1", - "xtend": "^4.0.0" - } - }, - "tar.gz": { - "version": "1.0.7", - "resolved": "https://registry.npmjs.org/tar.gz/-/tar.gz-1.0.7.tgz", - "integrity": "sha512-uhGatJvds/3diZrETqMj4RxBR779LKlIE74SsMcn5JProZsfs9j0QBwWO1RW+IWNJxS2x8Zzra1+AW6OQHWphg==", - "optional": true, - "requires": { - "bluebird": "^2.9.34", - "commander": "^2.8.1", - "fstream": "^1.0.8", - "mout": "^0.11.0", - "tar": "^2.1.1" - }, - "dependencies": { - "bluebird": { - "version": "2.11.0", - "resolved": "http://registry.npmjs.org/bluebird/-/bluebird-2.11.0.tgz", - "integrity": "sha1-U0uQM8AiyVecVro7Plpcqvu2UOE=", - "optional": true - } - } - }, - "thenify": { - "version": "3.3.0", - "resolved": "https://registry.npmjs.org/thenify/-/thenify-3.3.0.tgz", - "integrity": "sha1-5p44obq+lpsBCCB5eLn2K4hgSDk=", - "requires": { - "any-promise": "^1.0.0" - } - }, - "thenify-all": { - "version": "1.6.0", - "resolved": "https://registry.npmjs.org/thenify-all/-/thenify-all-1.6.0.tgz", - "integrity": "sha1-GhkY1ALY/D+Y+/I02wvMjMEOlyY=", - "requires": { - "thenify": ">= 3.1.0 < 4" - } - }, - "through": { - "version": "2.3.8", - "resolved": "http://registry.npmjs.org/through/-/through-2.3.8.tgz", - "integrity": "sha1-DdTJ/6q8NXlgsbckEV1+Doai4fU=" - }, - "through2": { - "version": "2.0.5", - "resolved": "https://registry.npmjs.org/through2/-/through2-2.0.5.tgz", - "integrity": "sha512-/mrRod8xqpA+IHSLyGCQ2s8SPHiCDEeQJSep1jqLYeEUClOFG2Qsh+4FU6G9VeqpZnGW/Su8LQGc4YKni5rYSQ==", - "requires": { - "readable-stream": "~2.3.6", - "xtend": "~4.0.1" - } - }, - "timed-out": { - "version": "4.0.1", - "resolved": "https://registry.npmjs.org/timed-out/-/timed-out-4.0.1.tgz", - "integrity": "sha1-8y6srFoXW+ol1/q1Zas+2HQe9W8=" - }, - "tmp": { - "version": "0.0.33", - "resolved": "https://registry.npmjs.org/tmp/-/tmp-0.0.33.tgz", - "integrity": "sha512-jRCJlojKnZ3addtTOjdIqoRuPEKBvNXcGYqzO6zWZX8KfKEpnGY5jfggJQ3EjKuu8D4bJRr0y+cYJFmYbImXGw==", - "requires": { - "os-tmpdir": "~1.0.2" - } - }, - "to-buffer": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/to-buffer/-/to-buffer-1.1.1.tgz", - "integrity": "sha512-lx9B5iv7msuFYE3dytT+KE5tap+rNYw+K4jVkb9R/asAb+pbBSM17jtunHplhBe6RRJdZx3Pn2Jph24O32mOVg==" - }, - "to-fast-properties": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/to-fast-properties/-/to-fast-properties-1.0.3.tgz", - "integrity": "sha1-uDVx+k2MJbguIxsG46MFXeTKGkc=" - }, - "tough-cookie": { - "version": "2.4.3", - "resolved": "https://registry.npmjs.org/tough-cookie/-/tough-cookie-2.4.3.tgz", - "integrity": "sha512-Q5srk/4vDM54WJsJio3XNn6K2sCG+CQ8G5Wz6bZhRZoAe/+TxjWB/GlFAnYEbkYVlON9FMk/fE3h2RLpPXo4lQ==", - "requires": { - "psl": "^1.1.24", - "punycode": "^1.4.1" - }, - "dependencies": { - "punycode": { - "version": "1.4.1", - "resolved": "https://registry.npmjs.org/punycode/-/punycode-1.4.1.tgz", - "integrity": "sha1-wNWmOycYgArY4esPpSachN1BhF4=" - } - } - }, - "treeify": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/treeify/-/treeify-1.1.0.tgz", - "integrity": "sha512-1m4RA7xVAJrSGrrXGs0L3YTwyvBs2S8PbRHaLZAkFw7JR8oIFwYtysxlBZhYIa7xSyiYJKZ3iGrrk55cGA3i9A==" - }, - "trim": { - "version": "0.0.1", - "resolved": "https://registry.npmjs.org/trim/-/trim-0.0.1.tgz", - "integrity": "sha1-WFhUf2spB1fulczMZm+1AITEYN0=" - }, - "trim-right": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/trim-right/-/trim-right-1.0.1.tgz", - "integrity": "sha1-yy4SAwZ+DI3h9hQJS5/kVwTqYAM=" - }, - "tunnel-agent": { - "version": "0.6.0", - "resolved": "https://registry.npmjs.org/tunnel-agent/-/tunnel-agent-0.6.0.tgz", - "integrity": "sha1-J6XeoGs2sEoKmWZ3SykIaPD8QP0=", - "requires": { - "safe-buffer": "^5.0.1" - } - }, - "tweetnacl": { - "version": "0.14.5", - "resolved": "https://registry.npmjs.org/tweetnacl/-/tweetnacl-0.14.5.tgz", - "integrity": "sha1-WuaBd/GS1EViadEIr6k/+HQ/T2Q=" - }, - "type-is": { - "version": "1.6.16", - "resolved": "https://registry.npmjs.org/type-is/-/type-is-1.6.16.tgz", - "integrity": "sha512-HRkVv/5qY2G6I8iab9cI7v1bOIdhm94dVjQCPFElW9W+3GeDOSHmy2EBYe4VTApuzolPcmgFTN3ftVJRKR2J9Q==", - "requires": { - "media-typer": "0.3.0", - "mime-types": "~2.1.18" - } - }, - "typedarray": { - "version": "0.0.6", - "resolved": "https://registry.npmjs.org/typedarray/-/typedarray-0.0.6.tgz", - "integrity": "sha1-hnrHTjhkGHsdPUfZlqeOxciDB3c=" - }, - "typedarray-to-buffer": { - "version": "3.1.5", - "resolved": "https://registry.npmjs.org/typedarray-to-buffer/-/typedarray-to-buffer-3.1.5.tgz", - "integrity": "sha512-zdu8XMNEDepKKR+XYOXAVPtWui0ly0NtohUscw+UmaHiAWT8hrV1rr//H6V+0DvJ3OQ19S979M0laLfX8rm82Q==", - "requires": { - "is-typedarray": "^1.0.0" - } - }, - "typewise": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/typewise/-/typewise-1.0.3.tgz", - "integrity": "sha1-EGeTZUCvl5N8xdz5kiSG6fooRlE=", - "requires": { - "typewise-core": "^1.2.0" - } - }, - "typewise-core": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/typewise-core/-/typewise-core-1.2.0.tgz", - "integrity": "sha1-l+uRgFx/VdL5QXSPpQ0xXZke8ZU=" - }, - "typewiselite": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/typewiselite/-/typewiselite-1.0.0.tgz", - "integrity": "sha1-yIgvobsQksBgBal/NO9chQjjZk4=" - }, - "ultron": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/ultron/-/ultron-1.1.1.tgz", - "integrity": "sha512-UIEXBNeYmKptWH6z8ZnqTeS8fV74zG0/eRU9VGkpzz+LIJNs8W/zM/L+7ctCkRrgbNnnR0xxw4bKOr0cW0N0Og==" - }, - "unbzip2-stream": { - "version": "1.3.1", - "resolved": "https://registry.npmjs.org/unbzip2-stream/-/unbzip2-stream-1.3.1.tgz", - "integrity": "sha512-fIZnvdjblYs7Cru/xC6tCPVhz7JkYcVQQkePwMLyQELzYTds2Xn8QefPVnvdVhhZqubxNA1cASXEH5wcK0Bucw==", - "optional": true, - "requires": { - "buffer": "^3.0.1", - "through": "^2.3.6" - }, - "dependencies": { - "base64-js": { - "version": "0.0.8", - "resolved": "https://registry.npmjs.org/base64-js/-/base64-js-0.0.8.tgz", - "integrity": "sha1-EQHpVE9KdrG8OybUUsqW16NeeXg=", - "optional": true - }, - "buffer": { - "version": "3.6.0", - "resolved": "http://registry.npmjs.org/buffer/-/buffer-3.6.0.tgz", - "integrity": "sha1-pyyTb3e5a/UvX357RnGAYoVR3vs=", - "optional": true, - "requires": { - "base64-js": "0.0.8", - "ieee754": "^1.1.4", - "isarray": "^1.0.0" - } - }, - "isarray": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/isarray/-/isarray-1.0.0.tgz", - "integrity": "sha1-u5NdSFgsuhaMBoNJV6VKPgcSTxE=", - "optional": true - } - } - }, - "underscore": { - "version": "1.8.3", - "resolved": "https://registry.npmjs.org/underscore/-/underscore-1.8.3.tgz", - "integrity": "sha1-Tz+1OxBuYJf8+ctBCfKl6b36UCI=" - }, - "unorm": { - "version": "1.4.1", - "resolved": "https://registry.npmjs.org/unorm/-/unorm-1.4.1.tgz", - "integrity": "sha1-NkIA1fE2RsqLzURJAnEzVhR5IwA=" - }, - "unpipe": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/unpipe/-/unpipe-1.0.0.tgz", - "integrity": "sha1-sr9O6FFKrmFltIF4KdIbLvSZBOw=" - }, - "uri-js": { - "version": "4.2.2", - "resolved": "https://registry.npmjs.org/uri-js/-/uri-js-4.2.2.tgz", - "integrity": "sha512-KY9Frmirql91X2Qgjry0Wd4Y+YTdrdZheS8TFwvkbLWf/G5KNJDCh6pKL5OZctEW4+0Baa5idK2ZQuELRwPznQ==", - "requires": { - "punycode": "^2.1.0" - } - }, - "url-parse-lax": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/url-parse-lax/-/url-parse-lax-1.0.0.tgz", - "integrity": "sha1-evjzA2Rem9eaJy56FKxovAYJ2nM=", - "requires": { - "prepend-http": "^1.0.1" - } - }, - "url-set-query": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/url-set-query/-/url-set-query-1.0.0.tgz", - "integrity": "sha1-AW6M/Xwg7gXK/neV6JK9BwL6ozk=" - }, - "url-to-options": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/url-to-options/-/url-to-options-1.0.1.tgz", - "integrity": "sha1-FQWgOiiaSMvXpDTvuu7FBV9WM6k=" - }, - "utf8": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/utf8/-/utf8-3.0.0.tgz", - "integrity": "sha512-E8VjFIQ/TyQgp+TZfS6l8yp/xWppSAHzidGiRrqe4bK4XP9pTRyKFgGJpO3SN7zdX4DeomTrwaseCHovfpFcqQ==", - "optional": true - }, - "util-deprecate": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/util-deprecate/-/util-deprecate-1.0.2.tgz", - "integrity": "sha1-RQ1Nyfpw3nMnYvvS1KKJgUGaDM8=" - }, - "utils-merge": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/utils-merge/-/utils-merge-1.0.1.tgz", - "integrity": "sha1-n5VxD1CiZ5R7LMwSR0HBAoQn5xM=" - }, - "uuid": { - "version": "3.3.2", - "resolved": "https://registry.npmjs.org/uuid/-/uuid-3.3.2.tgz", - "integrity": "sha512-yXJmeNaw3DnnKAOKJE51sL/ZaYfWJRl1pK9dr19YFCu0ObS231AB1/LbqTKRAQ5kw8A90rA6fr4riOUpTZvQZA==" - }, - "validate-npm-package-license": { - "version": "3.0.4", - "resolved": "https://registry.npmjs.org/validate-npm-package-license/-/validate-npm-package-license-3.0.4.tgz", - "integrity": "sha512-DpKm2Ui/xN7/HQKCtpZxoRWBhZ9Z0kqtygG8XCgNQ8ZlDnxuQmWhj566j8fN4Cu3/JmbhsDo7fcAJq4s9h27Ew==", - "requires": { - "spdx-correct": "^3.0.0", - "spdx-expression-parse": "^3.0.0" - } - }, - "vary": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/vary/-/vary-1.1.2.tgz", - "integrity": "sha1-IpnwLG3tMNSllhsLn3RSShj2NPw=" - }, - "verror": { - "version": "1.10.0", - "resolved": "https://registry.npmjs.org/verror/-/verror-1.10.0.tgz", - "integrity": "sha1-OhBcoXBTr1XW4nDB+CiGguGNpAA=", - "requires": { - "assert-plus": "^1.0.0", - "core-util-is": "1.0.2", - "extsprintf": "^1.2.0" - } - }, - "web3": { - "version": "1.0.0-beta.35", - "resolved": "https://registry.npmjs.org/web3/-/web3-1.0.0-beta.35.tgz", - "integrity": "sha512-xwDmUhvTcHQvvNnOPcPZZgCxKUsI2e+GbHy7JkTK3/Rmnutazy8x7fsAXT9myw7V1qpi3GgLoZ3fkglSUbg1Mg==", - "optional": true, - "requires": { - "web3-bzz": "1.0.0-beta.35", - "web3-core": "1.0.0-beta.35", - "web3-eth": "1.0.0-beta.35", - "web3-eth-personal": "1.0.0-beta.35", - "web3-net": "1.0.0-beta.35", - "web3-shh": "1.0.0-beta.35", - "web3-utils": "1.0.0-beta.35" - } - }, - "web3-bzz": { - "version": "1.0.0-beta.35", - "resolved": "https://registry.npmjs.org/web3-bzz/-/web3-bzz-1.0.0-beta.35.tgz", - "integrity": "sha512-BhAU0qhlr8zltm4gs/+P1gki2VkxHJaM2Rrh4DGesDW0lzwufRoNvWFlwx1bKHoFPWNbSmm9PRkHOYOINL/Tgw==", - "optional": true, - "requires": { - "got": "7.1.0", - "swarm-js": "0.1.37", - "underscore": "1.8.3" - } - }, - "web3-core": { - "version": "1.0.0-beta.35", - "resolved": "https://registry.npmjs.org/web3-core/-/web3-core-1.0.0-beta.35.tgz", - "integrity": "sha512-ayGavbgVk4KL9Y88Uv411fBJ0SVgVfKhKEBweKYzmP0zOqneMzWt6YsyD1n6kRvjAbqA0AfUPEOKyMNjcx2tjw==", - "requires": { - "web3-core-helpers": "1.0.0-beta.35", - "web3-core-method": "1.0.0-beta.35", - "web3-core-requestmanager": "1.0.0-beta.35", - "web3-utils": "1.0.0-beta.35" - } - }, - "web3-core-helpers": { - "version": "1.0.0-beta.35", - "resolved": "https://registry.npmjs.org/web3-core-helpers/-/web3-core-helpers-1.0.0-beta.35.tgz", - "integrity": "sha512-APOu3sEsamyqWt//8o4yq9KF25/uqGm+pQShson/sC4gKzmfJB07fLo2ond0X30E8fIqAPeVCotPXQxGciGUmA==", - "requires": { - "underscore": "1.8.3", - "web3-eth-iban": "1.0.0-beta.35", - "web3-utils": "1.0.0-beta.35" - } - }, - "web3-core-method": { - "version": "1.0.0-beta.35", - "resolved": "https://registry.npmjs.org/web3-core-method/-/web3-core-method-1.0.0-beta.35.tgz", - "integrity": "sha512-jidImCide8q0GpfsO4L73qoHrbkeWgwU3uOH5DKtJtv0ccmG086knNMRgryb/o9ZgetDWLmDEsJnHjBSoIwcbA==", - "requires": { - "underscore": "1.8.3", - "web3-core-helpers": "1.0.0-beta.35", - "web3-core-promievent": "1.0.0-beta.35", - "web3-core-subscriptions": "1.0.0-beta.35", - "web3-utils": "1.0.0-beta.35" - } - }, - "web3-core-promievent": { - "version": "1.0.0-beta.35", - "resolved": "https://registry.npmjs.org/web3-core-promievent/-/web3-core-promievent-1.0.0-beta.35.tgz", - "integrity": "sha512-GvqXqKq07OmHuVi5uNRg6k79a1/CI0ViCC+EtNv4CORHtDRmYEt5Bvdv6z6FJEiaaQkD0lKbFwNhLxutx7HItw==", - "requires": { - "any-promise": "1.3.0", - "eventemitter3": "1.1.1" - } - }, - "web3-core-requestmanager": { - "version": "1.0.0-beta.35", - "resolved": "https://registry.npmjs.org/web3-core-requestmanager/-/web3-core-requestmanager-1.0.0-beta.35.tgz", - "integrity": "sha512-S+zW2h17ZZQU9oe3yaCJE0E7aJS4C3Kf4kGPDv+nXjW0gKhQQhgVhw1Doq/aYQGqNSWJp7f1VHkz5gQWwg6RRg==", - "requires": { - "underscore": "1.8.3", - "web3-core-helpers": "1.0.0-beta.35", - "web3-providers-http": "1.0.0-beta.35", - "web3-providers-ipc": "1.0.0-beta.35", - "web3-providers-ws": "1.0.0-beta.35" - } - }, - "web3-core-subscriptions": { - "version": "1.0.0-beta.35", - "resolved": "https://registry.npmjs.org/web3-core-subscriptions/-/web3-core-subscriptions-1.0.0-beta.35.tgz", - "integrity": "sha512-gXzLrWvcGkGiWq1y33Z4Y80XI8XMrwowiQJkrPSjQ81K5PBKquOGwcMffLaKcwdmEy/NpsOXDeFo3eLE1Ghvvw==", - "requires": { - "eventemitter3": "1.1.1", - "underscore": "1.8.3", - "web3-core-helpers": "1.0.0-beta.35" - } - }, - "web3-eth": { - "version": "1.0.0-beta.35", - "resolved": "https://registry.npmjs.org/web3-eth/-/web3-eth-1.0.0-beta.35.tgz", - "integrity": "sha512-04mcb2nGPXThawuuYICPOxv0xOHofvQKsjZeIq+89nyOC8DQMGTAErDkGyMHQYtjpth5XDhic0wuEsA80AmFZA==", - "optional": true, - "requires": { - "underscore": "1.8.3", - "web3-core": "1.0.0-beta.35", - "web3-core-helpers": "1.0.0-beta.35", - "web3-core-method": "1.0.0-beta.35", - "web3-core-subscriptions": "1.0.0-beta.35", - "web3-eth-abi": "1.0.0-beta.35", - "web3-eth-accounts": "1.0.0-beta.35", - "web3-eth-contract": "1.0.0-beta.35", - "web3-eth-iban": "1.0.0-beta.35", - "web3-eth-personal": "1.0.0-beta.35", - "web3-net": "1.0.0-beta.35", - "web3-utils": "1.0.0-beta.35" - } - }, - "web3-eth-abi": { - "version": "1.0.0-beta.35", - "resolved": "https://registry.npmjs.org/web3-eth-abi/-/web3-eth-abi-1.0.0-beta.35.tgz", - "integrity": "sha512-KUDC+EtFFYG8z01ZleKrASdjj327/rtWHzEt6RWsEj7bBa0bGp9nEh+nqdZx/Sdgz1O8tnfFzJlrRcXpfr1vGg==", - "requires": { - "bn.js": "4.11.6", - "underscore": "1.8.3", - "web3-core-helpers": "1.0.0-beta.35", - "web3-utils": "1.0.0-beta.35" - }, - "dependencies": { - "bn.js": { - "version": "4.11.6", - "resolved": "https://registry.npmjs.org/bn.js/-/bn.js-4.11.6.tgz", - "integrity": "sha1-UzRK2xRhehP26N0s4okF0cC6MhU=" - } - } - }, - "web3-eth-accounts": { - "version": "1.0.0-beta.35", - "resolved": "https://registry.npmjs.org/web3-eth-accounts/-/web3-eth-accounts-1.0.0-beta.35.tgz", - "integrity": "sha512-duIgRsfht/0kAW/eQ0X9lKtVIykbETrnM2H7EnvplCzPHtQLodpib4o9JXfh9n6ZDgdDC7cuJoiVB9QJg089ew==", - "optional": true, - "requires": { - "any-promise": "1.3.0", - "crypto-browserify": "3.12.0", - "eth-lib": "0.2.7", - "scrypt.js": "0.2.0", - "underscore": "1.8.3", - "uuid": "2.0.1", - "web3-core": "1.0.0-beta.35", - "web3-core-helpers": "1.0.0-beta.35", - "web3-core-method": "1.0.0-beta.35", - "web3-utils": "1.0.0-beta.35" - }, - "dependencies": { - "eth-lib": { - "version": "0.2.7", - "resolved": "https://registry.npmjs.org/eth-lib/-/eth-lib-0.2.7.tgz", - "integrity": "sha1-L5Pxex4jrsN1nNSj/iDBKGo/wco=", - "optional": true, - "requires": { - "bn.js": "^4.11.6", - "elliptic": "^6.4.0", - "xhr-request-promise": "^0.1.2" - } - }, - "uuid": { - "version": "2.0.1", - "resolved": "http://registry.npmjs.org/uuid/-/uuid-2.0.1.tgz", - "integrity": "sha1-wqMN7bPlNdcsz4LjQ5QaULqFM6w=", - "optional": true - } - } - }, - "web3-eth-contract": { - "version": "1.0.0-beta.35", - "resolved": "https://registry.npmjs.org/web3-eth-contract/-/web3-eth-contract-1.0.0-beta.35.tgz", - "integrity": "sha512-foPohOg5O1UCGKGZOIs+kQK5IZdV2QQ7pAWwNxH8WHplUA+fre1MurXNpoxknUmH6mYplFhXjqgYq2MsrBpHrA==", - "optional": true, - "requires": { - "underscore": "1.8.3", - "web3-core": "1.0.0-beta.35", - "web3-core-helpers": "1.0.0-beta.35", - "web3-core-method": "1.0.0-beta.35", - "web3-core-promievent": "1.0.0-beta.35", - "web3-core-subscriptions": "1.0.0-beta.35", - "web3-eth-abi": "1.0.0-beta.35", - "web3-utils": "1.0.0-beta.35" - } - }, - "web3-eth-iban": { - "version": "1.0.0-beta.35", - "resolved": "https://registry.npmjs.org/web3-eth-iban/-/web3-eth-iban-1.0.0-beta.35.tgz", - "integrity": "sha512-H5wkcNcAIc+h/WoDIKv7ZYmrM2Xqu3O7jBQl1IWo73EDVQji+AoB2i3J8tuwI1yZRInRwrfpI3Zuwuf54hXHmQ==", - "requires": { - "bn.js": "4.11.6", - "web3-utils": "1.0.0-beta.35" - }, - "dependencies": { - "bn.js": { - "version": "4.11.6", - "resolved": "https://registry.npmjs.org/bn.js/-/bn.js-4.11.6.tgz", - "integrity": "sha1-UzRK2xRhehP26N0s4okF0cC6MhU=" - } - } - }, - "web3-eth-personal": { - "version": "1.0.0-beta.35", - "resolved": "https://registry.npmjs.org/web3-eth-personal/-/web3-eth-personal-1.0.0-beta.35.tgz", - "integrity": "sha512-AcM9nnlxu7ZRRxPvkrFB9eLxMM4A2cPfj2aCg21Wb2EpMnhR+b/O1cT33k7ApRowoMpM+T9M8vx2oPNwXfaCOQ==", - "requires": { - "web3-core": "1.0.0-beta.35", - "web3-core-helpers": "1.0.0-beta.35", - "web3-core-method": "1.0.0-beta.35", - "web3-net": "1.0.0-beta.35", - "web3-utils": "1.0.0-beta.35" - } - }, - "web3-net": { - "version": "1.0.0-beta.35", - "resolved": "https://registry.npmjs.org/web3-net/-/web3-net-1.0.0-beta.35.tgz", - "integrity": "sha512-bbwaQ/KohGjIJ6HAKbZ6KrklCAaG6/B7hIbAbVLSFLxF+Yz9lmAgQYaDInpidpC/NLb3WOmcbRF+P77J4qMVIA==", - "requires": { - "web3-core": "1.0.0-beta.35", - "web3-core-method": "1.0.0-beta.35", - "web3-utils": "1.0.0-beta.35" - } - }, - "web3-provider-engine": { - "version": "14.1.0", - "resolved": "https://registry.npmjs.org/web3-provider-engine/-/web3-provider-engine-14.1.0.tgz", - "integrity": "sha512-vGZtqhSUzGTiMGhJXNnB/aRDlrPZLhLnBZ2NPArkZtr8XSrwg9m08tw4+PuWg5za0TJuoE/vuPQc501HddZZWw==", - "requires": { - "async": "^2.5.0", - "backoff": "^2.5.0", - "clone": "^2.0.0", - "cross-fetch": "^2.1.0", - "eth-block-tracker": "^3.0.0", - "eth-json-rpc-infura": "^3.1.0", - "eth-sig-util": "^1.4.2", - "ethereumjs-block": "^1.2.2", - "ethereumjs-tx": "^1.2.0", - "ethereumjs-util": "^5.1.5", - "ethereumjs-vm": "^2.3.4", - "json-rpc-error": "^2.0.0", - "json-stable-stringify": "^1.0.1", - "promise-to-callback": "^1.0.0", - "readable-stream": "^2.2.9", - "request": "^2.85.0", - "semaphore": "^1.0.3", - "ws": "^5.1.1", - "xhr": "^2.2.0", - "xtend": "^4.0.1" - }, - "dependencies": { - "eth-sig-util": { - "version": "1.4.2", - "resolved": "https://registry.npmjs.org/eth-sig-util/-/eth-sig-util-1.4.2.tgz", - "integrity": "sha1-jZWCAsftuq6Dlwf7pvCf8ydgYhA=", - "requires": { - "ethereumjs-abi": "git+https://github.com/ethereumjs/ethereumjs-abi.git#2863c40e0982acfc0b7163f0285d4c56427c7799", - "ethereumjs-util": "^5.1.1" - } - }, - "ethereumjs-abi": { - "version": "git+https://github.com/ethereumjs/ethereumjs-abi.git#2863c40e0982acfc0b7163f0285d4c56427c7799", - "from": "git+https://github.com/ethereumjs/ethereumjs-abi.git", - "requires": { - "bn.js": "^4.10.0", - "ethereumjs-util": "^5.0.0" - } - }, - "ws": { - "version": "5.2.2", - "resolved": "https://registry.npmjs.org/ws/-/ws-5.2.2.tgz", - "integrity": "sha512-jaHFD6PFv6UgoIVda6qZllptQsMlDEJkTQcybzzXDYM1XO9Y8em691FGMPmM46WGyLU4z9KMgQN+qrux/nhlHA==", - "requires": { - "async-limiter": "~1.0.0" - } - } - } - }, - "web3-providers-http": { - "version": "1.0.0-beta.35", - "resolved": "https://registry.npmjs.org/web3-providers-http/-/web3-providers-http-1.0.0-beta.35.tgz", - "integrity": "sha512-DcIMFq52Fb08UpWyZ3ZlES6NsNqJnco4hBS/Ej6eOcASfuUayPI+GLkYVZsnF3cBYqlH+DOKuArcKSuIxK7jIA==", - "requires": { - "web3-core-helpers": "1.0.0-beta.35", - "xhr2-cookies": "1.1.0" - } - }, - "web3-providers-ipc": { - "version": "1.0.0-beta.35", - "resolved": "https://registry.npmjs.org/web3-providers-ipc/-/web3-providers-ipc-1.0.0-beta.35.tgz", - "integrity": "sha512-iB0FG0HcpUnayfa8pn4guqEQ4Y1nrroi/jffdtQgFkrNt0sD3fMSwwC0AbmECqj3tDLl0e1slBR0RENll+ZF0g==", - "requires": { - "oboe": "2.1.3", - "underscore": "1.8.3", - "web3-core-helpers": "1.0.0-beta.35" - } - }, - "web3-providers-ws": { - "version": "1.0.0-beta.35", - "resolved": "https://registry.npmjs.org/web3-providers-ws/-/web3-providers-ws-1.0.0-beta.35.tgz", - "integrity": "sha512-Cx64NgDStynKaUGDIIOfaCd0fZusL8h5avKTkdTjUu2aHhFJhZoVBGVLhoDtUaqZGWIZGcBJOoVf2JkGUOjDRQ==", - "requires": { - "underscore": "1.8.3", - "web3-core-helpers": "1.0.0-beta.35", - "websocket": "git://github.com/frozeman/WebSocket-Node.git#6c72925e3f8aaaea8dc8450f97627e85263999f2" - }, - "dependencies": { - "debug": { - "version": "2.6.9", - "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", - "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", - "requires": { - "ms": "2.0.0" - } - }, - "websocket": { - "version": "git://github.com/frozeman/WebSocket-Node.git#6c72925e3f8aaaea8dc8450f97627e85263999f2", - "from": "git://github.com/frozeman/WebSocket-Node.git#browserifyCompatible", - "requires": { - "debug": "^2.2.0", - "nan": "^2.3.3", - "typedarray-to-buffer": "^3.1.2", - "yaeti": "^0.0.6" - } - } - } - }, - "web3-shh": { - "version": "1.0.0-beta.35", - "resolved": "https://registry.npmjs.org/web3-shh/-/web3-shh-1.0.0-beta.35.tgz", - "integrity": "sha512-8qSonk/x0xabERS9Sr6AIADN/Ty+5KwARkkGIfSYHKqFpdMDz+76F7cUCxtoCZoS8K04xgZlDKYe0TJXLYA0Fw==", - "optional": true, - "requires": { - "web3-core": "1.0.0-beta.35", - "web3-core-method": "1.0.0-beta.35", - "web3-core-subscriptions": "1.0.0-beta.35", - "web3-net": "1.0.0-beta.35" - } - }, - "web3-utils": { - "version": "1.0.0-beta.35", - "resolved": "https://registry.npmjs.org/web3-utils/-/web3-utils-1.0.0-beta.35.tgz", - "integrity": "sha512-Dq6f0SOKj3BDFRgOPnE6ALbzBDCKVIW8mKWVf7tGVhTDHf+wQaWwQSC3aArFSqdExB75BPBPyDpuMTNszhljpA==", - "requires": { - "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" - }, - "dependencies": { - "bn.js": { - "version": "4.11.6", - "resolved": "https://registry.npmjs.org/bn.js/-/bn.js-4.11.6.tgz", - "integrity": "sha1-UzRK2xRhehP26N0s4okF0cC6MhU=" - }, - "utf8": { - "version": "2.1.1", - "resolved": "http://registry.npmjs.org/utf8/-/utf8-2.1.1.tgz", - "integrity": "sha1-LgHbAvfY0JRPdxBPFgnrDDBM92g=" - } - } - }, - "websocket": { - "version": "1.0.26", - "resolved": "https://registry.npmjs.org/websocket/-/websocket-1.0.26.tgz", - "integrity": "sha512-fjcrYDPIQxpTnqFQ9JjxUQcdvR89MFAOjPBlF+vjOt49w/XW4fJknUoMz/mDIn2eK1AdslVojcaOxOqyZZV8rw==", - "requires": { - "debug": "^2.2.0", - "nan": "^2.3.3", - "typedarray-to-buffer": "^3.1.2", - "yaeti": "^0.0.6" - }, - "dependencies": { - "debug": { - "version": "2.6.9", - "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", - "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", - "requires": { - "ms": "2.0.0" - } - } - } - }, - "whatwg-fetch": { - "version": "2.0.4", - "resolved": "http://registry.npmjs.org/whatwg-fetch/-/whatwg-fetch-2.0.4.tgz", - "integrity": "sha512-dcQ1GWpOD/eEQ97k66aiEVpNnapVj90/+R+SXTPYGHpYBBypfKJEQjLrvMZ7YXbKm21gXd4NcuxUTjiv1YtLng==" - }, - "which-module": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/which-module/-/which-module-1.0.0.tgz", - "integrity": "sha1-u6Y8qGGUiZT/MHc2CJ47lgJsKk8=" - }, - "window-size": { - "version": "0.2.0", - "resolved": "https://registry.npmjs.org/window-size/-/window-size-0.2.0.tgz", - "integrity": "sha1-tDFbtCFKPXBY6+7okuE/ok2YsHU=" - }, - "wrap-ansi": { - "version": "2.1.0", - "resolved": "http://registry.npmjs.org/wrap-ansi/-/wrap-ansi-2.1.0.tgz", - "integrity": "sha1-2Pw9KE3QV5T+hJc8rs3Rz4JP3YU=", - "requires": { - "string-width": "^1.0.1", - "strip-ansi": "^3.0.1" - } - }, - "wrappy": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/wrappy/-/wrappy-1.0.2.tgz", - "integrity": "sha1-tSQ9jz7BqjXxNkYFvA0QNuMKtp8=" - }, - "ws": { - "version": "3.3.3", - "resolved": "https://registry.npmjs.org/ws/-/ws-3.3.3.tgz", - "integrity": "sha512-nnWLa/NwZSt4KQJu51MYlCcSQ5g7INpOrOMt4XV8j4dqTXdmlUmSHQ8/oLC069ckre0fRsgfvsKwbTdtKLCDkA==", - "requires": { - "async-limiter": "~1.0.0", - "safe-buffer": "~5.1.0", - "ultron": "~1.1.0" - } - }, - "xhr": { - "version": "2.5.0", - "resolved": "https://registry.npmjs.org/xhr/-/xhr-2.5.0.tgz", - "integrity": "sha512-4nlO/14t3BNUZRXIXfXe+3N6w3s1KoxcJUUURctd64BLRe67E4gRwp4PjywtDY72fXpZ1y6Ch0VZQRY/gMPzzQ==", - "requires": { - "global": "~4.3.0", - "is-function": "^1.0.1", - "parse-headers": "^2.0.0", - "xtend": "^4.0.0" - } - }, - "xhr-request": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/xhr-request/-/xhr-request-1.1.0.tgz", - "integrity": "sha512-Y7qzEaR3FDtL3fP30k9wO/e+FBnBByZeybKOhASsGP30NIkRAAkKD/sCnLvgEfAIEC1rcmK7YG8f4oEnIrrWzA==", - "requires": { - "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" - } - }, - "xhr-request-promise": { - "version": "0.1.2", - "resolved": "https://registry.npmjs.org/xhr-request-promise/-/xhr-request-promise-0.1.2.tgz", - "integrity": "sha1-NDxE0e53JrhkgGloLQ+EDIO0Jh0=", - "requires": { - "xhr-request": "^1.0.1" - } - }, - "xhr2-cookies": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/xhr2-cookies/-/xhr2-cookies-1.1.0.tgz", - "integrity": "sha1-fXdEnQmZGX8VXLc7I99yUF7YnUg=", - "requires": { - "cookiejar": "^2.1.1" - } - }, - "xtend": { - "version": "4.0.1", - "resolved": "https://registry.npmjs.org/xtend/-/xtend-4.0.1.tgz", - "integrity": "sha1-pcbVMr5lbiPbgg77lDofBJmNY68=" - }, - "y18n": { - "version": "3.2.1", - "resolved": "https://registry.npmjs.org/y18n/-/y18n-3.2.1.tgz", - "integrity": "sha1-bRX7qITAhnnA136I53WegR4H+kE=" - }, - "yaeti": { - "version": "0.0.6", - "resolved": "https://registry.npmjs.org/yaeti/-/yaeti-0.0.6.tgz", - "integrity": "sha1-8m9ITXJoTPQr7ft2lwqhYI+/lXc=" - }, - "yargs": { - "version": "4.8.1", - "resolved": "http://registry.npmjs.org/yargs/-/yargs-4.8.1.tgz", - "integrity": "sha1-wMQpJMpKqmsObaFznfshZDn53cA=", - "requires": { - "cliui": "^3.2.0", - "decamelize": "^1.1.1", - "get-caller-file": "^1.0.1", - "lodash.assign": "^4.0.3", - "os-locale": "^1.4.0", - "read-pkg-up": "^1.0.1", - "require-directory": "^2.1.1", - "require-main-filename": "^1.0.1", - "set-blocking": "^2.0.0", - "string-width": "^1.0.1", - "which-module": "^1.0.0", - "window-size": "^0.2.0", - "y18n": "^3.2.1", - "yargs-parser": "^2.4.1" - } - }, - "yargs-parser": { - "version": "2.4.1", - "resolved": "http://registry.npmjs.org/yargs-parser/-/yargs-parser-2.4.1.tgz", - "integrity": "sha1-hVaN488VD/SfpRgl8DqMiA3cxcQ=", - "requires": { - "camelcase": "^3.0.0", - "lodash.assign": "^4.0.6" - } - }, - "yauzl": { - "version": "2.10.0", - "resolved": "https://registry.npmjs.org/yauzl/-/yauzl-2.10.0.tgz", - "integrity": "sha1-x+sXyT4RLLEIb6bY5R+wZnt5pfk=", - "optional": true, - "requires": { - "buffer-crc32": "~0.2.3", - "fd-slicer": "~1.1.0" - } - } - } - }, - "get-caller-file": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/get-caller-file/-/get-caller-file-1.0.3.tgz", - "integrity": "sha512-3t6rVToeoZfYSGd8YoLFR2DJkiQrIiUrGcjvFX2mDw3bn6k2OtwHN0TNCLbBO+w8qTvimhDkv+LSscbJY1vE6w==" - }, - "get-stream": { - "version": "3.0.0", - "resolved": "http://registry.npmjs.org/get-stream/-/get-stream-3.0.0.tgz", - "integrity": "sha1-jpQ9E1jcN1VQVOy+LtsFqhdO3hQ=" - }, - "invert-kv": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/invert-kv/-/invert-kv-1.0.0.tgz", - "integrity": "sha1-EEqOSqym09jNFXqO+L+rLXo//bY=" - }, - "is-fullwidth-code-point": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-2.0.0.tgz", - "integrity": "sha1-o7MKXE8ZkYMWeqq5O+764937ZU8=" - }, - "is-stream": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/is-stream/-/is-stream-1.1.0.tgz", - "integrity": "sha1-EtSj3U5o4Lec6428hBc66A2RykQ=" - }, - "isexe": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/isexe/-/isexe-2.0.0.tgz", - "integrity": "sha1-6PvzdNxVb/iUehDcsFctYz8s+hA=" - }, - "lcid": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/lcid/-/lcid-1.0.0.tgz", - "integrity": "sha1-MIrMr6C8SDo4Z7S28rlQYlHRuDU=", - "requires": { - "invert-kv": "^1.0.0" - } - }, - "locate-path": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-2.0.0.tgz", - "integrity": "sha1-K1aLJl7slExtnA3pw9u7ygNUzY4=", - "requires": { - "p-locate": "^2.0.0", - "path-exists": "^3.0.0" - } - }, - "lru-cache": { - "version": "4.1.3", - "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-4.1.3.tgz", - "integrity": "sha512-fFEhvcgzuIoJVUF8fYr5KR0YqxD238zgObTps31YdADwPPAp82a4M8TrckkWyx7ekNlf9aBcVn81cFwwXngrJA==", - "requires": { - "pseudomap": "^1.0.2", - "yallist": "^2.1.2" - } - }, - "mem": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/mem/-/mem-1.1.0.tgz", - "integrity": "sha1-Xt1StIXKHZAP5kiVUFOZoN+kX3Y=", - "requires": { - "mimic-fn": "^1.0.0" - } - }, - "mimic-fn": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/mimic-fn/-/mimic-fn-1.2.0.tgz", - "integrity": "sha512-jf84uxzwiuiIVKiOLpfYk7N46TSy8ubTonmneY9vrpHNAnp0QBt2BxWV9dO3/j+BoVAb+a5G6YDPW3M5HOdMWQ==" - }, - "npm-run-path": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/npm-run-path/-/npm-run-path-2.0.2.tgz", - "integrity": "sha1-NakjLfo11wZ7TLLd8jV7GHFTbF8=", - "requires": { - "path-key": "^2.0.0" - } - }, - "number-is-nan": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/number-is-nan/-/number-is-nan-1.0.1.tgz", - "integrity": "sha1-CXtgK1NCKlIsGvuHkDGDNpQaAR0=" - }, - "os-locale": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/os-locale/-/os-locale-2.1.0.tgz", - "integrity": "sha512-3sslG3zJbEYcaC4YVAvDorjGxc7tv6KVATnLPZONiljsUncvihe9BQoVCEs0RZ1kmf4Hk9OBqlZfJZWI4GanKA==", - "requires": { - "execa": "^0.7.0", - "lcid": "^1.0.0", - "mem": "^1.1.0" - } - }, - "p-finally": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/p-finally/-/p-finally-1.0.0.tgz", - "integrity": "sha1-P7z7FbiZpEEjs0ttzBi3JDNqLK4=" - }, - "p-limit": { - "version": "1.3.0", - "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-1.3.0.tgz", - "integrity": "sha512-vvcXsLAJ9Dr5rQOPk7toZQZJApBl2K4J6dANSsEuh6QI41JYcsS/qhTGa9ErIUUgK3WNQoJYvylxvjqmiqEA9Q==", - "requires": { - "p-try": "^1.0.0" - } - }, - "p-locate": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-2.0.0.tgz", - "integrity": "sha1-IKAQOyIqcMj9OcwuWAaA893l7EM=", - "requires": { - "p-limit": "^1.1.0" - } - }, - "p-try": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/p-try/-/p-try-1.0.0.tgz", - "integrity": "sha1-y8ec26+P1CKOE/Yh8rGiN8GyB7M=" - }, - "path-exists": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-3.0.0.tgz", - "integrity": "sha1-zg6+ql94yxiSXqfYENe1mwEP1RU=" - }, - "path-key": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/path-key/-/path-key-2.0.1.tgz", - "integrity": "sha1-QRyttXTFoUDTpLGRDUDYDMn0C0A=" - }, - "pseudomap": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/pseudomap/-/pseudomap-1.0.2.tgz", - "integrity": "sha1-8FKijacOYYkX7wqKw0wa5aaChrM=" - }, - "require-directory": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/require-directory/-/require-directory-2.1.1.tgz", - "integrity": "sha1-jGStX9MNqxyXbiNE/+f3kqam30I=" - }, - "require-main-filename": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/require-main-filename/-/require-main-filename-1.0.1.tgz", - "integrity": "sha1-l/cXtp1IeE9fUmpsWqj/3aBVpNE=" - }, - "set-blocking": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/set-blocking/-/set-blocking-2.0.0.tgz", - "integrity": "sha1-BF+XgtARrppoA93TgrJDkrPYkPc=" - }, - "shebang-command": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/shebang-command/-/shebang-command-1.2.0.tgz", - "integrity": "sha1-RKrGW2lbAzmJaMOfNj/uXer98eo=", - "requires": { - "shebang-regex": "^1.0.0" - } - }, - "shebang-regex": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/shebang-regex/-/shebang-regex-1.0.0.tgz", - "integrity": "sha1-2kL0l0DAtC2yypcoVxyxkMmO/qM=" - }, - "signal-exit": { - "version": "3.0.2", - "resolved": "https://registry.npmjs.org/signal-exit/-/signal-exit-3.0.2.tgz", - "integrity": "sha1-tf3AjxKH6hF4Yo5BXiUTK3NkbG0=" - }, - "source-map": { - "version": "0.6.1", - "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", - "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==" - }, - "source-map-support": { - "version": "0.5.9", - "resolved": "https://registry.npmjs.org/source-map-support/-/source-map-support-0.5.9.tgz", - "integrity": "sha512-gR6Rw4MvUlYy83vP0vxoVNzM6t8MUXqNuRsuBmBHQDu1Fh6X015FrLdgoDKcNdkwGubozq0P4N0Q37UyFVr1EA==", - "requires": { - "buffer-from": "^1.0.0", - "source-map": "^0.6.0" - } - }, - "string-width": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/string-width/-/string-width-2.1.1.tgz", - "integrity": "sha512-nOqH59deCq9SRHlxq1Aw85Jnt4w6KvLKqWVik6oA9ZklXLNIOlqg4F2yrT1MVaTjAqvVwdfeZ7w7aCvJD7ugkw==", - "requires": { - "is-fullwidth-code-point": "^2.0.0", - "strip-ansi": "^4.0.0" - } - }, - "strip-ansi": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-4.0.0.tgz", - "integrity": "sha1-qEeQIusaw2iocTibY1JixQXuNo8=", - "requires": { - "ansi-regex": "^3.0.0" - } - }, - "strip-eof": { - "version": "1.0.0", - "resolved": "http://registry.npmjs.org/strip-eof/-/strip-eof-1.0.0.tgz", - "integrity": "sha1-u0P/VZim6wXYm1n80SnJgzE2Br8=" - }, - "which": { - "version": "1.3.1", - "resolved": "https://registry.npmjs.org/which/-/which-1.3.1.tgz", - "integrity": "sha512-HxJdYWq1MTIQbJ3nw0cqssHoTNU267KlrDuGZ1WYlxDStUtKUhOaJmh112/TZmHxxUfuJqPXSOm7tDyas0OSIQ==", - "requires": { - "isexe": "^2.0.0" - } - }, - "which-module": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/which-module/-/which-module-2.0.0.tgz", - "integrity": "sha1-2e8H3Od7mQK4o6j6SzHD4/fm6Ho=" - }, - "wrap-ansi": { - "version": "2.1.0", - "resolved": "http://registry.npmjs.org/wrap-ansi/-/wrap-ansi-2.1.0.tgz", - "integrity": "sha1-2Pw9KE3QV5T+hJc8rs3Rz4JP3YU=", - "requires": { - "string-width": "^1.0.1", - "strip-ansi": "^3.0.1" - }, - "dependencies": { - "ansi-regex": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-2.1.1.tgz", - "integrity": "sha1-w7M6te42DYbg5ijwRorn7yfWVN8=" - }, - "is-fullwidth-code-point": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-1.0.0.tgz", - "integrity": "sha1-754xOG8DGn8NZDr4L95QxFfvAMs=", - "requires": { - "number-is-nan": "^1.0.0" - } - }, - "string-width": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/string-width/-/string-width-1.0.2.tgz", - "integrity": "sha1-EYvfW4zcUaKn5w0hHgfisLmxB9M=", - "requires": { - "code-point-at": "^1.0.0", - "is-fullwidth-code-point": "^1.0.0", - "strip-ansi": "^3.0.0" - } - }, - "strip-ansi": { - "version": "3.0.1", - "resolved": "http://registry.npmjs.org/strip-ansi/-/strip-ansi-3.0.1.tgz", - "integrity": "sha1-ajhfuIU9lS1f8F0Oiq+UJ43GPc8=", - "requires": { - "ansi-regex": "^2.0.0" - } - } - } - }, - "y18n": { - "version": "3.2.1", - "resolved": "https://registry.npmjs.org/y18n/-/y18n-3.2.1.tgz", - "integrity": "sha1-bRX7qITAhnnA136I53WegR4H+kE=" - }, - "yallist": { - "version": "2.1.2", - "resolved": "https://registry.npmjs.org/yallist/-/yallist-2.1.2.tgz", - "integrity": "sha1-HBH5IY8HYImkfdUS+TxmmaaoHVI=" - }, - "yargs": { - "version": "11.1.0", - "resolved": "http://registry.npmjs.org/yargs/-/yargs-11.1.0.tgz", - "integrity": "sha512-NwW69J42EsCSanF8kyn5upxvjp5ds+t3+udGBeTbFnERA+lF541DDpMawzo4z6W/QrzNM18D+BPMiOBibnFV5A==", - "requires": { - "cliui": "^4.0.0", - "decamelize": "^1.1.1", - "find-up": "^2.1.0", - "get-caller-file": "^1.0.1", - "os-locale": "^2.0.0", - "require-directory": "^2.1.1", - "require-main-filename": "^1.0.1", - "set-blocking": "^2.0.0", - "string-width": "^2.0.0", - "which-module": "^2.0.0", - "y18n": "^3.2.1", - "yargs-parser": "^9.0.2" - } - }, - "yargs-parser": { - "version": "9.0.2", - "resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-9.0.2.tgz", - "integrity": "sha1-nM9qQ0YP5O1Aqbto9I1DuKaMwHc=", - "requires": { - "camelcase": "^4.1.0" - } - } - } - }, - "get-caller-file": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/get-caller-file/-/get-caller-file-1.0.3.tgz", - "integrity": "sha512-3t6rVToeoZfYSGd8YoLFR2DJkiQrIiUrGcjvFX2mDw3bn6k2OtwHN0TNCLbBO+w8qTvimhDkv+LSscbJY1vE6w==" - }, - "getpass": { - "version": "0.1.7", - "resolved": "https://registry.npmjs.org/getpass/-/getpass-0.1.7.tgz", - "integrity": "sha1-Xv+OPmhNVprkyysSgmBOi6YhSfo=", - "requires": { - "assert-plus": "^1.0.0" - } - }, - "glob": { - "version": "7.1.3", - "resolved": "https://registry.npmjs.org/glob/-/glob-7.1.3.tgz", - "integrity": "sha512-vcfuiIxogLV4DlGBHIUOwI0IbrJ8HWPc4MU7HzviGeNho/UJDfi6B5p3sHeWIQ0KGIU0Jpxi5ZHxemQfLkkAwQ==", - "requires": { - "fs.realpath": "^1.0.0", - "inflight": "^1.0.4", - "inherits": "2", - "minimatch": "^3.0.4", - "once": "^1.3.0", - "path-is-absolute": "^1.0.0" - } - }, - "global": { - "version": "4.3.2", - "resolved": "https://registry.npmjs.org/global/-/global-4.3.2.tgz", - "integrity": "sha1-52mJJopsdMOJCLEwWxD8DjlOnQ8=", - "requires": { - "min-document": "^2.19.0", - "process": "~0.5.1" - } - }, - "globals": { - "version": "9.18.0", - "resolved": "https://registry.npmjs.org/globals/-/globals-9.18.0.tgz", - "integrity": "sha512-S0nG3CLEQiY/ILxqtztTWH/3iRRdyBLw6KMDxnKMchrtbj2OFmehVh0WUCfW3DUrIgx/qFrJPICrq4Z4sTR9UQ==" - }, - "graceful-fs": { - "version": "4.1.15", - "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.1.15.tgz", - "integrity": "sha512-6uHUhOPEBgQ24HM+r6b/QwWfZq+yiFcipKFrOFiBEnWdy5sdzYoi+pJeQaPI5qOLRFqWmAXUPQNsielzdLoecA==" - }, - "har-schema": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/har-schema/-/har-schema-2.0.0.tgz", - "integrity": "sha1-qUwiJOvKwEeCoNkDVSHyRzW37JI=" - }, - "har-validator": { - "version": "5.1.3", - "resolved": "https://registry.npmjs.org/har-validator/-/har-validator-5.1.3.tgz", - "integrity": "sha512-sNvOCzEQNr/qrvJgc3UG/kD4QtlHycrzwS+6mfTrrSq97BvaYcPZZI1ZSqGSPR73Cxn4LKTD4PttRwfU7jWq5g==", - "requires": { - "ajv": "^6.5.5", - "har-schema": "^2.0.0" - } - }, - "has": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/has/-/has-1.0.3.tgz", - "integrity": "sha512-f2dvO0VU6Oej7RkWJGrehjbzMAjFp5/VKPp5tTpWIV4JHHZK1/BxbFRtf/siA2SWTe09caDmVtYYzWEIbBS4zw==", - "requires": { - "function-bind": "^1.1.1" - } - }, - "has-ansi": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/has-ansi/-/has-ansi-2.0.0.tgz", - "integrity": "sha1-NPUEnOHs3ysGSa8+8k5F7TVBbZE=", - "requires": { - "ansi-regex": "^2.0.0" - } - }, - "has-symbols": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/has-symbols/-/has-symbols-1.0.0.tgz", - "integrity": "sha1-uhqPGvKg/DllD1yFA2dwQSIGO0Q=" - }, - "hash-base": { - "version": "3.0.4", - "resolved": "https://registry.npmjs.org/hash-base/-/hash-base-3.0.4.tgz", - "integrity": "sha1-X8hoaEfs1zSZQDMZprCj8/auSRg=", - "requires": { - "inherits": "^2.0.1", - "safe-buffer": "^5.0.1" - } - }, - "hash.js": { - "version": "1.1.7", - "resolved": "https://registry.npmjs.org/hash.js/-/hash.js-1.1.7.tgz", - "integrity": "sha512-taOaskGt4z4SOANNseOviYDvjEJinIkRgmp7LbKP2YTTmVxWBl87s/uzK9r+44BclBSp2X7K1hqeNfz9JbBeXA==", - "requires": { - "inherits": "^2.0.3", - "minimalistic-assert": "^1.0.1" - } - }, - "hdkey": { - "version": "0.7.1", - "resolved": "https://registry.npmjs.org/hdkey/-/hdkey-0.7.1.tgz", - "integrity": "sha1-yu5L6BqneSHpCbjSKN0PKayu5jI=", - "requires": { - "coinstring": "^2.0.0", - "secp256k1": "^3.0.1" - } - }, - "hmac-drbg": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/hmac-drbg/-/hmac-drbg-1.0.1.tgz", - "integrity": "sha1-0nRXAQJabHdabFRXk+1QL8DGSaE=", - "requires": { - "hash.js": "^1.0.3", - "minimalistic-assert": "^1.0.0", - "minimalistic-crypto-utils": "^1.0.1" - } - }, - "home-or-tmp": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/home-or-tmp/-/home-or-tmp-2.0.0.tgz", - "integrity": "sha1-42w/LSyufXRqhX440Y1fMqeILbg=", - "requires": { - "os-homedir": "^1.0.0", - "os-tmpdir": "^1.0.1" - } - }, - "hosted-git-info": { - "version": "2.7.1", - "resolved": "https://registry.npmjs.org/hosted-git-info/-/hosted-git-info-2.7.1.tgz", - "integrity": "sha512-7T/BxH19zbcCTa8XkMlbK5lTo1WtgkFi3GvdWEyNuc4Vex7/9Dqbnpsf4JMydcfj9HCg4zUWFTL3Za6lapg5/w==" - }, - "http-signature": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/http-signature/-/http-signature-1.2.0.tgz", - "integrity": "sha1-muzZJRFHcvPZW2WmCruPfBj7rOE=", - "requires": { - "assert-plus": "^1.0.0", - "jsprim": "^1.2.2", - "sshpk": "^1.7.0" - } - }, - "iconv-lite": { - "version": "0.4.24", - "resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.4.24.tgz", - "integrity": "sha512-v3MXnZAcvnywkTUEZomIActle7RXXeedOR31wwl7VlyoXO4Qi9arvSenNQWne1TcRwhCL1HwLI21bEqdpj8/rA==", - "requires": { - "safer-buffer": ">= 2.1.2 < 3" - } - }, - "immediate": { - "version": "3.2.3", - "resolved": "https://registry.npmjs.org/immediate/-/immediate-3.2.3.tgz", - "integrity": "sha1-0UD6j2FGWb1lQSMwl92qwlzdmRw=" - }, - "inflight": { - "version": "1.0.6", - "resolved": "https://registry.npmjs.org/inflight/-/inflight-1.0.6.tgz", - "integrity": "sha1-Sb1jMdfQLQwJvJEKEHW6gWW1bfk=", - "requires": { - "once": "^1.3.0", - "wrappy": "1" - } - }, - "inherits": { - "version": "2.0.3", - "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.3.tgz", - "integrity": "sha1-Yzwsg+PaQqUC9SRmAiSA9CCCYd4=" - }, - "invariant": { - "version": "2.2.4", - "resolved": "https://registry.npmjs.org/invariant/-/invariant-2.2.4.tgz", - "integrity": "sha512-phJfQVBuaJM5raOpJjSfkiD6BpbCE4Ns//LaXl6wGYtUBY83nWS6Rf9tXm2e8VaK60JEjYldbPif/A2B1C2gNA==", - "requires": { - "loose-envify": "^1.0.0" - } - }, - "invert-kv": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/invert-kv/-/invert-kv-1.0.0.tgz", - "integrity": "sha1-EEqOSqym09jNFXqO+L+rLXo//bY=" - }, - "is-arrayish": { - "version": "0.2.1", - "resolved": "https://registry.npmjs.org/is-arrayish/-/is-arrayish-0.2.1.tgz", - "integrity": "sha1-d8mYQFJ6qOyxqLppe4BkWnqSap0=" - }, - "is-builtin-module": { - "version": "1.0.0", - "resolved": "http://registry.npmjs.org/is-builtin-module/-/is-builtin-module-1.0.0.tgz", - "integrity": "sha1-VAVy0096wxGfj3bDDLwbHgN6/74=", - "requires": { - "builtin-modules": "^1.0.0" - } - }, - "is-callable": { - "version": "1.1.4", - "resolved": "https://registry.npmjs.org/is-callable/-/is-callable-1.1.4.tgz", - "integrity": "sha512-r5p9sxJjYnArLjObpjA4xu5EKI3CuKHkJXMhT7kwbpUyIFD1n5PMAsoPvWnvtZiNz7LjkYDRZhd7FlI0eMijEA==" - }, - "is-date-object": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/is-date-object/-/is-date-object-1.0.1.tgz", - "integrity": "sha1-mqIOtq7rv/d/vTPnTKAbM1gdOhY=" - }, - "is-finite": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/is-finite/-/is-finite-1.0.2.tgz", - "integrity": "sha1-zGZ3aVYCvlUO8R6LSqYwU0K20Ko=", - "requires": { - "number-is-nan": "^1.0.0" - } - }, - "is-fn": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/is-fn/-/is-fn-1.0.0.tgz", - "integrity": "sha1-lUPV3nvPWwiiLsiiC65uKG1RDYw=" - }, - "is-fullwidth-code-point": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-1.0.0.tgz", - "integrity": "sha1-754xOG8DGn8NZDr4L95QxFfvAMs=", - "requires": { - "number-is-nan": "^1.0.0" - } - }, - "is-function": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/is-function/-/is-function-1.0.1.tgz", - "integrity": "sha1-Es+5i2W1fdPRk6MSH19uL0N2ArU=" - }, - "is-hex-prefixed": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/is-hex-prefixed/-/is-hex-prefixed-1.0.0.tgz", - "integrity": "sha1-fY035q135dEnFIkTxXPggtd39VQ=" - }, - "is-regex": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/is-regex/-/is-regex-1.0.4.tgz", - "integrity": "sha1-VRdIm1RwkbCTDglWVM7SXul+lJE=", - "requires": { - "has": "^1.0.1" - } - }, - "is-stream": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/is-stream/-/is-stream-1.1.0.tgz", - "integrity": "sha1-EtSj3U5o4Lec6428hBc66A2RykQ=" - }, - "is-symbol": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/is-symbol/-/is-symbol-1.0.2.tgz", - "integrity": "sha512-HS8bZ9ox60yCJLH9snBpIwv9pYUAkcuLhSA1oero1UB5y9aiQpRA8y2ex945AOtCZL1lJDeIk3G5LthswI46Lw==", - "requires": { - "has-symbols": "^1.0.0" - } - }, - "is-typedarray": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/is-typedarray/-/is-typedarray-1.0.0.tgz", - "integrity": "sha1-5HnICFjfDBsR3dppQPlgEfzaSpo=" - }, - "is-utf8": { - "version": "0.2.1", - "resolved": "https://registry.npmjs.org/is-utf8/-/is-utf8-0.2.1.tgz", - "integrity": "sha1-Sw2hRCEE0bM2NA6AeX6GXPOffXI=" - }, - "isarray": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/isarray/-/isarray-1.0.0.tgz", - "integrity": "sha1-u5NdSFgsuhaMBoNJV6VKPgcSTxE=" - }, - "isstream": { - "version": "0.1.2", - "resolved": "https://registry.npmjs.org/isstream/-/isstream-0.1.2.tgz", - "integrity": "sha1-R+Y/evVa+m+S4VAOaQ64uFKcCZo=" - }, - "js-sha3": { - "version": "0.6.1", - "resolved": "https://registry.npmjs.org/js-sha3/-/js-sha3-0.6.1.tgz", - "integrity": "sha1-W4n3enR3Z5h39YxKB1JAk0sflcA=" - }, - "js-tokens": { - "version": "3.0.2", - "resolved": "https://registry.npmjs.org/js-tokens/-/js-tokens-3.0.2.tgz", - "integrity": "sha1-mGbfOVECEw449/mWvOtlRDIJwls=" - }, - "jsbn": { - "version": "0.1.1", - "resolved": "https://registry.npmjs.org/jsbn/-/jsbn-0.1.1.tgz", - "integrity": "sha1-peZUwuWi3rXyAdls77yoDA7y9RM=" - }, - "jsesc": { - "version": "0.5.0", - "resolved": "http://registry.npmjs.org/jsesc/-/jsesc-0.5.0.tgz", - "integrity": "sha1-597mbjXW/Bb3EP6R1c9p9w8IkR0=" - }, - "json-rpc-engine": { - "version": "3.8.0", - "resolved": "https://registry.npmjs.org/json-rpc-engine/-/json-rpc-engine-3.8.0.tgz", - "integrity": "sha512-6QNcvm2gFuuK4TKU1uwfH0Qd/cOSb9c1lls0gbnIhciktIUQJwz6NQNAW4B1KiGPenv7IKu97V222Yo1bNhGuA==", - "requires": { - "async": "^2.0.1", - "babel-preset-env": "^1.7.0", - "babelify": "^7.3.0", - "json-rpc-error": "^2.0.0", - "promise-to-callback": "^1.0.0", - "safe-event-emitter": "^1.0.1" - } - }, - "json-rpc-error": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/json-rpc-error/-/json-rpc-error-2.0.0.tgz", - "integrity": "sha1-p6+cICg4tekFxyUOVH8a/3cligI=", - "requires": { - "inherits": "^2.0.1" - } - }, - "json-rpc-random-id": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/json-rpc-random-id/-/json-rpc-random-id-1.0.1.tgz", - "integrity": "sha1-uknZat7RRE27jaPSA3SKy7zeyMg=" - }, - "json-schema": { - "version": "0.2.3", - "resolved": "https://registry.npmjs.org/json-schema/-/json-schema-0.2.3.tgz", - "integrity": "sha1-tIDIkuWaLwWVTOcnvT8qTogvnhM=" - }, - "json-schema-traverse": { - "version": "0.4.1", - "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-0.4.1.tgz", - "integrity": "sha512-xbbCH5dCYU5T8LcEhhuh7HJ88HXuW3qsI3Y0zOZFKfZEHcpWiHU/Jxzk629Brsab/mMiHQti9wMP+845RPe3Vg==" - }, - "json-stable-stringify": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/json-stable-stringify/-/json-stable-stringify-1.0.1.tgz", - "integrity": "sha1-mnWdOcXy/1A/1TAGRu1EX4jE+a8=", - "requires": { - "jsonify": "~0.0.0" - } - }, - "json-stringify-safe": { - "version": "5.0.1", - "resolved": "https://registry.npmjs.org/json-stringify-safe/-/json-stringify-safe-5.0.1.tgz", - "integrity": "sha1-Epai1Y/UXxmg9s4B1lcB4sc1tus=" - }, - "json5": { - "version": "0.5.1", - "resolved": "http://registry.npmjs.org/json5/-/json5-0.5.1.tgz", - "integrity": "sha1-Hq3nrMASA0rYTiOWdn6tn6VJWCE=" - }, - "jsonfile": { - "version": "2.4.0", - "resolved": "http://registry.npmjs.org/jsonfile/-/jsonfile-2.4.0.tgz", - "integrity": "sha1-NzaitCi4e72gzIO1P6PWM6NcKug=", - "requires": { - "graceful-fs": "^4.1.6" - } - }, - "jsonify": { - "version": "0.0.0", - "resolved": "https://registry.npmjs.org/jsonify/-/jsonify-0.0.0.tgz", - "integrity": "sha1-LHS27kHZPKUbe1qu6PUDYx0lKnM=" - }, - "jsprim": { - "version": "1.4.1", - "resolved": "https://registry.npmjs.org/jsprim/-/jsprim-1.4.1.tgz", - "integrity": "sha1-MT5mvB5cwG5Di8G3SZwuXFastqI=", - "requires": { - "assert-plus": "1.0.0", - "extsprintf": "1.3.0", - "json-schema": "0.2.3", - "verror": "1.10.0" - } - }, - "keccak": { - "version": "1.4.0", - "resolved": "https://registry.npmjs.org/keccak/-/keccak-1.4.0.tgz", - "integrity": "sha512-eZVaCpblK5formjPjeTBik7TAg+pqnDrMHIffSvi9Lh7PQgM1+hSzakUeZFCk9DVVG0dacZJuaz2ntwlzZUIBw==", - "requires": { - "bindings": "^1.2.1", - "inherits": "^2.0.3", - "nan": "^2.2.1", - "safe-buffer": "^5.1.0" - } - }, - "keccakjs": { - "version": "0.2.3", - "resolved": "https://registry.npmjs.org/keccakjs/-/keccakjs-0.2.3.tgz", - "integrity": "sha512-BjLkNDcfaZ6l8HBG9tH0tpmDv3sS2mA7FNQxFHpCdzP3Gb2MVruXBSuoM66SnVxKJpAr5dKGdkHD+bDokt8fTg==", - "requires": { - "browserify-sha3": "^0.0.4", - "sha3": "^1.2.2" - } - }, - "klaw": { - "version": "1.3.1", - "resolved": "https://registry.npmjs.org/klaw/-/klaw-1.3.1.tgz", - "integrity": "sha1-QIhDO0azsbolnXh4XY6W9zugJDk=", - "requires": { - "graceful-fs": "^4.1.9" - } - }, - "lcid": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/lcid/-/lcid-1.0.0.tgz", - "integrity": "sha1-MIrMr6C8SDo4Z7S28rlQYlHRuDU=", - "requires": { - "invert-kv": "^1.0.0" - } - }, - "level-codec": { - "version": "7.0.1", - "resolved": "https://registry.npmjs.org/level-codec/-/level-codec-7.0.1.tgz", - "integrity": "sha512-Ua/R9B9r3RasXdRmOtd+t9TCOEIIlts+TN/7XTT2unhDaL6sJn83S3rUyljbr6lVtw49N3/yA0HHjpV6Kzb2aQ==" - }, - "level-errors": { - "version": "1.0.5", - "resolved": "https://registry.npmjs.org/level-errors/-/level-errors-1.0.5.tgz", - "integrity": "sha512-/cLUpQduF6bNrWuAC4pwtUKA5t669pCsCi2XbmojG2tFeOr9j6ShtdDCtFFQO1DRt+EVZhx9gPzP9G2bUaG4ig==", - "requires": { - "errno": "~0.1.1" - } - }, - "level-iterator-stream": { - "version": "1.3.1", - "resolved": "http://registry.npmjs.org/level-iterator-stream/-/level-iterator-stream-1.3.1.tgz", - "integrity": "sha1-5Dt4sagUPm+pek9IXrjqUwNS8u0=", - "requires": { - "inherits": "^2.0.1", - "level-errors": "^1.0.3", - "readable-stream": "^1.0.33", - "xtend": "^4.0.0" - }, - "dependencies": { - "isarray": { - "version": "0.0.1", - "resolved": "https://registry.npmjs.org/isarray/-/isarray-0.0.1.tgz", - "integrity": "sha1-ihis/Kmo9Bd+Cav8YDiTmwXR7t8=" - }, - "readable-stream": { - "version": "1.1.14", - "resolved": "http://registry.npmjs.org/readable-stream/-/readable-stream-1.1.14.tgz", - "integrity": "sha1-fPTFTvZI44EwhMY23SB54WbAgdk=", - "requires": { - "core-util-is": "~1.0.0", - "inherits": "~2.0.1", - "isarray": "0.0.1", - "string_decoder": "~0.10.x" - } - }, - "string_decoder": { - "version": "0.10.31", - "resolved": "http://registry.npmjs.org/string_decoder/-/string_decoder-0.10.31.tgz", - "integrity": "sha1-YuIDvEF2bGwoyfyEMB2rHFMQ+pQ=" - } - } - }, - "level-ws": { - "version": "0.0.0", - "resolved": "https://registry.npmjs.org/level-ws/-/level-ws-0.0.0.tgz", - "integrity": "sha1-Ny5RIXeSSgBCSwtDrvK7QkltIos=", - "requires": { - "readable-stream": "~1.0.15", - "xtend": "~2.1.1" - }, - "dependencies": { - "isarray": { - "version": "0.0.1", - "resolved": "https://registry.npmjs.org/isarray/-/isarray-0.0.1.tgz", - "integrity": "sha1-ihis/Kmo9Bd+Cav8YDiTmwXR7t8=" - }, - "object-keys": { - "version": "0.4.0", - "resolved": "https://registry.npmjs.org/object-keys/-/object-keys-0.4.0.tgz", - "integrity": "sha1-KKaq50KN0sOpLz2V8hM13SBOAzY=" - }, - "readable-stream": { - "version": "1.0.34", - "resolved": "http://registry.npmjs.org/readable-stream/-/readable-stream-1.0.34.tgz", - "integrity": "sha1-Elgg40vIQtLyqq+v5MKRbuMsFXw=", - "requires": { - "core-util-is": "~1.0.0", - "inherits": "~2.0.1", - "isarray": "0.0.1", - "string_decoder": "~0.10.x" - } - }, - "string_decoder": { - "version": "0.10.31", - "resolved": "http://registry.npmjs.org/string_decoder/-/string_decoder-0.10.31.tgz", - "integrity": "sha1-YuIDvEF2bGwoyfyEMB2rHFMQ+pQ=" - }, - "xtend": { - "version": "2.1.2", - "resolved": "https://registry.npmjs.org/xtend/-/xtend-2.1.2.tgz", - "integrity": "sha1-bv7MKk2tjmlixJAbM3znuoe10os=", - "requires": { - "object-keys": "~0.4.0" - } - } - } - }, - "levelup": { - "version": "1.3.9", - "resolved": "https://registry.npmjs.org/levelup/-/levelup-1.3.9.tgz", - "integrity": "sha512-VVGHfKIlmw8w1XqpGOAGwq6sZm2WwWLmlDcULkKWQXEA5EopA8OBNJ2Ck2v6bdk8HeEZSbCSEgzXadyQFm76sQ==", - "requires": { - "deferred-leveldown": "~1.2.1", - "level-codec": "~7.0.0", - "level-errors": "~1.0.3", - "level-iterator-stream": "~1.3.0", - "prr": "~1.0.1", - "semver": "~5.4.1", - "xtend": "~4.0.0" - }, - "dependencies": { - "semver": { - "version": "5.4.1", - "resolved": "https://registry.npmjs.org/semver/-/semver-5.4.1.tgz", - "integrity": "sha512-WfG/X9+oATh81XtllIo/I8gOiY9EXRdv1cQdyykeXK17YcUW3EXUAi2To4pcH6nZtJPr7ZOpM5OMyWJZm+8Rsg==" - } - } - }, - "load-json-file": { - "version": "1.1.0", - "resolved": "http://registry.npmjs.org/load-json-file/-/load-json-file-1.1.0.tgz", - "integrity": "sha1-lWkFcI1YtLq0wiYbBPWfMcmTdMA=", - "requires": { - "graceful-fs": "^4.1.2", - "parse-json": "^2.2.0", - "pify": "^2.0.0", - "pinkie-promise": "^2.0.0", - "strip-bom": "^2.0.0" - } - }, - "lodash": { - "version": "4.17.11", - "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.11.tgz", - "integrity": "sha512-cQKh8igo5QUhZ7lg38DYWAxMvjSAKG0A8wGSVimP07SIUEK2UO+arSRKbRZWtelMtN5V0Hkwh5ryOto/SshYIg==" - }, - "lodash.assign": { - "version": "4.2.0", - "resolved": "https://registry.npmjs.org/lodash.assign/-/lodash.assign-4.2.0.tgz", - "integrity": "sha1-DZnzzNem0mHRm9rrkkUAXShYCOc=" - }, - "loose-envify": { - "version": "1.4.0", - "resolved": "https://registry.npmjs.org/loose-envify/-/loose-envify-1.4.0.tgz", - "integrity": "sha512-lyuxPGr/Wfhrlem2CL/UcnUc1zcqKAImBDzukY7Y5F/yQiNdko6+fRLevlw1HgMySw7f611UIY408EtxRSoK3Q==", - "requires": { - "js-tokens": "^3.0.0 || ^4.0.0" - } - }, - "ltgt": { - "version": "2.2.1", - "resolved": "https://registry.npmjs.org/ltgt/-/ltgt-2.2.1.tgz", - "integrity": "sha1-81ypHEk/e3PaDgdJUwTxezH4fuU=" - }, - "md5.js": { - "version": "1.3.5", - "resolved": "https://registry.npmjs.org/md5.js/-/md5.js-1.3.5.tgz", - "integrity": "sha512-xitP+WxNPcTTOgnTJcrhM0xvdPepipPSf3I8EIpGKeFLjt3PlJLIDG3u8EX53ZIubkb+5U2+3rELYpEhHhzdkg==", - "requires": { - "hash-base": "^3.0.0", - "inherits": "^2.0.1", - "safe-buffer": "^5.1.2" - } - }, - "memdown": { - "version": "1.4.1", - "resolved": "https://registry.npmjs.org/memdown/-/memdown-1.4.1.tgz", - "integrity": "sha1-tOThkhdGZP+65BNhqlAPMRnv4hU=", - "requires": { - "abstract-leveldown": "~2.7.1", - "functional-red-black-tree": "^1.0.1", - "immediate": "^3.2.3", - "inherits": "~2.0.1", - "ltgt": "~2.2.0", - "safe-buffer": "~5.1.1" - }, - "dependencies": { - "abstract-leveldown": { - "version": "2.7.2", - "resolved": "https://registry.npmjs.org/abstract-leveldown/-/abstract-leveldown-2.7.2.tgz", - "integrity": "sha512-+OVvxH2rHVEhWLdbudP6p0+dNMXu8JA1CbhP19T8paTYAcX7oJ4OVjT+ZUVpv7mITxXHqDMej+GdqXBmXkw09w==", - "requires": { - "xtend": "~4.0.0" - } - } - } - }, - "memorystream": { - "version": "0.3.1", - "resolved": "https://registry.npmjs.org/memorystream/-/memorystream-0.3.1.tgz", - "integrity": "sha1-htcJCzDORV1j+64S3aUaR93K+bI=" - }, - "merkle-patricia-tree": { - "version": "2.3.2", - "resolved": "https://registry.npmjs.org/merkle-patricia-tree/-/merkle-patricia-tree-2.3.2.tgz", - "integrity": "sha512-81PW5m8oz/pz3GvsAwbauj7Y00rqm81Tzad77tHBwU7pIAtN+TJnMSOJhxBKflSVYhptMMb9RskhqHqrSm1V+g==", - "requires": { - "async": "^1.4.2", - "ethereumjs-util": "^5.0.0", - "level-ws": "0.0.0", - "levelup": "^1.2.1", - "memdown": "^1.0.0", - "readable-stream": "^2.0.0", - "rlp": "^2.0.0", - "semaphore": ">=1.0.1" - }, - "dependencies": { - "async": { - "version": "1.5.2", - "resolved": "http://registry.npmjs.org/async/-/async-1.5.2.tgz", - "integrity": "sha1-7GphrlZIDAw8skHJVhjiCJL5Zyo=" - }, - "ethereumjs-util": { - "version": "5.2.0", - "resolved": "https://registry.npmjs.org/ethereumjs-util/-/ethereumjs-util-5.2.0.tgz", - "integrity": "sha512-CJAKdI0wgMbQFLlLRtZKGcy/L6pzVRgelIZqRqNbuVFM3K9VEnyfbcvz0ncWMRNCe4kaHWjwRYQcYMucmwsnWA==", - "requires": { - "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" - } - } - } - }, - "mime-db": { - "version": "1.37.0", - "resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.37.0.tgz", - "integrity": "sha512-R3C4db6bgQhlIhPU48fUtdVmKnflq+hRdad7IyKhtFj06VPNVdk2RhiYL3UjQIlso8L+YxAtFkobT0VK+S/ybg==" - }, - "mime-types": { - "version": "2.1.21", - "resolved": "https://registry.npmjs.org/mime-types/-/mime-types-2.1.21.tgz", - "integrity": "sha512-3iL6DbwpyLzjR3xHSFNFeb9Nz/M8WDkX33t1GFQnFOllWk8pOrh/LSrB5OXlnlW5P9LH73X6loW/eogc+F5lJg==", - "requires": { - "mime-db": "~1.37.0" - } - }, - "min-document": { - "version": "2.19.0", - "resolved": "https://registry.npmjs.org/min-document/-/min-document-2.19.0.tgz", - "integrity": "sha1-e9KC4/WELtKVu3SM3Z8f+iyCRoU=", - "requires": { - "dom-walk": "^0.1.0" - } - }, - "minimalistic-assert": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/minimalistic-assert/-/minimalistic-assert-1.0.1.tgz", - "integrity": "sha512-UtJcAD4yEaGtjPezWuO9wC4nwUnVH/8/Im3yEHQP4b67cXlD/Qr9hdITCU1xDbSEXg2XKNaP8jsReV7vQd00/A==" - }, - "minimalistic-crypto-utils": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/minimalistic-crypto-utils/-/minimalistic-crypto-utils-1.0.1.tgz", - "integrity": "sha1-9sAMHAsIIkblxNmd+4x8CDsrWCo=" - }, - "minimatch": { - "version": "3.0.4", - "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.0.4.tgz", - "integrity": "sha512-yJHVQEhyqPLUTgt9B83PXu6W3rx4MvvHvSUvToogpwoGDOUQ+yDrR0HRot+yOCdCO7u4hX3pWft6kWBBcqh0UA==", - "requires": { - "brace-expansion": "^1.1.7" - } - }, - "minimist": { - "version": "0.0.8", - "resolved": "http://registry.npmjs.org/minimist/-/minimist-0.0.8.tgz", - "integrity": "sha1-hX/Kv8M5fSYluCKCYuhqp6ARsF0=" - }, - "mkdirp": { - "version": "0.5.1", - "resolved": "http://registry.npmjs.org/mkdirp/-/mkdirp-0.5.1.tgz", - "integrity": "sha1-MAV0OOrGz3+MR2fzhkjWaX11yQM=", - "requires": { - "minimist": "0.0.8" - } - }, - "ms": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", - "integrity": "sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g=" - }, - "nan": { - "version": "2.10.0", - "resolved": "http://registry.npmjs.org/nan/-/nan-2.10.0.tgz", - "integrity": "sha512-bAdJv7fBLhWC+/Bls0Oza+mvTaNQtP+1RyhhhvD95pgUJz6XM5IzgmxOkItJ9tkoCiplvAnXI1tNmmUD/eScyA==" - }, - "node-fetch": { - "version": "2.1.2", - "resolved": "http://registry.npmjs.org/node-fetch/-/node-fetch-2.1.2.tgz", - "integrity": "sha1-q4hOjn5X44qUR1POxwb3iNF2i7U=" - }, - "normalize-package-data": { - "version": "2.4.0", - "resolved": "https://registry.npmjs.org/normalize-package-data/-/normalize-package-data-2.4.0.tgz", - "integrity": "sha512-9jjUFbTPfEy3R/ad/2oNbKtW9Hgovl5O1FvFWKkKblNXoN/Oou6+9+KKohPK13Yc3/TyunyWhJp6gvRNR/PPAw==", - "requires": { - "hosted-git-info": "^2.1.4", - "is-builtin-module": "^1.0.0", - "semver": "2 || 3 || 4 || 5", - "validate-npm-package-license": "^3.0.1" - } - }, - "npm": { - "version": "6.4.1", - "resolved": "https://registry.npmjs.org/npm/-/npm-6.4.1.tgz", - "integrity": "sha512-mXJL1NTVU136PtuopXCUQaNWuHlXCTp4McwlSW8S9/Aj8OEPAlSBgo8og7kJ01MjCDrkmqFQTvN5tTEhBMhXQg==", - "requires": { - "JSONStream": "^1.3.4", - "abbrev": "~1.1.1", - "ansicolors": "~0.3.2", - "ansistyles": "~0.1.3", - "aproba": "~1.2.0", - "archy": "~1.0.0", - "bin-links": "^1.1.2", - "bluebird": "~3.5.1", - "byte-size": "^4.0.3", - "cacache": "^11.2.0", - "call-limit": "~1.1.0", - "chownr": "~1.0.1", - "ci-info": "^1.4.0", - "cli-columns": "^3.1.2", - "cli-table3": "^0.5.0", - "cmd-shim": "~2.0.2", - "columnify": "~1.5.4", - "config-chain": "~1.1.11", - "debuglog": "*", - "detect-indent": "~5.0.0", - "detect-newline": "^2.1.0", - "dezalgo": "~1.0.3", - "editor": "~1.0.0", - "figgy-pudding": "^3.4.1", - "find-npm-prefix": "^1.0.2", - "fs-vacuum": "~1.2.10", - "fs-write-stream-atomic": "~1.0.10", - "gentle-fs": "^2.0.1", - "glob": "~7.1.2", - "graceful-fs": "~4.1.11", - "has-unicode": "~2.0.1", - "hosted-git-info": "^2.7.1", - "iferr": "^1.0.2", - "imurmurhash": "*", - "inflight": "~1.0.6", - "inherits": "~2.0.3", - "ini": "^1.3.5", - "init-package-json": "^1.10.3", - "is-cidr": "^2.0.6", - "json-parse-better-errors": "^1.0.2", - "lazy-property": "~1.0.0", - "libcipm": "^2.0.2", - "libnpmhook": "^4.0.1", - "libnpx": "^10.2.0", - "lock-verify": "^2.0.2", - "lockfile": "^1.0.4", - "lodash._baseindexof": "*", - "lodash._baseuniq": "~4.6.0", - "lodash._bindcallback": "*", - "lodash._cacheindexof": "*", - "lodash._createcache": "*", - "lodash._getnative": "*", - "lodash.clonedeep": "~4.5.0", - "lodash.restparam": "*", - "lodash.union": "~4.6.0", - "lodash.uniq": "~4.5.0", - "lodash.without": "~4.4.0", - "lru-cache": "^4.1.3", - "meant": "~1.0.1", - "mississippi": "^3.0.0", - "mkdirp": "~0.5.1", - "move-concurrently": "^1.0.1", - "node-gyp": "^3.8.0", - "nopt": "~4.0.1", - "normalize-package-data": "~2.4.0", - "npm-audit-report": "^1.3.1", - "npm-cache-filename": "~1.0.2", - "npm-install-checks": "~3.0.0", - "npm-lifecycle": "^2.1.0", - "npm-package-arg": "^6.1.0", - "npm-packlist": "^1.1.11", - "npm-pick-manifest": "^2.1.0", - "npm-profile": "^3.0.2", - "npm-registry-client": "^8.6.0", - "npm-registry-fetch": "^1.1.0", - "npm-user-validate": "~1.0.0", - "npmlog": "~4.1.2", - "once": "~1.4.0", - "opener": "^1.5.0", - "osenv": "^0.1.5", - "pacote": "^8.1.6", - "path-is-inside": "~1.0.2", - "promise-inflight": "~1.0.1", - "qrcode-terminal": "^0.12.0", - "query-string": "^6.1.0", - "qw": "~1.0.1", - "read": "~1.0.7", - "read-cmd-shim": "~1.0.1", - "read-installed": "~4.0.3", - "read-package-json": "^2.0.13", - "read-package-tree": "^5.2.1", - "readable-stream": "^2.3.6", - "readdir-scoped-modules": "*", - "request": "^2.88.0", - "retry": "^0.12.0", - "rimraf": "~2.6.2", - "safe-buffer": "^5.1.2", - "semver": "^5.5.0", - "sha": "~2.0.1", - "slide": "~1.1.6", - "sorted-object": "~2.0.1", - "sorted-union-stream": "~2.1.3", - "ssri": "^6.0.0", - "stringify-package": "^1.0.0", - "tar": "^4.4.6", - "text-table": "~0.2.0", - "tiny-relative-date": "^1.3.0", - "uid-number": "0.0.6", - "umask": "~1.1.0", - "unique-filename": "~1.1.0", - "unpipe": "~1.0.0", - "update-notifier": "^2.5.0", - "uuid": "^3.3.2", - "validate-npm-package-license": "^3.0.4", - "validate-npm-package-name": "~3.0.0", - "which": "^1.3.1", - "worker-farm": "^1.6.0", - "write-file-atomic": "^2.3.0" - }, - "dependencies": { - "JSONStream": { - "version": "1.3.4", - "bundled": true, - "requires": { - "jsonparse": "^1.2.0", - "through": ">=2.2.7 <3" - } - }, - "abbrev": { - "version": "1.1.1", - "bundled": true - }, - "agent-base": { - "version": "4.2.0", - "bundled": true, - "requires": { - "es6-promisify": "^5.0.0" - } - }, - "agentkeepalive": { - "version": "3.4.1", - "bundled": true, - "requires": { - "humanize-ms": "^1.2.1" - } - }, - "ajv": { - "version": "5.5.2", - "bundled": true, - "requires": { - "co": "^4.6.0", - "fast-deep-equal": "^1.0.0", - "fast-json-stable-stringify": "^2.0.0", - "json-schema-traverse": "^0.3.0" - } - }, - "ansi-align": { - "version": "2.0.0", - "bundled": true, - "requires": { - "string-width": "^2.0.0" - } - }, - "ansi-regex": { - "version": "2.1.1", - "bundled": true - }, - "ansi-styles": { - "version": "3.2.1", - "bundled": true, - "requires": { - "color-convert": "^1.9.0" - } - }, - "ansicolors": { - "version": "0.3.2", - "bundled": true - }, - "ansistyles": { - "version": "0.1.3", - "bundled": true - }, - "aproba": { - "version": "1.2.0", - "bundled": true - }, - "archy": { - "version": "1.0.0", - "bundled": true - }, - "are-we-there-yet": { - "version": "1.1.4", - "bundled": true, - "requires": { - "delegates": "^1.0.0", - "readable-stream": "^2.0.6" - } - }, - "asap": { - "version": "2.0.6", - "bundled": true - }, - "asn1": { - "version": "0.2.4", - "bundled": true, - "requires": { - "safer-buffer": "~2.1.0" - } - }, - "assert-plus": { - "version": "1.0.0", - "bundled": true - }, - "asynckit": { - "version": "0.4.0", - "bundled": true - }, - "aws-sign2": { - "version": "0.7.0", - "bundled": true - }, - "aws4": { - "version": "1.8.0", - "bundled": true - }, - "balanced-match": { - "version": "1.0.0", - "bundled": true - }, - "bcrypt-pbkdf": { - "version": "1.0.2", - "bundled": true, - "optional": true, - "requires": { - "tweetnacl": "^0.14.3" - } - }, - "bin-links": { - "version": "1.1.2", - "bundled": true, - "requires": { - "bluebird": "^3.5.0", - "cmd-shim": "^2.0.2", - "gentle-fs": "^2.0.0", - "graceful-fs": "^4.1.11", - "write-file-atomic": "^2.3.0" - } - }, - "block-stream": { - "version": "0.0.9", - "bundled": true, - "requires": { - "inherits": "~2.0.0" - } - }, - "bluebird": { - "version": "3.5.1", - "bundled": true - }, - "boxen": { - "version": "1.3.0", - "bundled": true, - "requires": { - "ansi-align": "^2.0.0", - "camelcase": "^4.0.0", - "chalk": "^2.0.1", - "cli-boxes": "^1.0.0", - "string-width": "^2.0.0", - "term-size": "^1.2.0", - "widest-line": "^2.0.0" - } - }, - "brace-expansion": { - "version": "1.1.11", - "bundled": true, - "requires": { - "balanced-match": "^1.0.0", - "concat-map": "0.0.1" - } - }, - "buffer-from": { - "version": "1.0.0", - "bundled": true - }, - "builtin-modules": { - "version": "1.1.1", - "bundled": true - }, - "builtins": { - "version": "1.0.3", - "bundled": true - }, - "byline": { - "version": "5.0.0", - "bundled": true - }, - "byte-size": { - "version": "4.0.3", - "bundled": true - }, - "cacache": { - "version": "11.2.0", - "bundled": true, - "requires": { - "bluebird": "^3.5.1", - "chownr": "^1.0.1", - "figgy-pudding": "^3.1.0", - "glob": "^7.1.2", - "graceful-fs": "^4.1.11", - "lru-cache": "^4.1.3", - "mississippi": "^3.0.0", - "mkdirp": "^0.5.1", - "move-concurrently": "^1.0.1", - "promise-inflight": "^1.0.1", - "rimraf": "^2.6.2", - "ssri": "^6.0.0", - "unique-filename": "^1.1.0", - "y18n": "^4.0.0" - } - }, - "call-limit": { - "version": "1.1.0", - "bundled": true - }, - "camelcase": { - "version": "4.1.0", - "bundled": true - }, - "capture-stack-trace": { - "version": "1.0.0", - "bundled": true - }, - "caseless": { - "version": "0.12.0", - "bundled": true - }, - "chalk": { - "version": "2.4.1", - "bundled": true, - "requires": { - "ansi-styles": "^3.2.1", - "escape-string-regexp": "^1.0.5", - "supports-color": "^5.3.0" - } - }, - "chownr": { - "version": "1.0.1", - "bundled": true - }, - "ci-info": { - "version": "1.4.0", - "bundled": true - }, - "cidr-regex": { - "version": "2.0.9", - "bundled": true, - "requires": { - "ip-regex": "^2.1.0" - } - }, - "cli-boxes": { - "version": "1.0.0", - "bundled": true - }, - "cli-columns": { - "version": "3.1.2", - "bundled": true, - "requires": { - "string-width": "^2.0.0", - "strip-ansi": "^3.0.1" - } - }, - "cli-table3": { - "version": "0.5.0", - "bundled": true, - "requires": { - "colors": "^1.1.2", - "object-assign": "^4.1.0", - "string-width": "^2.1.1" - } - }, - "cliui": { - "version": "4.1.0", - "bundled": true, - "requires": { - "string-width": "^2.1.1", - "strip-ansi": "^4.0.0", - "wrap-ansi": "^2.0.0" - }, - "dependencies": { - "ansi-regex": { - "version": "3.0.0", - "bundled": true - }, - "strip-ansi": { - "version": "4.0.0", - "bundled": true, - "requires": { - "ansi-regex": "^3.0.0" - } - } - } - }, - "clone": { - "version": "1.0.4", - "bundled": true - }, - "cmd-shim": { - "version": "2.0.2", - "bundled": true, - "requires": { - "graceful-fs": "^4.1.2", - "mkdirp": "~0.5.0" - } - }, - "co": { - "version": "4.6.0", - "bundled": true - }, - "code-point-at": { - "version": "1.1.0", - "bundled": true - }, - "color-convert": { - "version": "1.9.1", - "bundled": true, - "requires": { - "color-name": "^1.1.1" - } - }, - "color-name": { - "version": "1.1.3", - "bundled": true - }, - "colors": { - "version": "1.1.2", - "bundled": true, - "optional": true - }, - "columnify": { - "version": "1.5.4", - "bundled": true, - "requires": { - "strip-ansi": "^3.0.0", - "wcwidth": "^1.0.0" - } - }, - "combined-stream": { - "version": "1.0.6", - "bundled": true, - "requires": { - "delayed-stream": "~1.0.0" - } - }, - "concat-map": { - "version": "0.0.1", - "bundled": true - }, - "concat-stream": { - "version": "1.6.2", - "bundled": true, - "requires": { - "buffer-from": "^1.0.0", - "inherits": "^2.0.3", - "readable-stream": "^2.2.2", - "typedarray": "^0.0.6" - } - }, - "config-chain": { - "version": "1.1.11", - "bundled": true, - "requires": { - "ini": "^1.3.4", - "proto-list": "~1.2.1" - } - }, - "configstore": { - "version": "3.1.2", - "bundled": true, - "requires": { - "dot-prop": "^4.1.0", - "graceful-fs": "^4.1.2", - "make-dir": "^1.0.0", - "unique-string": "^1.0.0", - "write-file-atomic": "^2.0.0", - "xdg-basedir": "^3.0.0" - } - }, - "console-control-strings": { - "version": "1.1.0", - "bundled": true - }, - "copy-concurrently": { - "version": "1.0.5", - "bundled": true, - "requires": { - "aproba": "^1.1.1", - "fs-write-stream-atomic": "^1.0.8", - "iferr": "^0.1.5", - "mkdirp": "^0.5.1", - "rimraf": "^2.5.4", - "run-queue": "^1.0.0" - }, - "dependencies": { - "iferr": { - "version": "0.1.5", - "bundled": true - } - } - }, - "core-util-is": { - "version": "1.0.2", - "bundled": true - }, - "create-error-class": { - "version": "3.0.2", - "bundled": true, - "requires": { - "capture-stack-trace": "^1.0.0" - } - }, - "cross-spawn": { - "version": "5.1.0", - "bundled": true, - "requires": { - "lru-cache": "^4.0.1", - "shebang-command": "^1.2.0", - "which": "^1.2.9" - } - }, - "crypto-random-string": { - "version": "1.0.0", - "bundled": true - }, - "cyclist": { - "version": "0.2.2", - "bundled": true - }, - "dashdash": { - "version": "1.14.1", - "bundled": true, - "requires": { - "assert-plus": "^1.0.0" - } - }, - "debug": { - "version": "3.1.0", - "bundled": true, - "requires": { - "ms": "2.0.0" - }, - "dependencies": { - "ms": { - "version": "2.0.0", - "bundled": true - } - } - }, - "debuglog": { - "version": "1.0.1", - "bundled": true - }, - "decamelize": { - "version": "1.2.0", - "bundled": true - }, - "decode-uri-component": { - "version": "0.2.0", - "bundled": true - }, - "deep-extend": { - "version": "0.5.1", - "bundled": true - }, - "defaults": { - "version": "1.0.3", - "bundled": true, - "requires": { - "clone": "^1.0.2" - } - }, - "delayed-stream": { - "version": "1.0.0", - "bundled": true - }, - "delegates": { - "version": "1.0.0", - "bundled": true - }, - "detect-indent": { - "version": "5.0.0", - "bundled": true - }, - "detect-newline": { - "version": "2.1.0", - "bundled": true - }, - "dezalgo": { - "version": "1.0.3", - "bundled": true, - "requires": { - "asap": "^2.0.0", - "wrappy": "1" - } - }, - "dot-prop": { - "version": "4.2.0", - "bundled": true, - "requires": { - "is-obj": "^1.0.0" - } - }, - "dotenv": { - "version": "5.0.1", - "bundled": true - }, - "duplexer3": { - "version": "0.1.4", - "bundled": true - }, - "duplexify": { - "version": "3.6.0", - "bundled": true, - "requires": { - "end-of-stream": "^1.0.0", - "inherits": "^2.0.1", - "readable-stream": "^2.0.0", - "stream-shift": "^1.0.0" - } - }, - "ecc-jsbn": { - "version": "0.1.2", - "bundled": true, - "optional": true, - "requires": { - "jsbn": "~0.1.0", - "safer-buffer": "^2.1.0" - } - }, - "editor": { - "version": "1.0.0", - "bundled": true - }, - "encoding": { - "version": "0.1.12", - "bundled": true, - "requires": { - "iconv-lite": "~0.4.13" - } - }, - "end-of-stream": { - "version": "1.4.1", - "bundled": true, - "requires": { - "once": "^1.4.0" - } - }, - "err-code": { - "version": "1.1.2", - "bundled": true - }, - "errno": { - "version": "0.1.7", - "bundled": true, - "requires": { - "prr": "~1.0.1" - } - }, - "es6-promise": { - "version": "4.2.4", - "bundled": true - }, - "es6-promisify": { - "version": "5.0.0", - "bundled": true, - "requires": { - "es6-promise": "^4.0.3" - } - }, - "escape-string-regexp": { - "version": "1.0.5", - "bundled": true - }, - "execa": { - "version": "0.7.0", - "bundled": true, - "requires": { - "cross-spawn": "^5.0.1", - "get-stream": "^3.0.0", - "is-stream": "^1.1.0", - "npm-run-path": "^2.0.0", - "p-finally": "^1.0.0", - "signal-exit": "^3.0.0", - "strip-eof": "^1.0.0" - } - }, - "extend": { - "version": "3.0.2", - "bundled": true - }, - "extsprintf": { - "version": "1.3.0", - "bundled": true - }, - "fast-deep-equal": { - "version": "1.1.0", - "bundled": true - }, - "fast-json-stable-stringify": { - "version": "2.0.0", - "bundled": true - }, - "figgy-pudding": { - "version": "3.4.1", - "bundled": true - }, - "find-npm-prefix": { - "version": "1.0.2", - "bundled": true - }, - "find-up": { - "version": "2.1.0", - "bundled": true, - "requires": { - "locate-path": "^2.0.0" - } - }, - "flush-write-stream": { - "version": "1.0.3", - "bundled": true, - "requires": { - "inherits": "^2.0.1", - "readable-stream": "^2.0.4" - } - }, - "forever-agent": { - "version": "0.6.1", - "bundled": true - }, - "form-data": { - "version": "2.3.2", - "bundled": true, - "requires": { - "asynckit": "^0.4.0", - "combined-stream": "1.0.6", - "mime-types": "^2.1.12" - } - }, - "from2": { - "version": "2.3.0", - "bundled": true, - "requires": { - "inherits": "^2.0.1", - "readable-stream": "^2.0.0" - } - }, - "fs-minipass": { - "version": "1.2.5", - "bundled": true, - "requires": { - "minipass": "^2.2.1" - } - }, - "fs-vacuum": { - "version": "1.2.10", - "bundled": true, - "requires": { - "graceful-fs": "^4.1.2", - "path-is-inside": "^1.0.1", - "rimraf": "^2.5.2" - } - }, - "fs-write-stream-atomic": { - "version": "1.0.10", - "bundled": true, - "requires": { - "graceful-fs": "^4.1.2", - "iferr": "^0.1.5", - "imurmurhash": "^0.1.4", - "readable-stream": "1 || 2" - }, - "dependencies": { - "iferr": { - "version": "0.1.5", - "bundled": true - } - } - }, - "fs.realpath": { - "version": "1.0.0", - "bundled": true - }, - "fstream": { - "version": "1.0.11", - "bundled": true, - "requires": { - "graceful-fs": "^4.1.2", - "inherits": "~2.0.0", - "mkdirp": ">=0.5 0", - "rimraf": "2" - } - }, - "gauge": { - "version": "2.7.4", - "bundled": true, - "requires": { - "aproba": "^1.0.3", - "console-control-strings": "^1.0.0", - "has-unicode": "^2.0.0", - "object-assign": "^4.1.0", - "signal-exit": "^3.0.0", - "string-width": "^1.0.1", - "strip-ansi": "^3.0.1", - "wide-align": "^1.1.0" - }, - "dependencies": { - "string-width": { - "version": "1.0.2", - "bundled": true, - "requires": { - "code-point-at": "^1.0.0", - "is-fullwidth-code-point": "^1.0.0", - "strip-ansi": "^3.0.0" - } - } - } - }, - "genfun": { - "version": "4.0.1", - "bundled": true - }, - "gentle-fs": { - "version": "2.0.1", - "bundled": true, - "requires": { - "aproba": "^1.1.2", - "fs-vacuum": "^1.2.10", - "graceful-fs": "^4.1.11", - "iferr": "^0.1.5", - "mkdirp": "^0.5.1", - "path-is-inside": "^1.0.2", - "read-cmd-shim": "^1.0.1", - "slide": "^1.1.6" - }, - "dependencies": { - "iferr": { - "version": "0.1.5", - "bundled": true - } - } - }, - "get-caller-file": { - "version": "1.0.2", - "bundled": true - }, - "get-stream": { - "version": "3.0.0", - "bundled": true - }, - "getpass": { - "version": "0.1.7", - "bundled": true, - "requires": { - "assert-plus": "^1.0.0" - } - }, - "glob": { - "version": "7.1.2", - "bundled": true, - "requires": { - "fs.realpath": "^1.0.0", - "inflight": "^1.0.4", - "inherits": "2", - "minimatch": "^3.0.4", - "once": "^1.3.0", - "path-is-absolute": "^1.0.0" - } - }, - "global-dirs": { - "version": "0.1.1", - "bundled": true, - "requires": { - "ini": "^1.3.4" - } - }, - "got": { - "version": "6.7.1", - "bundled": true, - "requires": { - "create-error-class": "^3.0.0", - "duplexer3": "^0.1.4", - "get-stream": "^3.0.0", - "is-redirect": "^1.0.0", - "is-retry-allowed": "^1.0.0", - "is-stream": "^1.0.0", - "lowercase-keys": "^1.0.0", - "safe-buffer": "^5.0.1", - "timed-out": "^4.0.0", - "unzip-response": "^2.0.1", - "url-parse-lax": "^1.0.0" - } - }, - "graceful-fs": { - "version": "4.1.11", - "bundled": true - }, - "har-schema": { - "version": "2.0.0", - "bundled": true - }, - "har-validator": { - "version": "5.1.0", - "bundled": true, - "requires": { - "ajv": "^5.3.0", - "har-schema": "^2.0.0" - } - }, - "has-flag": { - "version": "3.0.0", - "bundled": true - }, - "has-unicode": { - "version": "2.0.1", - "bundled": true - }, - "hosted-git-info": { - "version": "2.7.1", - "bundled": true - }, - "http-cache-semantics": { - "version": "3.8.1", - "bundled": true - }, - "http-proxy-agent": { - "version": "2.1.0", - "bundled": true, - "requires": { - "agent-base": "4", - "debug": "3.1.0" - } - }, - "http-signature": { - "version": "1.2.0", - "bundled": true, - "requires": { - "assert-plus": "^1.0.0", - "jsprim": "^1.2.2", - "sshpk": "^1.7.0" - } - }, - "https-proxy-agent": { - "version": "2.2.1", - "bundled": true, - "requires": { - "agent-base": "^4.1.0", - "debug": "^3.1.0" - } - }, - "humanize-ms": { - "version": "1.2.1", - "bundled": true, - "requires": { - "ms": "^2.0.0" - } - }, - "iconv-lite": { - "version": "0.4.23", - "bundled": true, - "requires": { - "safer-buffer": ">= 2.1.2 < 3" - } - }, - "iferr": { - "version": "1.0.2", - "bundled": true - }, - "ignore-walk": { - "version": "3.0.1", - "bundled": true, - "requires": { - "minimatch": "^3.0.4" - } - }, - "import-lazy": { - "version": "2.1.0", - "bundled": true - }, - "imurmurhash": { - "version": "0.1.4", - "bundled": true - }, - "inflight": { - "version": "1.0.6", - "bundled": true, - "requires": { - "once": "^1.3.0", - "wrappy": "1" - } - }, - "inherits": { - "version": "2.0.3", - "bundled": true - }, - "ini": { - "version": "1.3.5", - "bundled": true - }, - "init-package-json": { - "version": "1.10.3", - "bundled": true, - "requires": { - "glob": "^7.1.1", - "npm-package-arg": "^4.0.0 || ^5.0.0 || ^6.0.0", - "promzard": "^0.3.0", - "read": "~1.0.1", - "read-package-json": "1 || 2", - "semver": "2.x || 3.x || 4 || 5", - "validate-npm-package-license": "^3.0.1", - "validate-npm-package-name": "^3.0.0" - } - }, - "invert-kv": { - "version": "1.0.0", - "bundled": true - }, - "ip": { - "version": "1.1.5", - "bundled": true - }, - "ip-regex": { - "version": "2.1.0", - "bundled": true - }, - "is-builtin-module": { - "version": "1.0.0", - "bundled": true, - "requires": { - "builtin-modules": "^1.0.0" - } - }, - "is-ci": { - "version": "1.1.0", - "bundled": true, - "requires": { - "ci-info": "^1.0.0" - } - }, - "is-cidr": { - "version": "2.0.6", - "bundled": true, - "requires": { - "cidr-regex": "^2.0.8" - } - }, - "is-fullwidth-code-point": { - "version": "1.0.0", - "bundled": true, - "requires": { - "number-is-nan": "^1.0.0" - } - }, - "is-installed-globally": { - "version": "0.1.0", - "bundled": true, - "requires": { - "global-dirs": "^0.1.0", - "is-path-inside": "^1.0.0" - } - }, - "is-npm": { - "version": "1.0.0", - "bundled": true - }, - "is-obj": { - "version": "1.0.1", - "bundled": true - }, - "is-path-inside": { - "version": "1.0.1", - "bundled": true, - "requires": { - "path-is-inside": "^1.0.1" - } - }, - "is-redirect": { - "version": "1.0.0", - "bundled": true - }, - "is-retry-allowed": { - "version": "1.1.0", - "bundled": true - }, - "is-stream": { - "version": "1.1.0", - "bundled": true - }, - "is-typedarray": { - "version": "1.0.0", - "bundled": true - }, - "isarray": { - "version": "1.0.0", - "bundled": true - }, - "isexe": { - "version": "2.0.0", - "bundled": true - }, - "isstream": { - "version": "0.1.2", - "bundled": true - }, - "jsbn": { - "version": "0.1.1", - "bundled": true, - "optional": true - }, - "json-parse-better-errors": { - "version": "1.0.2", - "bundled": true - }, - "json-schema": { - "version": "0.2.3", - "bundled": true - }, - "json-schema-traverse": { - "version": "0.3.1", - "bundled": true - }, - "json-stringify-safe": { - "version": "5.0.1", - "bundled": true - }, - "jsonparse": { - "version": "1.3.1", - "bundled": true - }, - "jsprim": { - "version": "1.4.1", - "bundled": true, - "requires": { - "assert-plus": "1.0.0", - "extsprintf": "1.3.0", - "json-schema": "0.2.3", - "verror": "1.10.0" - } - }, - "latest-version": { - "version": "3.1.0", - "bundled": true, - "requires": { - "package-json": "^4.0.0" - } - }, - "lazy-property": { - "version": "1.0.0", - "bundled": true - }, - "lcid": { - "version": "1.0.0", - "bundled": true, - "requires": { - "invert-kv": "^1.0.0" - } - }, - "libcipm": { - "version": "2.0.2", - "bundled": true, - "requires": { - "bin-links": "^1.1.2", - "bluebird": "^3.5.1", - "find-npm-prefix": "^1.0.2", - "graceful-fs": "^4.1.11", - "lock-verify": "^2.0.2", - "mkdirp": "^0.5.1", - "npm-lifecycle": "^2.0.3", - "npm-logical-tree": "^1.2.1", - "npm-package-arg": "^6.1.0", - "pacote": "^8.1.6", - "protoduck": "^5.0.0", - "read-package-json": "^2.0.13", - "rimraf": "^2.6.2", - "worker-farm": "^1.6.0" - } - }, - "libnpmhook": { - "version": "4.0.1", - "bundled": true, - "requires": { - "figgy-pudding": "^3.1.0", - "npm-registry-fetch": "^3.0.0" - }, - "dependencies": { - "npm-registry-fetch": { - "version": "3.1.1", - "bundled": true, - "requires": { - "bluebird": "^3.5.1", - "figgy-pudding": "^3.1.0", - "lru-cache": "^4.1.2", - "make-fetch-happen": "^4.0.0", - "npm-package-arg": "^6.0.0" - } - } - } - }, - "libnpx": { - "version": "10.2.0", - "bundled": true, - "requires": { - "dotenv": "^5.0.1", - "npm-package-arg": "^6.0.0", - "rimraf": "^2.6.2", - "safe-buffer": "^5.1.0", - "update-notifier": "^2.3.0", - "which": "^1.3.0", - "y18n": "^4.0.0", - "yargs": "^11.0.0" - } - }, - "locate-path": { - "version": "2.0.0", - "bundled": true, - "requires": { - "p-locate": "^2.0.0", - "path-exists": "^3.0.0" - } - }, - "lock-verify": { - "version": "2.0.2", - "bundled": true, - "requires": { - "npm-package-arg": "^5.1.2 || 6", - "semver": "^5.4.1" - } - }, - "lockfile": { - "version": "1.0.4", - "bundled": true, - "requires": { - "signal-exit": "^3.0.2" - } - }, - "lodash._baseindexof": { - "version": "3.1.0", - "bundled": true - }, - "lodash._baseuniq": { - "version": "4.6.0", - "bundled": true, - "requires": { - "lodash._createset": "~4.0.0", - "lodash._root": "~3.0.0" - } - }, - "lodash._bindcallback": { - "version": "3.0.1", - "bundled": true - }, - "lodash._cacheindexof": { - "version": "3.0.2", - "bundled": true - }, - "lodash._createcache": { - "version": "3.1.2", - "bundled": true, - "requires": { - "lodash._getnative": "^3.0.0" - } - }, - "lodash._createset": { - "version": "4.0.3", - "bundled": true - }, - "lodash._getnative": { - "version": "3.9.1", - "bundled": true - }, - "lodash._root": { - "version": "3.0.1", - "bundled": true - }, - "lodash.clonedeep": { - "version": "4.5.0", - "bundled": true - }, - "lodash.restparam": { - "version": "3.6.1", - "bundled": true - }, - "lodash.union": { - "version": "4.6.0", - "bundled": true - }, - "lodash.uniq": { - "version": "4.5.0", - "bundled": true - }, - "lodash.without": { - "version": "4.4.0", - "bundled": true - }, - "lowercase-keys": { - "version": "1.0.1", - "bundled": true - }, - "lru-cache": { - "version": "4.1.3", - "bundled": true, - "requires": { - "pseudomap": "^1.0.2", - "yallist": "^2.1.2" - } - }, - "make-dir": { - "version": "1.3.0", - "bundled": true, - "requires": { - "pify": "^3.0.0" - } - }, - "make-fetch-happen": { - "version": "4.0.1", - "bundled": true, - "requires": { - "agentkeepalive": "^3.4.1", - "cacache": "^11.0.1", - "http-cache-semantics": "^3.8.1", - "http-proxy-agent": "^2.1.0", - "https-proxy-agent": "^2.2.1", - "lru-cache": "^4.1.2", - "mississippi": "^3.0.0", - "node-fetch-npm": "^2.0.2", - "promise-retry": "^1.1.1", - "socks-proxy-agent": "^4.0.0", - "ssri": "^6.0.0" - } - }, - "meant": { - "version": "1.0.1", - "bundled": true - }, - "mem": { - "version": "1.1.0", - "bundled": true, - "requires": { - "mimic-fn": "^1.0.0" - } - }, - "mime-db": { - "version": "1.35.0", - "bundled": true - }, - "mime-types": { - "version": "2.1.19", - "bundled": true, - "requires": { - "mime-db": "~1.35.0" - } - }, - "mimic-fn": { - "version": "1.2.0", - "bundled": true - }, - "minimatch": { - "version": "3.0.4", - "bundled": true, - "requires": { - "brace-expansion": "^1.1.7" - } - }, - "minimist": { - "version": "0.0.8", - "bundled": true - }, - "minipass": { - "version": "2.3.3", - "bundled": true, - "requires": { - "safe-buffer": "^5.1.2", - "yallist": "^3.0.0" - }, - "dependencies": { - "yallist": { - "version": "3.0.2", - "bundled": true - } - } - }, - "minizlib": { - "version": "1.1.0", - "bundled": true, - "requires": { - "minipass": "^2.2.1" - } - }, - "mississippi": { - "version": "3.0.0", - "bundled": true, - "requires": { - "concat-stream": "^1.5.0", - "duplexify": "^3.4.2", - "end-of-stream": "^1.1.0", - "flush-write-stream": "^1.0.0", - "from2": "^2.1.0", - "parallel-transform": "^1.1.0", - "pump": "^3.0.0", - "pumpify": "^1.3.3", - "stream-each": "^1.1.0", - "through2": "^2.0.0" - } - }, - "mkdirp": { - "version": "0.5.1", - "bundled": true, - "requires": { - "minimist": "0.0.8" - } - }, - "move-concurrently": { - "version": "1.0.1", - "bundled": true, - "requires": { - "aproba": "^1.1.1", - "copy-concurrently": "^1.0.0", - "fs-write-stream-atomic": "^1.0.8", - "mkdirp": "^0.5.1", - "rimraf": "^2.5.4", - "run-queue": "^1.0.3" - } - }, - "ms": { - "version": "2.1.1", - "bundled": true - }, - "mute-stream": { - "version": "0.0.7", - "bundled": true - }, - "node-fetch-npm": { - "version": "2.0.2", - "bundled": true, - "requires": { - "encoding": "^0.1.11", - "json-parse-better-errors": "^1.0.0", - "safe-buffer": "^5.1.1" - } - }, - "node-gyp": { - "version": "3.8.0", - "bundled": true, - "requires": { - "fstream": "^1.0.0", - "glob": "^7.0.3", - "graceful-fs": "^4.1.2", - "mkdirp": "^0.5.0", - "nopt": "2 || 3", - "npmlog": "0 || 1 || 2 || 3 || 4", - "osenv": "0", - "request": "^2.87.0", - "rimraf": "2", - "semver": "~5.3.0", - "tar": "^2.0.0", - "which": "1" - }, - "dependencies": { - "nopt": { - "version": "3.0.6", - "bundled": true, - "requires": { - "abbrev": "1" - } - }, - "semver": { - "version": "5.3.0", - "bundled": true - }, - "tar": { - "version": "2.2.1", - "bundled": true, - "requires": { - "block-stream": "*", - "fstream": "^1.0.2", - "inherits": "2" - } - } - } - }, - "nopt": { - "version": "4.0.1", - "bundled": true, - "requires": { - "abbrev": "1", - "osenv": "^0.1.4" - } - }, - "normalize-package-data": { - "version": "2.4.0", - "bundled": true, - "requires": { - "hosted-git-info": "^2.1.4", - "is-builtin-module": "^1.0.0", - "semver": "2 || 3 || 4 || 5", - "validate-npm-package-license": "^3.0.1" - } - }, - "npm-audit-report": { - "version": "1.3.1", - "bundled": true, - "requires": { - "cli-table3": "^0.5.0", - "console-control-strings": "^1.1.0" - } - }, - "npm-bundled": { - "version": "1.0.5", - "bundled": true - }, - "npm-cache-filename": { - "version": "1.0.2", - "bundled": true - }, - "npm-install-checks": { - "version": "3.0.0", - "bundled": true, - "requires": { - "semver": "^2.3.0 || 3.x || 4 || 5" - } - }, - "npm-lifecycle": { - "version": "2.1.0", - "bundled": true, - "requires": { - "byline": "^5.0.0", - "graceful-fs": "^4.1.11", - "node-gyp": "^3.8.0", - "resolve-from": "^4.0.0", - "slide": "^1.1.6", - "uid-number": "0.0.6", - "umask": "^1.1.0", - "which": "^1.3.1" - } - }, - "npm-logical-tree": { - "version": "1.2.1", - "bundled": true - }, - "npm-package-arg": { - "version": "6.1.0", - "bundled": true, - "requires": { - "hosted-git-info": "^2.6.0", - "osenv": "^0.1.5", - "semver": "^5.5.0", - "validate-npm-package-name": "^3.0.0" - } - }, - "npm-packlist": { - "version": "1.1.11", - "bundled": true, - "requires": { - "ignore-walk": "^3.0.1", - "npm-bundled": "^1.0.1" - } - }, - "npm-pick-manifest": { - "version": "2.1.0", - "bundled": true, - "requires": { - "npm-package-arg": "^6.0.0", - "semver": "^5.4.1" - } - }, - "npm-profile": { - "version": "3.0.2", - "bundled": true, - "requires": { - "aproba": "^1.1.2 || 2", - "make-fetch-happen": "^2.5.0 || 3 || 4" - } - }, - "npm-registry-client": { - "version": "8.6.0", - "bundled": true, - "requires": { - "concat-stream": "^1.5.2", - "graceful-fs": "^4.1.6", - "normalize-package-data": "~1.0.1 || ^2.0.0", - "npm-package-arg": "^3.0.0 || ^4.0.0 || ^5.0.0 || ^6.0.0", - "npmlog": "2 || ^3.1.0 || ^4.0.0", - "once": "^1.3.3", - "request": "^2.74.0", - "retry": "^0.10.0", - "safe-buffer": "^5.1.1", - "semver": "2 >=2.2.1 || 3.x || 4 || 5", - "slide": "^1.1.3", - "ssri": "^5.2.4" - }, - "dependencies": { - "retry": { - "version": "0.10.1", - "bundled": true - }, - "ssri": { - "version": "5.3.0", - "bundled": true, - "requires": { - "safe-buffer": "^5.1.1" - } - } - } - }, - "npm-registry-fetch": { - "version": "1.1.0", - "bundled": true, - "requires": { - "bluebird": "^3.5.1", - "figgy-pudding": "^2.0.1", - "lru-cache": "^4.1.2", - "make-fetch-happen": "^3.0.0", - "npm-package-arg": "^6.0.0", - "safe-buffer": "^5.1.1" - }, - "dependencies": { - "cacache": { - "version": "10.0.4", - "bundled": true, - "requires": { - "bluebird": "^3.5.1", - "chownr": "^1.0.1", - "glob": "^7.1.2", - "graceful-fs": "^4.1.11", - "lru-cache": "^4.1.1", - "mississippi": "^2.0.0", - "mkdirp": "^0.5.1", - "move-concurrently": "^1.0.1", - "promise-inflight": "^1.0.1", - "rimraf": "^2.6.2", - "ssri": "^5.2.4", - "unique-filename": "^1.1.0", - "y18n": "^4.0.0" - }, - "dependencies": { - "mississippi": { - "version": "2.0.0", - "bundled": true, - "requires": { - "concat-stream": "^1.5.0", - "duplexify": "^3.4.2", - "end-of-stream": "^1.1.0", - "flush-write-stream": "^1.0.0", - "from2": "^2.1.0", - "parallel-transform": "^1.1.0", - "pump": "^2.0.1", - "pumpify": "^1.3.3", - "stream-each": "^1.1.0", - "through2": "^2.0.0" - } - } - } - }, - "figgy-pudding": { - "version": "2.0.1", - "bundled": true - }, - "make-fetch-happen": { - "version": "3.0.0", - "bundled": true, - "requires": { - "agentkeepalive": "^3.4.1", - "cacache": "^10.0.4", - "http-cache-semantics": "^3.8.1", - "http-proxy-agent": "^2.1.0", - "https-proxy-agent": "^2.2.0", - "lru-cache": "^4.1.2", - "mississippi": "^3.0.0", - "node-fetch-npm": "^2.0.2", - "promise-retry": "^1.1.1", - "socks-proxy-agent": "^3.0.1", - "ssri": "^5.2.4" - } - }, - "pump": { - "version": "2.0.1", - "bundled": true, - "requires": { - "end-of-stream": "^1.1.0", - "once": "^1.3.1" - } - }, - "smart-buffer": { - "version": "1.1.15", - "bundled": true - }, - "socks": { - "version": "1.1.10", - "bundled": true, - "requires": { - "ip": "^1.1.4", - "smart-buffer": "^1.0.13" - } - }, - "socks-proxy-agent": { - "version": "3.0.1", - "bundled": true, - "requires": { - "agent-base": "^4.1.0", - "socks": "^1.1.10" - } - }, - "ssri": { - "version": "5.3.0", - "bundled": true, - "requires": { - "safe-buffer": "^5.1.1" - } - } - } - }, - "npm-run-path": { - "version": "2.0.2", - "bundled": true, - "requires": { - "path-key": "^2.0.0" - } - }, - "npm-user-validate": { - "version": "1.0.0", - "bundled": true - }, - "npmlog": { - "version": "4.1.2", - "bundled": true, - "requires": { - "are-we-there-yet": "~1.1.2", - "console-control-strings": "~1.1.0", - "gauge": "~2.7.3", - "set-blocking": "~2.0.0" - } - }, - "number-is-nan": { - "version": "1.0.1", - "bundled": true - }, - "oauth-sign": { - "version": "0.9.0", - "bundled": true - }, - "object-assign": { - "version": "4.1.1", - "bundled": true - }, - "once": { - "version": "1.4.0", - "bundled": true, - "requires": { - "wrappy": "1" - } - }, - "opener": { - "version": "1.5.0", - "bundled": true - }, - "os-homedir": { - "version": "1.0.2", - "bundled": true - }, - "os-locale": { - "version": "2.1.0", - "bundled": true, - "requires": { - "execa": "^0.7.0", - "lcid": "^1.0.0", - "mem": "^1.1.0" - } - }, - "os-tmpdir": { - "version": "1.0.2", - "bundled": true - }, - "osenv": { - "version": "0.1.5", - "bundled": true, - "requires": { - "os-homedir": "^1.0.0", - "os-tmpdir": "^1.0.0" - } - }, - "p-finally": { - "version": "1.0.0", - "bundled": true - }, - "p-limit": { - "version": "1.2.0", - "bundled": true, - "requires": { - "p-try": "^1.0.0" - } - }, - "p-locate": { - "version": "2.0.0", - "bundled": true, - "requires": { - "p-limit": "^1.1.0" - } - }, - "p-try": { - "version": "1.0.0", - "bundled": true - }, - "package-json": { - "version": "4.0.1", - "bundled": true, - "requires": { - "got": "^6.7.1", - "registry-auth-token": "^3.0.1", - "registry-url": "^3.0.3", - "semver": "^5.1.0" - } - }, - "pacote": { - "version": "8.1.6", - "bundled": true, - "requires": { - "bluebird": "^3.5.1", - "cacache": "^11.0.2", - "get-stream": "^3.0.0", - "glob": "^7.1.2", - "lru-cache": "^4.1.3", - "make-fetch-happen": "^4.0.1", - "minimatch": "^3.0.4", - "minipass": "^2.3.3", - "mississippi": "^3.0.0", - "mkdirp": "^0.5.1", - "normalize-package-data": "^2.4.0", - "npm-package-arg": "^6.1.0", - "npm-packlist": "^1.1.10", - "npm-pick-manifest": "^2.1.0", - "osenv": "^0.1.5", - "promise-inflight": "^1.0.1", - "promise-retry": "^1.1.1", - "protoduck": "^5.0.0", - "rimraf": "^2.6.2", - "safe-buffer": "^5.1.2", - "semver": "^5.5.0", - "ssri": "^6.0.0", - "tar": "^4.4.3", - "unique-filename": "^1.1.0", - "which": "^1.3.0" - } - }, - "parallel-transform": { - "version": "1.1.0", - "bundled": true, - "requires": { - "cyclist": "~0.2.2", - "inherits": "^2.0.3", - "readable-stream": "^2.1.5" - } - }, - "path-exists": { - "version": "3.0.0", - "bundled": true - }, - "path-is-absolute": { - "version": "1.0.1", - "bundled": true - }, - "path-is-inside": { - "version": "1.0.2", - "bundled": true - }, - "path-key": { - "version": "2.0.1", - "bundled": true - }, - "performance-now": { - "version": "2.1.0", - "bundled": true - }, - "pify": { - "version": "3.0.0", - "bundled": true - }, - "prepend-http": { - "version": "1.0.4", - "bundled": true - }, - "process-nextick-args": { - "version": "2.0.0", - "bundled": true - }, - "promise-inflight": { - "version": "1.0.1", - "bundled": true - }, - "promise-retry": { - "version": "1.1.1", - "bundled": true, - "requires": { - "err-code": "^1.0.0", - "retry": "^0.10.0" - }, - "dependencies": { - "retry": { - "version": "0.10.1", - "bundled": true - } - } - }, - "promzard": { - "version": "0.3.0", - "bundled": true, - "requires": { - "read": "1" - } - }, - "proto-list": { - "version": "1.2.4", - "bundled": true - }, - "protoduck": { - "version": "5.0.0", - "bundled": true, - "requires": { - "genfun": "^4.0.1" - } - }, - "prr": { - "version": "1.0.1", - "bundled": true - }, - "pseudomap": { - "version": "1.0.2", - "bundled": true - }, - "psl": { - "version": "1.1.29", - "bundled": true - }, - "pump": { - "version": "3.0.0", - "bundled": true, - "requires": { - "end-of-stream": "^1.1.0", - "once": "^1.3.1" - } - }, - "pumpify": { - "version": "1.5.1", - "bundled": true, - "requires": { - "duplexify": "^3.6.0", - "inherits": "^2.0.3", - "pump": "^2.0.0" - }, - "dependencies": { - "pump": { - "version": "2.0.1", - "bundled": true, - "requires": { - "end-of-stream": "^1.1.0", - "once": "^1.3.1" - } - } - } - }, - "punycode": { - "version": "1.4.1", - "bundled": true - }, - "qrcode-terminal": { - "version": "0.12.0", - "bundled": true - }, - "qs": { - "version": "6.5.2", - "bundled": true - }, - "query-string": { - "version": "6.1.0", - "bundled": true, - "requires": { - "decode-uri-component": "^0.2.0", - "strict-uri-encode": "^2.0.0" - } - }, - "qw": { - "version": "1.0.1", - "bundled": true - }, - "rc": { - "version": "1.2.7", - "bundled": true, - "requires": { - "deep-extend": "^0.5.1", - "ini": "~1.3.0", - "minimist": "^1.2.0", - "strip-json-comments": "~2.0.1" - }, - "dependencies": { - "minimist": { - "version": "1.2.0", - "bundled": true - } - } - }, - "read": { - "version": "1.0.7", - "bundled": true, - "requires": { - "mute-stream": "~0.0.4" - } - }, - "read-cmd-shim": { - "version": "1.0.1", - "bundled": true, - "requires": { - "graceful-fs": "^4.1.2" - } - }, - "read-installed": { - "version": "4.0.3", - "bundled": true, - "requires": { - "debuglog": "^1.0.1", - "graceful-fs": "^4.1.2", - "read-package-json": "^2.0.0", - "readdir-scoped-modules": "^1.0.0", - "semver": "2 || 3 || 4 || 5", - "slide": "~1.1.3", - "util-extend": "^1.0.1" - } - }, - "read-package-json": { - "version": "2.0.13", - "bundled": true, - "requires": { - "glob": "^7.1.1", - "graceful-fs": "^4.1.2", - "json-parse-better-errors": "^1.0.1", - "normalize-package-data": "^2.0.0", - "slash": "^1.0.0" - } - }, - "read-package-tree": { - "version": "5.2.1", - "bundled": true, - "requires": { - "debuglog": "^1.0.1", - "dezalgo": "^1.0.0", - "once": "^1.3.0", - "read-package-json": "^2.0.0", - "readdir-scoped-modules": "^1.0.0" - } - }, - "readable-stream": { - "version": "2.3.6", - "bundled": true, - "requires": { - "core-util-is": "~1.0.0", - "inherits": "~2.0.3", - "isarray": "~1.0.0", - "process-nextick-args": "~2.0.0", - "safe-buffer": "~5.1.1", - "string_decoder": "~1.1.1", - "util-deprecate": "~1.0.1" - } - }, - "readdir-scoped-modules": { - "version": "1.0.2", - "bundled": true, - "requires": { - "debuglog": "^1.0.1", - "dezalgo": "^1.0.0", - "graceful-fs": "^4.1.2", - "once": "^1.3.0" - } - }, - "registry-auth-token": { - "version": "3.3.2", - "bundled": true, - "requires": { - "rc": "^1.1.6", - "safe-buffer": "^5.0.1" - } - }, - "registry-url": { - "version": "3.1.0", - "bundled": true, - "requires": { - "rc": "^1.0.1" - } - }, - "request": { - "version": "2.88.0", - "bundled": true, - "requires": { - "aws-sign2": "~0.7.0", - "aws4": "^1.8.0", - "caseless": "~0.12.0", - "combined-stream": "~1.0.6", - "extend": "~3.0.2", - "forever-agent": "~0.6.1", - "form-data": "~2.3.2", - "har-validator": "~5.1.0", - "http-signature": "~1.2.0", - "is-typedarray": "~1.0.0", - "isstream": "~0.1.2", - "json-stringify-safe": "~5.0.1", - "mime-types": "~2.1.19", - "oauth-sign": "~0.9.0", - "performance-now": "^2.1.0", - "qs": "~6.5.2", - "safe-buffer": "^5.1.2", - "tough-cookie": "~2.4.3", - "tunnel-agent": "^0.6.0", - "uuid": "^3.3.2" - } - }, - "require-directory": { - "version": "2.1.1", - "bundled": true - }, - "require-main-filename": { - "version": "1.0.1", - "bundled": true - }, - "resolve-from": { - "version": "4.0.0", - "bundled": true - }, - "retry": { - "version": "0.12.0", - "bundled": true - }, - "rimraf": { - "version": "2.6.2", - "bundled": true, - "requires": { - "glob": "^7.0.5" - } - }, - "run-queue": { - "version": "1.0.3", - "bundled": true, - "requires": { - "aproba": "^1.1.1" - } - }, - "safe-buffer": { - "version": "5.1.2", - "bundled": true - }, - "safer-buffer": { - "version": "2.1.2", - "bundled": true - }, - "semver": { - "version": "5.5.0", - "bundled": true - }, - "semver-diff": { - "version": "2.1.0", - "bundled": true, - "requires": { - "semver": "^5.0.3" - } - }, - "set-blocking": { - "version": "2.0.0", - "bundled": true - }, - "sha": { - "version": "2.0.1", - "bundled": true, - "requires": { - "graceful-fs": "^4.1.2", - "readable-stream": "^2.0.2" - } - }, - "shebang-command": { - "version": "1.2.0", - "bundled": true, - "requires": { - "shebang-regex": "^1.0.0" - } - }, - "shebang-regex": { - "version": "1.0.0", - "bundled": true - }, - "signal-exit": { - "version": "3.0.2", - "bundled": true - }, - "slash": { - "version": "1.0.0", - "bundled": true - }, - "slide": { - "version": "1.1.6", - "bundled": true - }, - "smart-buffer": { - "version": "4.0.1", - "bundled": true - }, - "socks": { - "version": "2.2.0", - "bundled": true, - "requires": { - "ip": "^1.1.5", - "smart-buffer": "^4.0.1" - } - }, - "socks-proxy-agent": { - "version": "4.0.1", - "bundled": true, - "requires": { - "agent-base": "~4.2.0", - "socks": "~2.2.0" - } - }, - "sorted-object": { - "version": "2.0.1", - "bundled": true - }, - "sorted-union-stream": { - "version": "2.1.3", - "bundled": true, - "requires": { - "from2": "^1.3.0", - "stream-iterate": "^1.1.0" - }, - "dependencies": { - "from2": { - "version": "1.3.0", - "bundled": true, - "requires": { - "inherits": "~2.0.1", - "readable-stream": "~1.1.10" - } - }, - "isarray": { - "version": "0.0.1", - "bundled": true - }, - "readable-stream": { - "version": "1.1.14", - "bundled": true, - "requires": { - "core-util-is": "~1.0.0", - "inherits": "~2.0.1", - "isarray": "0.0.1", - "string_decoder": "~0.10.x" - } - }, - "string_decoder": { - "version": "0.10.31", - "bundled": true - } - } - }, - "spdx-correct": { - "version": "3.0.0", - "bundled": true, - "requires": { - "spdx-expression-parse": "^3.0.0", - "spdx-license-ids": "^3.0.0" - } - }, - "spdx-exceptions": { - "version": "2.1.0", - "bundled": true - }, - "spdx-expression-parse": { - "version": "3.0.0", - "bundled": true, - "requires": { - "spdx-exceptions": "^2.1.0", - "spdx-license-ids": "^3.0.0" - } - }, - "spdx-license-ids": { - "version": "3.0.0", - "bundled": true - }, - "sshpk": { - "version": "1.14.2", - "bundled": true, - "requires": { - "asn1": "~0.2.3", - "assert-plus": "^1.0.0", - "bcrypt-pbkdf": "^1.0.0", - "dashdash": "^1.12.0", - "ecc-jsbn": "~0.1.1", - "getpass": "^0.1.1", - "jsbn": "~0.1.0", - "safer-buffer": "^2.0.2", - "tweetnacl": "~0.14.0" - } - }, - "ssri": { - "version": "6.0.0", - "bundled": true - }, - "stream-each": { - "version": "1.2.2", - "bundled": true, - "requires": { - "end-of-stream": "^1.1.0", - "stream-shift": "^1.0.0" - } - }, - "stream-iterate": { - "version": "1.2.0", - "bundled": true, - "requires": { - "readable-stream": "^2.1.5", - "stream-shift": "^1.0.0" - } - }, - "stream-shift": { - "version": "1.0.0", - "bundled": true - }, - "strict-uri-encode": { - "version": "2.0.0", - "bundled": true - }, - "string-width": { - "version": "2.1.1", - "bundled": true, - "requires": { - "is-fullwidth-code-point": "^2.0.0", - "strip-ansi": "^4.0.0" - }, - "dependencies": { - "ansi-regex": { - "version": "3.0.0", - "bundled": true - }, - "is-fullwidth-code-point": { - "version": "2.0.0", - "bundled": true - }, - "strip-ansi": { - "version": "4.0.0", - "bundled": true, - "requires": { - "ansi-regex": "^3.0.0" - } - } - } - }, - "string_decoder": { - "version": "1.1.1", - "bundled": true, - "requires": { - "safe-buffer": "~5.1.0" - } - }, - "stringify-package": { - "version": "1.0.0", - "bundled": true - }, - "strip-ansi": { - "version": "3.0.1", - "bundled": true, - "requires": { - "ansi-regex": "^2.0.0" - } - }, - "strip-eof": { - "version": "1.0.0", - "bundled": true - }, - "strip-json-comments": { - "version": "2.0.1", - "bundled": true - }, - "supports-color": { - "version": "5.4.0", - "bundled": true, - "requires": { - "has-flag": "^3.0.0" - } - }, - "tar": { - "version": "4.4.6", - "bundled": true, - "requires": { - "chownr": "^1.0.1", - "fs-minipass": "^1.2.5", - "minipass": "^2.3.3", - "minizlib": "^1.1.0", - "mkdirp": "^0.5.0", - "safe-buffer": "^5.1.2", - "yallist": "^3.0.2" - }, - "dependencies": { - "yallist": { - "version": "3.0.2", - "bundled": true - } - } - }, - "term-size": { - "version": "1.2.0", - "bundled": true, - "requires": { - "execa": "^0.7.0" - } - }, - "text-table": { - "version": "0.2.0", - "bundled": true - }, - "through": { - "version": "2.3.8", - "bundled": true - }, - "through2": { - "version": "2.0.3", - "bundled": true, - "requires": { - "readable-stream": "^2.1.5", - "xtend": "~4.0.1" - } - }, - "timed-out": { - "version": "4.0.1", - "bundled": true - }, - "tiny-relative-date": { - "version": "1.3.0", - "bundled": true - }, - "tough-cookie": { - "version": "2.4.3", - "bundled": true, - "requires": { - "psl": "^1.1.24", - "punycode": "^1.4.1" - } - }, - "tunnel-agent": { - "version": "0.6.0", - "bundled": true, - "requires": { - "safe-buffer": "^5.0.1" - } - }, - "tweetnacl": { - "version": "0.14.5", - "bundled": true, - "optional": true - }, - "typedarray": { - "version": "0.0.6", - "bundled": true - }, - "uid-number": { - "version": "0.0.6", - "bundled": true - }, - "umask": { - "version": "1.1.0", - "bundled": true - }, - "unique-filename": { - "version": "1.1.0", - "bundled": true, - "requires": { - "unique-slug": "^2.0.0" - } - }, - "unique-slug": { - "version": "2.0.0", - "bundled": true, - "requires": { - "imurmurhash": "^0.1.4" - } - }, - "unique-string": { - "version": "1.0.0", - "bundled": true, - "requires": { - "crypto-random-string": "^1.0.0" - } - }, - "unpipe": { - "version": "1.0.0", - "bundled": true - }, - "unzip-response": { - "version": "2.0.1", - "bundled": true - }, - "update-notifier": { - "version": "2.5.0", - "bundled": true, - "requires": { - "boxen": "^1.2.1", - "chalk": "^2.0.1", - "configstore": "^3.0.0", - "import-lazy": "^2.1.0", - "is-ci": "^1.0.10", - "is-installed-globally": "^0.1.0", - "is-npm": "^1.0.0", - "latest-version": "^3.0.0", - "semver-diff": "^2.0.0", - "xdg-basedir": "^3.0.0" - } - }, - "url-parse-lax": { - "version": "1.0.0", - "bundled": true, - "requires": { - "prepend-http": "^1.0.1" - } - }, - "util-deprecate": { - "version": "1.0.2", - "bundled": true - }, - "util-extend": { - "version": "1.0.3", - "bundled": true - }, - "uuid": { - "version": "3.3.2", - "bundled": true - }, - "validate-npm-package-license": { - "version": "3.0.4", - "bundled": true, - "requires": { - "spdx-correct": "^3.0.0", - "spdx-expression-parse": "^3.0.0" - } - }, - "validate-npm-package-name": { - "version": "3.0.0", - "bundled": true, - "requires": { - "builtins": "^1.0.3" - } - }, - "verror": { - "version": "1.10.0", - "bundled": true, - "requires": { - "assert-plus": "^1.0.0", - "core-util-is": "1.0.2", - "extsprintf": "^1.2.0" - } - }, - "wcwidth": { - "version": "1.0.1", - "bundled": true, - "requires": { - "defaults": "^1.0.3" - } - }, - "which": { - "version": "1.3.1", - "bundled": true, - "requires": { - "isexe": "^2.0.0" - } - }, - "which-module": { - "version": "2.0.0", - "bundled": true - }, - "wide-align": { - "version": "1.1.2", - "bundled": true, - "requires": { - "string-width": "^1.0.2" - }, - "dependencies": { - "string-width": { - "version": "1.0.2", - "bundled": true, - "requires": { - "code-point-at": "^1.0.0", - "is-fullwidth-code-point": "^1.0.0", - "strip-ansi": "^3.0.0" - } - } - } - }, - "widest-line": { - "version": "2.0.0", - "bundled": true, - "requires": { - "string-width": "^2.1.1" - } - }, - "worker-farm": { - "version": "1.6.0", - "bundled": true, - "requires": { - "errno": "~0.1.7" - } - }, - "wrap-ansi": { - "version": "2.1.0", - "bundled": true, - "requires": { - "string-width": "^1.0.1", - "strip-ansi": "^3.0.1" - }, - "dependencies": { - "string-width": { - "version": "1.0.2", - "bundled": true, - "requires": { - "code-point-at": "^1.0.0", - "is-fullwidth-code-point": "^1.0.0", - "strip-ansi": "^3.0.0" - } - } - } - }, - "wrappy": { - "version": "1.0.2", - "bundled": true - }, - "write-file-atomic": { - "version": "2.3.0", - "bundled": true, - "requires": { - "graceful-fs": "^4.1.11", - "imurmurhash": "^0.1.4", - "signal-exit": "^3.0.2" - } - }, - "xdg-basedir": { - "version": "3.0.0", - "bundled": true - }, - "xtend": { - "version": "4.0.1", - "bundled": true - }, - "y18n": { - "version": "4.0.0", - "bundled": true - }, - "yallist": { - "version": "2.1.2", - "bundled": true - }, - "yargs": { - "version": "11.0.0", - "bundled": true, - "requires": { - "cliui": "^4.0.0", - "decamelize": "^1.1.1", - "find-up": "^2.1.0", - "get-caller-file": "^1.0.1", - "os-locale": "^2.0.0", - "require-directory": "^2.1.1", - "require-main-filename": "^1.0.1", - "set-blocking": "^2.0.0", - "string-width": "^2.0.0", - "which-module": "^2.0.0", - "y18n": "^3.2.1", - "yargs-parser": "^9.0.2" - }, - "dependencies": { - "y18n": { - "version": "3.2.1", - "bundled": true - } - } - }, - "yargs-parser": { - "version": "9.0.2", - "bundled": true, - "requires": { - "camelcase": "^4.1.0" - } - } - } - }, - "number-is-nan": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/number-is-nan/-/number-is-nan-1.0.1.tgz", - "integrity": "sha1-CXtgK1NCKlIsGvuHkDGDNpQaAR0=" - }, - "oauth-sign": { - "version": "0.9.0", - "resolved": "https://registry.npmjs.org/oauth-sign/-/oauth-sign-0.9.0.tgz", - "integrity": "sha512-fexhUFFPTGV8ybAtSIGbV6gOkSv8UtRbDBnAyLQw4QPKkgNlsH2ByPGtMUqdWkos6YCRmAqViwgZrJc/mRDzZQ==" - }, - "object-assign": { - "version": "4.1.1", - "resolved": "https://registry.npmjs.org/object-assign/-/object-assign-4.1.1.tgz", - "integrity": "sha1-IQmtx5ZYh8/AXLvUQsrIv7s2CGM=" - }, - "object-inspect": { - "version": "1.6.0", - "resolved": "https://registry.npmjs.org/object-inspect/-/object-inspect-1.6.0.tgz", - "integrity": "sha512-GJzfBZ6DgDAmnuaM3104jR4s1Myxr3Y3zfIyN4z3UdqN69oSRacNK8UhnobDdC+7J2AHCjGwxQubNJfE70SXXQ==" - }, - "object-keys": { - "version": "1.0.12", - "resolved": "https://registry.npmjs.org/object-keys/-/object-keys-1.0.12.tgz", - "integrity": "sha512-FTMyFUm2wBcGHnH2eXmz7tC6IwlqQZ6mVZ+6dm6vZ4IQIHjs6FdNsQBuKGPuUUUY6NfJw2PshC08Tn6LzLDOag==" - }, - "once": { - "version": "1.4.0", - "resolved": "https://registry.npmjs.org/once/-/once-1.4.0.tgz", - "integrity": "sha1-WDsap3WWHUsROsF9nFC6753Xa9E=", - "requires": { - "wrappy": "1" - } - }, - "os-homedir": { - "version": "1.0.2", - "resolved": "http://registry.npmjs.org/os-homedir/-/os-homedir-1.0.2.tgz", - "integrity": "sha1-/7xJiDNuDoM94MFox+8VISGqf7M=" - }, - "os-locale": { - "version": "1.4.0", - "resolved": "http://registry.npmjs.org/os-locale/-/os-locale-1.4.0.tgz", - "integrity": "sha1-IPnxeuKe00XoveWDsT0gCYA8FNk=", - "requires": { - "lcid": "^1.0.0" - } - }, - "os-tmpdir": { - "version": "1.0.2", - "resolved": "http://registry.npmjs.org/os-tmpdir/-/os-tmpdir-1.0.2.tgz", - "integrity": "sha1-u+Z0BseaqFxc/sdm/lc0VV36EnQ=" - }, - "parse-headers": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/parse-headers/-/parse-headers-2.0.1.tgz", - "integrity": "sha1-aug6eqJanZtwCswoaYzR8e1+lTY=", - "requires": { - "for-each": "^0.3.2", - "trim": "0.0.1" - } - }, - "parse-json": { - "version": "2.2.0", - "resolved": "https://registry.npmjs.org/parse-json/-/parse-json-2.2.0.tgz", - "integrity": "sha1-9ID0BDTvgHQfhGkJn43qGPVaTck=", - "requires": { - "error-ex": "^1.2.0" - } - }, - "path-exists": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-2.1.0.tgz", - "integrity": "sha1-D+tsZPD8UY2adU3V77YscCJ2H0s=", - "requires": { - "pinkie-promise": "^2.0.0" - } - }, - "path-is-absolute": { - "version": "1.0.1", - "resolved": "http://registry.npmjs.org/path-is-absolute/-/path-is-absolute-1.0.1.tgz", - "integrity": "sha1-F0uSaHNVNP+8es5r9TpanhtcX18=" - }, - "path-parse": { - "version": "1.0.6", - "resolved": "https://registry.npmjs.org/path-parse/-/path-parse-1.0.6.tgz", - "integrity": "sha512-GSmOT2EbHrINBf9SR7CDELwlJ8AENk3Qn7OikK4nFYAu3Ote2+JYNVvkpAEQm3/TLNEJFD/xZJjzyxg3KBWOzw==" - }, - "path-type": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/path-type/-/path-type-1.1.0.tgz", - "integrity": "sha1-WcRPfuSR2nBNpBXaWkBwuk+P5EE=", - "requires": { - "graceful-fs": "^4.1.2", - "pify": "^2.0.0", - "pinkie-promise": "^2.0.0" - } - }, - "pbkdf2": { - "version": "3.0.17", - "resolved": "https://registry.npmjs.org/pbkdf2/-/pbkdf2-3.0.17.tgz", - "integrity": "sha512-U/il5MsrZp7mGg3mSQfn742na2T+1/vHDCG5/iTI3X9MKUuYUZVLQhyRsg06mCgDBTd57TxzgZt7P+fYfjRLtA==", - "requires": { - "create-hash": "^1.1.2", - "create-hmac": "^1.1.4", - "ripemd160": "^2.0.1", - "safe-buffer": "^5.0.1", - "sha.js": "^2.4.8" - } - }, - "performance-now": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/performance-now/-/performance-now-2.1.0.tgz", - "integrity": "sha1-Ywn04OX6kT7BxpMHrjZLSzd8nns=" - }, - "pify": { - "version": "2.3.0", - "resolved": "http://registry.npmjs.org/pify/-/pify-2.3.0.tgz", - "integrity": "sha1-7RQaasBDqEnqWISY59yosVMw6Qw=" - }, - "pinkie": { - "version": "2.0.4", - "resolved": "https://registry.npmjs.org/pinkie/-/pinkie-2.0.4.tgz", - "integrity": "sha1-clVrgM+g1IqXToDnckjoDtT3+HA=" - }, - "pinkie-promise": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/pinkie-promise/-/pinkie-promise-2.0.1.tgz", - "integrity": "sha1-ITXW36ejWMBprJsXh3YogihFD/o=", - "requires": { - "pinkie": "^2.0.0" - } - }, - "precond": { - "version": "0.2.3", - "resolved": "https://registry.npmjs.org/precond/-/precond-0.2.3.tgz", - "integrity": "sha1-qpWRvKokkj8eD0hJ0kD0fvwQdaw=" - }, - "private": { - "version": "0.1.8", - "resolved": "https://registry.npmjs.org/private/-/private-0.1.8.tgz", - "integrity": "sha512-VvivMrbvd2nKkiG38qjULzlc+4Vx4wm/whI9pQD35YrARNnhxeiRktSOhSukRLFNlzg6Br/cJPet5J/u19r/mg==" - }, - "process": { - "version": "0.5.2", - "resolved": "https://registry.npmjs.org/process/-/process-0.5.2.tgz", - "integrity": "sha1-FjjYqONML0QKkduVq5rrZ3/Bhc8=" - }, - "process-nextick-args": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/process-nextick-args/-/process-nextick-args-2.0.0.tgz", - "integrity": "sha512-MtEC1TqN0EU5nephaJ4rAtThHtC86dNN9qCuEhtshvpVBkAW5ZO7BASN9REnF9eoXGcRub+pFuKEpOHE+HbEMw==" - }, - "promise-to-callback": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/promise-to-callback/-/promise-to-callback-1.0.0.tgz", - "integrity": "sha1-XSp0kBC/tn2WNZj805YHRqaP7vc=", - "requires": { - "is-fn": "^1.0.0", - "set-immediate-shim": "^1.0.1" - } - }, - "prr": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/prr/-/prr-1.0.1.tgz", - "integrity": "sha1-0/wRS6BplaRexok/SEzrHXj19HY=" - }, - "psl": { - "version": "1.1.31", - "resolved": "https://registry.npmjs.org/psl/-/psl-1.1.31.tgz", - "integrity": "sha512-/6pt4+C+T+wZUieKR620OpzN/LlnNKuWjy1iFLQ/UG35JqHlR/89MP1d96dUfkf6Dne3TuLQzOYEYshJ+Hx8mw==" - }, - "punycode": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/punycode/-/punycode-2.1.1.tgz", - "integrity": "sha512-XRsRjdf+j5ml+y/6GKHPZbrF/8p2Yga0JPtdqTIY2Xe5ohJPD9saDJJLPvp9+NSBprVvevdXZybnj2cv8OEd0A==" - }, - "qs": { - "version": "6.5.2", - "resolved": "https://registry.npmjs.org/qs/-/qs-6.5.2.tgz", - "integrity": "sha512-N5ZAX4/LxJmF+7wN74pUD6qAh9/wnvdQcjq9TZjevvXzSUo7bfmw91saqMjzGS2xq91/odN2dW/WOl7qQHNDGA==" - }, - "randombytes": { - "version": "2.0.6", - "resolved": "https://registry.npmjs.org/randombytes/-/randombytes-2.0.6.tgz", - "integrity": "sha512-CIQ5OFxf4Jou6uOKe9t1AOgqpeU5fd70A8NPdHSGeYXqXsPe6peOwI0cUl88RWZ6sP1vPMV3avd/R6cZ5/sP1A==", - "requires": { - "safe-buffer": "^5.1.0" - } - }, - "read-pkg": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/read-pkg/-/read-pkg-1.1.0.tgz", - "integrity": "sha1-9f+qXs0pyzHAR0vKfXVra7KePyg=", - "requires": { - "load-json-file": "^1.0.0", - "normalize-package-data": "^2.3.2", - "path-type": "^1.0.0" - } - }, - "read-pkg-up": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/read-pkg-up/-/read-pkg-up-1.0.1.tgz", - "integrity": "sha1-nWPBMnbAZZGNV/ACpX9AobZD+wI=", - "requires": { - "find-up": "^1.0.0", - "read-pkg": "^1.0.0" - } - }, - "readable-stream": { - "version": "2.3.6", - "resolved": "http://registry.npmjs.org/readable-stream/-/readable-stream-2.3.6.tgz", - "integrity": "sha512-tQtKA9WIAhBF3+VLAseyMqZeBjW0AHJoxOtYqSUZNJxauErmLbVm2FW1y+J/YA9dUrAC39ITejlZWhVIwawkKw==", - "requires": { - "core-util-is": "~1.0.0", - "inherits": "~2.0.3", - "isarray": "~1.0.0", - "process-nextick-args": "~2.0.0", - "safe-buffer": "~5.1.1", - "string_decoder": "~1.1.1", - "util-deprecate": "~1.0.1" - } - }, - "regenerate": { - "version": "1.4.0", - "resolved": "https://registry.npmjs.org/regenerate/-/regenerate-1.4.0.tgz", - "integrity": "sha512-1G6jJVDWrt0rK99kBjvEtziZNCICAuvIPkSiUFIQxVP06RCVpq3dmDo2oi6ABpYaDYaTRr67BEhL8r1wgEZZKg==" - }, - "regenerator-runtime": { - "version": "0.11.1", - "resolved": "https://registry.npmjs.org/regenerator-runtime/-/regenerator-runtime-0.11.1.tgz", - "integrity": "sha512-MguG95oij0fC3QV3URf4V2SDYGJhJnJGqvIIgdECeODCT98wSWDAJ94SSuVpYQUoTcGUIL6L4yNB7j1DFFHSBg==" - }, - "regenerator-transform": { - "version": "0.10.1", - "resolved": "https://registry.npmjs.org/regenerator-transform/-/regenerator-transform-0.10.1.tgz", - "integrity": "sha512-PJepbvDbuK1xgIgnau7Y90cwaAmO/LCLMI2mPvaXq2heGMR3aWW5/BQvYrhJ8jgmQjXewXvBjzfqKcVOmhjZ6Q==", - "requires": { - "babel-runtime": "^6.18.0", - "babel-types": "^6.19.0", - "private": "^0.1.6" - } - }, - "regexpu-core": { - "version": "2.0.0", - "resolved": "http://registry.npmjs.org/regexpu-core/-/regexpu-core-2.0.0.tgz", - "integrity": "sha1-SdA4g3uNz4v6W5pCE5k45uoq4kA=", - "requires": { - "regenerate": "^1.2.1", - "regjsgen": "^0.2.0", - "regjsparser": "^0.1.4" - } - }, - "regjsgen": { - "version": "0.2.0", - "resolved": "http://registry.npmjs.org/regjsgen/-/regjsgen-0.2.0.tgz", - "integrity": "sha1-bAFq3qxVT3WCP+N6wFuS1aTtsfc=" - }, - "regjsparser": { - "version": "0.1.5", - "resolved": "http://registry.npmjs.org/regjsparser/-/regjsparser-0.1.5.tgz", - "integrity": "sha1-fuj4Tcb6eS0/0K4ijSS9lJ6tIFw=", - "requires": { - "jsesc": "~0.5.0" - } - }, - "repeating": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/repeating/-/repeating-2.0.1.tgz", - "integrity": "sha1-UhTFOpJtNVJwdSf7q0FdvAjQbdo=", - "requires": { - "is-finite": "^1.0.0" - } - }, - "request": { - "version": "2.88.0", - "resolved": "https://registry.npmjs.org/request/-/request-2.88.0.tgz", - "integrity": "sha512-NAqBSrijGLZdM0WZNsInLJpkJokL72XYjUpnB0iwsRgxh7dB6COrHnTBNwN0E+lHDAJzu7kLAkDeY08z2/A0hg==", - "requires": { - "aws-sign2": "~0.7.0", - "aws4": "^1.8.0", - "caseless": "~0.12.0", - "combined-stream": "~1.0.6", - "extend": "~3.0.2", - "forever-agent": "~0.6.1", - "form-data": "~2.3.2", - "har-validator": "~5.1.0", - "http-signature": "~1.2.0", - "is-typedarray": "~1.0.0", - "isstream": "~0.1.2", - "json-stringify-safe": "~5.0.1", - "mime-types": "~2.1.19", - "oauth-sign": "~0.9.0", - "performance-now": "^2.1.0", - "qs": "~6.5.2", - "safe-buffer": "^5.1.2", - "tough-cookie": "~2.4.3", - "tunnel-agent": "^0.6.0", - "uuid": "^3.3.2" - }, - "dependencies": { - "uuid": { - "version": "3.3.2", - "resolved": "https://registry.npmjs.org/uuid/-/uuid-3.3.2.tgz", - "integrity": "sha512-yXJmeNaw3DnnKAOKJE51sL/ZaYfWJRl1pK9dr19YFCu0ObS231AB1/LbqTKRAQ5kw8A90rA6fr4riOUpTZvQZA==" - } - } - }, - "require-directory": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/require-directory/-/require-directory-2.1.1.tgz", - "integrity": "sha1-jGStX9MNqxyXbiNE/+f3kqam30I=" - }, - "require-from-string": { - "version": "1.2.1", - "resolved": "https://registry.npmjs.org/require-from-string/-/require-from-string-1.2.1.tgz", - "integrity": "sha1-UpyczvJzgK3+yaL5ZbZJu+5jZBg=" - }, - "require-main-filename": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/require-main-filename/-/require-main-filename-1.0.1.tgz", - "integrity": "sha1-l/cXtp1IeE9fUmpsWqj/3aBVpNE=" - }, - "resolve": { - "version": "1.7.1", - "resolved": "http://registry.npmjs.org/resolve/-/resolve-1.7.1.tgz", - "integrity": "sha512-c7rwLofp8g1U+h1KNyHL/jicrKg1Ek4q+Lr33AL65uZTinUZHe30D5HlyN5V9NW0JX1D5dXQ4jqW5l7Sy/kGfw==", - "requires": { - "path-parse": "^1.0.5" - } - }, - "resumer": { - "version": "0.0.0", - "resolved": "https://registry.npmjs.org/resumer/-/resumer-0.0.0.tgz", - "integrity": "sha1-8ej0YeQGS6Oegq883CqMiT0HZ1k=", - "requires": { - "through": "~2.3.4" - } - }, - "rimraf": { - "version": "2.6.2", - "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-2.6.2.tgz", - "integrity": "sha512-lreewLK/BlghmxtfH36YYVg1i8IAce4TI7oao75I1g245+6BctqTVQiBP3YUJ9C6DQOXJmkYR9X9fCLtCOJc5w==", - "requires": { - "glob": "^7.0.5" - } - }, - "ripemd160": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/ripemd160/-/ripemd160-2.0.2.tgz", - "integrity": "sha512-ii4iagi25WusVoiC4B4lq7pbXfAp3D9v5CwfkY33vffw2+pkDjY1D8GaN7spsxvCSx8dkPqOZCEZyfxcmJG2IA==", - "requires": { - "hash-base": "^3.0.0", - "inherits": "^2.0.1" - } - }, - "rlp": { - "version": "2.2.0", - "resolved": "https://registry.npmjs.org/rlp/-/rlp-2.2.0.tgz", - "integrity": "sha512-rGDIOeKPYj82rgml9Fpi28dU9n2JYyqTXaBeCLTT9rk9+Ry+/l7oDgVuHcKYDSJ6WZfa2mD16fRWPpNzk0kTHw==", - "requires": { - "safe-buffer": "^5.1.1" - } - }, - "rustbn.js": { - "version": "0.1.2", - "resolved": "https://registry.npmjs.org/rustbn.js/-/rustbn.js-0.1.2.tgz", - "integrity": "sha512-bAkNqSHYdJdFsBC7Z11JgzYktL31HIpB2o70jZcGiL1U1TVtPyvaVhDrGWwS8uZtaqwW2k6NOPGZCqW/Dgh5Lg==" - }, - "safe-buffer": { - "version": "5.1.2", - "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz", - "integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==" - }, - "safe-event-emitter": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/safe-event-emitter/-/safe-event-emitter-1.0.1.tgz", - "integrity": "sha512-e1wFe99A91XYYxoQbcq2ZJUWurxEyP8vfz7A7vuUe1s95q8r5ebraVaA1BukYJcpM6V16ugWoD9vngi8Ccu5fg==", - "requires": { - "events": "^3.0.0" - } - }, - "safer-buffer": { - "version": "2.1.2", - "resolved": "https://registry.npmjs.org/safer-buffer/-/safer-buffer-2.1.2.tgz", - "integrity": "sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg==" - }, - "scrypt": { - "version": "6.0.3", - "resolved": "https://registry.npmjs.org/scrypt/-/scrypt-6.0.3.tgz", - "integrity": "sha1-BOAUpWgrU/pQwtXM4WfXGcBthw0=", - "requires": { - "nan": "^2.0.8" - } - }, - "scrypt.js": { - "version": "0.2.1", - "resolved": "https://registry.npmjs.org/scrypt.js/-/scrypt.js-0.2.1.tgz", - "integrity": "sha512-XMoqxwABdotuW+l+qACmJ/h0kVSCgMPZXpbncA/zyBO90z/NnDISzVw+xJ4tUY+X/Hh0EFT269OYHm26VCPgmA==", - "requires": { - "scrypt": "^6.0.2", - "scryptsy": "^1.2.1" - } - }, - "scryptsy": { - "version": "1.2.1", - "resolved": "https://registry.npmjs.org/scryptsy/-/scryptsy-1.2.1.tgz", - "integrity": "sha1-oyJfpLJST4AnAHYeKFW987LZIWM=", - "requires": { - "pbkdf2": "^3.0.3" - } - }, - "secp256k1": { - "version": "3.5.2", - "resolved": "https://registry.npmjs.org/secp256k1/-/secp256k1-3.5.2.tgz", - "integrity": "sha512-iin3kojdybY6NArd+UFsoTuapOF7bnJNf2UbcWXaY3z+E1sJDipl60vtzB5hbO/uquBu7z0fd4VC4Irp+xoFVQ==", - "requires": { - "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" - } - }, - "semaphore": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/semaphore/-/semaphore-1.1.0.tgz", - "integrity": "sha512-O4OZEaNtkMd/K0i6js9SL+gqy0ZCBMgUvlSqHKi4IBdjhe7wB8pwztUk1BbZ1fmrvpwFrPbHzqd2w5pTcJH6LA==" - }, - "semver": { - "version": "5.6.0", - "resolved": "https://registry.npmjs.org/semver/-/semver-5.6.0.tgz", - "integrity": "sha512-RS9R6R35NYgQn++fkDWaOmqGoj4Ek9gGs+DPxNUZKuwE183xjJroKvyo1IzVFeXvUrvmALy6FWD5xrdJT25gMg==" - }, - "set-blocking": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/set-blocking/-/set-blocking-2.0.0.tgz", - "integrity": "sha1-BF+XgtARrppoA93TgrJDkrPYkPc=" - }, - "set-immediate-shim": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/set-immediate-shim/-/set-immediate-shim-1.0.1.tgz", - "integrity": "sha1-SysbJ+uAip+NzEgaWOXlb1mfP2E=" - }, - "sha.js": { - "version": "2.4.11", - "resolved": "http://registry.npmjs.org/sha.js/-/sha.js-2.4.11.tgz", - "integrity": "sha512-QMEp5B7cftE7APOjk5Y6xgrbWu+WkLVQwk8JNjZ8nKRciZaByEW6MubieAiToS7+dwvrjGhH8jRXz3MVd0AYqQ==", - "requires": { - "inherits": "^2.0.1", - "safe-buffer": "^5.0.1" - } - }, - "sha3": { - "version": "1.2.2", - "resolved": "https://registry.npmjs.org/sha3/-/sha3-1.2.2.tgz", - "integrity": "sha1-pmxQmN5MJbyIM27ItIF9AFvKe6k=", - "requires": { - "nan": "2.10.0" - } - }, - "slash": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/slash/-/slash-1.0.0.tgz", - "integrity": "sha1-xB8vbDn8FtHNF61LXYlhFK5HDVU=" - }, - "solc": { - "version": "0.4.25", - "resolved": "https://registry.npmjs.org/solc/-/solc-0.4.25.tgz", - "integrity": "sha512-jU1YygRVy6zatgXrLY2rRm7HW1d7a8CkkEgNJwvH2VLpWhMFsMdWcJn6kUqZwcSz/Vm+w89dy7Z/aB5p6AFTrg==", - "requires": { - "fs-extra": "^0.30.0", - "memorystream": "^0.3.1", - "require-from-string": "^1.1.0", - "semver": "^5.3.0", - "yargs": "^4.7.1" - } - }, - "source-map": { - "version": "0.5.7", - "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.5.7.tgz", - "integrity": "sha1-igOdLRAh0i0eoUyA2OpGi6LvP8w=" - }, - "source-map-support": { - "version": "0.4.18", - "resolved": "https://registry.npmjs.org/source-map-support/-/source-map-support-0.4.18.tgz", - "integrity": "sha512-try0/JqxPLF9nOjvSta7tVondkP5dwgyLDjVoyMDlmjugT2lRZ1OfsrYTkCd2hkDnJTKRbO/Rl3orm8vlsUzbA==", - "requires": { - "source-map": "^0.5.6" - } - }, - "spdx-correct": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/spdx-correct/-/spdx-correct-3.1.0.tgz", - "integrity": "sha512-lr2EZCctC2BNR7j7WzJ2FpDznxky1sjfxvvYEyzxNyb6lZXHODmEoJeFu4JupYlkfha1KZpJyoqiJ7pgA1qq8Q==", - "requires": { - "spdx-expression-parse": "^3.0.0", - "spdx-license-ids": "^3.0.0" - } - }, - "spdx-exceptions": { - "version": "2.2.0", - "resolved": "https://registry.npmjs.org/spdx-exceptions/-/spdx-exceptions-2.2.0.tgz", - "integrity": "sha512-2XQACfElKi9SlVb1CYadKDXvoajPgBVPn/gOQLrTvHdElaVhr7ZEbqJaRnJLVNeaI4cMEAgVCeBMKF6MWRDCRA==" - }, - "spdx-expression-parse": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/spdx-expression-parse/-/spdx-expression-parse-3.0.0.tgz", - "integrity": "sha512-Yg6D3XpRD4kkOmTpdgbUiEJFKghJH03fiC1OPll5h/0sO6neh2jqRDVHOQ4o/LMea0tgCkbMgea5ip/e+MkWyg==", - "requires": { - "spdx-exceptions": "^2.1.0", - "spdx-license-ids": "^3.0.0" - } - }, - "spdx-license-ids": { - "version": "3.0.2", - "resolved": "https://registry.npmjs.org/spdx-license-ids/-/spdx-license-ids-3.0.2.tgz", - "integrity": "sha512-qky9CVt0lVIECkEsYbNILVnPvycuEBkXoMFLRWsREkomQLevYhtRKC+R91a5TOAQ3bCMjikRwhyaRqj1VYatYg==" - }, - "sshpk": { - "version": "1.15.2", - "resolved": "https://registry.npmjs.org/sshpk/-/sshpk-1.15.2.tgz", - "integrity": "sha512-Ra/OXQtuh0/enyl4ETZAfTaeksa6BXks5ZcjpSUNrjBr0DvrJKX+1fsKDPpT9TBXgHAFsa4510aNVgI8g/+SzA==", - "requires": { - "asn1": "~0.2.3", - "assert-plus": "^1.0.0", - "bcrypt-pbkdf": "^1.0.0", - "dashdash": "^1.12.0", - "ecc-jsbn": "~0.1.1", - "getpass": "^0.1.1", - "jsbn": "~0.1.0", - "safer-buffer": "^2.0.2", - "tweetnacl": "~0.14.0" - } - }, - "string-width": { - "version": "1.0.2", - "resolved": "http://registry.npmjs.org/string-width/-/string-width-1.0.2.tgz", - "integrity": "sha1-EYvfW4zcUaKn5w0hHgfisLmxB9M=", - "requires": { - "code-point-at": "^1.0.0", - "is-fullwidth-code-point": "^1.0.0", - "strip-ansi": "^3.0.0" - } - }, - "string.prototype.trim": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/string.prototype.trim/-/string.prototype.trim-1.1.2.tgz", - "integrity": "sha1-0E3iyJ4Tf019IG8Ia17S+ua+jOo=", - "requires": { - "define-properties": "^1.1.2", - "es-abstract": "^1.5.0", - "function-bind": "^1.0.2" - } - }, - "string_decoder": { - "version": "1.1.1", - "resolved": "http://registry.npmjs.org/string_decoder/-/string_decoder-1.1.1.tgz", - "integrity": "sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg==", - "requires": { - "safe-buffer": "~5.1.0" - } - }, - "strip-ansi": { - "version": "3.0.1", - "resolved": "http://registry.npmjs.org/strip-ansi/-/strip-ansi-3.0.1.tgz", - "integrity": "sha1-ajhfuIU9lS1f8F0Oiq+UJ43GPc8=", - "requires": { - "ansi-regex": "^2.0.0" - } - }, - "strip-bom": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/strip-bom/-/strip-bom-2.0.0.tgz", - "integrity": "sha1-YhmoVhZSBJHzV4i9vxRHqZx+aw4=", - "requires": { - "is-utf8": "^0.2.0" - } - }, - "strip-hex-prefix": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/strip-hex-prefix/-/strip-hex-prefix-1.0.0.tgz", - "integrity": "sha1-DF8VX+8RUTczd96du1iNoFUA428=", - "requires": { - "is-hex-prefixed": "1.0.0" - } - }, - "supports-color": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-2.0.0.tgz", - "integrity": "sha1-U10EXOa2Nj+kARcIRimZXp3zJMc=" - }, - "tape": { - "version": "4.9.1", - "resolved": "https://registry.npmjs.org/tape/-/tape-4.9.1.tgz", - "integrity": "sha512-6fKIXknLpoe/Jp4rzHKFPpJUHDHDqn8jus99IfPnHIjyz78HYlefTGD3b5EkbQzuLfaEvmfPK3IolLgq2xT3kw==", - "requires": { - "deep-equal": "~1.0.1", - "defined": "~1.0.0", - "for-each": "~0.3.3", - "function-bind": "~1.1.1", - "glob": "~7.1.2", - "has": "~1.0.3", - "inherits": "~2.0.3", - "minimist": "~1.2.0", - "object-inspect": "~1.6.0", - "resolve": "~1.7.1", - "resumer": "~0.0.0", - "string.prototype.trim": "~1.1.2", - "through": "~2.3.8" - }, - "dependencies": { - "minimist": { - "version": "1.2.0", - "resolved": "http://registry.npmjs.org/minimist/-/minimist-1.2.0.tgz", - "integrity": "sha1-o1AIsg9BOD7sH7kU9M1d95omQoQ=" - } - } - }, - "through": { - "version": "2.3.8", - "resolved": "http://registry.npmjs.org/through/-/through-2.3.8.tgz", - "integrity": "sha1-DdTJ/6q8NXlgsbckEV1+Doai4fU=" - }, - "through2": { - "version": "2.0.5", - "resolved": "https://registry.npmjs.org/through2/-/through2-2.0.5.tgz", - "integrity": "sha512-/mrRod8xqpA+IHSLyGCQ2s8SPHiCDEeQJSep1jqLYeEUClOFG2Qsh+4FU6G9VeqpZnGW/Su8LQGc4YKni5rYSQ==", - "requires": { - "readable-stream": "~2.3.6", - "xtend": "~4.0.1" - } - }, - "to-fast-properties": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/to-fast-properties/-/to-fast-properties-1.0.3.tgz", - "integrity": "sha1-uDVx+k2MJbguIxsG46MFXeTKGkc=" - }, - "tough-cookie": { - "version": "2.4.3", - "resolved": "https://registry.npmjs.org/tough-cookie/-/tough-cookie-2.4.3.tgz", - "integrity": "sha512-Q5srk/4vDM54WJsJio3XNn6K2sCG+CQ8G5Wz6bZhRZoAe/+TxjWB/GlFAnYEbkYVlON9FMk/fE3h2RLpPXo4lQ==", - "requires": { - "psl": "^1.1.24", - "punycode": "^1.4.1" - }, - "dependencies": { - "punycode": { - "version": "1.4.1", - "resolved": "https://registry.npmjs.org/punycode/-/punycode-1.4.1.tgz", - "integrity": "sha1-wNWmOycYgArY4esPpSachN1BhF4=" - } - } - }, - "treeify": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/treeify/-/treeify-1.1.0.tgz", - "integrity": "sha512-1m4RA7xVAJrSGrrXGs0L3YTwyvBs2S8PbRHaLZAkFw7JR8oIFwYtysxlBZhYIa7xSyiYJKZ3iGrrk55cGA3i9A==" - }, - "trim": { - "version": "0.0.1", - "resolved": "https://registry.npmjs.org/trim/-/trim-0.0.1.tgz", - "integrity": "sha1-WFhUf2spB1fulczMZm+1AITEYN0=" - }, - "trim-right": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/trim-right/-/trim-right-1.0.1.tgz", - "integrity": "sha1-yy4SAwZ+DI3h9hQJS5/kVwTqYAM=" - }, - "truffle-hdwallet-provider": { - "version": "0.0.6", - "resolved": "https://registry.npmjs.org/truffle-hdwallet-provider/-/truffle-hdwallet-provider-0.0.6.tgz", - "integrity": "sha512-vh1nCk9+COz9Z1BnDYjrZEc8Z4KCWeoThAX6U13SpHMuSL7gX40ZDWszlVmovPLEwHSJBh/OaFmaduKfeXT9rA==", - "requires": { - "bip39": "^2.2.0", - "ethereumjs-wallet": "0.6.0", - "web3": "^0.18.2", - "web3-provider-engine": "^14.0.5" - } - }, - "tunnel-agent": { - "version": "0.6.0", - "resolved": "https://registry.npmjs.org/tunnel-agent/-/tunnel-agent-0.6.0.tgz", - "integrity": "sha1-J6XeoGs2sEoKmWZ3SykIaPD8QP0=", - "requires": { - "safe-buffer": "^5.0.1" - } - }, - "tweetnacl": { - "version": "0.14.5", - "resolved": "https://registry.npmjs.org/tweetnacl/-/tweetnacl-0.14.5.tgz", - "integrity": "sha1-WuaBd/GS1EViadEIr6k/+HQ/T2Q=" - }, - "typedarray": { - "version": "0.0.6", - "resolved": "https://registry.npmjs.org/typedarray/-/typedarray-0.0.6.tgz", - "integrity": "sha1-hnrHTjhkGHsdPUfZlqeOxciDB3c=" - }, - "unorm": { - "version": "1.4.1", - "resolved": "https://registry.npmjs.org/unorm/-/unorm-1.4.1.tgz", - "integrity": "sha1-NkIA1fE2RsqLzURJAnEzVhR5IwA=" - }, - "uri-js": { - "version": "4.2.2", - "resolved": "https://registry.npmjs.org/uri-js/-/uri-js-4.2.2.tgz", - "integrity": "sha512-KY9Frmirql91X2Qgjry0Wd4Y+YTdrdZheS8TFwvkbLWf/G5KNJDCh6pKL5OZctEW4+0Baa5idK2ZQuELRwPznQ==", - "requires": { - "punycode": "^2.1.0" - } - }, - "utf8": { - "version": "2.1.2", - "resolved": "http://registry.npmjs.org/utf8/-/utf8-2.1.2.tgz", - "integrity": "sha1-H6DZJw6b6FDZsFAn9jUZv0ZFfZY=" - }, - "util-deprecate": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/util-deprecate/-/util-deprecate-1.0.2.tgz", - "integrity": "sha1-RQ1Nyfpw3nMnYvvS1KKJgUGaDM8=" - }, - "uuid": { - "version": "2.0.3", - "resolved": "http://registry.npmjs.org/uuid/-/uuid-2.0.3.tgz", - "integrity": "sha1-Z+LoY3lyFVMN/zGOW/nc6/1Hsho=" - }, - "validate-npm-package-license": { - "version": "3.0.4", - "resolved": "https://registry.npmjs.org/validate-npm-package-license/-/validate-npm-package-license-3.0.4.tgz", - "integrity": "sha512-DpKm2Ui/xN7/HQKCtpZxoRWBhZ9Z0kqtygG8XCgNQ8ZlDnxuQmWhj566j8fN4Cu3/JmbhsDo7fcAJq4s9h27Ew==", - "requires": { - "spdx-correct": "^3.0.0", - "spdx-expression-parse": "^3.0.0" - } - }, - "verror": { - "version": "1.10.0", - "resolved": "https://registry.npmjs.org/verror/-/verror-1.10.0.tgz", - "integrity": "sha1-OhBcoXBTr1XW4nDB+CiGguGNpAA=", - "requires": { - "assert-plus": "^1.0.0", - "core-util-is": "1.0.2", - "extsprintf": "^1.2.0" - } - }, - "web3": { - "version": "0.18.4", - "resolved": "https://registry.npmjs.org/web3/-/web3-0.18.4.tgz", - "integrity": "sha1-gewXhBRUkfLqqJVbMcBgSeB8Xn0=", - "requires": { - "bignumber.js": "git+https://github.com/debris/bignumber.js.git#94d7146671b9719e00a09c29b01a691bc85048c2", - "crypto-js": "^3.1.4", - "utf8": "^2.1.1", - "xhr2": "*", - "xmlhttprequest": "*" - } - }, - "web3-provider-engine": { - "version": "14.1.0", - "resolved": "https://registry.npmjs.org/web3-provider-engine/-/web3-provider-engine-14.1.0.tgz", - "integrity": "sha512-vGZtqhSUzGTiMGhJXNnB/aRDlrPZLhLnBZ2NPArkZtr8XSrwg9m08tw4+PuWg5za0TJuoE/vuPQc501HddZZWw==", - "requires": { - "async": "^2.5.0", - "backoff": "^2.5.0", - "clone": "^2.0.0", - "cross-fetch": "^2.1.0", - "eth-block-tracker": "^3.0.0", - "eth-json-rpc-infura": "^3.1.0", - "eth-sig-util": "^1.4.2", - "ethereumjs-block": "^1.2.2", - "ethereumjs-tx": "^1.2.0", - "ethereumjs-util": "^5.1.5", - "ethereumjs-vm": "^2.3.4", - "json-rpc-error": "^2.0.0", - "json-stable-stringify": "^1.0.1", - "promise-to-callback": "^1.0.0", - "readable-stream": "^2.2.9", - "request": "^2.85.0", - "semaphore": "^1.0.3", - "ws": "^5.1.1", - "xhr": "^2.2.0", - "xtend": "^4.0.1" - }, - "dependencies": { - "ethereumjs-util": { - "version": "5.2.0", - "resolved": "https://registry.npmjs.org/ethereumjs-util/-/ethereumjs-util-5.2.0.tgz", - "integrity": "sha512-CJAKdI0wgMbQFLlLRtZKGcy/L6pzVRgelIZqRqNbuVFM3K9VEnyfbcvz0ncWMRNCe4kaHWjwRYQcYMucmwsnWA==", - "requires": { - "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" - } - } - } - }, - "whatwg-fetch": { - "version": "2.0.4", - "resolved": "http://registry.npmjs.org/whatwg-fetch/-/whatwg-fetch-2.0.4.tgz", - "integrity": "sha512-dcQ1GWpOD/eEQ97k66aiEVpNnapVj90/+R+SXTPYGHpYBBypfKJEQjLrvMZ7YXbKm21gXd4NcuxUTjiv1YtLng==" - }, - "which-module": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/which-module/-/which-module-1.0.0.tgz", - "integrity": "sha1-u6Y8qGGUiZT/MHc2CJ47lgJsKk8=" - }, - "window-size": { - "version": "0.2.0", - "resolved": "https://registry.npmjs.org/window-size/-/window-size-0.2.0.tgz", - "integrity": "sha1-tDFbtCFKPXBY6+7okuE/ok2YsHU=" - }, - "wrap-ansi": { - "version": "2.1.0", - "resolved": "http://registry.npmjs.org/wrap-ansi/-/wrap-ansi-2.1.0.tgz", - "integrity": "sha1-2Pw9KE3QV5T+hJc8rs3Rz4JP3YU=", - "requires": { - "string-width": "^1.0.1", - "strip-ansi": "^3.0.1" - } - }, - "wrappy": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/wrappy/-/wrappy-1.0.2.tgz", - "integrity": "sha1-tSQ9jz7BqjXxNkYFvA0QNuMKtp8=" - }, - "ws": { - "version": "5.2.2", - "resolved": "https://registry.npmjs.org/ws/-/ws-5.2.2.tgz", - "integrity": "sha512-jaHFD6PFv6UgoIVda6qZllptQsMlDEJkTQcybzzXDYM1XO9Y8em691FGMPmM46WGyLU4z9KMgQN+qrux/nhlHA==", - "requires": { - "async-limiter": "~1.0.0" - } - }, - "xhr": { - "version": "2.5.0", - "resolved": "https://registry.npmjs.org/xhr/-/xhr-2.5.0.tgz", - "integrity": "sha512-4nlO/14t3BNUZRXIXfXe+3N6w3s1KoxcJUUURctd64BLRe67E4gRwp4PjywtDY72fXpZ1y6Ch0VZQRY/gMPzzQ==", - "requires": { - "global": "~4.3.0", - "is-function": "^1.0.1", - "parse-headers": "^2.0.0", - "xtend": "^4.0.0" - } - }, - "xhr2": { - "version": "0.1.4", - "resolved": "https://registry.npmjs.org/xhr2/-/xhr2-0.1.4.tgz", - "integrity": "sha1-f4dliEdxbbUCYyOBL4GMras4el8=" - }, - "xmlhttprequest": { - "version": "1.8.0", - "resolved": "https://registry.npmjs.org/xmlhttprequest/-/xmlhttprequest-1.8.0.tgz", - "integrity": "sha1-Z/4HXFwk/vOfnWX197f+dRcZaPw=" - }, - "xtend": { - "version": "4.0.1", - "resolved": "https://registry.npmjs.org/xtend/-/xtend-4.0.1.tgz", - "integrity": "sha1-pcbVMr5lbiPbgg77lDofBJmNY68=" - }, - "y18n": { - "version": "3.2.1", - "resolved": "https://registry.npmjs.org/y18n/-/y18n-3.2.1.tgz", - "integrity": "sha1-bRX7qITAhnnA136I53WegR4H+kE=" - }, - "yargs": { - "version": "4.8.1", - "resolved": "http://registry.npmjs.org/yargs/-/yargs-4.8.1.tgz", - "integrity": "sha1-wMQpJMpKqmsObaFznfshZDn53cA=", - "requires": { - "cliui": "^3.2.0", - "decamelize": "^1.1.1", - "get-caller-file": "^1.0.1", - "lodash.assign": "^4.0.3", - "os-locale": "^1.4.0", - "read-pkg-up": "^1.0.1", - "require-directory": "^2.1.1", - "require-main-filename": "^1.0.1", - "set-blocking": "^2.0.0", - "string-width": "^1.0.1", - "which-module": "^1.0.0", - "window-size": "^0.2.0", - "y18n": "^3.2.1", - "yargs-parser": "^2.4.1" - } - }, - "yargs-parser": { - "version": "2.4.1", - "resolved": "http://registry.npmjs.org/yargs-parser/-/yargs-parser-2.4.1.tgz", - "integrity": "sha1-hVaN488VD/SfpRgl8DqMiA3cxcQ=", - "requires": { - "camelcase": "^3.0.0", - "lodash.assign": "^4.0.6" - } - } - } -} diff --git a/package.json b/package.json index e14b14e..afc9102 100644 --- a/package.json +++ b/package.json @@ -2,8 +2,19 @@ "name": "contracts", "version": "1.0.0", "dependencies": { - "ganache-cli": "^6.2.3", - "npm": "^6.4.1", - "truffle-hdwallet-provider": "0.0.6" + "@truffle/hdwallet-provider": "^1.0.42", + "assert": "^2.0.0", + "jsonpath": "^1.1.0", + "truffle-assertions": "^0.9.2" + }, + "devDependencies": { + "@openzeppelin/test-helpers": "^0.5.3", + "bl": ">=1.2.3", + "elliptic": ">=6.5.4", + "lodash": ">=4.17.21", + "minimist": ">=1.2.2", + "node-fetch": ">=2.6.1", + "path-parse": ">=1.0.7", + "yargs-parser": ">=13.1.2" } } diff --git a/scripts/README.md b/scripts/README.md new file mode 100644 index 0000000..2636960 --- /dev/null +++ b/scripts/README.md @@ -0,0 +1,11 @@ +### Compile +* `cd .. && npm install` +* `truffle compile --all` + +### Config +* Change `httpProvider` for supported chains. +* Change `MetaSource` for guardian node to check data changes and notify on-chain systems. + +### Execute +* `export PK=xxxxx` () +* `pm2 start guardian.js` diff --git a/scripts/config_bsctest.js b/scripts/config_bsctest.js new file mode 100644 index 0000000..a9884d0 --- /dev/null +++ b/scripts/config_bsctest.js @@ -0,0 +1,17 @@ +const deployed = require('../deployed.json'); +const stream = require('../build/contracts/Stream.json'); +const manager = require('../build/contracts/StreamsManager.json'); +const mega = require('../build/contracts/MegaStream.json'); + +module.exports = { + httpProvider: 'https://data-seed-prebsc-1-s1.binance.org:8545', + coingeckoMegaSource: 'https://api.coingecko.com/api/v3/simple/price?vs_currencies=usd&ids=binancecoin,bitcoin,dos-network,ethereum,filecoin,polkadot', + coingeckoMegaSelector: '$..usd', + coingeckoStreamsManagerAddr: deployed.bscTestnet.CoingeckoStreamsManager, + managerABI: manager.abi, + streamABI: stream.abi, + megaStreamABI: mega.abi, + triggerMaxGas: 800000, + gasPriceGwei: 10, // Gwei + heartbeat: 60 * 1000, // 60 seconds +}; diff --git a/scripts/config_heco.js b/scripts/config_heco.js new file mode 100644 index 0000000..6b089a7 --- /dev/null +++ b/scripts/config_heco.js @@ -0,0 +1,17 @@ +const deployed = require('../deployed.json'); +const stream = require('../build/contracts/Stream.json'); +const manager = require('../build/contracts/StreamsManager.json'); +const mega = require('../build/contracts/MegaStream.json'); + +module.exports = { + httpProvider: 'https://http-mainnet.hecochain.com', + coingeckoMegaSource: 'https://api.coingecko.com/api/v3/simple/price?vs_currencies=usd&ids=bitcoin,dos-network,ethereum,filecoin,huobi-pool-token,huobi-token,polkadot', + coingeckoMegaSelector: '$..usd', + coingeckoStreamsManagerAddr: deployed.heco.CoingeckoStreamsManager, + managerABI: manager.abi, + streamABI: stream.abi, + megaStreamABI: mega.abi, + triggerMaxGas: 800000, + gasPriceGwei: 1.01, // Gwei + heartbeat: 60 * 1000, // 60 seconds +}; diff --git a/scripts/config_hecotest.js b/scripts/config_hecotest.js new file mode 100644 index 0000000..aed3c9a --- /dev/null +++ b/scripts/config_hecotest.js @@ -0,0 +1,16 @@ +const deployed = require('../deployed.json'); +const stream = require('../build/contracts/Stream.json'); +const manager = require('../build/contracts/StreamsManager.json'); +const mega = require('../build/contracts/MegaStream.json'); + +module.exports = { + httpProvider: 'https://http-testnet.hecochain.com', + coingeckoMegaSource: 'https://api.coingecko.com/api/v3/simple/price?vs_currencies=usd&ids=bitcoin,dos-network,ethereum,huobi-token,polkadot', + coingeckoMegaSelector: '$..usd', + coingeckoStreamsManagerAddr: deployed.hecoTestnet.CoingeckoStreamsManager, + managerABI: manager.abi, + streamABI: stream.abi, + megaStreamABI: mega.abi, + triggerMaxGas: 800000, + heartbeat: 60 * 1000, // 60 seconds +}; diff --git a/scripts/guardian_bsc.js b/scripts/guardian_bsc.js new file mode 100644 index 0000000..7dc8f63 --- /dev/null +++ b/scripts/guardian_bsc.js @@ -0,0 +1,262 @@ +const assert = require('assert'); +const BN = require('bignumber.js'); +const fetch = require('node-fetch'); +const jp = require('jsonpath'); +const Web3 = require('web3'); +const config = require('./config_bsctest'); +const web3 = new Web3(new Web3.providers.HttpProvider(config.httpProvider)); +const privateKey = '0x' + process.env.PK; +// streams' state +const states = []; +var streamsManager = null; +var megaStream = null; +var errCnt = 0; + +async function init(debug) { + assert(privateKey.length == 66, + "Please export hex-formatted private key into env without leading '0x'"); + + streamsManager = new web3.eth.Contract(config.managerABI, config.coingeckoStreamsManagerAddr); + streamsManager.address = config.coingeckoStreamsManagerAddr; + let sortedStreams = await streamsManager.methods.sortedStreams().call(); + if (sortedStreams.length == 0) { + console.log('@@@@@@ No stream to watch, exit!'); + process.exit(1); + } + + let megaStreamAddr = await streamsManager.methods._streams(0).call(); + megaStream = new web3.eth.Contract(config.megaStreamABI, megaStreamAddr); + megaStream.address = megaStreamAddr; + megaStream.decimal = await megaStream.methods.decimal().call(); + + for (let i = 0; i < sortedStreams.length; i++) { + let stream = new web3.eth.Contract(config.streamABI, sortedStreams[i]); + stream.address = sortedStreams[i]; + let state = { + stream: stream, + source: await stream.methods.source().call(), + selector: await stream.methods.selector().call(), + windowSize: parseInt(await stream.methods.windowSize().call()), + deviation: parseInt(await stream.methods.deviation().call()), + decimal: parseInt(await stream.methods.decimal().call()), + lastUpdated: 0, + lastPrice: BN(0), + } + let len = parseInt(await stream.methods.numPoints().call()); + if (len > 0) { + let last = await stream.methods.latestResult().call(); + state.lastPrice = BN(last._lastPrice); + state.lastUpdated = parseInt(last._lastUpdatedTime); + } + states.push(state); + } + if (debug) console.log('+++++ streams inited ...'); +} + +async function sync() { + for (let i = 0; i < states.length; i++) { + states[i].deviation = parseInt(await states[i].stream.methods.deviation().call()); + let last = await states[i].stream.methods.latestResult().call(); + states[i].lastPrice = BN(last._lastPrice); + states[i].lastUpdated = parseInt(last._lastUpdatedTime); + } +} + +// Normalize selector string to equivalent format in case of special characters. +// e.g. '$.huobi-token.usd' => '$["huobi-token"]["usd"]' +function normalizeSelector(selector) { + if (selector.indexOf('-') == -1) return selector; + return selector + .split('.') + .map((val, i) => { + if (i == 0) return val; + return '[\"' + val + '\"]'; + }) + .join(''); +} + +// Sort response json by object keys. This is to normalize the jsonpath +// behavior between client software and this guardian bot. +function normalizeResponseJson(respJson) { + return Object.keys(respJson).sort().reduce(function (result, key) { + result[key] = respJson[key]; + return result; + }, {}); +} + +async function queryCoingeckoStreamsData(debug = false) { + let ret = []; + let resp = await fetch(config.coingeckoMegaSource); + let respJson = await resp.json(); + for (let i = 0; i < states.length; i++) { + let data = jp.value(respJson, normalizeSelector(states[i].selector)); + data = BN(data).times(BN(10).pow(states[i].decimal)); + ret.push(data); + if (debug) { + console.log(`+++++ coingecko ${states[i].selector}: ${data}`); + } + } + return ret; +} + +async function queryCoingeckoMegaData(megaDecimal) { + let resp = await fetch(config.coingeckoMegaSource); + let respJson = await resp.json(); + respJson = normalizeResponseJson(respJson); + let data = jp.query(respJson, config.coingeckoMegaSelector); + return data.map((val) => { + return BN(val).times(BN(10).pow(megaDecimal)) + }); +} + +// Returns true if Bignumber p1 is beyond the upper/lower threshold of Bignumber p0. +function deviated(p1, p0, threshold) { + if (threshold == 0) return false; + return p1.gt(BN(1000).plus(threshold).div(1000).times(p0)) || p1.lt(BN(1000).minus(threshold).div(1000).times(p0)); +} + +function sleep(ms) { + return new Promise((resolve, reject) => { + setTimeout(() => { + resolve(ms) + }, ms) + }) +} + +async function pullTriggerStream(state, debug) { + let callData = state.stream.methods.pullTrigger().encodeABI(); + // let estimatedGas = await state.stream.methods.pullTrigger().estimateGas({gas: config.triggerMaxGas}); + let txObj = await web3.eth.accounts.signTransaction({ + to: state.stream.address, + data: callData, + value: '0', + gas: config.triggerMaxGas + }, privateKey); + await web3.eth.sendSignedTransaction(txObj.rawTransaction) + .on('confirmation', function(confirmationNumber, receipt) { + // Fired for every confirmation up to the 12th confirmation (0-indexed). We treat 2 confirmations as finalized state. + if (confirmationNumber == 1) { + if (debug) { + console.log(`+++++ ${state.selector} tx ${receipt.transactionHash} 2 confirmations, gasUsed ${receipt.gasUsed}`); + } + } + }) + .on('error', function(err, receipt) { + if (debug) { + console.log(`@@@@@ Error (${errCnt}): tx ${receipt.transactionHash} error, gasUsed ${receipt.gasUsed}`); + } + if (++errCnt > 5) { + states = []; // re-Init + errCnt = 0; + } + }); +} + +async function pullTriggerMega(debug) { + let callData = megaStream.methods.pullTrigger().encodeABI(); + // let estimatedGas = await state.stream.methods.pullTrigger().estimateGas({gas: config.triggerMaxGas}); + let txObj = await web3.eth.accounts.signTransaction({ + to: megaStream.address, + data: callData, + value: '0', + gas: config.triggerMaxGas, + gasPrice: web3.utils.toWei(Number(config.gasPriceGwei).toString(), 'Gwei') + }, privateKey); + await web3.eth.sendSignedTransaction(txObj.rawTransaction) + .on('confirmation', function(confirmationNumber, receipt) { + // Fired for every confirmation up to the 12th confirmation (0-indexed). We treat 2 confirmations as finalized state. + if (confirmationNumber == 1) { + if (debug) { + console.log(`+++++ tx ${receipt.transactionHash} 2 confirmations, gasUsed ${receipt.gasUsed}`); + } + } + }) + .on('error', function(err, receipt) { + if (debug) { + console.log(`@@@@@ Error (${errCnt}): tx ${receipt.transactionHash} error, gasUsed ${receipt.gasUsed}`); + } + if (++errCnt > 5) { + states = []; // re-Init + errCnt = 0; + } + }); +} + +async function heartbeatStreams(debug = process.env.DEBUG) { + if (states.length == 0) { + await init(debug); + } else { + await sync(); + } + + let data = await queryCoingeckoStreamsData(); + for (let i = 0; i < states.length; i++) { + let now = parseInt((new Date()).getTime() / 1000); + let now_str = (new Date()).toTimeString().split(' ')[0]; + if (i == 0 && debug) console.log(`----- heartbeatStreams ${now_str} ...`); + let isDeviated = deviated(data[i], states[i].lastPrice, states[i].deviation); + let isExpired = now > states[i].lastUpdated + states[i].windowSize; + if (!isDeviated && !isExpired) { + continue; + } else if (isDeviated) { + console.log(`+++++ Stream ${states[i].selector} ${now_str} d(${data[i]}), beyond last data (${states[i].lastPrice}) ±${states[i].deviation / 1000}, Deviation trigger`); + } else if (isExpired) { + console.log(`+++++ Stream ${states[i].selector} ${now_str} d(${data[i]}), last data (${states[i].lastPrice}) outdated, Timer trigger`); + } + await pullTriggerStream(states[i], debug); + } + setTimeout(heartbeatStreams, config.heartbeat); +} + +async function heartbeatMega(debug = process.env.DEBUG) { + if (states.length == 0) { + await init(debug); + } else { + await sync(); + } + + let data = await queryCoingeckoMegaData(megaStream.decimal); + if (data.length != states.length) { + console.log('@@@@@ Mega data & Mega query / selector mismatch, exit!'); + process.exit(1); + } + + let trigger = false; + for (let i = 0; i < states.length; i++) { + let now = parseInt((new Date()).getTime() / 1000); + let now_str = (new Date()).toTimeString().split(' ')[0]; + if (i == 0 && debug) console.log(`----- heartbeatMega ${now_str} ...`); + let isDeviated = deviated(data[i], states[i].lastPrice, states[i].deviation); + let isExpired = now > states[i].lastUpdated + states[i].windowSize; + if (!isDeviated && !isExpired) { + continue; + } else if (isDeviated) { + console.log(`+++++ Mega Stream[${i}] ${states[i].selector} ${now_str} d(${data[i]}), beyond last data (${states[i].lastPrice}) ±${states[i].deviation / 1000}, Deviation trigger`); + trigger = true; + } else if (isExpired) { + console.log(`+++++ Mega Stream[${i}] ${states[i].selector} ${now_str} d(${data[i]}), last data (${states[i].lastPrice}) outdated, Timer trigger`); + trigger = true; + } + } + if (trigger) { + await pullTriggerMega(debug); + setTimeout(heartbeatMega, config.heartbeat); + } else { + setTimeout(heartbeatMega, config.heartbeat); + } +} + +function errorHandler(e) { + console.log(e); + let now = (new Date()).toTimeString().split(' ')[0]; + console.log(`@@@@@ Error caught on ${now}, preparing for a restart...`); + setTimeout(() => { + process.exit(1) + }, 3000) +} + +process.on('uncaughtException', errorHandler); +process.on('unhandledRejection', errorHandler); + + +heartbeatMega(); diff --git a/scripts/guardian_heco.js b/scripts/guardian_heco.js new file mode 100644 index 0000000..26e0e0c --- /dev/null +++ b/scripts/guardian_heco.js @@ -0,0 +1,262 @@ +const assert = require('assert'); +const BN = require('bignumber.js'); +const fetch = require('node-fetch'); +const jp = require('jsonpath'); +const Web3 = require('web3'); +const config = require('./config_heco'); +const web3 = new Web3(new Web3.providers.HttpProvider(config.httpProvider)); +const privateKey = '0x' + process.env.PK; +// streams' state +const states = []; +var streamsManager = null; +var megaStream = null; +var errCnt = 0; + +async function init(debug) { + assert(privateKey.length == 66, + "Please export hex-formatted private key into env without leading '0x'"); + + streamsManager = new web3.eth.Contract(config.managerABI, config.coingeckoStreamsManagerAddr); + streamsManager.address = config.coingeckoStreamsManagerAddr; + let sortedStreams = await streamsManager.methods.sortedStreams().call(); + if (sortedStreams.length == 0) { + console.log('@@@@@@ No stream to watch, exit!'); + process.exit(1); + } + + let megaStreamAddr = await streamsManager.methods._streams(0).call(); + megaStream = new web3.eth.Contract(config.megaStreamABI, megaStreamAddr); + megaStream.address = megaStreamAddr; + megaStream.decimal = await megaStream.methods.decimal().call(); + + for (let i = 0; i < sortedStreams.length; i++) { + let stream = new web3.eth.Contract(config.streamABI, sortedStreams[i]); + stream.address = sortedStreams[i]; + let state = { + stream: stream, + source: await stream.methods.source().call(), + selector: await stream.methods.selector().call(), + windowSize: parseInt(await stream.methods.windowSize().call()), + deviation: parseInt(await stream.methods.deviation().call()), + decimal: parseInt(await stream.methods.decimal().call()), + lastUpdated: 0, + lastPrice: BN(0), + } + let len = parseInt(await stream.methods.numPoints().call()); + if (len > 0) { + let last = await stream.methods.latestResult().call(); + state.lastPrice = BN(last._lastPrice); + state.lastUpdated = parseInt(last._lastUpdatedTime); + } + states.push(state); + } + if (debug) console.log('+++++ streams inited ...'); +} + +async function sync() { + for (let i = 0; i < states.length; i++) { + states[i].deviation = parseInt(await states[i].stream.methods.deviation().call()); + let last = await states[i].stream.methods.latestResult().call(); + states[i].lastPrice = BN(last._lastPrice); + states[i].lastUpdated = parseInt(last._lastUpdatedTime); + } +} + +// Normalize selector string to equivalent format in case of special characters. +// e.g. '$.huobi-token.usd' => '$["huobi-token"]["usd"]' +function normalizeSelector(selector) { + if (selector.indexOf('-') == -1) return selector; + return selector + .split('.') + .map((val, i) => { + if (i == 0) return val; + return '[\"' + val + '\"]'; + }) + .join(''); +} + +// Sort response json by object keys. This is to normalize the jsonpath +// behavior between client software and this guardian bot. +function normalizeResponseJson(respJson) { + return Object.keys(respJson).sort().reduce(function (result, key) { + result[key] = respJson[key]; + return result; + }, {}); +} + +async function queryCoingeckoStreamsData(debug = false) { + let ret = []; + let resp = await fetch(config.coingeckoMegaSource); + let respJson = await resp.json(); + for (let i = 0; i < states.length; i++) { + let data = jp.value(respJson, normalizeSelector(states[i].selector)); + data = BN(data).times(BN(10).pow(states[i].decimal)); + ret.push(data); + if (debug) { + console.log(`+++++ coingecko ${states[i].selector}: ${data}`); + } + } + return ret; +} + +async function queryCoingeckoMegaData(megaDecimal) { + let resp = await fetch(config.coingeckoMegaSource); + let respJson = await resp.json(); + respJson = normalizeResponseJson(respJson); + let data = jp.query(respJson, config.coingeckoMegaSelector); + return data.map((val) => { + return BN(val).times(BN(10).pow(megaDecimal)) + }); +} + +// Returns true if Bignumber p1 is beyond the upper/lower threshold of Bignumber p0. +function deviated(p1, p0, threshold) { + if (threshold == 0) return false; + return p1.gt(BN(1000).plus(threshold).div(1000).times(p0)) || p1.lt(BN(1000).minus(threshold).div(1000).times(p0)); +} + +function sleep(ms) { + return new Promise((resolve, reject) => { + setTimeout(() => { + resolve(ms) + }, ms) + }) +} + +async function pullTriggerStream(state, debug) { + let callData = state.stream.methods.pullTrigger().encodeABI(); + // let estimatedGas = await state.stream.methods.pullTrigger().estimateGas({gas: config.triggerMaxGas}); + let txObj = await web3.eth.accounts.signTransaction({ + to: state.stream.address, + data: callData, + value: '0', + gas: config.triggerMaxGas + }, privateKey); + await web3.eth.sendSignedTransaction(txObj.rawTransaction) + .on('confirmation', function(confirmationNumber, receipt) { + // Fired for every confirmation up to the 12th confirmation (0-indexed). We treat 2 confirmations as finalized state. + if (confirmationNumber == 1) { + if (debug) { + console.log(`+++++ ${state.selector} tx ${receipt.transactionHash} 2 confirmations, gasUsed ${receipt.gasUsed}`); + } + } + }) + .on('error', function(err, receipt) { + if (debug) { + console.log(`@@@@@ Error (${errCnt}): tx ${receipt.transactionHash} error, gasUsed ${receipt.gasUsed}`); + } + if (++errCnt > 5) { + states = []; // re-Init + errCnt = 0; + } + }); +} + +async function pullTriggerMega(debug) { + let callData = megaStream.methods.pullTrigger().encodeABI(); + // let estimatedGas = await state.stream.methods.pullTrigger().estimateGas({gas: config.triggerMaxGas}); + let txObj = await web3.eth.accounts.signTransaction({ + to: megaStream.address, + data: callData, + value: '0', + gas: config.triggerMaxGas, + gasPrice: web3.utils.toWei(Number(config.gasPriceGwei).toString(), 'Gwei') + }, privateKey); + await web3.eth.sendSignedTransaction(txObj.rawTransaction) + .on('confirmation', function(confirmationNumber, receipt) { + // Fired for every confirmation up to the 12th confirmation (0-indexed). We treat 2 confirmations as finalized state. + if (confirmationNumber == 1) { + if (debug) { + console.log(`+++++ tx ${receipt.transactionHash} 2 confirmations, gasUsed ${receipt.gasUsed}`); + } + } + }) + .on('error', function(err, receipt) { + if (debug) { + console.log(`@@@@@ Error (${errCnt}): tx ${receipt.transactionHash} error, gasUsed ${receipt.gasUsed}`); + } + if (++errCnt > 5) { + states = []; // re-Init + errCnt = 0; + } + }); +} + +async function heartbeatStreams(debug = process.env.DEBUG) { + if (states.length == 0) { + await init(debug); + } else { + await sync(); + } + + let data = await queryCoingeckoStreamsData(); + for (let i = 0; i < states.length; i++) { + let now = parseInt((new Date()).getTime() / 1000); + let now_str = (new Date()).toTimeString().split(' ')[0]; + if (i == 0 && debug) console.log(`----- heartbeatStreams ${now_str} ...`); + let isDeviated = deviated(data[i], states[i].lastPrice, states[i].deviation); + let isExpired = now > states[i].lastUpdated + states[i].windowSize; + if (!isDeviated && !isExpired) { + continue; + } else if (isDeviated) { + console.log(`+++++ Stream ${states[i].selector} ${now_str} d(${data[i]}), beyond last data (${states[i].lastPrice}) ±${states[i].deviation / 1000}, Deviation trigger`); + } else if (isExpired) { + console.log(`+++++ Stream ${states[i].selector} ${now_str} d(${data[i]}), last data (${states[i].lastPrice}) outdated, Timer trigger`); + } + await pullTriggerStream(states[i], debug); + } + setTimeout(heartbeatStreams, config.heartbeat); +} + +async function heartbeatMega(debug = process.env.DEBUG) { + if (states.length == 0) { + await init(debug); + } else { + await sync(); + } + + let data = await queryCoingeckoMegaData(megaStream.decimal); + if (data.length != states.length) { + console.log('@@@@@ Mega data & Mega query / selector mismatch, exit!'); + process.exit(1); + } + + let trigger = false; + for (let i = 0; i < states.length; i++) { + let now = parseInt((new Date()).getTime() / 1000); + let now_str = (new Date()).toTimeString().split(' ')[0]; + if (i == 0 && debug) console.log(`----- heartbeatMega ${now_str} ...`); + let isDeviated = deviated(data[i], states[i].lastPrice, states[i].deviation); + let isExpired = now > states[i].lastUpdated + states[i].windowSize; + if (!isDeviated && !isExpired) { + continue; + } else if (isDeviated) { + console.log(`+++++ Mega Stream[${i}] ${states[i].selector} ${now_str} d(${data[i]}), beyond last data (${states[i].lastPrice}) ±${states[i].deviation / 1000}, Deviation trigger`); + trigger = true; + } else if (isExpired) { + console.log(`+++++ Mega Stream[${i}] ${states[i].selector} ${now_str} d(${data[i]}), last data (${states[i].lastPrice}) outdated, Timer trigger`); + trigger = true; + } + } + if (trigger) { + await pullTriggerMega(debug); + setTimeout(heartbeatMega, config.heartbeat); + } else { + setTimeout(heartbeatMega, config.heartbeat); + } +} + +function errorHandler(e) { + console.log(e); + let now = (new Date()).toTimeString().split(' ')[0]; + console.log(`@@@@@ Error caught on ${now}, preparing for a restart...`); + setTimeout(() => { + process.exit(1) + }, 3000) +} + +process.on('uncaughtException', errorHandler); +process.on('unhandledRejection', errorHandler); + + +heartbeatMega(); diff --git a/test/bn256_test.js b/test/bn256_test.js index cf4195a..a9f4a67 100644 --- a/test/bn256_test.js +++ b/test/bn256_test.js @@ -58,10 +58,10 @@ contract("BN256 Test", async (accounts) => { // Generated secret key / public key pair. let SK = web3.utils.toBN('0x250ebf796264728de1dc24d208c4cec4f813b1bcc2bb647ac8cf66206568db03'); let PK = [ - web3.utils.toBN('0x25d7caf90ac28ba3cd8a96aff5c5bf004fc16d9bdcc2cead069e70f783397e5b'), - web3.utils.toBN('0x04ef63f195409b451179767b06673758e621d9db71a058231623d1cb2e594460'), - web3.utils.toBN('0x15729e3589dcb871cd46eb6774388aad867521dc07d1e0c0d9c99f444f93ca53'), - web3.utils.toBN('0x15db87d74b02df70d62f7f8afe5811ade35ca08bdb2308b4153624083fcf580e'), + web3.utils.toBN('0x25d7caf90ac28ba3cd8a96aff5c5bf004fc16d9bdcc2cead069e70f783397e5b'), + web3.utils.toBN('0x04ef63f195409b451179767b06673758e621d9db71a058231623d1cb2e594460'), + web3.utils.toBN('0x15729e3589dcb871cd46eb6774388aad867521dc07d1e0c0d9c99f444f93ca53'), + web3.utils.toBN('0x15db87d74b02df70d62f7f8afe5811ade35ca08bdb2308b4153624083fcf580e'), ]; let msg = web3.utils.asciiToHex("test random bytes"); @@ -73,5 +73,6 @@ contract("BN256 Test", async (accounts) => { let pass = await bn256.pairingCheck.call([sig_n, hashed_msg], [G2, PK]); assert(pass, "Pairing check e({HM, PublicKey}, {-Sig, G2}) should be true"); - }) + }); + }) diff --git a/test/dosproxy_test.js b/test/dosproxy_test.js new file mode 100644 index 0000000..9fe792a --- /dev/null +++ b/test/dosproxy_test.js @@ -0,0 +1,289 @@ +const DOSProxyMock = artifacts.require("DOSProxyMock"); +const truffleAssert = require('truffle-assertions'); +contract("DOSProxy Test", async accounts => { + it("test unregister node from pendingNodeList", async () => { + let dosproxy = await DOSProxyMock.new() + let tx = await dosproxy.registerNewNode({ from: accounts[0] }); + let tx2 = await dosproxy.registerNewNode({ from: accounts[1] }); + truffleAssert.eventEmitted(tx, 'LogRegisteredNewPendingNode', (ev) => { + return ev.node === accounts[0]; + }); + truffleAssert.eventEmitted(tx2, 'LogInsufficientPendingNode', (ev) => { + return ev.numPendingNodes.toNumber() === web3.utils.toBN(2).toNumber(); + }); + var node = await dosproxy.pendingNodeList.call(accounts[0]); + assert.equal(node, accounts[1], + "After register, account 0 should point to account 1"); + + let tx3 = await dosproxy.unregisterNode({ from: accounts[0] }); + var node = await dosproxy.pendingNodeList.call(accounts[0]); + assert.equal(node, 0, + "After register, account 0 should not be in the list"); + truffleAssert.eventEmitted(tx3, 'LogUnRegisteredNewPendingNode', (ev) => { + return ev.node === accounts[0]; + }); + }); + it("test unregister node from pendingGroup", () => { + let dosproxy; + let groupid1; + let groupid2; + let groupid3; + let group1Mem1; + let group1Mem2; + let group1Mem3; + let group2Mem1; + let group2Mem2; + let group2Mem3; + let group3Mem1; + let group3Mem2; + let group3Mem3; + let numPendingNodes + let numPendingGroups + let workingGroupIdsLength + let expiredWorkingGroupIdsLength + let tx + let tx2 + let tx3 + return DOSProxyMock.new() + .then(async (instance) => { + dosproxy = instance; + await dosproxy.registerNewNode({ from: accounts[0] }); + await dosproxy.registerNewNode({ from: accounts[1] }); + await dosproxy.registerNewNode({ from: accounts[2] }); + await dosproxy.registerNewNode({ from: accounts[3] }); + await dosproxy.registerNewNode({ from: accounts[4] }); + await dosproxy.registerNewNode({ from: accounts[5] }); + await dosproxy.registerNewNode({ from: accounts[6] }); + await dosproxy.registerNewNode({ from: accounts[7] }); + tx = await dosproxy.registerNewNode({ from: accounts[8] }); + await dosproxy.registerNewNode({ from: accounts[9] }); + + numPendingNodes = await dosproxy.numPendingNodes.call(); + numPendingGroups = await dosproxy.numPendingGroups.call(); + workingGroupIdsLength = await dosproxy.workingGroupIdsLength.call() + expiredWorkingGroupIdsLength = await dosproxy.expiredWorkingGroupIdsLength.call() + + truffleAssert.eventNotEmitted(tx, 'LogError'); + assert.equal(numPendingNodes.toNumber(), 10, + "After register, numPendingNodes should be 10"); + assert.equal(numPendingGroups.toNumber(), 0, + "After register, numPendingGroups should be 0"); + assert.equal(workingGroupIdsLength.toNumber(), 0, + "Before signalBootstrap, length of workingGroupIds should be 0"); + assert.equal(expiredWorkingGroupIdsLength.toNumber(), 0, + "Before signalBootstrap, length of expiredWorkingGroupIds should be 0"); + return numPendingNodes; + }) + .then(async (numPendingNodes) => { + tx = await dosproxy.signalBootstrap(1,{ from: accounts[0] }); + numPendingNodes = await dosproxy.numPendingNodes.call(); + numPendingGroups = await dosproxy.numPendingGroups.call(); + workingGroupIdsLength = await dosproxy.workingGroupIdsLength.call() + expiredWorkingGroupIdsLength = await dosproxy.expiredWorkingGroupIdsLength.call() + + assert.equal(numPendingNodes.toNumber(), 1, + "After signalBootstrap, numPendingNodes should be 1"); + assert.equal(numPendingGroups.toNumber(), 3, + "After signalBootstrap, numPendingGroups should be 3"); + assert.equal(workingGroupIdsLength.toNumber(), 0, + "After signalBootstrap, workingGroupIds length should be 0"); + assert.equal(expiredWorkingGroupIdsLength.toNumber(), 0, + "After signalBootstrap, length of expiredWorkingGroupIds should be 0"); + return tx; + }) + .then(async (res) => { + tx = await dosproxy.getPastEvents( 'LogGrouping', { fromBlock: 0, toBlock: 'latest' } ) + assert.equal(tx.length, 3, + "After signalBootstrap, length of LogGrouping should be 3"); + groupid1 = tx[0].returnValues.groupId; + group1Mem1 = tx[0].returnValues.nodeId[0]; + group1Mem2 = tx[0].returnValues.nodeId[1]; + group1Mem3 = tx[0].returnValues.nodeId[2]; + groupid2 = tx[1].returnValues.groupId; + group2Mem1 = tx[1].returnValues.nodeId[0]; + group2Mem2 = tx[1].returnValues.nodeId[1]; + group2Mem3 = tx[1].returnValues.nodeId[2]; + groupid3 = tx[2].returnValues.groupId; + group3Mem1 = tx[2].returnValues.nodeId[0]; + group3Mem2 = tx[2].returnValues.nodeId[1]; + group3Mem3 = tx[2].returnValues.nodeId[2]; + return tx; + }) + .then(async (res) => { + await dosproxy.unregisterNode({ from: group1Mem1 }); + let tx = await dosproxy.unregisterNode({ from: group2Mem2 }); + return tx + }) + .then(async (res) => { + numPendingNodes = await dosproxy.numPendingNodes.call(); + numPendingGroups = await dosproxy.numPendingGroups.call(); + workingGroupIdsLength = await dosproxy.workingGroupIdsLength.call() + expiredWorkingGroupIdsLength = await dosproxy.expiredWorkingGroupIdsLength.call() +// console.log("numPendingNodes : ",numPendingNodes.toNumber()) +// console.log("numPendingGroups : ",numPendingGroups.toNumber()) +// console.log("workingGroupIdsLength : ",workingGroupIdsLength.toNumber()) +// console.log("expiredWorkingGroupIdsLength : ",expiredWorkingGroupIdsLength.toNumber()) + }); + }); + it("test unregister node from workingGroup", () => { + let dosproxy; + let groupid1; + let groupid2; + let groupid3; + let group1Mem1; + let group1Mem2; + let group1Mem3; + let group2Mem1; + let group2Mem2; + let group2Mem3; + let group3Mem1; + let group3Mem2; + let group3Mem3; + let numPendingNodes + let numPendingGroups + let workingGroupIdsLength + let expiredWorkingGroupIdsLength + let tx + let tx2 + let tx3 + return DOSProxyMock.new() + .then(async (instance) => { + dosproxy = instance; + await dosproxy.registerNewNode({ from: accounts[0] }); + await dosproxy.registerNewNode({ from: accounts[1] }); + await dosproxy.registerNewNode({ from: accounts[2] }); + await dosproxy.registerNewNode({ from: accounts[3] }); + await dosproxy.registerNewNode({ from: accounts[4] }); + await dosproxy.registerNewNode({ from: accounts[5] }); + await dosproxy.registerNewNode({ from: accounts[6] }); + await dosproxy.registerNewNode({ from: accounts[7] }); + tx = await dosproxy.registerNewNode({ from: accounts[8] }); + await dosproxy.registerNewNode({ from: accounts[9] }); + + numPendingNodes = await dosproxy.numPendingNodes.call(); + numPendingGroups = await dosproxy.numPendingGroups.call(); + workingGroupIdsLength = await dosproxy.workingGroupIdsLength.call() + expiredWorkingGroupIdsLength = await dosproxy.expiredWorkingGroupIdsLength.call() + + truffleAssert.eventNotEmitted(tx, 'LogError'); + assert.equal(numPendingNodes.toNumber(), 10, + "After register, numPendingNodes should be 10"); + assert.equal(numPendingGroups.toNumber(), 0, + "After register, numPendingGroups should be 0"); + assert.equal(workingGroupIdsLength.toNumber(), 0, + "Before signalBootstrap, length of workingGroupIds should be 0"); + assert.equal(expiredWorkingGroupIdsLength.toNumber(), 0, + "Before signalBootstrap, length of expiredWorkingGroupIds should be 0"); + return numPendingNodes; + }) + .then(async (numPendingNodes) => { + tx = await dosproxy.signalBootstrap(1,{ from: accounts[0] }); + numPendingNodes = await dosproxy.numPendingNodes.call(); + numPendingGroups = await dosproxy.numPendingGroups.call(); + workingGroupIdsLength = await dosproxy.workingGroupIdsLength.call() + expiredWorkingGroupIdsLength = await dosproxy.expiredWorkingGroupIdsLength.call() + + assert.equal(numPendingNodes.toNumber(), 1, + "After signalBootstrap, numPendingNodes should be 1"); + assert.equal(numPendingGroups.toNumber(), 3, + "After signalBootstrap, numPendingGroups should be 3"); + assert.equal(workingGroupIdsLength.toNumber(), 0, + "After signalBootstrap, workingGroupIds length should be 0"); + assert.equal(expiredWorkingGroupIdsLength.toNumber(), 0, + "After signalBootstrap, length of expiredWorkingGroupIds should be 0"); + return tx; + }) + .then(async (res) => { + tx = await dosproxy.getPastEvents( 'LogGrouping', { fromBlock: 0, toBlock: 'latest' } ) + assert.equal(tx.length, 3, + "After signalBootstrap, length of LogGrouping should be 3"); + groupid1 = tx[0].returnValues.groupId; + group1Mem1 = tx[0].returnValues.nodeId[0]; + group1Mem2 = tx[0].returnValues.nodeId[1]; + group1Mem3 = tx[0].returnValues.nodeId[2]; + groupid2 = tx[1].returnValues.groupId; + group2Mem1 = tx[1].returnValues.nodeId[0]; + group2Mem2 = tx[1].returnValues.nodeId[1]; + group2Mem3 = tx[1].returnValues.nodeId[2]; + groupid3 = tx[2].returnValues.groupId; + group3Mem1 = tx[2].returnValues.nodeId[0]; + group3Mem2 = tx[2].returnValues.nodeId[1]; + group3Mem3 = tx[2].returnValues.nodeId[2]; + return tx; + }) + .then(async (res) => { + var gpubKey1 = []; + for(var i=0;i<4;i++){ + gpubKey1.push(web3.utils.toBN(1)); + } + await dosproxy.registerGroupPubKey(groupid1,gpubKey1,{ from: group1Mem1 }) + tx = await dosproxy.registerGroupPubKey(groupid1,gpubKey1,{ from: group1Mem2 }) + + var gpubKey2 = []; + for(var i=0;i<4;i++){ + gpubKey2.push(web3.utils.toBN(2)); + } + await dosproxy.registerGroupPubKey(groupid2,gpubKey2,{ from: group2Mem2 }) + tx2 = await dosproxy.registerGroupPubKey(groupid2,gpubKey2,{ from: group2Mem2 }) + + var gpubKey3 = []; + for(var i=0;i<4;i++){ + gpubKey3.push(web3.utils.toBN(3)); + } + await dosproxy.registerGroupPubKey(groupid3,gpubKey3,{ from: group3Mem1 }) + tx3 = await dosproxy.registerGroupPubKey(groupid3,gpubKey3,{ from: group3Mem2 }) + + return tx3; + }) + .then(async (tx3) => { + numPendingNodes = await dosproxy.numPendingNodes.call(); + numPendingGroups = await dosproxy.numPendingGroups.call(); + workingGroupIdsLength = await dosproxy.workingGroupIdsLength.call() + expiredWorkingGroupIdsLength = await dosproxy.expiredWorkingGroupIdsLength.call() + assert.equal(numPendingNodes.toNumber(), 1, + "After registerGroupPubKey, numPendingNodes should be 1"); + assert.equal(numPendingGroups.toNumber(), 0, + "After registerGroupPubKey, numPendingGroups should be 0"); + assert.equal(workingGroupIdsLength.toNumber(), 3, + "After registerGroupPubKey, length of workingGroupIds should be 3"); + assert.equal(expiredWorkingGroupIdsLength.toNumber(), 0, + "After registerGroupPubKey, length of expiredWorkingGroupIds should be 0"); + + truffleAssert.eventNotEmitted(tx, 'LogError'); + truffleAssert.eventEmitted(tx, 'LogPublicKeyAccepted', (ev) => { + return ev.numWorkingGroups.toNumber() === 1; + }); + truffleAssert.eventEmitted(tx2, 'LogPublicKeyAccepted', (ev) => { + return ev.numWorkingGroups.toNumber() === 2; + }); + truffleAssert.eventEmitted(tx3, 'LogPublicKeyAccepted', (ev) => { + return ev.numWorkingGroups.toNumber() === 3; + }); + + return tx3; + }) + .then(async (res) => { + await dosproxy.unregisterNode({ from: accounts[0] }); + await dosproxy.unregisterNode({ from: accounts[1] }); + await dosproxy.unregisterNode({ from: accounts[2] }); + await dosproxy.unregisterNode({ from: accounts[3] }); + await dosproxy.unregisterNode({ from: accounts[4] }); + await dosproxy.unregisterNode({ from: accounts[5] }); + await dosproxy.unregisterNode({ from: accounts[6] }); + await dosproxy.unregisterNode({ from: accounts[7] }); + await dosproxy.unregisterNode({ from: accounts[8] }); + let tx = await dosproxy.unregisterNode({ from: accounts[9] }); + return tx + }) + .then(async (res) => { + numPendingNodes = await dosproxy.numPendingNodes.call(); + numPendingGroups = await dosproxy.numPendingGroups.call(); + workingGroupIdsLength = await dosproxy.workingGroupIdsLength.call() + expiredWorkingGroupIdsLength = await dosproxy.expiredWorkingGroupIdsLength.call() +// console.log("numPendingNodes : ",numPendingNodes.toNumber()) +// console.log("numPendingGroups : ",numPendingGroups.toNumber()) +// console.log("workingGroupIdsLength : ",workingGroupIdsLength.toNumber()) +// console.log("expiredWorkingGroupIdsLength : ",expiredWorkingGroupIdsLength.toNumber()) + }); + }); +}) diff --git a/test/staking_test.js b/test/staking_test.js new file mode 100644 index 0000000..524f649 --- /dev/null +++ b/test/staking_test.js @@ -0,0 +1,895 @@ +var Staking = artifacts.require("Staking"); +var Bridge = artifacts.require("DOSAddressBridge"); +var Ttk = artifacts.require("TestToken"); +const truffleAssert = require("truffle-assertions"); +const { + BN, + time, + constants, + balance, + expectEvent, + expectRevert +} = require("@openzeppelin/test-helpers"); +const BigNumber = require('bignumber.js'); +const maxAllowance = ((new BigNumber(2)).pow(256).minus(1)).toString(10); + +contract("Staking", async accounts => { + it("test totalStakedTokens", async () => { + let stakedTokenPerNode = 1000000; + let proxyAddr = accounts[11]; + let stakingRewardsVault = accounts[0]; + let tokenPool = accounts[0]; + let nodeStakingAddr = accounts[1]; + let nodeAddr = accounts[1]; + + let ttk = await Ttk.new(); + let bridge = await Bridge.new(); + await bridge.setProxyAddress(proxyAddr); + let staking = await Staking.new( + ttk.address, + ttk.address, + stakingRewardsVault, + bridge.address + ); + await ttk.approve(staking.address, maxAllowance, { from: stakingRewardsVault }); + + let decimals = web3.utils.toBN(18); + let amount = web3.utils.toBN(stakedTokenPerNode); + let value = amount.mul(web3.utils.toBN(10).pow(decimals)); + + await ttk.transfer(nodeStakingAddr, value, { from: tokenPool }); + await ttk.approve(staking.address, maxAllowance, { from: nodeStakingAddr }); + await staking.newNode(nodeAddr, value, 0, 10, "test", "", { + from: nodeStakingAddr + }); + let apr = await staking.getCurrentAPR(); + assert.equal(apr, 8000, "After 1 year, delegator balance should be 8000 "); + + let total = await staking.totalStakedTokens.call(); + assert.equal( + total.toString(), + value, + "totalStakedTokens should be equal"); + + await staking.nodeStart(nodeAddr, { + from: proxyAddr + }); + + total = await staking.totalStakedTokens.call(); + assert.equal( + total.toString(), + value, + "totalStakedTokens should be equal" + ); + + let advancement = 86400 * 1; // 1 Days + await time.increase(advancement); + + await staking.nodeStop(nodeAddr, { + from: proxyAddr + }); + total = await staking.totalStakedTokens.call(); + assert.equal( + total.toString(), + value, + "totalStakedTokens should be equal"); + + await staking.nodeStart(nodeAddr, { + from: proxyAddr + }); + total = await staking.totalStakedTokens.call(); + assert.equal( + total.toString(), + value, + "totalStakedTokens should be equal" + ); + await staking.nodeUnregister(nodeAddr, { + from: nodeStakingAddr + }); + await staking.nodeStart(nodeAddr, { + from: proxyAddr + }); + total = await staking.totalStakedTokens.call(); + assert.equal(total.toString(), 0, "totalStakedTokens should be 0 "); + }); + + it("test newNode - node has no enough balance", async () => { + let ttk = await Ttk.new(); + let bridge = await Bridge.new(); + bridge.setProxyAddress(accounts[0]); + let staking = await Staking.new( + ttk.address, + ttk.address, + ttk.address, + bridge.address + ); + + await ttk.transfer(accounts[1], 30000, { from: accounts[0] }); + let balance = await ttk.balanceOf(accounts[1]); + assert.equal(balance.valueOf(), 30000); + ttk.approve(staking.address, maxAllowance, { from: accounts[1] }); + try { + let tx = await staking.newNode(accounts[1], 50000, 0, 1, "test", "", { + from: accounts[1] + }); + assert.fail(true, false, "The function should throw error"); + } catch (err) { + assert.include(String(err), "revert", ""); + } + }); + + + it("test newNode - node should only be registered once", async () => { + let stakedTokenPerNode = 1000000; + let proxyAddr = accounts[11]; + let stakingRewardsVault = accounts[0]; + let tokenPool = accounts[0]; + let nodeStakingAddr = accounts[1]; + let nodeAddr = accounts[1]; + + let ttk = await Ttk.new(); + let bridge = await Bridge.new(); + await bridge.setProxyAddress(proxyAddr); + let staking = await Staking.new( + ttk.address, + ttk.address, + stakingRewardsVault, + bridge.address + ); + await ttk.approve(staking.address, maxAllowance, { from: stakingRewardsVault }); + + let decimals = web3.utils.toBN(18); + let amount = web3.utils.toBN(stakedTokenPerNode); + let value = amount.mul(web3.utils.toBN(10).pow(decimals)); + + await ttk.transfer(nodeStakingAddr, value, { from: tokenPool }); + await ttk.approve(staking.address, maxAllowance, { from: nodeStakingAddr }); + await ttk.transfer(accounts[2], value, { from: tokenPool }); + await ttk.approve(staking.address, maxAllowance, { from: accounts[2] }); + + await staking.newNode(nodeAddr, value, 0, 10, "test", "", { + from: nodeStakingAddr + }); + + try { + await staking.newNode(nodeAddr, value, 0, 10, "test", "", { + from: accounts[2] + }); + assert.fail(true, false, "The function should throw error"); + } catch (err) { + assert.include(String(err), "revert", ""); + } + }); + + + it("test unregister-newNode - node should be able to register after unregister", async () => { + let stakedTokenPerNode = 1000000; + let proxyAddr = accounts[11]; + let stakingRewardsVault = accounts[0]; + let tokenPool = accounts[0]; + let nodeStakingAddr = accounts[1]; + let nodeAddr = accounts[1]; + + let ttk = await Ttk.new(); + let bridge = await Bridge.new(); + await bridge.setProxyAddress(proxyAddr); + let staking = await Staking.new( + ttk.address, + ttk.address, + stakingRewardsVault, + bridge.address + ); + await ttk.approve(staking.address, maxAllowance, { from: stakingRewardsVault }); + + let decimals = web3.utils.toBN(18); + let amount = web3.utils.toBN(stakedTokenPerNode); + let value = amount.mul(web3.utils.toBN(10).pow(decimals)); + + await ttk.transfer(nodeStakingAddr, value, { from: tokenPool }); + await ttk.approve(staking.address, maxAllowance, { from: nodeStakingAddr }); + await ttk.transfer(accounts[2], value, { from: tokenPool }); + await ttk.approve(staking.address, maxAllowance, { from: accounts[2] }); + + await staking.newNode(nodeAddr, value, 0, 10, "test", "", { + from: nodeStakingAddr + }); + let nodeAddrs = await staking.getNodeAddrs(); + assert.equal( + nodeAddrs.length, + 1, + "After newNode, length of nodeAddrs should be 1 " + ); + await staking.nodeUnregister(nodeAddr, { + from: nodeStakingAddr + }); + let advancement = 86400 * 7; // 1 Days + await time.increase(advancement); + await staking.nodeWithdraw(nodeAddr, { + from: nodeStakingAddr + }); + nodeAddrs = await staking.getNodeAddrs(); + assert.equal( + nodeAddrs.length, + 0, + "After nodeWithdraw, length of nodeAddrs should be 0 " + ); + await staking.newNode(nodeAddr, value, 0, 10, "test", "", { + from: nodeStakingAddr + }); + }); + + + it("test updateNodeStaking", async () => { + let stakedTokenPerNode = 1000000; + let proxyAddr = accounts[11]; + let stakingRewardsVault = accounts[0]; + let tokenPool = accounts[0]; + let nodeStakingAddr = accounts[1]; + let nodeAddr = accounts[1]; + + let ttk = await Ttk.new(); + let bridge = await Bridge.new(); + await bridge.setProxyAddress(proxyAddr); + let staking = await Staking.new( + ttk.address, + ttk.address, + stakingRewardsVault, + bridge.address + ); + await ttk.approve(staking.address, maxAllowance, { from: stakingRewardsVault }); + + let decimals = web3.utils.toBN(18); + let amount = web3.utils.toBN(stakedTokenPerNode); + let value = amount.mul(web3.utils.toBN(10).pow(decimals)); + + await ttk.transfer(nodeStakingAddr, value, { from: tokenPool }); + await ttk.approve(staking.address, maxAllowance, { from: nodeStakingAddr }); + await staking.newNode(nodeAddr, value, 0, 10, "test", "", { + from: nodeStakingAddr + }); + let apr = await staking.getCurrentAPR(); + assert.equal(apr, 8000, "After 1 year, apr should be 80.00%"); + + for (var i = 1; i <= 9; i++) { + await ttk.transfer(nodeStakingAddr, value, { from: tokenPool }); + await staking.updateNodeStaking(nodeAddr, value, 0, 10, 'new-desc', "", { + from: nodeStakingAddr + }); + } + let total = await staking.totalStakedTokens.call(); + assert.equal( + total.toString(), + web3.utils.toBN(value).mul(web3.utils.toBN(10)), + "totalStakedTokens should be equal"); + + await staking.nodeStart(nodeAddr, { + from: proxyAddr + }); + total = await staking.totalStakedTokens.call(); + assert.equal( + total.toString(), + web3.utils.toBN(value).mul(web3.utils.toBN(10)), + "totalStakedTokens should be equal" + ); + }); + + + it("test uptime", async () => { + let stakedTokenPerNode = 1000000; + let proxyAddr = accounts[14]; + let stakingRewardsVault = accounts[0]; + let tokenPool = accounts[0]; + + let ttk = await Ttk.new(); + let bridge = await Bridge.new(); + await bridge.setProxyAddress(proxyAddr); + let staking = await Staking.new( + ttk.address, + ttk.address, + stakingRewardsVault, + bridge.address + ); + await ttk.approve(staking.address, maxAllowance, { from: stakingRewardsVault }); + + let decimals = web3.utils.toBN(18); + let amount = web3.utils.toBN(stakedTokenPerNode); + let value = amount.mul(web3.utils.toBN(10).pow(decimals)); + + await ttk.transfer(accounts[1], value, { from: tokenPool }); + await ttk.approve(staking.address, maxAllowance, { from: accounts[1] }); + await staking.newNode(accounts[1], value, 0, 1, "test", "", { + from: accounts[1] + }); + await staking.nodeStart(accounts[1], { from: proxyAddr }); + + let advancement = 86400 * 1; // 1 Days + await time.increase(advancement); + await staking.nodeStop(accounts[1], { from: proxyAddr }); + advancement = 86400 * 1; // 1 Days + await time.increase(advancement); + let node = await staking.nodes.call(accounts[1]); + let uptime = await staking.getNodeUptime(accounts[1]); + assert.equal( + Math.round(uptime.toNumber() / (60 * 60 * 24)), + 0, + "After 1 day up then 1 day down, uptime should be 0 day" + ); + }); + + + it("test nodeClaimReward", async () => { + let stakedTokenPerNode = 1000000; + let circulatingSupply = 263900000; + let proxyAddr = accounts[14]; + let stakingRewardsVault = accounts[0]; + let tokenPool = accounts[0]; + let nodes = 13; + + let ttk = await Ttk.new(); + let bridge = await Bridge.new(); + await bridge.setProxyAddress(proxyAddr); + let staking = await Staking.new( + ttk.address, + ttk.address, + stakingRewardsVault, + bridge.address + ); + await ttk.approve(staking.address, maxAllowance, { from: stakingRewardsVault }); + + let decimals = web3.utils.toBN(18); + let amount = web3.utils.toBN(stakedTokenPerNode); + let value = amount.mul(web3.utils.toBN(10).pow(decimals)); + + let SupplyAmount = web3.utils.toBN(circulatingSupply); + let SupplyValue = SupplyAmount.mul(web3.utils.toBN(10).pow(decimals)); + await staking.setCirculatingSupply(SupplyValue, { + from: accounts[0] + }); + + for (var i = 1; i <= nodes; i++) { + await ttk.transfer(accounts[i], value, { from: tokenPool }); + await ttk.approve(staking.address, maxAllowance, { from: accounts[i] }); + await staking.newNode(accounts[i], value, 0, 1, "test", "", { + from: accounts[i] + }); + } + for (var i = 1; i <= nodes; i++) { + await staking.nodeStart(accounts[i], { + from: proxyAddr + }); + } + let apr = await staking.getCurrentAPR(); + assert.equal(apr.toNumber(), 8000, "APR should be 8000 "); + let advancement = 86400 * 365; // 365 Days + await time.increase(advancement); + for (var i = 1; i <= nodes; i++) { + await staking.nodeClaimReward(accounts[i], { from: accounts[i] }); + let balance = await ttk.balanceOf(accounts[i]); + let nodeBalance = Math.round(balance.valueOf() / 1e18); + assert.equal( + nodeBalance, + "800000", + "After 1 year, nodeBalance should be 1000000 * 0.8 " + ); + } + }); + + + it("test nodeClaimReward - node only runs 73 days during a year", async () => { + let stakedTokenPerNode = 1000000; + let circulatingSupply = 263900000; + let proxyAddr = accounts[14]; + let stakingRewardsVault = accounts[0]; + let tokenPool = accounts[0]; + let nodes = 13; + + let ttk = await Ttk.new(); + let bridge = await Bridge.new(); + await bridge.setProxyAddress(proxyAddr); + let staking = await Staking.new( + ttk.address, + ttk.address, + stakingRewardsVault, + bridge.address + ); + await ttk.approve(staking.address, maxAllowance, { from: stakingRewardsVault }); + + let decimals = web3.utils.toBN(18); + let amount = web3.utils.toBN(stakedTokenPerNode); + let value = amount.mul(web3.utils.toBN(10).pow(decimals)); + let SupplyAmount = web3.utils.toBN(circulatingSupply); + let SupplyValue = SupplyAmount.mul(web3.utils.toBN(10).pow(decimals)); + await staking.setCirculatingSupply(SupplyValue, { + from: accounts[0] + }); + + let apr = await staking.getCurrentAPR(); + assert.equal(apr.toNumber(), 8000, "APR should be 8000 "); + + for (var i = 1; i <= nodes; i++) { + await ttk.transfer(accounts[i], value, { from: tokenPool }); + await ttk.approve(staking.address, maxAllowance, { from: accounts[i] }); + let tx = await staking.newNode(accounts[i], value, 0, 1, "test", "", { + from: accounts[i] + }); + } + + for (var i = 1; i <= nodes; i++) { + await staking.nodeStart(accounts[i], { + from: proxyAddr + }); + } + let advancement = 86400 * 20; // 20 Days + await time.increase(advancement); + + for (var i = 1; i <= nodes; i++) { + await staking.nodeStop(accounts[i], { + from: proxyAddr + }); + } + advancement = 86400 * 100; // 100 Days + await time.increase(advancement); + + for (var i = 1; i <= nodes; i++) { + await staking.nodeStart(accounts[i], { + from: proxyAddr + }); + } + advancement = 86400 * 53; // 53 Days + await time.increase(advancement); + + for (var i = 1; i <= nodes; i++) { + await staking.nodeStop(accounts[i], { + from: proxyAddr + }); + } + advancement = 86400 * 192; // 1 Days + await time.increase(advancement); + + totalReward = 0; + for (var i = 1; i <= nodes; i++) { + await staking.nodeClaimReward(accounts[i], { from: accounts[i] }); + let balance = await ttk.balanceOf(accounts[i]); + let nodeBalance = Math.round(balance.valueOf() / 1e18); + assert.equal( + nodeBalance, + 160000, + "After 1 year, nodeBalance should be 1000000 * 0.8 / (365 / 73) " + ); + } + }); + + + it("test withdrawable", async () => { + let stakedTokenPerNode = 1000000; + let circulatingSupply = 263900000; + let proxyAddr = accounts[11]; + let stakingRewardsVault = accounts[0]; + let tokenPool = accounts[0]; + let nodeStakingAddr = accounts[1]; + let nodeAddr = accounts[1]; + let delegater = 8; + + let ttk = await Ttk.new(); + let bridge = await Bridge.new(); + await bridge.setProxyAddress(proxyAddr); + let staking = await Staking.new( + ttk.address, + ttk.address, + stakingRewardsVault, + bridge.address + ); + await ttk.approve(staking.address, maxAllowance, { from: stakingRewardsVault }); + + let decimals = web3.utils.toBN(18); + let amount = web3.utils.toBN(stakedTokenPerNode * 2); + let value = amount.mul(web3.utils.toBN(10).pow(decimals)); + let SupplyAmount = web3.utils.toBN(circulatingSupply); + let SupplyValue = SupplyAmount.mul(web3.utils.toBN(10).pow(decimals)); + await staking.setCirculatingSupply(SupplyValue, { + from: accounts[0] + }); + + await ttk.transfer(nodeStakingAddr, value, { from: tokenPool }); + await ttk.approve(staking.address, maxAllowance, { from: nodeStakingAddr }); + await staking.newNode(nodeAddr, value, 0, 10, "test", "", { + from: nodeStakingAddr + }); + + await staking.nodeStart(nodeAddr, { + from: proxyAddr + }); + + amount = web3.utils.toBN(stakedTokenPerNode); + value = amount.mul(web3.utils.toBN(10).pow(decimals)); + for (var i = 1; i <= delegater; i++) { + let idx = i + 1; + await ttk.transfer(accounts[idx], value, { from: tokenPool }); + await ttk.approve(staking.address, maxAllowance, { from: accounts[idx] }); + let tx = await staking.delegate(value, nodeAddr, { + from: accounts[idx] + }); + } + + let unboundAmount = web3.utils.toBN(stakedTokenPerNode / 2); + let unboundValue = unboundAmount.mul(web3.utils.toBN(10).pow(decimals)); + await staking.nodeUnbond(unboundValue, 0, nodeAddr, { + from: nodeStakingAddr + }); + for (var i = 1; i <= delegater; i++) { + let idx = i + 1; + await staking.delegatorUnbond(unboundValue, nodeAddr, { + from: accounts[idx] + }); + } + + let advancement = 86400 * 3; // 3 Days + await time.increase(advancement); + + for (var i = 1; i <= delegater; i++) { + let idx = i + 1; + await staking.delegatorUnbond(unboundValue, nodeAddr, { + from: accounts[idx] + }); + let wei = await staking.delegatorWithdrawable(accounts[idx], nodeAddr, { + from: accounts[idx] + }); + let withdrawableAmount = Math.round(wei.valueOf() / 1e18); + assert.equal( + withdrawableAmount, + 0, + "After 3 days, delegator withdrawable should be 0 " + ); + } + advancement = 86400 * 4; // 4 Days + await time.increase(advancement); + let wei = await staking.nodeWithdrawable(nodeStakingAddr, nodeAddr, { + from: nodeStakingAddr + }); + let withdrawableAmount = Math.round(wei[0].valueOf() / 1e18); + assert.equal( + withdrawableAmount, + stakedTokenPerNode / 2, + "After 7 days, node withdrawable should be 50000 " + ); + for (var i = 1; i <= delegater; i++) { + let idx = i + 1; + let wei = await staking.delegatorWithdrawable(accounts[idx], nodeAddr, { + from: accounts[idx] + }); + let withdrawableAmount = Math.round(wei.valueOf() / 1e18); + assert.equal( + withdrawableAmount, + stakedTokenPerNode / 2, + "After 7 days, delegator withdrawable should be 50000 " + ); + } + advancement = 86400 * 3; // 3 Days + await time.increase(advancement); + + for (var i = 1; i <= delegater; i++) { + let idx = i + 1; + let wei = await staking.delegatorWithdrawable(accounts[idx], nodeAddr, { + from: accounts[idx] + }); + let withdrawableAmount = Math.round(wei.valueOf() / 1e18); + assert.equal( + withdrawableAmount, + stakedTokenPerNode, + "After 10 days, delegator withdrawable should be 50000 " + ); + } + }); + + + it("test delegatorClaimReward", async () => { + let stakedTokenPerNode = 1000000; + let circulatingSupply = 263900000; + + let proxyAddr = accounts[11]; + let stakingRewardsVault = accounts[0]; + let tokenPool = accounts[0]; + let nodeStakingAddr = accounts[1]; + let nodeAddr = accounts[1]; + let delegater = 9; + + let ttk = await Ttk.new(); + let bridge = await Bridge.new(); + await bridge.setProxyAddress(proxyAddr); + let staking = await Staking.new( + ttk.address, + ttk.address, + stakingRewardsVault, + bridge.address + ); + await ttk.approve(staking.address, maxAllowance, { from: stakingRewardsVault }); + + let decimals = web3.utils.toBN(18); + let amount = web3.utils.toBN(stakedTokenPerNode); + let value = amount.mul(web3.utils.toBN(10).pow(decimals)); + let SupplyAmount = web3.utils.toBN(circulatingSupply); + let SupplyValue = SupplyAmount.mul(web3.utils.toBN(10).pow(decimals)); + await staking.setCirculatingSupply(SupplyValue, { + from: accounts[0] + }); + await ttk.transfer(nodeStakingAddr, value, { from: tokenPool }); + await ttk.approve(staking.address, maxAllowance, { from: nodeStakingAddr }); + await staking.newNode(nodeAddr, value, 0, 10, "test", "", { + from: nodeStakingAddr + }); + + await staking.nodeStart(nodeAddr, { + from: proxyAddr + }); + + for (var i = 1; i <= delegater; i++) { + let idx = i + 1; + await ttk.transfer(accounts[idx], value, { from: tokenPool }); + await ttk.approve(staking.address, maxAllowance, { from: accounts[idx] }); + let tx = await staking.delegate(value, nodeAddr, { + from: accounts[idx] + }); + truffleAssert.eventEmitted(tx, "Delegate", ev => { + return ev.from === accounts[idx] && ev.to === nodeAddr; + }); + } + + let apr = await staking.getCurrentAPR(); + let advancement = 86400 * 365; // 365 Days + await time.increase(advancement); + + await staking.nodeClaimReward(nodeAddr, { from: nodeStakingAddr }); + let balance = await ttk.balanceOf(nodeStakingAddr); + nodeBalance = Math.round(balance.valueOf() / 1e18); + assert.equal( + nodeBalance, + 1520000, + "After 1 year, node balance should be 1520000" + ); + let delegatorBalance = 0; + for (var i = 1; i <= delegater; i++) { + let idx = i + 1; + await staking.delegatorClaimReward(nodeAddr, { + from: accounts[idx] + }); + let balance = await ttk.balanceOf(accounts[idx]); + delegatorBalance = Math.round(balance.valueOf() / 1e18); + assert.equal( + delegatorBalance, + 720000, + "After 1 year, delegator balance should be 720000" + ); + } + const options = { + filter: { from: accounts[2] }, + fromBlock: 0, + toBlock: "latest" + }; + + const eventList = await staking.getPastEvents("Delegate", options); + assert.equal(eventList.length, 1, ""); + }); + + + it("test delegatorClaimReward - node only runs 73 days during a year", async () => { + let stakedTokenPerNode = 1000000; + let circulatingSupply = 263900000; + + let proxyAddr = accounts[11]; + let stakingRewardsVault = accounts[0]; + let tokenPool = accounts[0]; + let nodeStakingAddr = accounts[1]; + let nodeAddr = accounts[1]; + let delegater = 9; + + let ttk = await Ttk.new(); + let bridge = await Bridge.new(); + await bridge.setProxyAddress(proxyAddr); + let staking = await Staking.new( + ttk.address, + ttk.address, + stakingRewardsVault, + bridge.address + ); + await ttk.approve(staking.address, maxAllowance, { from: stakingRewardsVault }); + + let decimals = web3.utils.toBN(18); + let amount = web3.utils.toBN(stakedTokenPerNode); + let value = amount.mul(web3.utils.toBN(10).pow(decimals)); + let SupplyAmount = web3.utils.toBN(circulatingSupply); + let SupplyValue = SupplyAmount.mul(web3.utils.toBN(10).pow(decimals)); + await staking.setCirculatingSupply(SupplyValue, { + from: accounts[0] + }); + await ttk.transfer(nodeStakingAddr, value, { from: tokenPool }); + await ttk.approve(staking.address, maxAllowance, { from: nodeStakingAddr }); + await staking.newNode(nodeAddr, value, 0, 10, "test", "", { + from: nodeStakingAddr + }); + + for (var i = 1; i <= delegater; i++) { + let idx = i + 1; + await ttk.transfer(accounts[idx], value, { from: tokenPool }); + await ttk.approve(staking.address, maxAllowance, { from: accounts[idx] }); + let tx = await staking.delegate(value, nodeAddr, { + from: accounts[idx] + }); + } + let apr = await staking.getCurrentAPR(); + + await staking.nodeStart(nodeAddr, { + from: proxyAddr + }); + let advancement = 86400 * 20; // 365 Days + await time.increase(advancement); + + await staking.nodeStop(nodeAddr, { + from: proxyAddr + }); + advancement = 86400 * 100; // 365 Days + await time.increase(advancement); + + await staking.nodeStart(nodeAddr, { + from: proxyAddr + }); + advancement = 86400 * 53; // 365 Days + await time.increase(advancement); + + await staking.nodeStop(nodeAddr, { + from: proxyAddr + }); + advancement = 86400 * 192; // 365 Days + await time.increase(advancement); + + await staking.nodeClaimReward(nodeAddr, { from: nodeStakingAddr }); + let balance = await ttk.balanceOf(nodeStakingAddr); + nodeBalance = Math.round(balance.valueOf() / 1e18); + assert.equal( + nodeBalance, + 304000, + "After 1 year, node balance should be 304000" + ); + let delegatorBalance = 0; + for (var i = 1; i <= delegater; i++) { + let idx = i + 1; + await staking.delegatorClaimReward(nodeAddr, { + from: accounts[idx] + }); + let balance = await ttk.balanceOf(accounts[idx]); + delegatorBalance = Math.round(balance.valueOf() / 1e18); + assert.equal( + delegatorBalance, + 144000, + "After 1 year, delegator balance should be 144000" + ); + } + }); + + + it("test nodeUnregister - node only runs 73 days during a year", async () => { + let stakedTokenPerNode = 1000000; + let circulatingSupply = 263900000; + + let proxyAddr = accounts[11]; + let stakingRewardsVault = accounts[0]; + let tokenPool = accounts[0]; + let nodeStakingAddr = accounts[1]; + let nodeAddr = accounts[1]; + let delegater = 9; + + let ttk = await Ttk.new(); + let bridge = await Bridge.new(); + await bridge.setProxyAddress(proxyAddr); + let staking = await Staking.new( + ttk.address, + ttk.address, + stakingRewardsVault, + bridge.address + ); + await ttk.approve(staking.address, maxAllowance, { from: stakingRewardsVault }); + + let decimals = web3.utils.toBN(18); + let amount = web3.utils.toBN(stakedTokenPerNode); + let value = amount.mul(web3.utils.toBN(10).pow(decimals)); + let SupplyAmount = web3.utils.toBN(circulatingSupply); + let SupplyValue = SupplyAmount.mul(web3.utils.toBN(10).pow(decimals)); + await staking.setCirculatingSupply(SupplyValue, { + from: accounts[0] + }); + await ttk.transfer(nodeStakingAddr, value, { from: tokenPool }); + await ttk.approve(staking.address, maxAllowance, { from: nodeStakingAddr }); + await staking.newNode(nodeAddr, value, 0, 10, "test", "", { + from: nodeStakingAddr + }); + let nodeAddrs = await staking.getNodeAddrs(); + assert.equal( + nodeAddrs.length, + 1, + "After newNode, length of nodeAddrs should be 1 " + ); + + for (var i = 1; i <= delegater; i++) { + let idx = i + 1; + await ttk.transfer(accounts[idx], value, { from: tokenPool }); + await ttk.approve(staking.address, maxAllowance, { from: accounts[idx] }); + await staking.delegate(value, nodeAddr, { + from: accounts[idx] + }); + } + + let apr = await staking.getCurrentAPR(); + await staking.nodeStart(nodeAddr, { + from: proxyAddr + }); + + let advancement = 86400 * 73; // 365 Days + await time.increase(advancement); + await staking.nodeUnregister(nodeAddr, { + from: nodeStakingAddr + }); + + advancement = 86400 * 100; // 365 Days + await time.increase(advancement); + + for (var i = 1; i <= delegater; i++) { + let idx = i + 1; + await staking.delegatorUnbond(value, nodeAddr, { + from: accounts[idx] + }); + } + + dvancement = 86400 * 7; // 365 Days + await time.increase(advancement); + + let delegatorBalance = 0; + for (var i = 1; i <= delegater; i++) { + let idx = i + 1; + + await staking.delegatorClaimReward(nodeAddr, { + from: accounts[idx] + }); + let balance = await ttk.balanceOf(accounts[idx]); + delegatorBalance = Math.round(balance.valueOf() / 1e18); + assert.equal( + delegatorBalance, + 144000, + "After 1 year, delegator balance should be 144000" + ); + + await staking.delegatorWithdraw(nodeAddr, { + from: accounts[idx] + }); + balance = await ttk.balanceOf(accounts[idx]); + delegatorBalance = Math.round(balance.valueOf() / 1e18); + assert.equal( + delegatorBalance, + 1144000, + "After 1 year, delegator balance should be 1144000" + ); + } + + await staking.nodeClaimReward(nodeAddr, { from: nodeStakingAddr }); + let balance = await ttk.balanceOf(nodeStakingAddr); + nodeBalance = Math.round(balance.valueOf() / 1e18); + assert.equal( + nodeBalance, + 304000, + "After 1 year, node balance should be 304000" + ); + await staking.nodeWithdraw(nodeAddr, { from: nodeStakingAddr }); + balance = await ttk.balanceOf(nodeStakingAddr); + nodeBalance = Math.round(balance.valueOf() / 1e18); + assert.equal( + nodeBalance, + 1304000, + "After 1 year, node balance should be 1304000" + ); + nodeAddrs = await staking.getNodeAddrs(); + assert.equal( + nodeAddrs.length, + 0, + "After unregister, length of nodeAddrs should be 0 " + ); + }); + +}); diff --git a/test/utils_test.js b/test/stringutils_test.js similarity index 61% rename from test/utils_test.js rename to test/stringutils_test.js index 0491c8f..38a8618 100644 --- a/test/utils_test.js +++ b/test/stringutils_test.js @@ -1,27 +1,27 @@ -const UtilsMock = artifacts.require("UtilsMock"); +const StringUtilsMock = artifacts.require("StringUtilsMock"); -contract("Utils test", async() => { - let utils; +contract("StringUtils test", async() => { + let stringUtils; before(async() => { - utils = await UtilsMock.new(); + stringUtils = await StringUtilsMock.new(); }) it("Test transfer byte to uint", async() => { - let num = await utils.createByte.call(); + let num = await stringUtils.createByte.call(); let numOverflow = web3.utils.toHex('A'); - let result = await utils.byte2Uint.call(num); - let resultOverflow = await utils.byte2Uint.call(numOverflow); + let result = await stringUtils.byte2Uint.call(num); + let resultOverflow = await stringUtils.byte2Uint.call(numOverflow); assert.equal(result, 6, "transfer byte to uint"); assert.equal(resultOverflow, 10, "transfer overflow"); - }) + }) it("Test transfer hexByte to uint", async() => { - let num = await utils.createByte.call(); + let num = await stringUtils.createByte.call(); let char = web3.utils.toHex('F'); let charOverflow = web3.utils.toHex('G'); - let result = await utils.byte2Uint.call(num); - let charResult = await utils.hexByte2Uint.call(char); - let charResultOverflow = await utils.hexByte2Uint.call(charOverflow); + let result = await stringUtils.byte2Uint.call(num); + let charResult = await stringUtils.hexByte2Uint.call(char); + let charResultOverflow = await stringUtils.hexByte2Uint.call(charOverflow); assert.equal(result, 6, "transfer hex byte to uint"); assert.equal(charResult, 15, "transfer hexByte to uint"); assert.equal(charResultOverflow, 16, "transfer hexByte to uint"); @@ -31,27 +31,27 @@ contract("Utils test", async() => { let stringDecimal = "846686978"; let stringChar = "678Aaaa"; let stringOverflow ="11579208923731619542357098500868790785326998466564056403945758400791312963993555555"; - let stringDecimalResult = await utils.str2Uint.call(stringDecimal); - let stringCharResult = await utils.str2Uint.call(stringChar); - let stringDecimalOverflow = await utils.str2Uint.call(stringOverflow); - const UINT256MAX = await utils.returnUINT256MAX.call(); + let stringDecimalResult = await stringUtils.str2Uint.call(stringDecimal); + let stringCharResult = await stringUtils.str2Uint.call(stringChar); + let stringDecimalOverflow = await stringUtils.str2Uint.call(stringOverflow); + const UINT256MAX = await stringUtils.returnUINT256MAX.call(); assert.equal(stringDecimalResult, 846686978, "transfer a decimal string to uint" ); assert.equal(stringCharResult, 678,"transefer a char string to uint"); assert.equal(stringDecimalOverflow.toString(10), UINT256MAX.toString(10), "Overflow:transfer a decimal string to uint"); }) it("Test hexStr to uint", async() => { - const UINT256MAX = await utils.returnUINT256MAX.call(); + const UINT256MAX = await stringUtils.returnUINT256MAX.call(); let hexString0 = "d19Ab"; let hexString1 = "0xd19Ab"; let hexString2 = "0Xd19Ab"; let hexStringInvalid = "0x"; let hexStringOverflow = "0x11579208923A73161b9542357098500d86879078534545455454545454544545554444adadaadadaddad"; - let hexStringResult0 = await utils.hexStr2Uint.call(hexString0); - let hexStringResult1 = await utils.hexStr2Uint.call(hexString1); - let hexStringResult2 = await utils.hexStr2Uint.call(hexString2); - let hexStringInvalidResult = await utils.hexStr2Uint.call(hexStringInvalid); - let hexStringResultOverflow = await utils.hexStr2Uint.call(hexStringOverflow); + let hexStringResult0 = await stringUtils.hexStr2Uint.call(hexString0); + let hexStringResult1 = await stringUtils.hexStr2Uint.call(hexString1); + let hexStringResult2 = await stringUtils.hexStr2Uint.call(hexString2); + let hexStringInvalidResult = await stringUtils.hexStr2Uint.call(hexStringInvalid); + let hexStringResultOverflow = await stringUtils.hexStr2Uint.call(hexStringOverflow); assert.equal(hexStringResult0,858539,"transfer a hex string to uint"); assert.equal(hexStringResult1,858539,"transfer a hex string to uint"); assert.equal(hexStringResult2,858539,"transfer a hex string to uint"); @@ -61,21 +61,21 @@ contract("Utils test", async() => { it("Test 20-byte hex string to address", async() => { let hexString = "0x0e7ad63d2a305a7b9f46541c386aafbd2af6b263"; - let hexStringResult = await utils.str2Addr.call(hexString); + let hexStringResult = await stringUtils.str2Addr.call(hexString); assert.equal(hexStringResult, 0x0e7ad63d2a305a7b9f46541c386aafbd2af6b263, "transfer 20-byte hex string to uint"); }) it("Test address to string", async() => { let hexAddr = "0x0e7ad63d2a305a7b9f46541c386aafbd2af6b263"; - let hexAddrResult = await utils.addr2Str.call(hexAddr); + let hexAddrResult = await stringUtils.addr2Str.call(hexAddr); assert.equal(hexAddrResult, "0x0e7ad63d2a305a7b9f46541c386aafbd2af6b263", "transfer address to string"); }) it("Test uint to hex string", async() => { let uintZero = 0; let uintValid = 12; - let uintZeroResult = await utils.uint2HexStr.call(uintZero); - let uintValidResult = await utils.uint2HexStr.call(uintValid); + let uintZeroResult = await stringUtils.uint2HexStr.call(uintZero); + let uintValidResult = await stringUtils.uint2HexStr.call(uintValid); assert.equal(uintZeroResult, 0, "transfer uint to hex string"); assert.equal(uintValidResult, 'C', "transfer uint to hex string"); }) @@ -83,8 +83,8 @@ contract("Utils test", async() => { it("Test uint to string", async() => { let uintZero = 0; let uintValid = 12; - let uintZeroResult = await utils.uint2Str.call(uintZero); - let uintValidResult = await utils.uint2Str.call(uintValid); + let uintZeroResult = await stringUtils.uint2Str.call(uintZero); + let uintValidResult = await stringUtils.uint2Str.call(uintValid); assert.equal(uintZeroResult, "0", "transfer uint to hex string"); assert.equal(uintValidResult, "12", "transfer uint to hex string"); }) @@ -92,21 +92,21 @@ contract("Utils test", async() => { it("Test strConcat and byteConcat", async() => { let aa = "Hello "; let bb = "world!"; - let result = await utils.strConcat.call(aa, bb); + let result = await stringUtils.strConcat.call(aa, bb); assert.equal(result, "Hello world!", "string concat"); }) it("Test strCompare and byteCompare", async() => { let aa = "abd"; let bb = "abcde"; - let result = await utils.strCompare.call(aa,bb); + let result = await stringUtils.strCompare.call(aa,bb); assert.equal(result,1,"string compare"); }) it("Test strEqual and byteEqual", async() => { let aa = "dosnetwork"; let bb = "dosnetwork"; - let result = await utils.strEqual.call(aa,bb); + let result = await stringUtils.strEqual.call(aa,bb); assert.equal(result,true,"string equal"); }) @@ -119,13 +119,13 @@ contract("Utils test", async() => { let needle2 = "1234"; let haystack3 = "123.45"; let needle3 = "."; - let result0 = await utils.indexOf(haystack0,needle0); - let result1 = await utils.indexOf(haystack1,needle1); - let result2 = await utils.indexOf(haystack2,needle2); - let result3 = await utils.indexOf(haystack3,needle3); + let result0 = await stringUtils.indexOf(haystack0,needle0); + let result1 = await stringUtils.indexOf(haystack1,needle1); + let result2 = await stringUtils.indexOf(haystack2,needle2); + let result3 = await stringUtils.indexOf(haystack3,needle3); assert.equal(result0,0,"get index"); - assert.equal(result1,-1,"get index"); - assert.equal(result2,-1,"get index"); + assert.equal(result1,haystack1.length,"get index"); + assert.equal(result2,haystack2.length,"get index"); assert.equal(result3,3,"get index"); }) @@ -133,13 +133,13 @@ contract("Utils test", async() => { let a = "1234567890"; let start = 2; let len = 5; - let result = await utils.subStr.call(a, start, len); + let result = await stringUtils.subStr.call(a, start, len); assert.equal(result, "34567", "get substring"); }) it("Test subStr(string,uint) and subStr(bytes,uint)", async() => { let num = "123.4567"; - let result = await utils.subStr1.call(num, 4); + let result = await stringUtils.subStr1.call(num, 4); assert.equal(result, "4567", "get substring"); }) }) diff --git a/truffle-config.js b/truffle-config.js new file mode 100644 index 0000000..60234a7 --- /dev/null +++ b/truffle-config.js @@ -0,0 +1,76 @@ +const HDWalletProvider = require("@truffle/hdwallet-provider"); +const assert = require('assert'); +const infura_token = "8e609c76fce442f8a1735fbea9999747"; +const mainnetInfura = `https://mainnet.infura.io/v3/${infura_token}`; +const rinkebyInfura = `https://rinkeby.infura.io/v3/${infura_token}`; +const okchainTest = 'https://exchaintest.okexcn.com'; +const hecoTestnet = 'https://http-testnet.hecochain.com'; +const heco = 'https://http-mainnet.hecochain.com'; +const bscTestnet = 'https://data-seed-prebsc-1-s2.binance.org:8545/'; +const bsc = 'https://bsc-dataseed.binance.org/'; +const pk = process.env.PK; + +module.exports = { + networks: { + development: { + host: "localhost", + port: 8545, + network_id: "*" // Match any network id + }, + rinkeby: { + provider: () => new HDWalletProvider(pk, rinkebyInfura), + network_id: 4, + gas: 8000000 + }, + okchainTest: { + provider: () => new HDWalletProvider(pk, okchainTest), + network_id: 65, + gas: 8000000, + gasPrice: 1e9 // 1 Gwei + }, + hecoTestnet: { + provider: () => new HDWalletProvider(pk, hecoTestnet), + network_id: 256, + gas: 8000000, + gasPrice: 1e9 // 1 Gwei + }, + heco: { + provider: () => new HDWalletProvider(pk, heco), + network_id: 128, + gas: 8000000, + gasPrice: 2e9 // 2 Gwei + }, + bscTestnet: { + provider: () => new HDWalletProvider(pk, bscTestnet), + networkCheckTimeout: 100000, + timeoutBlocks: 2000, + network_id: 97, + gas: 8000000, + gasPrice: 10e9 // 10 Gwei + }, + bsc: { + provider: () => new HDWalletProvider(pk, bsc), + networkCheckTimeout: 100000, + timeoutBlocks: 2000, + network_id: 56, + gas: 8000000, + gasPrice: 6e9 // 6 Gwei + }, + live: { + provider: () => new HDWalletProvider(pk, mainetInfura), + network_id: 1, + gas: 8000000 + }, + }, + compilers: { + solc: { + version: "0.5.17", + settings: { + optimizer: { + enabled: true, + runs: 200 + }, + } + } + } +}; diff --git a/truffle.js b/truffle.js deleted file mode 100644 index a3cf981..0000000 --- a/truffle.js +++ /dev/null @@ -1,31 +0,0 @@ -var HDWalletProvider = require("truffle-hdwallet-provider"); -var infura_token = "8e609c76fce442f8a1735fbea9999747"; - -// Replace with valid mnemonic -var mnemonic = "aaa bbb ccc ddd eee fff ggg hhh iii jjj kkk lll"; - -module.exports = { - networks: { - development: { - host: "localhost", - port: 8545, - network_id: "*" // Match any network id - }, - ropsten: { - provider: new HDWalletProvider(mnemonic, "https://ropsten.infura.io/v3/" + infura_token), - network_id: 3, - gas: 8000000 - }, - rinkeby: { - provider: new HDWalletProvider(mnemonic, "https://rinkeby.infura.io/v3/" + infura_token), - network_id: 4, - gas: 8000000 // Gas limit used for deploys, choose block gas limit - }, - }, - solc: { - optimizer: { - enabled: true, - runs: 200 - } - } -};