diff --git a/.gitignore b/.gitignore index 3caaf89..9751894 100644 --- a/.gitignore +++ b/.gitignore @@ -9,3 +9,7 @@ scTopics deploy*.log tmp* _solDist +_distEns +.DS_Store +yarn-error.log +db diff --git a/.travis.yml b/.travis.yml index 30b064e..9250748 100644 --- a/.travis.yml +++ b/.travis.yml @@ -5,11 +5,16 @@ cache: yarn: true directories: - "node_modules" -sudo: enabled + - "build" + - "db" +sudo: required before_install: - sudo add-apt-repository -y ppa:ethereum/ethereum - sudo apt-get update - sudo apt-get install -y solc +before_script: + - mkdir -p db + - yarn reset-test script: - yarn test after_script: diff --git a/README.md b/README.md index a8f13af..3652dcf 100644 --- a/README.md +++ b/README.md @@ -66,3 +66,10 @@ You'll need to interact with the paymentSettings SC used by the democIndex (this **Problems installing dependencies** (2018-06-04) had some problems installing dependencies of `sha3` and `scrypt` libs after upgrading `yarn` via `brew` (because it installed node). resetting `nvm` via `nvm install 8 && nvm alias default 8` fixed. + + +## License Stuff + +### https://github.com/aragon/aragonOS - GPL 3 + +* scripts/manage-nodes.sh and associated package.json scripts, modified geth startup wait time diff --git a/contracts/BBFarmAux2.sol b/contracts/BBFarmAux2.sol new file mode 100644 index 0000000..a81cf22 --- /dev/null +++ b/contracts/BBFarmAux2.sol @@ -0,0 +1,81 @@ +pragma solidity 0.4.24; + +interface IndexInterface { + function getBBFarm(uint8) external view returns (BBFarmInterface); + function getBBFarmID(bytes4) external view returns (uint8); + function getBackend() external view returns (BackendInterface); +} + +interface BackendInterface { + function getDBallotID(bytes32, uint) external view returns (uint256); +} + +interface BBFarmInterface { + function getDetails(uint, address) external view returns + ( bool hasVoted + , uint nVotesCast + , bytes32 secKey + , uint16 submissionBits + , uint64 startTime + , uint64 endTime + , bytes32 specHash + , bool deprecated + , address ballotOwner + , bytes16 extraData + ); +} + + +contract BBFarmAux2 { + function _ballotIdToNamespace(uint ballotId) internal pure returns (bytes4) { + return bytes4(ballotId >> 224); + } + + function getBBFarmAddressFromBallotId(IndexInterface ix, uint256 ballotId) internal view returns (address) { + return ix.getBBFarm(ix.getBBFarmID(_ballotIdToNamespace(ballotId))); + } + + function getBallotId(BackendInterface ixBackend, bytes32 democHash, uint ballotN) internal view returns (uint ballotId) { + ballotId = ixBackend.getDBallotID(democHash, ballotN); + } + + function getBBFarmAddressAndBallotId( + IndexInterface ix, + bytes32 democHash, + uint ballotN + ) external view returns (address bbFarmAddress, uint256 ballotId) { + ballotId = getBallotId(ix.getBackend(), democHash, ballotN); + bbFarmAddress = getBBFarmAddressFromBallotId(ix, ballotId); + } + + function getBallotDetails(BBFarmInterface bbFarm, uint ballotId, address voterAddress) external view returns + ( bool hasVoted + , uint nVotesCast + , bytes32 secKey + , uint16 submissionBits + , uint64 startTime + , uint64 endTime + , bytes32 specHash + , bool deprecated + , address ballotOwner + , bytes16 extraData + ) + { + return bbFarm.getDetails(ballotId, voterAddress); + } + + function ballotIdToDetails(IndexInterface ix, uint ballotId) external view returns + ( uint nVotesCast + , bytes32 secKey + , uint16 submissionBits + , uint64 startTime + , uint64 endTime + , bytes32 specHash + , bool deprecated + ) + { + BBFarmInterface bbFarm = ix.getBBFarm(ix.getBBFarmID(_ballotIdToNamespace(ballotId))); + (, nVotesCast, secKey, submissionBits, startTime, endTime, specHash, deprecated,,) = bbFarm.getDetails(ballotId, address(0)); + } + +} diff --git a/contracts/Ed25519Delegation.sol b/contracts/Ed25519Delegation.sol new file mode 100644 index 0000000..a67e406 --- /dev/null +++ b/contracts/Ed25519Delegation.sol @@ -0,0 +1,110 @@ +pragma solidity 0.4.24; + +import {MemArrApp as M} from "../libs/MemArrApp.sol"; + +contract UnsafeEd25519SelfDelegation { + + event DelegationCreated(bytes32 dlgtRequest, bytes32 pubKey, bytes32[2] signature); + + struct Delegation { + bytes32 dlgtRequest; + bytes32 sig1; + bytes32 sig2; + uint recordedTs; + } + + // Maps a public key to delegation + // We need a list here because we can't validate delegations on-chain, + // so we store all delegaitons such that we can find the most recent valid delegation + mapping (bytes32 => Delegation[]) public delegations; + // allows us to loop through all pubkeys for which delegations have been made + bytes32[] public delegationsLog; + + // Log addresses ppl are delegating _to_ + mapping (address => bool) public seenAddress; + // allows us to loop through all eth addresses which have been made delegates + // (note: based on unverified delegations) + address[] public addressLog; + + // Log delegation requests we haven't seen before - prevent replay attacks + mapping (bytes32 => bool) public dlgtReqsSeen; + + // Constructor + constructor() public {} + + // Adding a delegation - the single write operation in this contract + function addUntrustedSelfDelegation(bytes32 dlgtRequest, bytes32 pubKey, bytes32[2] signature) external { + // note: dlgtRequest is split into 9, 3, and 20 bytes; the former is a unique tag to ensure signatures from + // ED25519 keys can't be reused for transactions or other networks, the 3 bytes are used as a nonce, and + // the final 20 bytes is the ethereum address we're delegating too. + + // take first 9 bytes of dlgtRequest + require(bytes9(dlgtRequest) == bytes9(0x53562d45442d455448), "dlgtReq header != SV-ED-ETH"); + + // // make sure we haven't seen this delegation request before with this pubkey and sig + bytes32 dlgtReqAllHash = keccak256(abi.encodePacked(dlgtRequest, pubKey, signature[0], signature[1])); + require(dlgtReqsSeen[dlgtReqAllHash] == false, "replay"); + dlgtReqsSeen[dlgtReqAllHash] = true; + + // log the pubkey if we haven't seen it before + if (delegations[pubKey].length == 0) + delegationsLog.push(pubKey); + + delegations[pubKey].push(Delegation(dlgtRequest, signature[0], signature[1], now)); + emit DelegationCreated(dlgtRequest, pubKey, signature); + + // take last 20 bytes and convert to address + address dlgtTo = address(uint160(dlgtRequest)); + + if (!seenAddress[dlgtTo]) { + seenAddress[dlgtTo] = true; + addressLog.push(dlgtTo); + } + } + + // Simple getters for list lengths + function dLogN() external view returns (uint) { + return delegationsLog.length; + } + + function nDelegations(bytes32 pubKey) external view returns (uint) { + return delegations[pubKey].length; + } + + function nAddressLog() external view returns (uint) { + return addressLog.length; + } + + // Complex Getters + + // Get all delegations recorded for a particular public key + function getAllForPubKey(bytes32 pubKey) external view returns ( + bytes32[] memory dlgtRequests, + bytes32[] memory sigs1, + bytes32[] memory sigs2, + uint[] recordedTs + ) { + return getAllForPubKeyBetween(pubKey, 0, 2**64-1); + } + + function _delegationInRange(Delegation storage d, uint start, uint end) internal view returns (bool) { + return d.recordedTs >= start && d.recordedTs <= end; + } + + // Get all recorded delegations between a start date and end date + function getAllForPubKeyBetween(bytes32 pubKey, uint startDate, uint endDate) public view returns ( + bytes32[] memory dlgtRequests, + bytes32[] memory sig1s, + bytes32[] memory sig2s, + uint[] timestamps + ) { + for (uint i = 0; i < delegations[pubKey].length; i++) { + if (_delegationInRange(delegations[pubKey][i], startDate, endDate)) { + dlgtRequests = M.appendBytes32(dlgtRequests, delegations[pubKey][i].dlgtRequest); + sig1s = M.appendBytes32(sig1s, delegations[pubKey][i].sig1); + sig2s = M.appendBytes32(sig2s, delegations[pubKey][i].sig2); + timestamps = M.appendUint256(timestamps, delegations[pubKey][i].recordedTs); + } + } + } +} diff --git a/doTests.sh b/doTests.sh index eba28b4..ea518e0 100755 --- a/doTests.sh +++ b/doTests.sh @@ -1,5 +1,7 @@ #!/bin/bash +mkdir -p db + echo "Use RUN_ALL_TESTS=true to run all tests." if [ -n "$TRAVIS" ] || [ -n "$RUN_ALL_TESTS" ]; then echo "Loading all env vars" diff --git a/package.json b/package.json index 51f323a..f5ddfc1 100644 --- a/package.json +++ b/package.json @@ -18,7 +18,7 @@ "eth-lib": "^0.2.8", "ethereumjs-testrpc": "^6.0.3", "ethereumjs-util": "^5.1.5", - "ganache-cli": "^6.1.0", + "ganache-cli": "^6.1.6", "graceful-fs": "^4.1.11", "jq": "^1.7.2", "js-nacl": "^1.2.2", @@ -28,8 +28,9 @@ "sanctuary": "^0.14.1", "solidity-coverage": "^0.5.1", "solium": "^1.1.6", - "sv-lib": "^0.1.2", + "sv-lib": "^0.2.1", "truffle": "trufflesuite/truffle", + "tweetnacl": "^1.0.0", "web3": "^1.0.0-beta.33", "yargs": "^11.0.0" }, @@ -46,6 +47,8 @@ "compile-ens": "for f in $(ls ./ens | grep sol); do ./bin/compile.sh -d ens -c $f -o _distEns; done", "coverage": "RUN_ALL_TESTS=true solidity-coverage", "c": "./bin/compile.sh -c", - "diff": "git diff -- . ':(exclude)_solDist/*'" + "diff": "git diff -- . ':(exclude)_solDist/*'", + "manage-nodes:dev": "scripts/manage-nodes.sh", + "test:geth": "export GETH_CLIENT=geth; yarn manage-nodes:dev && truffle test --network rpc" } } diff --git a/scripts/manage-nodes.sh b/scripts/manage-nodes.sh new file mode 100755 index 0000000..ea2797f --- /dev/null +++ b/scripts/manage-nodes.sh @@ -0,0 +1,77 @@ +#!/usr/bin/env bash + +# Exit script as soon as a command fails. +set -o errexit + +# check for coverage which will specify new port for ethereum client +if [ "$SOLIDITY_COVERAGE" = true ]; then + GETH_PORT=8555 +else + GETH_PORT=8545 +fi + +PARITY_VERSION=v1.8.0 +GETH_VERSION=v1.7.3-instantseal + +client_running() { + nc -z localhost "$GETH_PORT" +} + +start_testrpc() { + if [ "$SOLIDITY_COVERAGE" = true ]; then + node_modules/.bin/testrpc-sc -i 16 --gasLimit 0xfffffffffff --port "$GETH_PORT" > /dev/null & + else + node_modules/.bin/ganache-cli -i 15 --gasLimit 50000000 > /dev/null & + fi + + rpc_pid=$! +} + +check_docker() { + # check that docker exists before attempting to pull/run images + if ! [ -x "$(command -v docker)" ]; then + echo 'Error: docker is not installed' >&2 + exit 1 + fi +} + +start_parity() { + check_docker + # pull the most stable release of parity + docker pull purta/parity-instantseal:$PARITY_VERSION + # run the container in detached mode + docker run -d -p 8545:8545 purta/parity-instantseal:$PARITY_VERSION + + sleep 5 +} + +start_geth() { + check_docker + # pull the latest image using the dev test network + docker pull purta/geth-devnet:$GETH_VERSION + # run the geth dev network container + docker run -d -p 8545:8545 purta/geth-devnet:$GETH_VERSION + + echo "Letting client warmup for 5 seconds..." + sleep 5 +} + +if client_running; then + echo "Using existing geth instance at port $GETH_PORT" +else + echo "Starting our own ethereum client at port $GETH_PORT" + case $GETH_CLIENT in + geth ) + start_geth + ;; + parity ) + start_parity + ;; + * ) + echo "No ethereum client specified, using testrpc..." + start_testrpc + ;; + esac +fi + +sleep 5 diff --git a/test/ballotBox.js b/test/ballotBox.js index 86f4b6f..de55947 100644 --- a/test/ballotBox.js +++ b/test/ballotBox.js @@ -5,13 +5,14 @@ var BallotAux = artifacts.require("./BallotAux"); var BBFarm = artifacts.require("./BBFarm") var BBFarmPx = artifacts.require("./BBFarmProxy") var BBFarmAux = artifacts.require("./BBFarmAux") +var BBFarmAux2 = artifacts.require("./BBFarmAux2") var TestHelper = artifacts.require("./TestHelper") require("./testUtils")(); const naclJs = require("js-nacl") const crypto = require("crypto") -const svLib = require("sv-lib") +const { mkSignedBallotForProxy } = require("sv-lib/lib/ballotBox") const Account = require("eth-lib/lib/account") const R = require('ramda') @@ -402,10 +403,7 @@ const testGetVotes = async ({accounts, BB, bbaux, doLog}) => { const bbNoEnc = await BB.new(genRandomBytes32(), mkPacked(s, e, (USE_ETH | USE_NO_ENC)), zeroAddr); const bbEnc = await BB.new(genRandomBytes32(), mkPacked(s, e, (USE_ETH | USE_ENC)), zeroAddr); - // const bb2NoEnc = await BB.new(specHash, mkPacked(s, e, (USE_ETH | USE_NO_ENC)), zeroAddr); - // const bb2Enc = await BB.new(specHash, mkPacked(s, e, (USE_ETH | USE_ENC)), zeroAddr); - - const getBallotsTest = async ({bb, useEnc}) => { + const testBBFarmAux = async ({bb, useEnc}) => { let aux, getVotesFrom, getVotes; aux = await BBFarmAux.new(); getVotesFrom = acct => aux.getVotesFrom(bb.farm.address, bb.ballotId, acct) @@ -447,8 +445,41 @@ const testGetVotes = async ({accounts, BB, bbaux, doLog}) => { assert.deepEqual(await bb.getVote(1), [_ballot2, accounts[1], useEnc ? _pk2 : "0x"], 'vote 1 should match') } - await getBallotsTest({bb: bbNoEnc, useEnc: false}); - await getBallotsTest({bb: bbEnc, useEnc: true}); + await testBBFarmAux({bb: bbNoEnc, useEnc: false}); + await testBBFarmAux({bb: bbEnc, useEnc: true}); +} + + +const testBBFarmAux2 = async ({accounts, BB, bbaux, doLog, owner}) => { + const [_, u1, u2, u3, u4] = accounts + + let [s, e] = await genStartEndTimes(); + const _ballot1 = genRandomBytes32(); + const _ballot2 = genRandomBytes32(); + + const sb = (USE_ETH | USE_NO_ENC) + const packed = mkPacked(s, e, sb) + const specHash = genRandomBytes32(); + const bb = await BB.new(specHash, packed, owner); + const aux = await BBFarmAux2.new() + + const expInitGetBallotDetails = [false, toBigNumber(0), zeroHash, toBigNumber(sb), toBigNumber(s), toBigNumber(e), specHash, false, owner, zeroHash.slice(0, 34)] + const initGetBallotDetails = await aux.getBallotDetails(bb.farm.address, bb.ballotId, u1) + assert.deepEqual(initGetBallotDetails, expInitGetBallotDetails, 'init getBallotDetails matches') + + await doLog(`submitting votes now`) + await bb.submitVote(_ballot1, "", {from: u1}); + await doLog(`voted once`) + await bb.submitVote(_ballot2, "", {from: u2}); + await doLog(`voted twice`) + + await doLog(`getting ballot details`) + const expGetBallotDetails = [true, toBigNumber(2), zeroHash, toBigNumber(sb), toBigNumber(s), toBigNumber(e), specHash, false, owner, zeroHash.slice(0, 34)] + const getBallotDetails = await aux.getBallotDetails(bb.farm.address, bb.ballotId, u1) + assert.deepEqual(expGetBallotDetails, getBallotDetails, 'getBallotDetails after 2 votes matches') + + // note: getBBFarmAddressAndBallotId and ballotIdToDetails tested in indexTests + await doLog("done") } @@ -466,7 +497,7 @@ const mkProxyVote = async ({ballotId, sequence = 4919, extra = '0x', privKey = n const _ballotId = w3.utils.toBN(ballotId) const vote = genRandomBytes(32) - const {proxyReq} = svLib.ballotBox.mkSignedBallotForProxy(_ballotId, sequence, vote, extra, privKey, {skipSequenceSizeCheck: true}) + const {proxyReq} = mkSignedBallotForProxy(_ballotId, sequence, vote, extra, privKey, {skipSequenceSizeCheck: true}) return {proxyReq, extra, vote, sequence, address, privKey} } @@ -474,7 +505,7 @@ const mkProxyVote = async ({ballotId, sequence = 4919, extra = '0x', privKey = n const testProxyVote = async ({BB, accounts, doLog, farm}) => { const [u0, u1, u2, u3] = accounts; - const bb = await BB.new(genRandomBytes32(), await genStdPacked(), u0) + const bb = await BB.new(genRandomBytes32(), await genStdPacked(), zeroAddr, u0) const {proxyReq, extra, vote, sequence, address} = await mkProxyVote({ballotId: bb.ballotId}) @@ -555,15 +586,22 @@ const _wrapTest = ({accounts, bbName, mkFarm}, f) => { const Emitter = await EmitterTesting.new(); const log = m => Emitter.log(m); const doLog = log; + + await log("Starting test wrap") + const bbaux = await BallotAux.new(); const farm = await BBFarm.new(); await farm.setPermissions(accounts[0], true) + await log("Finished wrap contract deployment") + const mkNewBB = async function(specHash, packed, index, lastArg) { + await log(`Deploying new BB with args: ${[specHash, packed, index, lastArg]}`) + const from = (lastArg && lastArg.from) ? lastArg.from : accounts[0]; const txOpts = isTxOpts(lastArg) ? {...lastArg, from: accounts[0]} : {} - const _initBBEvent = await farm.initBallot(specHash, packed, index, from, genRandomBytes(31) + "01", txOpts) + const _initBBEvent = await farm.initBallot(specHash, packed, index, from, zeroHash.slice(0, 2+24*2), txOpts) const {args: {ballotId}} = getEventFromTxR("BallotCreatedWithID", _initBBEvent) await doLog(`wrapper: Created ballot with ID: ${ballotId.toFixed()}`); @@ -620,7 +658,9 @@ const _wrapTest = ({accounts, bbName, mkFarm}, f) => { farm } - return await f({accounts, BB, log, doLog, bbaux, bbName, farm}); + await log("Finished test wrapping - starting test now") + + return await f({owner: accounts[0], accounts, BB, log, doLog, bbaux, bbName, farm}); }; } @@ -628,6 +668,7 @@ const _wrapTest = ({accounts, bbName, mkFarm}, f) => { contract("BallotBox", function(accounts) { const tests = [ ["should instantiate correctly", testInstantiation], + ["test bbFarmAux2", testBBFarmAux2], ["test sponsorship", testSponsorship], ["test revert conditions", testRevertConditions], ["test proxy vote", testProxyVote], diff --git a/test/ed25519Delegation.js b/test/ed25519Delegation.js new file mode 100644 index 0000000..6c35ac8 --- /dev/null +++ b/test/ed25519Delegation.js @@ -0,0 +1,146 @@ +const SelfDelegaiton = artifacts.require("./UnsafeEd25519SelfDelegation"); +const EmitterTesting = artifacts.require("./EmitterTesting"); + +const { prepareEd25519Delegation, ed25519DelegationIsValid } = require('sv-lib/lib/light') + +const nacl = require('tweetnacl') + +require("./testUtils")(); + + +const genDelegation = () => { + const kp = nacl.sign.keyPair() + const addr = w3.utils.randomHex(20) + const nonce = w3.utils.randomHex(3) + + return mkDelegation(addr, nonce, kp) +} + + +const mkDelegation = (toAddr, nonce, kp) => { + const dlgtReq = prepareEd25519Delegation(toAddr, nonce); + + const sigRaw = nacl.sign.detached(hexToUint8Array(dlgtReq), kp.secretKey) + + const sig1 = w3.utils.bytesToHex(sigRaw.slice(0, 32)) + const sig2 = w3.utils.bytesToHex(sigRaw.slice(32)) + const pk = w3.utils.bytesToHex(kp.publicKey) + + return {data: [dlgtReq, pk, [sig1, sig2]], kp, toAddr} +} + +const mkBadHdrDelegation = (toAddr, nonce, kp) => { + let dlgtReq = prepareEd25519Delegation(toAddr, nonce); + + // corrupt the header - this part is constant so 0 always invalid + dlgtReq = "0x00" + dlgtReq.slice(4) + + const sigRaw = nacl.sign.detached(hexToUint8Array(dlgtReq), kp.secretKey) + + const sig1 = w3.utils.bytesToHex(sigRaw.slice(0, 32)) + const sig2 = w3.utils.bytesToHex(sigRaw.slice(32)) + const pk = w3.utils.bytesToHex(kp.publicKey) + + return {data: [dlgtReq, pk, [sig1, sig2]], kp, toAddr} +} + + +const wrapTest = ({accounts}, f) => { + return async () => { + const owner = accounts[0]; + + const scLog = await EmitterTesting.new(); + + // use this doLog function in the wrapper to easily turn on and off this logging + // just in this initialization function + let loggingActive = true; + const doLog = async msg => { + if (loggingActive) + return await scLog.log(msg); + } + + await doLog(`Created logger...`); + + const selfDelegation = await SelfDelegaiton.new(); + + await doLog(`Created self delegation SC at: ${selfDelegation.address}`) + + return await f({selfDelegation, doLog, owner, accounts}, accounts); + }; +}; + + +const testTemplate = async ({selfDelegation, doLog, owner, accounts}) => { + const [_, u1, u2, u3, u4, u5] = accounts; +} + + +const testInit = async ({selfDelegation, doLog, owner, accounts}) => { + const [_, u1, u2, u3, u4, u5] = accounts; + + assert.equal(await selfDelegation.dLogN(), 0, 'no delegations') + assert.equal(await selfDelegation.nDelegations(zeroHash), 0, 'no delegations (pk)') + assert.equal(await selfDelegation.nAddressLog(), 0, 'no delegatees') + assert.deepEqual(await selfDelegation.getAllForPubKey(zeroHash), [[],[],[],[]], 'no delegations for pk') +} + + +const testDelegation = async ({selfDelegation, doLog, owner, accounts}) => { + const [_, u1, u2, u3, u4, u5] = accounts; + + // generate and perform first delegation + const d1 = genDelegation() + await doLog(`d1.data: ${toJson(d1.data)}`) + await selfDelegation.addUntrustedSelfDelegation(...d1.data) + const d1Dlgtions = await selfDelegation.getAllForPubKey(d1.data[1]) + const expectedD1 = [[d1.data[0]], [d1.data[2][0]], [d1.data[2][1]]] + + // verify first delegaiton + assert.equal(await selfDelegation.dLogN(), 1, '1 pk - dlgtion') + assert.equal(await selfDelegation.nDelegations(d1.data[1]), 1, '1 dlgtion for pk') + assert.equal(await selfDelegation.nAddressLog(), 1, '1 addr - dlgtion') + assert.deepEqual(d1Dlgtions.slice(0,3), expectedD1, 'dlgation 1 match, sans timestamp') + + // do another delegation + const d2 = mkDelegation(d1.toAddr, w3.utils.randomHex(3), d1.kp) + await selfDelegation.addUntrustedSelfDelegation(...d2.data) + const d2Dlgtions = await selfDelegation.getAllForPubKey(d2.data[1]) + const expectedD2 = R.compose(R.map(R.flatten), R.zip(expectedD1))([[d2.data[0]], [d2.data[2][0]], [d2.data[2][1]]]) + + assert.equal(await selfDelegation.dLogN(), 1, '1 pk - dlgtion') + assert.deepEqual(await selfDelegation.nDelegations(d1.data[1]), toBigNumber(2), '2 dlgtion for pk') + assert.equal(await selfDelegation.nAddressLog(), 1, '1 addr - dlgtion') + assert.deepEqual(d2Dlgtions.slice(0,3), expectedD2, 'dlgation 2 match, sans timestamp') + + // do test with silly time range to get 0 results + assert.deepEqual(await selfDelegation.getAllForPubKeyBetween(d2.data[1], 0, 1), [[],[],[],[]], 'dlgation get with silly timestamps returns empty') +} + + +const testReverts = async ({selfDelegation, doLog, owner, accounts}) => { + const [_, u1, u2, u3, u4, u5] = accounts; + + const kp = nacl.sign.keyPair() + const addr = w3.utils.randomHex(20) + const nonce = w3.utils.randomHex(3) + + const d1 = mkBadHdrDelegation(addr, nonce, kp) + + // bad header + await asyncAssertThrow(() => selfDelegation.addUntrustedSelfDelegation(...d1.data), 'bad header fails') + // do replay + + const d2 = genDelegation() + await selfDelegation.addUntrustedSelfDelegation(...d2.data) + await asyncAssertThrow(() => selfDelegation.addUntrustedSelfDelegation(...d2.data), 'replay fails') +} + + +contract("UnsafeEd25519SelfDelegation", function (accounts) { + tests = [ + ["test init", testInit], + ["test delegation", testDelegation], + ["test reverts", testReverts], + ]; + R.map(([desc, f]) => it(desc, wrapTest({accounts}, f)), tests); +}); diff --git a/test/indexTests.js b/test/indexTests.js index a9e84a6..4af3d5b 100644 --- a/test/indexTests.js +++ b/test/indexTests.js @@ -10,6 +10,7 @@ const EmitterTesting = artifacts.require("./EmitterTesting"); const TestHelper = artifacts.require("./TestHelper"); const FaucetErc20 = artifacts.require("./FaucetErc20"); const BBFarm = artifacts.require("./BBFarm") +const BBFarmAux2 = artifacts.require("./BBFarmAux2") const BBFarmTesting = artifacts.require("./BBFarmTesting") const CommunityAuctionSimple = artifacts.require("./CommunityAuctionSimple") const ControlledTest = artifacts.require("./ControlledTest") @@ -211,7 +212,9 @@ const testInit = async ({ixPayments, owner, svIx, erc20, doLog, ixBackend, bbFar assert.deepEqual(await ixBackend.getDInfo(democHash), [erc20.address, owner, toBigNumber(0)], 'getDInfo works as expected (0)') const specHash = genRandomBytes32() - await svIx.dDeployBallot(democHash, specHash, zeroHash, await mkStdPacked()) + const packed = await mkStdPacked() + const deployBTxr = await svIx.dDeployBallot(democHash, specHash, zeroAddr + w3.utils.randomHex(12).slice(2), packed) + const {args: {ballotId}} = getEventFromTxR('BallotCreatedWithID', deployBTxr) assert.deepEqual(await ixBackend.getDInfo(democHash), [erc20.address, owner, toBigNumber(1)], 'getDInfo works as expected (1)') await assertRevert(svIx.dDeployBallot(democHash, specHash, zeroHash, await mkStdPacked()), 'deploying a ballot with same spechash should revert') @@ -221,6 +224,19 @@ const testInit = async ({ixPayments, owner, svIx, erc20, doLog, ixBackend, bbFar assert.deepEqual(await ixBackend.getVersion(), toBigNumber(2), 'ixBackend ver') assert.deepEqual(await ixPayments.getVersion(), toBigNumber(2), 'ixPayments ver') assert.deepEqual(await bbFarm.getVersion(), toBigNumber(2), 'bbFarm ver') + + // test BBFarmAux2 w/ the ballot we created above + const aux = await BBFarmAux2.new() + + await doLog("checking bIDToDetails") + const bIdToDetails = await aux.ballotIdToDetails(svIx.address, ballotId) + const expBIdToDetails = [toBigNumber(0), zeroHash, getSB(packed), getStartTS(packed), getEndTS(packed), specHash, false] + assert.deepEqual(bIdToDetails, expBIdToDetails, 'bIdToDetails init matches') + + await doLog("checking getBBFarmAddressAndBallotId") + const expGetBBFarmAddrAndBId = [bbFarm.address, ballotId] + const getBBFarmAddrAndBID = await aux.getBBFarmAddressAndBallotId(svIx.address, democHash, 0) + assert.deepEqual(getBBFarmAddrAndBID, expGetBBFarmAddrAndBId, 'getBBFarmAddrAndBId matches init') } @@ -1242,7 +1258,7 @@ contract("SVLightIndex", function (accounts) { const allT = process.env.RUN_ALL_TESTS const condAll = (allT && allT.toLowerCase() === "true") const cond = (eVar && eVar.toLowerCase() === "true") || condAll - console.log(`Test (${testStr}) will be skipped if the following env var is present:\n${envVarStr}=true`) + console.log(`Test (${testStr}) will be skipped unless the following env var is present:\n${envVarStr}=true`) console.log(cond ? "running this time" : "skipping this time") const defaultF = async () => { return true; } return [testStr, cond ? testF : defaultF] diff --git a/test/testUtils.js b/test/testUtils.js index dd4c0f7..fff7ddf 100644 --- a/test/testUtils.js +++ b/test/testUtils.js @@ -56,7 +56,7 @@ module.exports = function () { this.genStartEndTimes = async () => { const {timestamp} = await this.getBlock('latest') - var startTime = timestamp - 1; + var startTime = timestamp; var endTime = startTime + 600; return [startTime, endTime]; } @@ -81,6 +81,20 @@ module.exports = function () { return mkPacked(s, e, this.USE_NO_ENC | this.USE_ETH) } + this.getSB = (packed) => { + return toBigNumber(toBN(packed).shrn(128).and(toBN(0xFFFF))) + } + + this.getStartTS = packed => { + // we and with 5 bytes of 1's b/c that's enough to ensure we get the right timestamp for like another 10k years + return toBigNumber(toBN(packed).shrn(64).and(toBN(0xFFFFFFFFFF))) + } + + this.getEndTS = packed => { + // we and with 5 bytes of 1's b/c that's enough to ensure we get the right timestamp for like another 10k years + return toBigNumber(toBN(packed).and(toBN(0xFFFFFFFFFF))) + } + this.wrapTest = (accounts, f) => { return async () => { return await f({accounts}); @@ -233,6 +247,12 @@ module.exports = function () { return Web3.utils.bytesToHex(Web3.utils.hexToBytes(bytes32Addr).slice(0, 12)); } + + this.hexToUint8Array = hex => { + return Uint8Array.from(w3.utils.hexToBytes(hex)) + } + + // this is from the bech32 spec (Bitcoin) const B32_ALPHA = "qpzry9x8gf2tvdw0s3jn54khce6mua7l"; const toAlphabet = arr => { diff --git a/truffle.js b/truffle.js index 17f1717..3d16020 100644 --- a/truffle.js +++ b/truffle.js @@ -1,16 +1,30 @@ -var TestRPC = require("ethereumjs-testrpc"); +const l = str => console.log(new Date().getTime() / 1000, 'truffle.js:', str) +l("Loading truffle.js") + +// var TestRPC = require("ethereumjs-testrpc"); const { create, env } = require("sanctuary"); const S = create({ checkTypes: true, env }); +l("init'd sactuary") + +const w3Utils = require('web3-utils') var ganache = require("ganache-cli"); +l("Loaded ganache; declaring provider") + +const accounts = S.map(i => ({ balance: "0xffffffffffffffffffffff", secretKey: w3Utils.padLeft(w3Utils.toHex(i+10), 64)}), S.range(0, 20)) +// console.log("Development network accounts: ", accounts) + let provider = ganache.provider({ port: 34839, - accounts: S.map(_ => ({ balance: "0xffffffffffffffffff" }), S.range(0, 20)), - gasLimit: 20000000 + accounts, + gasLimit: 20000000, + db_path: "./db", }) +l("provider init'd") + // needed to make ganache-cli work... // curiously, if you don't have this AND don't have gasLimit high, then truffle // crashes with "exceeds block gas limit", so some communication must be going @@ -22,16 +36,21 @@ provider = new Proxy(provider, { return obj[method] } if(method === "sendAsync"){ - return (...args) => new Promise((resolve, reject) => { - provider.send(...args, (err, val) => { - err ? reject(err) : resolve(val); - }) - }) + return provider.send + // // this pattern started breaking with ganache 6.1.6 + // return (...args) => new Promise((resolve, reject) => { + // provider.send(...args, (err, val) => { + // err ? reject(err) : resolve(val); + // }) + // }) } return obj[method] } }) +l("Created provider + sendAsync shim") + + module.exports = { networks: { development: { @@ -50,6 +69,14 @@ module.exports = { network_id: "*", gas: 7000000, gasPrice: 1, - } + }, + rpc: { + network_id: 15, + host: 'localhost', + port: 8545, + gas: 6.5e6, + }, } }; + +l("declared exports") diff --git a/yarn.lock b/yarn.lock index 36fac72..09fc7a2 100644 --- a/yarn.lock +++ b/yarn.lock @@ -23,6 +23,30 @@ version "0.7.0" resolved "https://registry.yarnpkg.com/@sindresorhus/is/-/is-0.7.0.tgz#9a06f4f137ee84d7df0460c1fdb1135ffa6c50fd" +"@types/base-x@*": + version "1.0.29" + resolved "https://registry.yarnpkg.com/@types/base-x/-/base-x-1.0.29.tgz#8a2d73e4a5c3121757a5f8870cfa4509655186b6" + +"@types/bn.js@^4.11.1": + version "4.11.1" + resolved "https://registry.yarnpkg.com/@types/bn.js/-/bn.js-4.11.1.tgz#6fd07b93490ecf0f3501a31ea9cfd330885b10fa" + dependencies: + "@types/node" "*" + +"@types/bs58@^3.0.30": + version "3.0.30" + resolved "https://registry.yarnpkg.com/@types/bs58/-/bs58-3.0.30.tgz#916ba10992465e56f81afc735e7935fd749893e1" + dependencies: + "@types/base-x" "*" + +"@types/node@*": + version "10.5.4" + resolved "https://registry.yarnpkg.com/@types/node/-/node-10.5.4.tgz#6eccc158504357d1da91434d75e86acde94bb10b" + +"@types/ramda@^0.25.35": + version "0.25.35" + resolved "https://registry.yarnpkg.com/@types/ramda/-/ramda-0.25.35.tgz#94500755a8dd7365f80e9e99e31331add41e9880" + abbrev@1: version "1.1.1" resolved "https://registry.yarnpkg.com/abbrev/-/abbrev-1.1.1.tgz#f8f2c887ad10bf67f634f005b6987fed3179aac8" @@ -477,6 +501,13 @@ aws4@^1.6.0: version "1.7.0" resolved "https://registry.yarnpkg.com/aws4/-/aws4-1.7.0.tgz#d4d0e9b9dbfca77bf08eeb0a8a471550fe39e289" +axios@^0.18.0: + version "0.18.0" + resolved "https://registry.yarnpkg.com/axios/-/axios-0.18.0.tgz#32d53e4851efdc0a11993b6cd000789d70c05102" + dependencies: + follow-redirects "^1.3.0" + is-buffer "^1.1.5" + babel-code-frame@^6.26.0: version "6.26.0" resolved "https://registry.yarnpkg.com/babel-code-frame/-/babel-code-frame-6.26.0.tgz#63fd43f7dc1e3bb7ce35947db8fe369a3f58c74b" @@ -1017,6 +1048,12 @@ babel-register@^6.26.0, babel-register@^6.9.0: mkdirp "^0.5.1" source-map-support "^0.4.15" +babel-runtime@^4.7.16: + version "4.7.16" + resolved "https://registry.yarnpkg.com/babel-runtime/-/babel-runtime-4.7.16.tgz#7a3995ad8c9eb5b4d0dd35febf170d0d1420262b" + dependencies: + core-js "^0.6.1" + babel-runtime@^6.18.0, babel-runtime@^6.22.0, babel-runtime@^6.26.0: version "6.26.0" resolved "https://registry.yarnpkg.com/babel-runtime/-/babel-runtime-6.26.0.tgz#965c7058668e82b55d7bfe04ff2337bc8b5647fe" @@ -1075,6 +1112,10 @@ base-x@^3.0.2: dependencies: safe-buffer "^5.0.1" +base32.js@~0.1.0: + version "0.1.0" + resolved "https://registry.yarnpkg.com/base32.js/-/base32.js-0.1.0.tgz#b582dec693c2f11e893cf064ee6ac5b6131a2202" + base64-js@0.0.8: version "0.0.8" resolved "https://registry.yarnpkg.com/base64-js/-/base64-js-0.0.8.tgz#1101e9544f4a76b1bc3b26d452ca96d7a35e7978" @@ -1109,6 +1150,10 @@ big.js@^3.1.3: version "3.2.0" resolved "https://registry.yarnpkg.com/big.js/-/big.js-3.2.0.tgz#a5fc298b81b9e0dca2e458824784b65c52ba588e" +bignumber.js@^4.0.0: + version "4.1.0" + resolved "https://registry.yarnpkg.com/bignumber.js/-/bignumber.js-4.1.0.tgz#db6f14067c140bd46624815a7916c92d9b6c24b1" + "bignumber.js@git+https://github.com/debris/bignumber.js.git#94d7146671b9719e00a09c29b01a691bc85048c2": version "2.0.7" resolved "git+https://github.com/debris/bignumber.js.git#94d7146671b9719e00a09c29b01a691bc85048c2" @@ -1148,7 +1193,7 @@ bluebird@^2.9.34: version "2.11.0" resolved "https://registry.yarnpkg.com/bluebird/-/bluebird-2.11.0.tgz#534b9033c022c9579c56ba3b3e5a5caafbb650e1" -bluebird@^3.5.0: +bluebird@^3.5.0, bluebird@^3.5.1: version "3.5.1" resolved "https://registry.yarnpkg.com/bluebird/-/bluebird-3.5.1.tgz#d9551f9de98f1fcda1e683d17ee91a0602ee2eb9" @@ -1346,6 +1391,13 @@ buffer@^5.0.5: base64-js "^1.0.2" ieee754 "^1.1.4" +buffer@^5.1.0: + version "5.2.0" + resolved "https://registry.yarnpkg.com/buffer/-/buffer-5.2.0.tgz#53cf98241100099e9eeae20ee6d51d21b16e541e" + dependencies: + base64-js "^1.0.2" + ieee754 "^1.1.4" + builtin-modules@^1.0.0: version "1.1.1" resolved "https://registry.yarnpkg.com/builtin-modules/-/builtin-modules-1.1.1.tgz#270f076c5a72c02f5b65a47df94c5fe3a278892f" @@ -1712,10 +1764,18 @@ contextify@0.1.x: bindings "^1.2.1" nan "^2.1.0" +convert-hex@~0.1.0: + version "0.1.0" + resolved "https://registry.yarnpkg.com/convert-hex/-/convert-hex-0.1.0.tgz#08c04568922c27776b8a2e81a95d393362ea0b65" + convert-source-map@^1.5.1: version "1.5.1" resolved "https://registry.yarnpkg.com/convert-source-map/-/convert-source-map-1.5.1.tgz#b8278097b9bc229365de5c62cf5fcaed8b5599e5" +convert-string@~0.1.0: + version "0.1.0" + resolved "https://registry.yarnpkg.com/convert-string/-/convert-string-0.1.0.tgz#79ce41a9bb0d03bcf72cdc6a8f3c56fbbc64410a" + cookie-signature@1.0.6: version "1.0.6" resolved "https://registry.yarnpkg.com/cookie-signature/-/cookie-signature-1.0.6.tgz#e303a882b342cc3ee8ca513a79999734dab3ae2c" @@ -1724,10 +1784,18 @@ cookie@0.3.1: version "0.3.1" resolved "https://registry.yarnpkg.com/cookie/-/cookie-0.3.1.tgz#e7e0a1f9ef43b4c8ba925c5c5a96e806d16873bb" +cookiejar@^2.1.1: + version "2.1.2" + resolved "https://registry.yarnpkg.com/cookiejar/-/cookiejar-2.1.2.tgz#dd8a235530752f988f9a0844f3fc589e3111125c" + copy-descriptor@^0.1.0: version "0.1.1" resolved "https://registry.yarnpkg.com/copy-descriptor/-/copy-descriptor-0.1.1.tgz#676f6eb3c39997c2ee1ac3a924fd6124748f578d" +core-js@^0.6.1: + version "0.6.1" + resolved "https://registry.yarnpkg.com/core-js/-/core-js-0.6.1.tgz#1b4970873e8101bf8c435af095faa9024f4b9b58" + core-js@^2.4.0, core-js@^2.4.1, core-js@^2.5.0: version "2.5.7" resolved "https://registry.yarnpkg.com/core-js/-/core-js-2.5.7.tgz#f972608ff0cead68b841a16a932d0b183791814e" @@ -1753,6 +1821,10 @@ coveralls@^3.0.1: minimist "^1.2.0" request "^2.79.0" +crc@3.5.0: + version "3.5.0" + resolved "https://registry.yarnpkg.com/crc/-/crc-3.5.0.tgz#98b8ba7d489665ba3979f59b21381374101a1964" + create-ecdh@^4.0.0: version "4.0.3" resolved "https://registry.yarnpkg.com/create-ecdh/-/create-ecdh-4.0.3.tgz#c9111b6f33045c4697f144787f9254cdc77c45ff" @@ -1833,6 +1905,10 @@ cssstyle@>=0.2.3: dependencies: cssom "0.3.x" +cursor@^0.1.5: + version "0.1.5" + resolved "https://registry.yarnpkg.com/cursor/-/cursor-0.1.5.tgz#ea778c2b09d33c2e564fd92147076750483ebb2c" + d@1: version "1.0.0" resolved "https://registry.yarnpkg.com/d/-/d-1.0.0.tgz#754bb5bfe55451da69a58b94d45f4c5b0462d58f" @@ -2060,6 +2136,13 @@ ecc-jsbn@~0.1.1: dependencies: jsbn "~0.1.0" +ed25519@0.0.4: + version "0.0.4" + resolved "https://registry.yarnpkg.com/ed25519/-/ed25519-0.0.4.tgz#e56218ace2fc903d259593aef0b2a9639f475beb" + dependencies: + bindings "^1.2.1" + nan "^2.0.9" + editions@^1.3.3: version "1.3.4" resolved "https://registry.yarnpkg.com/editions/-/editions-1.3.4.tgz#3662cb592347c3168eb8e498a0ff73271d67f50b" @@ -2244,6 +2327,12 @@ escope@^3.6.0: esrecurse "^4.1.0" estraverse "^4.1.1" +esdoc-typescript-plugin@^1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/esdoc-typescript-plugin/-/esdoc-typescript-plugin-1.0.1.tgz#d4b929677f2ee5587a86ec70e766537040b98662" + dependencies: + typescript "^2.8.3" + esprima@2.7.x, esprima@^2.7.1: version "2.7.3" resolved "https://registry.yarnpkg.com/esprima/-/esprima-2.7.3.tgz#96e3b70d5779f6ad49cd032673d1c312767ba581" @@ -2619,6 +2708,12 @@ flow-parser@^0.*: version "0.73.0" resolved "https://registry.yarnpkg.com/flow-parser/-/flow-parser-0.73.0.tgz#525ac0776f743e16b6dca1a3dd6c602260b15773" +follow-redirects@^1.3.0: + version "1.5.1" + resolved "https://registry.yarnpkg.com/follow-redirects/-/follow-redirects-1.5.1.tgz#67a8f14f5a1f67f962c2c46469c79eaec0a90291" + dependencies: + debug "^3.1.0" + for-each@^0.3.2: version "0.3.3" resolved "https://registry.yarnpkg.com/for-each/-/for-each-0.3.3.tgz#69b447e88a0a5d32c3e7084f3f1710034b21376e" @@ -2661,6 +2756,10 @@ forwarded@~0.1.2: version "0.1.2" resolved "https://registry.yarnpkg.com/forwarded/-/forwarded-0.1.2.tgz#98c23dab1175657b8c0573e8ceccd91b0ff18c84" +fp-ts@^1.0.0, fp-ts@^1.7.1: + version "1.7.1" + resolved "https://registry.yarnpkg.com/fp-ts/-/fp-ts-1.7.1.tgz#b1ff2a39f345a7aa31bb53f26edab1ac3fc70b75" + fragment-cache@^0.2.1: version "0.2.1" resolved "https://registry.yarnpkg.com/fragment-cache/-/fragment-cache-0.2.1.tgz#4290fad27f13e89be7f33799c6bc5a0abfff0d19" @@ -2734,12 +2833,11 @@ fstream@^1.0.2, fstream@^1.0.8: mkdirp ">=0.5 0" rimraf "2" -ganache-cli@^6.1.0: - version "6.1.0" - resolved "https://registry.yarnpkg.com/ganache-cli/-/ganache-cli-6.1.0.tgz#486c846497204b644166b5f0f74c9b41d02bdc25" +ganache-cli@^6.1.6: + version "6.1.6" + resolved "https://registry.yarnpkg.com/ganache-cli/-/ganache-cli-6.1.6.tgz#99b500a25f571271a6978ef3f9c9c53e1a3854f0" dependencies: source-map-support "^0.5.3" - webpack-cli "^2.0.9" gauge@~2.7.3: version "2.7.4" @@ -3230,6 +3328,12 @@ invert-kv@^1.0.0: version "1.0.0" resolved "https://registry.yarnpkg.com/invert-kv/-/invert-kv-1.0.0.tgz#104a8e4aaca6d3d8cd157a8ef8bfab2d7a3ffdb6" +io-ts@^1.2.1: + version "1.2.1" + resolved "https://registry.yarnpkg.com/io-ts/-/io-ts-1.2.1.tgz#0f3cc43dff08d1656f2c1ad7462650dab4a6bae7" + dependencies: + fp-ts "^1.0.0" + ipaddr.js@1.6.0: version "1.6.0" resolved "https://registry.yarnpkg.com/ipaddr.js/-/ipaddr.js-1.6.0.tgz#e3fa357b773da619f26e95f049d055c72796f86b" @@ -3543,6 +3647,15 @@ js-tokens@^3.0.0, js-tokens@^3.0.2: version "3.0.2" resolved "https://registry.yarnpkg.com/js-tokens/-/js-tokens-3.0.2.tgz#9866df395102130e38f7f996bceb65443209c25b" +js-xdr@^1.0.0: + version "1.0.3" + resolved "https://registry.yarnpkg.com/js-xdr/-/js-xdr-1.0.3.tgz#7ae0aba03969771a28dfe423ffc9e9d02d9301d7" + dependencies: + babel-runtime "^4.7.16" + cursor "^0.1.5" + lodash "^4.17.5" + long "^2.2.3" + js-yaml@3.x, js-yaml@^3.6.1: version "3.12.0" resolved "https://registry.yarnpkg.com/js-yaml/-/js-yaml-3.12.0.tgz#eaed656ec8344f10f527c6bfa1b6e2244de167d1" @@ -3843,7 +3956,7 @@ lodash.assign@^4.0.3, lodash.assign@^4.0.6: version "4.2.0" resolved "https://registry.yarnpkg.com/lodash.assign/-/lodash.assign-4.2.0.tgz#0d99f3ccd7a6d261d19bdaeb9245005d285808e7" -lodash@^4.13.1, lodash@^4.14.2, lodash@^4.17.10, lodash@^4.17.2, lodash@^4.17.4, lodash@^4.3.0: +lodash@^4.13.1, lodash@^4.14.2, lodash@^4.17.10, lodash@^4.17.2, lodash@^4.17.4, lodash@^4.17.5, lodash@^4.3.0: version "4.17.10" resolved "https://registry.yarnpkg.com/lodash/-/lodash-4.17.10.tgz#1b7793cf7259ea38fb3661d4d38b3260af8ae4e7" @@ -3889,6 +4002,10 @@ log-utils@^0.2.1: time-stamp "^1.0.1" warning-symbol "^0.1.0" +long@^2.2.3: + version "2.4.0" + resolved "https://registry.yarnpkg.com/long/-/long-2.4.0.tgz#9fa180bb1d9500cdc29c4156766a1995e1f4524f" + longest@^1.0.1: version "1.0.1" resolved "https://registry.yarnpkg.com/longest/-/longest-1.0.1.tgz#30a0b2da38f73770e8294a0d22e6625ed77d0097" @@ -4186,7 +4303,7 @@ mz@^2.6.0: object-assign "^4.0.1" thenify-all "^1.0.0" -nan@2.10.0, nan@^2.0.8, nan@^2.1.0, nan@^2.2.1, nan@^2.3.3, nan@^2.9.2: +nan@2.10.0, nan@^2.0.8, nan@^2.0.9, nan@^2.1.0, nan@^2.2.1, nan@^2.3.3, nan@^2.9.2: version "2.10.0" resolved "https://registry.yarnpkg.com/nan/-/nan-2.10.0.tgz#96d0cd610ebd58d4b4de9cc0c6828cda99c7548f" @@ -4569,6 +4686,10 @@ parse-asn1@^5.0.0: evp_bytestokey "^1.0.0" pbkdf2 "^3.0.3" +parse-domain@^1.1.0: + version "1.2.0" + resolved "https://registry.yarnpkg.com/parse-domain/-/parse-domain-1.2.0.tgz#f3a28f3e103fa9cff8a4761eb7208f9596f29bc9" + parse-glob@^3.0.4: version "3.0.4" resolved "https://registry.yarnpkg.com/parse-glob/-/parse-glob-3.0.4.tgz#b2c376cfb11f35513badd173ef0bb6e3a388391c" @@ -5538,13 +5659,20 @@ setprototypeof@1.1.0: version "1.1.0" resolved "https://registry.yarnpkg.com/setprototypeof/-/setprototypeof-1.1.0.tgz#d0bd85536887b6fe7c0d818cb962d9d91c54e656" -sha.js@^2.4.0, sha.js@^2.4.8: +sha.js@^2.3.6, sha.js@^2.4.0, sha.js@^2.4.8: version "2.4.11" resolved "https://registry.yarnpkg.com/sha.js/-/sha.js-2.4.11.tgz#37a5cf0b81ecbc6943de109ba2960d1b26584ae7" dependencies: inherits "^2.0.1" safe-buffer "^5.0.1" +sha256@^0.2.0: + version "0.2.0" + resolved "https://registry.yarnpkg.com/sha256/-/sha256-0.2.0.tgz#73a0b418daab7035bff86e8491e363412fc2ab05" + dependencies: + convert-hex "~0.1.0" + convert-string "~0.1.0" + sha3@^1.1.0: version "1.2.2" resolved "https://registry.yarnpkg.com/sha3/-/sha3-1.2.2.tgz#a66c5098de4c25bc88336ec8b4817d005bca7ba9" @@ -5846,6 +5974,20 @@ statuses@~1.4.0: version "1.4.0" resolved "https://registry.yarnpkg.com/statuses/-/statuses-1.4.0.tgz#bb73d446da2796106efcc1b601a253d6c46bd087" +stellar-base@^0.8.0: + version "0.8.0" + resolved "https://registry.yarnpkg.com/stellar-base/-/stellar-base-0.8.0.tgz#98ca471c588ec44200ec113632d35729477b3f8c" + dependencies: + base32.js "~0.1.0" + bignumber.js "^4.0.0" + crc "3.5.0" + js-xdr "^1.0.0" + lodash "^4.17.10" + sha.js "^2.3.6" + tweetnacl "^1.0.0" + optionalDependencies: + ed25519 "0.0.4" + stream-browserify@^2.0.1: version "2.0.1" resolved "https://registry.yarnpkg.com/stream-browserify/-/stream-browserify-2.0.1.tgz#66266ee5f9bdb9940a4e4514cafb43bb71e5c9db" @@ -5981,18 +6123,32 @@ supports-color@^5.3.0, supports-color@^5.4.0: dependencies: has-flag "^3.0.0" -sv-lib@^0.1.2: - version "0.1.8" - resolved "https://registry.yarnpkg.com/sv-lib/-/sv-lib-0.1.8.tgz#8afde3f62f84f56e06c843e6804718739b701589" +sv-lib@^0.2.1: + version "0.2.1" + resolved "https://registry.yarnpkg.com/sv-lib/-/sv-lib-0.2.1.tgz#472d6d203fe312c724452fc1fb7bf15154de53b9" dependencies: + "@types/bn.js" "^4.11.1" + "@types/bs58" "^3.0.30" + "@types/ramda" "^0.25.35" assert "^1.4.1" + axios "^0.18.0" + bs58 "^4.0.1" + buffer "^5.1.0" colors "^1.3.0" + esdoc-typescript-plugin "^1.0.1" eth-ens-namehash "^2.0.8" eth-lib "^0.2.8" ethereumjs-util "^5.2.0" + fp-ts "^1.7.1" + io-ts "^1.2.1" ramda "^0.25.0" + sha256 "^0.2.0" + stellar-base "^0.8.0" + web3 "^1.0.0-beta.34" + web3-detect-network "^0.0.17" web3-eth-abi "^1.0.0-beta.34" web3-eth-accounts "^1.0.0-beta.34" + web3-providers-ws "^1.0.0-beta.34" web3-utils "^1.0.0-beta.34" swarm-js@0.1.37: @@ -6221,6 +6377,10 @@ tweetnacl@^0.14.3, tweetnacl@~0.14.0: version "0.14.5" resolved "https://registry.yarnpkg.com/tweetnacl/-/tweetnacl-0.14.5.tgz#5ae68177f192d4456269d108afa93ff8743f4f64" +tweetnacl@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/tweetnacl/-/tweetnacl-1.0.0.tgz#713d8b818da42068740bf68386d0479e66fc8a7b" + type-check@~0.3.2: version "0.3.2" resolved "https://registry.yarnpkg.com/type-check/-/type-check-0.3.2.tgz#5884cab512cf1d355e3fb784f30804b2b520db72" @@ -6240,6 +6400,10 @@ typedarray-to-buffer@^3.1.2: dependencies: is-typedarray "^1.0.0" +typescript@^2.8.3: + version "2.9.2" + resolved "https://registry.yarnpkg.com/typescript/-/typescript-2.9.2.tgz#1cbf61d05d6b96269244eb6a3bce4bd914e0f00c" + uglify-js@^2.6, uglify-js@^2.8.29: version "2.8.29" resolved "https://registry.yarnpkg.com/uglify-js/-/uglify-js-2.8.29.tgz#29c5733148057bb4e1f75df35b7a9cb72e6a59dd" @@ -6466,6 +6630,14 @@ web3-bzz@1.0.0-beta.34: swarm-js "0.1.37" underscore "1.8.3" +web3-bzz@1.0.0-beta.35: + version "1.0.0-beta.35" + resolved "https://registry.yarnpkg.com/web3-bzz/-/web3-bzz-1.0.0-beta.35.tgz#9d5e1362b3db2afd77d65619b7cd46dd5845c192" + dependencies: + got "7.1.0" + swarm-js "0.1.37" + underscore "1.8.3" + web3-core-helpers@1.0.0-beta.34: version "1.0.0-beta.34" resolved "https://registry.yarnpkg.com/web3-core-helpers/-/web3-core-helpers-1.0.0-beta.34.tgz#b168da00d3e19e156bc15ae203203dd4dfee2d03" @@ -6474,6 +6646,14 @@ web3-core-helpers@1.0.0-beta.34: web3-eth-iban "1.0.0-beta.34" web3-utils "1.0.0-beta.34" +web3-core-helpers@1.0.0-beta.35: + version "1.0.0-beta.35" + resolved "https://registry.yarnpkg.com/web3-core-helpers/-/web3-core-helpers-1.0.0-beta.35.tgz#d681d218a0c6e3283ee1f99a078ab9d3eef037f1" + dependencies: + underscore "1.8.3" + web3-eth-iban "1.0.0-beta.35" + web3-utils "1.0.0-beta.35" + web3-core-method@1.0.0-beta.34: version "1.0.0-beta.34" resolved "https://registry.yarnpkg.com/web3-core-method/-/web3-core-method-1.0.0-beta.34.tgz#ec163c8a2c490fa02a7ec15559fa7307fc7cc6dd" @@ -6484,6 +6664,16 @@ web3-core-method@1.0.0-beta.34: web3-core-subscriptions "1.0.0-beta.34" web3-utils "1.0.0-beta.34" +web3-core-method@1.0.0-beta.35: + version "1.0.0-beta.35" + resolved "https://registry.yarnpkg.com/web3-core-method/-/web3-core-method-1.0.0-beta.35.tgz#fc10e2d546cf4886038e6130bd5726b0952a4e5f" + dependencies: + 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@1.0.0-beta.34: version "1.0.0-beta.34" resolved "https://registry.yarnpkg.com/web3-core-promievent/-/web3-core-promievent-1.0.0-beta.34.tgz#a4f4fa6784bb293e82c60960ae5b56a94cd03edc" @@ -6491,6 +6681,13 @@ web3-core-promievent@1.0.0-beta.34: any-promise "1.3.0" eventemitter3 "1.1.1" +web3-core-promievent@1.0.0-beta.35: + version "1.0.0-beta.35" + resolved "https://registry.yarnpkg.com/web3-core-promievent/-/web3-core-promievent-1.0.0-beta.35.tgz#4f1b24737520fa423fee3afee110fbe82bcb8691" + dependencies: + any-promise "1.3.0" + eventemitter3 "1.1.1" + web3-core-requestmanager@1.0.0-beta.34: version "1.0.0-beta.34" resolved "https://registry.yarnpkg.com/web3-core-requestmanager/-/web3-core-requestmanager-1.0.0-beta.34.tgz#01f8f6cf2ae6b6f0b70c38bae1ef741b5bab215c" @@ -6501,6 +6698,16 @@ web3-core-requestmanager@1.0.0-beta.34: web3-providers-ipc "1.0.0-beta.34" web3-providers-ws "1.0.0-beta.34" +web3-core-requestmanager@1.0.0-beta.35: + version "1.0.0-beta.35" + resolved "https://registry.yarnpkg.com/web3-core-requestmanager/-/web3-core-requestmanager-1.0.0-beta.35.tgz#2b77cbf6303720ad68899b39fa7f584dc03dbc8f" + dependencies: + 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@1.0.0-beta.34: version "1.0.0-beta.34" resolved "https://registry.yarnpkg.com/web3-core-subscriptions/-/web3-core-subscriptions-1.0.0-beta.34.tgz#9fed144033f221c3cf21060302ffdaf5ef2de2de" @@ -6509,6 +6716,14 @@ web3-core-subscriptions@1.0.0-beta.34: underscore "1.8.3" web3-core-helpers "1.0.0-beta.34" +web3-core-subscriptions@1.0.0-beta.35: + version "1.0.0-beta.35" + resolved "https://registry.yarnpkg.com/web3-core-subscriptions/-/web3-core-subscriptions-1.0.0-beta.35.tgz#c1b76a2ad3c6e80f5d40b8ba560f01e0f4628758" + dependencies: + eventemitter3 "1.1.1" + underscore "1.8.3" + web3-core-helpers "1.0.0-beta.35" + web3-core@1.0.0-beta.34: version "1.0.0-beta.34" resolved "https://registry.yarnpkg.com/web3-core/-/web3-core-1.0.0-beta.34.tgz#121be8555e9fb00d2c5d05ddd3381d0c9e46987e" @@ -6518,6 +6733,22 @@ web3-core@1.0.0-beta.34: web3-core-requestmanager "1.0.0-beta.34" web3-utils "1.0.0-beta.34" +web3-core@1.0.0-beta.35: + version "1.0.0-beta.35" + resolved "https://registry.yarnpkg.com/web3-core/-/web3-core-1.0.0-beta.35.tgz#0c44d3c50d23219b0b1531d145607a9bc7cd4b4f" + dependencies: + 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-detect-network@^0.0.17: + version "0.0.17" + resolved "https://registry.yarnpkg.com/web3-detect-network/-/web3-detect-network-0.0.17.tgz#b531bd8c8e40d0c588f28a53b057e1be43db8a31" + dependencies: + bluebird "^3.5.1" + parse-domain "^1.1.0" + web3-eth-abi@1.0.0-beta.34, web3-eth-abi@^1.0.0-beta.34: version "1.0.0-beta.34" resolved "https://registry.yarnpkg.com/web3-eth-abi/-/web3-eth-abi-1.0.0-beta.34.tgz#034533e3aa2f7e59ff31793eaea685c0ed5af67a" @@ -6527,6 +6758,15 @@ web3-eth-abi@1.0.0-beta.34, web3-eth-abi@^1.0.0-beta.34: web3-core-helpers "1.0.0-beta.34" web3-utils "1.0.0-beta.34" +web3-eth-abi@1.0.0-beta.35: + version "1.0.0-beta.35" + resolved "https://registry.yarnpkg.com/web3-eth-abi/-/web3-eth-abi-1.0.0-beta.35.tgz#2eb9c1c7c7233db04010defcb192293e0db250e6" + dependencies: + bn.js "4.11.6" + underscore "1.8.3" + web3-core-helpers "1.0.0-beta.35" + web3-utils "1.0.0-beta.35" + web3-eth-accounts@1.0.0-beta.34, web3-eth-accounts@^1.0.0-beta.34: version "1.0.0-beta.34" resolved "https://registry.yarnpkg.com/web3-eth-accounts/-/web3-eth-accounts-1.0.0-beta.34.tgz#e09142eeecc797ac3459b75e9b23946d3695f333" @@ -6542,6 +6782,21 @@ web3-eth-accounts@1.0.0-beta.34, web3-eth-accounts@^1.0.0-beta.34: web3-core-method "1.0.0-beta.34" web3-utils "1.0.0-beta.34" +web3-eth-accounts@1.0.0-beta.35: + version "1.0.0-beta.35" + resolved "https://registry.yarnpkg.com/web3-eth-accounts/-/web3-eth-accounts-1.0.0-beta.35.tgz#7d0e5a69f510dc93874471599eb7abfa9ddf3e63" + dependencies: + 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" + web3-eth-contract@1.0.0-beta.34: version "1.0.0-beta.34" resolved "https://registry.yarnpkg.com/web3-eth-contract/-/web3-eth-contract-1.0.0-beta.34.tgz#9dbb38fae7643a808427a20180470ec7415c91e6" @@ -6555,6 +6810,19 @@ web3-eth-contract@1.0.0-beta.34: web3-eth-abi "1.0.0-beta.34" web3-utils "1.0.0-beta.34" +web3-eth-contract@1.0.0-beta.35: + version "1.0.0-beta.35" + resolved "https://registry.yarnpkg.com/web3-eth-contract/-/web3-eth-contract-1.0.0-beta.35.tgz#5276242d8a3358d9f1ce92b71575c74f9015935c" + dependencies: + 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@1.0.0-beta.34: version "1.0.0-beta.34" resolved "https://registry.yarnpkg.com/web3-eth-iban/-/web3-eth-iban-1.0.0-beta.34.tgz#9af458605867ccf74ea979aaf326b38ba6a5ba0c" @@ -6562,6 +6830,13 @@ web3-eth-iban@1.0.0-beta.34: bn.js "4.11.6" web3-utils "1.0.0-beta.34" +web3-eth-iban@1.0.0-beta.35: + version "1.0.0-beta.35" + resolved "https://registry.yarnpkg.com/web3-eth-iban/-/web3-eth-iban-1.0.0-beta.35.tgz#5aa10327a9abb26bcfc4ba79d7bad18a002b332c" + dependencies: + bn.js "4.11.6" + web3-utils "1.0.0-beta.35" + web3-eth-personal@1.0.0-beta.34: version "1.0.0-beta.34" resolved "https://registry.yarnpkg.com/web3-eth-personal/-/web3-eth-personal-1.0.0-beta.34.tgz#9afba167342ebde5420bcd5895c3f6c34388f205" @@ -6572,6 +6847,16 @@ web3-eth-personal@1.0.0-beta.34: web3-net "1.0.0-beta.34" web3-utils "1.0.0-beta.34" +web3-eth-personal@1.0.0-beta.35: + version "1.0.0-beta.35" + resolved "https://registry.yarnpkg.com/web3-eth-personal/-/web3-eth-personal-1.0.0-beta.35.tgz#ecac95b7a53d04a567447062d5cae5f49879e89f" + dependencies: + 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-eth@1.0.0-beta.34: version "1.0.0-beta.34" resolved "https://registry.yarnpkg.com/web3-eth/-/web3-eth-1.0.0-beta.34.tgz#74086000850c6fe6f535ef49837d6d4bb6113268" @@ -6589,6 +6874,23 @@ web3-eth@1.0.0-beta.34: web3-net "1.0.0-beta.34" web3-utils "1.0.0-beta.34" +web3-eth@1.0.0-beta.35: + version "1.0.0-beta.35" + resolved "https://registry.yarnpkg.com/web3-eth/-/web3-eth-1.0.0-beta.35.tgz#c52c804afb95e6624b6f5e72a9af90fbf5005b68" + dependencies: + 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-net@1.0.0-beta.34: version "1.0.0-beta.34" resolved "https://registry.yarnpkg.com/web3-net/-/web3-net-1.0.0-beta.34.tgz#427cea2f431881449c8e38d523290f173f9ff63d" @@ -6597,6 +6899,14 @@ web3-net@1.0.0-beta.34: web3-core-method "1.0.0-beta.34" web3-utils "1.0.0-beta.34" +web3-net@1.0.0-beta.35: + version "1.0.0-beta.35" + resolved "https://registry.yarnpkg.com/web3-net/-/web3-net-1.0.0-beta.35.tgz#5c6688e0dea71fcd910ee9dc5437b94b7f6b3354" + dependencies: + web3-core "1.0.0-beta.35" + web3-core-method "1.0.0-beta.35" + web3-utils "1.0.0-beta.35" + web3-providers-http@1.0.0-beta.34: version "1.0.0-beta.34" resolved "https://registry.yarnpkg.com/web3-providers-http/-/web3-providers-http-1.0.0-beta.34.tgz#e561b52bbb43766282007d40285bfe3550c27e7a" @@ -6604,6 +6914,13 @@ web3-providers-http@1.0.0-beta.34: web3-core-helpers "1.0.0-beta.34" xhr2 "0.1.4" +web3-providers-http@1.0.0-beta.35: + version "1.0.0-beta.35" + resolved "https://registry.yarnpkg.com/web3-providers-http/-/web3-providers-http-1.0.0-beta.35.tgz#92059d9d6de6e9f82f4fae30b743efd841afc1e1" + dependencies: + web3-core-helpers "1.0.0-beta.35" + xhr2-cookies "1.1.0" + web3-providers-ipc@1.0.0-beta.34: version "1.0.0-beta.34" resolved "https://registry.yarnpkg.com/web3-providers-ipc/-/web3-providers-ipc-1.0.0-beta.34.tgz#a1b77f1a306d73649a9c039052e40cb71328d00a" @@ -6612,6 +6929,14 @@ web3-providers-ipc@1.0.0-beta.34: underscore "1.8.3" web3-core-helpers "1.0.0-beta.34" +web3-providers-ipc@1.0.0-beta.35: + version "1.0.0-beta.35" + resolved "https://registry.yarnpkg.com/web3-providers-ipc/-/web3-providers-ipc-1.0.0-beta.35.tgz#031afeb10fade2ebb0ef2fb82f5e58c04be842d9" + dependencies: + oboe "2.1.3" + underscore "1.8.3" + web3-core-helpers "1.0.0-beta.35" + web3-providers-ws@1.0.0-beta.34: version "1.0.0-beta.34" resolved "https://registry.yarnpkg.com/web3-providers-ws/-/web3-providers-ws-1.0.0-beta.34.tgz#7de70f1b83f2de36476772156becfef6e3516eb3" @@ -6620,6 +6945,14 @@ web3-providers-ws@1.0.0-beta.34: web3-core-helpers "1.0.0-beta.34" websocket "git://github.com/frozeman/WebSocket-Node.git#browserifyCompatible" +web3-providers-ws@1.0.0-beta.35, web3-providers-ws@^1.0.0-beta.34: + version "1.0.0-beta.35" + resolved "https://registry.yarnpkg.com/web3-providers-ws/-/web3-providers-ws-1.0.0-beta.35.tgz#5d38603fd450243a26aae0ff7f680644e77fa240" + dependencies: + underscore "1.8.3" + web3-core-helpers "1.0.0-beta.35" + websocket "git://github.com/frozeman/WebSocket-Node.git#browserifyCompatible" + web3-shh@1.0.0-beta.34: version "1.0.0-beta.34" resolved "https://registry.yarnpkg.com/web3-shh/-/web3-shh-1.0.0-beta.34.tgz#975061d71eaec42ccee576f7bd8f70f03844afe0" @@ -6629,6 +6962,15 @@ web3-shh@1.0.0-beta.34: web3-core-subscriptions "1.0.0-beta.34" web3-net "1.0.0-beta.34" +web3-shh@1.0.0-beta.35: + version "1.0.0-beta.35" + resolved "https://registry.yarnpkg.com/web3-shh/-/web3-shh-1.0.0-beta.35.tgz#7e4a585f8beee0c1927390937c6537748a5d1a58" + dependencies: + 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@1.0.0-beta.34, web3-utils@^1.0.0-beta.34: version "1.0.0-beta.34" resolved "https://registry.yarnpkg.com/web3-utils/-/web3-utils-1.0.0-beta.34.tgz#9411fc39aaef39ca4e06169f762297d9ff020970" @@ -6641,6 +6983,18 @@ web3-utils@1.0.0-beta.34, web3-utils@^1.0.0-beta.34: underscore "1.8.3" utf8 "2.1.1" +web3-utils@1.0.0-beta.35: + version "1.0.0-beta.35" + resolved "https://registry.yarnpkg.com/web3-utils/-/web3-utils-1.0.0-beta.35.tgz#ced9e1df47c65581c441c5f2af76b05a37a273d7" + dependencies: + bn.js "4.11.6" + eth-lib "0.1.27" + ethjs-unit "0.1.6" + number-to-bn "1.7.0" + randomhex "0.1.5" + underscore "1.8.3" + utf8 "2.1.1" + web3@^0.18.4: version "0.18.4" resolved "https://registry.yarnpkg.com/web3/-/web3-0.18.4.tgz#81ec1784145491f2eaa8955b31c06049e07c5e7d" @@ -6663,6 +7017,18 @@ web3@^1.0.0-beta.33: web3-shh "1.0.0-beta.34" web3-utils "1.0.0-beta.34" +web3@^1.0.0-beta.34: + version "1.0.0-beta.35" + resolved "https://registry.yarnpkg.com/web3/-/web3-1.0.0-beta.35.tgz#6475095bd451a96e50a32b997ddee82279292f11" + dependencies: + 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" + webpack-addons@^1.1.5: version "1.1.5" resolved "https://registry.yarnpkg.com/webpack-addons/-/webpack-addons-1.1.5.tgz#2b178dfe873fb6e75e40a819fa5c26e4a9bc837a" @@ -6835,6 +7201,12 @@ xhr-request@^1.0.1: url-set-query "^1.0.0" xhr "^2.0.4" +xhr2-cookies@1.1.0: + version "1.1.0" + resolved "https://registry.yarnpkg.com/xhr2-cookies/-/xhr2-cookies-1.1.0.tgz#7d77449d0999197f155cb73b23df72505ed89d48" + dependencies: + cookiejar "^2.1.1" + xhr2@*, xhr2@0.1.4: version "0.1.4" resolved "https://registry.yarnpkg.com/xhr2/-/xhr2-0.1.4.tgz#7f87658847716db5026323812f818cadab387a5f"