diff --git a/package.json b/package.json index 2605c3f..db37831 100644 --- a/package.json +++ b/package.json @@ -6,6 +6,7 @@ "dependencies": { "@ledgerhq/hw-app-eth": "^4.7.3", "@ledgerhq/hw-transport-u2f": "^4.7.3", + "abi-decoder": "^1.2.0", "autoprefixer": "7.1.2", "babel-core": "6.25.0", "babel-eslint": "7.2.3", diff --git a/src/components/Routes.jsx b/src/components/Routes.jsx index 1af260f..b860545 100644 --- a/src/components/Routes.jsx +++ b/src/components/Routes.jsx @@ -3,8 +3,6 @@ import React from "react"; import {withRouter, Route, Switch} from "react-router-dom"; // Components -import FAQ from "./FAQ"; -import Main from "./Main"; import Widget from "./Widget"; @withRouter @@ -18,9 +16,7 @@ class Routes extends React.Component { render() { return ( - } /> - } /> -
} />} /> + } /> {/* */} ); diff --git a/src/components/TaxWidget.jsx b/src/components/TaxWidget.jsx new file mode 100644 index 0000000..0194bd0 --- /dev/null +++ b/src/components/TaxWidget.jsx @@ -0,0 +1,514 @@ +import React, { Component } from 'react'; +import abiDecoder from 'abi-decoder'; +import config from '../exporter-config'; +import web3 from '../utils/web3'; +import * as Blockchain from '../utils/blockchain'; +import { fromWei, isAddress } from '../utils/helpers'; +import { vulcan0x } from '../utils/vulcan0x'; +import Spinner from '../components-ui/Spinner'; + + +const schema = {}; + +schema.dstoken = require('../abi/dstoken'); +schema.dsethtoken = require('../abi/dsethtoken'); +schema.proxyregistry = require('../abi/proxyregistry'); +schema.legacyproxyregistry = require('../abi/legacyproxyregistry'); +schema.dsproxy = require('../abi/dsproxy'); +schema.matchingmarket = require('../abi/matchingmarket'); +schema.proxycreateandexecute = require('../abi/proxycreateandexecute'); + +class TaxWidget extends Component { + constructor(props) { + super(); + this.props = props; + this.state = { + isLoading: false, + accounts: [ + this.props.account, + ], + exchanges: [ + 'oasis' + ], + newAddress: "", + csvData: [] + } + } + + removeAccount = id => { + // making copy of the accounts + const accounts = [...this.state.accounts]; + + // Splice removes the selected element and modifies the array beneath + // We discard the returned value because we care only in the modified version + accounts.splice(id, 1); + + // Set the new array with the removed account + this.setState({accounts}); + } + + addAccount = event => { + event.preventDefault(); + const address = (this.state.newAddress || "").trim(); + + if (isAddress(address)) { + const accounts = [...this.state.accounts]; + + if (!accounts.includes(address)) { + accounts.push(address); + this.setState({accounts, newAddress: ''}); + } else { + alert("This address is already in the list"); + } + } else { + alert("This is not a valid address"); + } + } + + getLegacyProxies = (registry, address) => { + return new Promise((resolve, reject) => { + const proxies = []; + const registryObj = Blockchain.loadObject('legacyproxyregistry', registry); + registryObj.proxiesCount(address, async (e, count) => { + if (!e) { + if (count.gt(0)) { + for (let i = count.toNumber() - 1; i >= 0; i--) { + proxies.push(await Blockchain.legacy_getProxy(registryObj, address, i)); + } + } + resolve(proxies); + } else { + reject(e); + } + }); + }); + } + + getPossibleProxies = address => { + return new Promise((resolve, reject) => { + const promises = []; + config.taxProxyRegistries[this.props.network].legacy.forEach(registry => { + promises.push(this.getLegacyProxies(registry, address)); + }); + promises.push(Blockchain.getProxy(address)); + let proxies = []; + Promise.all(promises).then(r => { + for (let i = 0; i < r.length; i++) { + if (typeof r[i] === 'object') { + proxies = proxies.concat(r[i]); + } else { + proxies.push(r[i]); + } + } + resolve(proxies); + }, e => reject(e)); + }); + } + + fetchOasisTradesFromAccount = (contract, filter) => { + return new Promise((resolve, reject) => { + Blockchain.loadObject('matchingmarket', contract.address).LogTake(filter, { + fromBlock: contract.block_start, + toBlock: contract.block_end + }).get((error, logs) => { + if (!error) { + resolve(logs); + } else { + reject(error); + } + }); + }); + } + + getOwnerTransaction = tx => { + return new Promise((resolve, reject) => { + Blockchain.getTransactionReceipt(tx).then(r => resolve(r.from), e => reject(e)); + }); + } + + fetchOasisMakeTrades = (contract, address) => { + return new Promise((resolve, reject) => { + + this.fetchOasisTradesFromAccount(contract, {maker: address}).then(logs => { + const promises = []; + logs.forEach(log => { + promises.push(this.addOasisTradeFor(address, 'maker', log.args)); + }); + Promise.all(promises).then(() => resolve(true)); + }, () => { + reject(); + }) + }); + } + + fetchOasisMakeTradesCached = (address) => { + return new Promise(async (resolve, reject) => { + try { + const promises = []; + + address = web3.toChecksumAddress(address); + + const take_trades = await this.getTradesFromCache([address], 'maker'); + + for (let i = 0; i < take_trades.length; i++) { + promises.push(this.addOasisTradeForCached(address, 'maker', take_trades[i])); + } + Promise.all(promises).then(() => resolve(true)); + }catch (e) { + reject(e); + } + }); + } + + fetchOasisTakeTrades = (contract, address) => { + return new Promise(async (resolve, reject) => { + try { + const promises = []; + const proxiesAddr = await this.getPossibleProxies(address); + + promises.push(this.fetchOasisTradesFromAccount(contract, {taker: address})); + proxiesAddr.forEach(proxyAddr => { + promises.push(this.fetchOasisTradesFromAccount(contract, {taker: proxyAddr})); + }); + config.supportContracts[this.props.network].forEach(supportContract => { + promises.push(this.fetchOasisTradesFromAccount(contract, {taker: supportContract.address})); + }); + Promise.all(promises).then(async r => { + const promises2 = []; + + for (let i = 0; i < r.length; i++) { + for (let j = 0; j < r[i].length; j++) { + + const owner = await this.getOwnerTransaction(r[i][j].transactionHash); + if (i === 0 || owner === address) { + // For the cases of proxy trades we need to verify if they were done by the address requested or the proxy might have been transferred before + promises2.push(this.addOasisTradeFor(address, 'taker', r[i][j].args)); + } + } + } + Promise.all(promises2).then(() => resolve(true)); + }, e => { + reject(e); + }) + } catch (e) { + reject(e); + } + }); + } + + getTradesFromCache = (addresses, side) => { + return new Promise((resolve, reject) => { + try { + const vulcanquery = vulcan0x(addresses, side); + vulcanquery.then((res) => { + const trades = []; + const nodes = res.data['allOasisTrades']['nodes']; + for (let i = 0; i < nodes.length; i++) { + trades.push(nodes[i]); + } + resolve(trades); + }); + }catch (e) { + reject(e); + } + }); + } + + getTransactionInfo = (tx) => { + return new Promise((resolve, reject) => { + Blockchain.getTransaction(tx).then(r => { + + abiDecoder.addABI(schema.proxyregistry.abi); + abiDecoder.addABI(schema.dstoken.abi); + abiDecoder.addABI(schema.dsethtoken.abi); + abiDecoder.addABI(schema.legacyproxyregistry.abi); + abiDecoder.addABI(schema.dsproxy.abi); + abiDecoder.addABI(schema.matchingmarket.abi); + abiDecoder.addABI(schema.proxycreateandexecute.abi); + + const transactionData = abiDecoder.decodeMethod(r.input); + + resolve(transactionData); + + }); + + }); + + }; + + fetchOasisTakeTradesCached = (address) => { + return new Promise(async (resolve, reject) => { + try { + const promises = []; + const proxiesAddr = await this.getPossibleProxies(address); + + const supportContracts = []; + config.supportContracts[this.props.network].forEach(supportContract => { + supportContracts.push(supportContract.address); + }); + + const addresses = [address, ...proxiesAddr, ...supportContracts].filter(address => address).map(address => web3.toChecksumAddress(address)); + const take_trades = await this.getTradesFromCache(addresses, 'taker'); + + for (let i = 0; i < take_trades.length; i++) { + promises.push(this.addOasisTradeForCached(address, 'taker', take_trades[i])); + } + + Promise.all(promises).then(() => resolve(true)); + + } catch (e) { + reject(e); + } + }); + } + + setLoading = value => { + this.setState(() => { + return {isLoading: value}; + }); + } + + fetchData = e => { + e.preventDefault(); + this.setLoading(true); + let accounts = [...this.state.accounts]; + let oasisPromises = []; + this.setState({csvData: []}, () => { + accounts.forEach(account => { + + // New methods to fetch make/take trades from vulcan0x cache instead of web3 instance. + // Old fetch methods left below for testing purposes. + + oasisPromises.push(this.fetchOasisMakeTradesCached(account)); + oasisPromises.push(this.fetchOasisTakeTradesCached(account)); + + // config.oasis.contract[this.props.network].forEach(contract => { + // oasisPromises.push(this.fetchOasisMakeTrades(contract, account)); + // oasisPromises.push(this.fetchOasisTakeTrades(contract, account)); + // }); + + + if (this.props.network === 'main') { + oasisPromises.push(this.fetchLegacyTrades(account)); + } + }); + + Promise.all(oasisPromises).then(() => { + this.downloadCSV(); + this.setLoading(false); + }); + }); + } + + fetchLegacyFile = (fileIndex, address) => { + return new Promise((resolve, reject) => { + const xhr = new XMLHttpRequest(); + xhr.open('GET', `https://oasisdex.github.io/oasis-dex-script/maker-otc-${fileIndex < 10 ? "0" : ""}${fileIndex}.trades.json`, true); + xhr.onreadystatechange = () => { + if (xhr.readyState === 4 && xhr.status === 200) { + const promises = []; + const data = JSON.parse(xhr.responseText); + for (let i = 0; i < data.length; i++) { + const taker = `0x${data[i].taker}`; + const maker = `0x${data[i].maker}`; + if (taker === address || maker === address) { + promises.push(this.addOasisLegacyTradeFor(address, maker === address ? 'maker' : 'taker', data[i])); + } + } + Promise.all(promises).then(() => resolve(true)); + } else if (xhr.readyState === 4 && xhr.status !== 200) { + reject(xhr.status); + } + } + xhr.send(); + }); + } + + fetchLegacyTrades = address => { + return new Promise((resolve, reject) => { + const promises = []; + for (let i = 2; i <= 19; i++) { + promises.push(this.fetchLegacyFile(i, address)); + } + Promise.all(promises).then(() => resolve(true)); + }); + } + + addOasisTradeFor = (address, side, log) => { + return new Promise((resolve, reject) => { + const sellAmount = fromWei(side === 'maker' ? log.take_amt : log.give_amt).toString(10); + const buyAmount = fromWei(side === 'maker' ? log.give_amt : log.take_amt).toString(10); + const sellTokenAddress = side === 'maker' ? log.pay_gem : log.buy_gem; + const buyTokenAddress = side === 'maker' ? log.buy_gem : log.pay_gem; + const sellToken = config.tokens[this.props.network][sellTokenAddress]; + const buyToken = config.tokens[this.props.network][buyTokenAddress]; + + const trade = { + type: 'Trade', + buyAmount, + buyToken, + sellAmount, + sellToken: sellToken, + fee: '', + feeToken: '', + exchange: 'Oasisdex.com', + group: '', + address, + timestamp: log.timestamp, + }; + + //add trade to CSV + this.addTradeToCSV(trade).then(() => resolve(true)); + }); + } + + addOasisTradeForCached = (address, side, log) => { + + return new Promise((resolve, reject) => { + const sellAmount = side === 'maker' ? log['lotAmt'] : log['bidAmt']; + const buyAmount = side === 'maker' ? log['bidAmt'] : log['lotAmt']; + const sellToken = side === 'maker' ? log.lotTkn : log.bidTkn; + const buyToken = side === 'maker' ? log.bidTkn : log.lotTkn; + + const trade = { + type: 'Trade', + side, + buyAmount: buyAmount, + buyToken: buyToken, + sellAmount: sellAmount, + sellToken: sellToken, + exchange: 'Oasisdex.com', + tx: log['tx'], + address, + timestamp: Date.parse(log['time'])/1000, + }; + + //add trade to CSV + this.addTradeToCSV(trade).then(() => resolve(true)); + }); + } + + addOasisLegacyTradeFor = (address, side, log) => { + return new Promise((resolve, reject) => { + const sellAmount = fromWei(`0x${side === 'maker' ? log.takeAmount : log.giveAmount}`).toString(10); + const buyAmount = fromWei(`0x${side === 'maker' ? log.giveAmount : log.takeAmount}`).toString(10); + const sellTokenAddress = `0x${side === 'maker' ? log.haveToken : log.wantToken}`; + const buyTokenAddress = `0x${side === 'maker' ? log.wantToken : log.haveToken}`; + const sellToken = config.tokens[this.props.network][sellTokenAddress]; + const buyToken = config.tokens[this.props.network][buyTokenAddress]; + + const trade = { + type: 'Trade', + buyAmount, + buyToken, + sellAmount, + sellToken: sellToken, + fee: '', + feeToken: '', + exchange: 'Oasisdex.com', + group: '', + address, + timestamp: log.timestamp, + }; + + //add trade to CSV + this.addTradeToCSV(trade).then(() => resolve(true), e => reject(e)); + }); + } + + addTradeToCSV = trade => { + return new Promise((resolve, reject) => { + //add a line break after each row + this.setState(prevState => { + const csvData = [...prevState.csvData]; + csvData.push(trade); + return {csvData}; + }, () => resolve(true)); + }); + } + + downloadCSV = () => { + const currentDate = new Date(); + const fileName = `trades-report-${currentDate.getFullYear()}-${ (currentDate.getMonth()+1) <= 9 ? '0'+(currentDate.getMonth()+1) : (currentDate.getMonth()+1) }-${currentDate.getDate()}`; + let csvData = [...this.state.csvData]; + csvData = csvData.sort((a, b) => a.timestamp > b.timestamp); + csvData.map(trade => { + trade.date = new Date(trade.timestamp * 1000).toLocaleString().replace(',', ''); + // delete trade.timestamp; + return trade; + }) + var uri = 'data:text/csv;charset=utf-8,' + + + encodeURIComponent(`"Type";"Side";"Buy";"Cur.";"Sell";"Cur.";"Exchange";"Tx";"Address";"TS";"Date"\r\n${csvData.map(trade => `"${Object.keys(trade).map(key => trade[key]).join('";"')}"\r\n`).join('')}`); + const link = document.createElement("a"); + link.href = uri; + + link.style = 'visibility:hidden'; + link.download = fileName + ".csv"; + + //this part will append the anchor tag and remove it after automatic click + document.body.appendChild(link); + link.click(); + document.body.removeChild(link); + } + + toggleExchange = (thisOne) => { + if(!thisOne) return; + + this.setState(prevState => { + const currentExchanges = [...prevState.exchanges]; + + if (currentExchanges.includes(thisOne) && currentExchanges.length > 1) { + const position = currentExchanges.indexOf(thisOne); + currentExchanges.splice(position, 1); + } else if (!currentExchanges.includes(thisOne)) { + currentExchanges.push(thisOne); + } + + return { exchanges: currentExchanges }; + }); + } + + render() { + return ( +
+
+

Enter Addresses

+
+
+
+
    + { + this.state.accounts.map((account, index) => { + + return ( +
  • + + {account.toLowerCase()} + +
  • + ) + }) + } +
+
+
+ this.setState({newAddress: event.target.value})}/> + +
+
+ +
+ ) + } +} + +export default TaxWidget; diff --git a/src/components/Widget.jsx b/src/components/Widget.jsx index 50f018e..4a16622 100644 --- a/src/components/Widget.jsx +++ b/src/components/Widget.jsx @@ -5,7 +5,7 @@ import {inject, observer} from "mobx-react"; // Components import HardWallet from "./HardWallet"; import LockedAccount from "./LockedAccount"; -import TradeWidget from "./TradeWidget"; +import TaxWidget from './TaxWidget'; import Wallets from "./Wallets"; // Utils @@ -15,6 +15,7 @@ import {isAddress} from "../utils/helpers"; @observer class Widget extends React.Component { render() { + return (
{ @@ -28,7 +29,10 @@ class Widget extends React.Component { : this.props.network.defaultAccount && isAddress(this.props.network.defaultAccount) ? - + : } diff --git a/src/exporter-config.json b/src/exporter-config.json new file mode 100644 index 0000000..0d4281d --- /dev/null +++ b/src/exporter-config.json @@ -0,0 +1,157 @@ +{ + "volcan0x": { + "url": "https://kovan-oasisvulcan0x.makerfoundation.com/v1" + }, + "csv": { + "title": "TaxReport", + "header": [ + "Type", + "Buy", + "Cur.", + "Sell", + "Cur.", + "Fee", + "Cur.", + "Exchange", + "Comment", + "Date" + ] + }, + "tokens": { + "kovan": { + "0x53eccc9246c1e537d79199d0c7231e425a40f896": "ETH", + "0x4bb514a7f83fbb13c2b41448208e89fabbcfe2fb": "MKR", + "0xbb7697d091a2b9428053e2d42d088fcd2a6a0aaf": "DGD", + "0xece9fa304cc965b00afc186f5d0281a00d3dbbfd": "GNT", + "0xbd1ceb35769eb44b641c8e257005817183fc2817": "W-GNT", + "0x99e846cfe0321260e51963a2114bc4008d092e24": "REP", + "0x8a55df5de91eceb816bd9263d2e5f35fd516d4d0": "ICN", + "0x846f258ac72f8a60920d9b613ce9e91f8a7a7b54": "1ST", + "0xf7d57c676ac2bc4997ca5d4d34adc0d072213d29": "SNGLS", + "0x2e65483308968f5210167a23bdb46ec94752fe39": "VSL", + "0x00a0fcaa32b47c4ab4a8fdda6d108e5c1ffd8e4f": "PLU", + "0xc3ce96164012ed51c9b1e34a9323fdc38c96ad8a": "MLN", + "0x7352c20e00d3c89037a8959699741c341771ed59": "RHOC", + "0xd944954588061c969fbd828d1f00c297c3511dbd": "TIME", + "0xa786d73316e43c3361145241755566e72424274c": "GUP", + "0xd0a1e359811322d97991e03f863a0c30c2cf029c": "WETH", + "0xc4375b7de8af5a38a93548eb8453a498222c4ff2": "DAI", + "0xaaf64bfcc32d0f15873a02163e7e500671a4ffcd": "MKR" + }, + "main": { + "0xecf8f87f810ecf450940c9f60066b4a7a501d6a7": "WETH", + "0xc02aaa39b223fe8d0a0e5c4f27ead9083c756cc2": "WETH", + "0xc66ea802717bfb9833400264dd12c2bceaa34a6d": "MKR", + "0x9f8f72aa9304c8b593d555f12ef6589cc3a579a2": "MKR", + "0x89d24a6b4ccb1b6faa2625fe562bdd9a23260359": "DAI", + "0x59adcf176ed2f6788a41b8ea4c4904518e62b6a4": "SAI", + "0x0000000000000000000000000000000000000000": "ETH", + "0xd8912c10681d8b21fd3742244f44658dba12264e": "PLU", + "0xaf30d2a7e90d7dc361c8c4585e9bb7d2f6f15bc7": "1ST", + "0x936f78b9852d12f5cb93177c1f84fb8513d06263": "GNT", + "0x01afc37f4f85babc47c0e2d0eababc7fb49793c8": "GNT", + "0xa74476443119a942de498590fe1f2454d7d4ac0d": "GNT", + "0x5c543e7ae0a1104f78406c340e9c64fd9fce5170": "VSL", + "0xac709fcb44a43c35f0da4e3163b117a17f3770f5": "ARC", + "0x14f37b574242d366558db61f3335289a5035c506": "HKG", + "0x888666ca69e0f178ded6d75b5726cee99a87d698": "ICN", + "0x48c80f1f4d53d5951e5d5438b54cba84f29f32a5": "REP", + "0xaec2e87e0a235266d9c5adc9deb4b2e29b54d009": "SNGLS", + "0x4df812f6064def1e5e029f1ca858777cc98d2d81": "XAUR", + "0xe0b7927c4af23765cb51314a0e0521a9645f0e2a": "DGD", + "0xce3d9c3f3d302436d12f18eca97a3b00e97be7cd": "EPOSY", + "0x289fe11c6f46e28f9f1cfc72119aee92c1da50d0": "EPOSN", + "0xbb9bc244d798123fde783fcc1c72d3bb8c189413": "DAO", + "0x55e7c4a77821d5c50b4570b08f9f92896a25e012": "P+", + "0x45e42d659d9f9466cd5df622506033145a9b89bc": "NXC", + "0x08d32b0da63e2C3bcF8019c9c5d849d7a9d791e6": "DCN", + "0x01a7018e6d1fde8a68d12f59b6532fb523b6259d": "USD.DC", + "0xffad42d96e43df36652c8eaf61a7e6dba2ad0e41": "BTC.DC", + "0x949bed886c739f1a3273629b3320db0c5024c719": "AMIS", + "0xb9e7f8568e08d5659f5d29c4997173d84cdf2607": "SWT", + "0xf77089f2f00fca83501705b711cbb10a0de77628": "BME", + "0xb802b24e0637c2b87d2e8b7784c055bbe921011a": "EMV", + "0x6531f133e6deebe7f2dce5a0441aa7ef330b4e53": "TIME", + "0x059d4329078dcA62c521779c0Ce98EB9329349e6": "TIG", + "0xbeb9ef514a379b997e0798fdcc901ee474b6d9a1": "MLN", + "0x168296bb09e24a88805cb9c33356536b980d3fc5": "RHOC", + "0x08711d3b02c8758f2fb3ab4e80228418a7f8e39c": "EDG", + "0xf7b098298f7c69fc14610bf71d5e02c60792894c": "GUP", + "0xc2921ea1c150405ef952f73952f37fa2746168d8": "ETB", + "0x607f4c5bb672230e8672085532f7e901544a7375": "RLC", + "0xcb94be6f13a1182e4a4b6140cb7bf2025d28e41b": "TRST", + "0x2e071d2966aa7d8decb1005885ba1977d6038a65": "DICE", + "0xe7775a6e9bcf904eb39da2b68c5efb4f9360e08c": "TAAS", + "0x6810e776880c02933d47db1b9fc05908e5386b96": "GNO", + "0x667088b212ce3d06a1b553a7221e1fd19000d9af": "WINGS", + "0xfa05a73ffe78ef8f1a739473e462c54bae6567d9": "LUN", + "0xaaaf91d9b90df800df4f55c205fd6989c977e73a": "TKN", + "0xcbcc0f036ed4788f63fc0fee32873d6a7487b908": "HMQ" + } + }, + "oasis": { + "contract": { + "kovan": [ + { + "address": "0x45ab8d410049116c7a01f6edfc08d564475c08ed", + "block_start": 685569, + "block_end": 5216718 + }, + { + "address": "0x8cf1cab422a0b6b554077a361f8419cdf122a9f9", + "block_start": 5216718, + "block_end": "latest" + } + ], + "main": [ + { + "address": "0x83ce340889c15a3b4d38cfcd1fc93e5d8497691f", + "block_start": 3435757, + "block_end": 4262880 + }, + { + "address": "0x3aa927a97594c3ab7d7bf0d47c71c3877d1de4a1", + "block_start": 4262057, + "block_end": 4761589 + }, + { + "address": "0x91dfe531ff8ba876a505c8f1c98bafede6c7effc", + "block_start": 4732388, + "block_end": 4732986 + }, + { + "address": "0x14fbca95be7e99c15cc2996c6c9d841e54b79425", + "block_start": 4751582, + "block_end": "latest" + } + ] + } + }, + "taxProxyRegistries": { + "kovan": { + "legacy": [ + "0x383a7fc29edde64aec7f776e2517ec8819e147f1" + ] + }, + "main": { + "legacy": [ + "0xaa63c8683647ef91b3fdab4b4989ee9588da297b" + ] + } + }, + "supportContracts": { + "kovan": [], + "main": [ + { + "address": "0xb0a00896f34655edff6c8d915fb342194c4a6d48", + "block_start": 5120103, + "block_end": 5267186 + }, + { + "address": "0x793ebbe21607e4f04788f89c7a9b97320773ec59", + "block_start": 5267186, + "block_end": "latest" + } + ] + } +} diff --git a/src/styles/App.css b/src/styles/App.css index 3762425..14b96df 100644 --- a/src/styles/App.css +++ b/src/styles/App.css @@ -199,6 +199,10 @@ height: 18px; } +.frame { + margin: 40px auto 0; +} + .label { font-family: Montserrat, sans-serif; font-size: 12px; @@ -1037,8 +1041,7 @@ button[disabled] { .frame button.close { position: absolute; - top: 18px; - right: 22px; + right: 30px; } .swap-tokens { diff --git a/src/utils/vulcan0x.js b/src/utils/vulcan0x.js new file mode 100644 index 0000000..d03d85f --- /dev/null +++ b/src/utils/vulcan0x.js @@ -0,0 +1,46 @@ +import config from '../exporter-config'; + +export const vulcan0x = async (accounts, type) => { + + const res = await fetch(config.volcan0x.url, + { + headers: {"Content-Type": "application/json; charset=utf-8"}, + method: 'POST', + body: JSON.stringify({ + query: `query tradesForAddresses($filter: OasisTradeFilter) { + allOasisTrades(filter: $filter) { + nodes { + offerId + act + maker + taker + bidAmt + bidTkn + bidGem + lotAmt + lotTkn + lotGem + price + time + tx + } + } + }`, + variables: { + "devMode": "2232759874", + "filter": { + [type]: { + "in": accounts + }, + // "time": { + // "lessThan": "2018-08-05T19:15:19.062Z", + // "greaterThan": "2018-06-05T19:15:19.062Z" + // }, + } + } + }) + } + ); + + return res.json(); +}; diff --git a/yarn.lock b/yarn.lock index 298a51a..254b058 100644 --- a/yarn.lock +++ b/yarn.lock @@ -113,6 +113,13 @@ abbrev@1: version "1.1.1" resolved "https://registry.yarnpkg.com/abbrev/-/abbrev-1.1.1.tgz#f8f2c887ad10bf67f634f005b6987fed3179aac8" +abi-decoder@^1.2.0: + version "1.2.0" + resolved "https://registry.yarnpkg.com/abi-decoder/-/abi-decoder-1.2.0.tgz#c42882dbb91b444805f0cd203a87a5cc3c22f4a8" + integrity sha512-y2OKSEW4gf2838Eavc56vQY9V46zaXkf3Jl1WpTfUBbzAVrXSr4JRZAAWv55Tv9s5WNz1rVgBgz5d2aJIL1QCg== + dependencies: + web3 "^0.18.4" + abstract-leveldown@~2.6.0: version "2.6.3" resolved "https://registry.yarnpkg.com/abstract-leveldown/-/abstract-leveldown-2.6.3.tgz#1c5e8c6a5ef965ae8c35dfb3a8770c476b82c4b8" @@ -1356,6 +1363,10 @@ bignumber.js@^7.2.1: version "7.2.1" resolved "https://registry.yarnpkg.com/bignumber.js/-/bignumber.js-7.2.1.tgz#80c048759d826800807c4bfd521e50edbba57a5f" +"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" + "bignumber.js@git+https://github.com/frozeman/bignumber.js-nolookahead.git": version "2.0.7" resolved "git+https://github.com/frozeman/bignumber.js-nolookahead.git#57692b3ecfc98bbdd6b3a516cb2353652ea49934" @@ -9889,6 +9900,17 @@ web3-utils@1.0.0-beta.36: 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" + integrity sha1-gewXhBRUkfLqqJVbMcBgSeB8Xn0= + dependencies: + bignumber.js "git+https://github.com/debris/bignumber.js.git#94d7146671b9719e00a09c29b01a691bc85048c2" + crypto-js "^3.1.4" + utf8 "^2.1.1" + xhr2 "*" + xmlhttprequest "*" + web3@^0.20.6: version "0.20.7" resolved "https://registry.yarnpkg.com/web3/-/web3-0.20.7.tgz#1605e6d81399ed6f85a471a4f3da0c8be57df2f7" @@ -10175,6 +10197,11 @@ xhr2-cookies@1.1.0, xhr2-cookies@^1.1.0: dependencies: cookiejar "^2.1.1" +xhr2@*: + version "0.1.4" + resolved "https://registry.yarnpkg.com/xhr2/-/xhr2-0.1.4.tgz#7f87658847716db5026323812f818cadab387a5f" + integrity sha1-f4dliEdxbbUCYyOBL4GMras4el8= + xhr@^2.0.4, xhr@^2.2.0, xhr@^2.3.3: version "2.5.0" resolved "https://registry.yarnpkg.com/xhr/-/xhr-2.5.0.tgz#bed8d1676d5ca36108667692b74b316c496e49dd"