feat: custom provider that only acts as relayer on low balance and calling specific functions (#300)
* feat: hide token offers if you don't have ETH in your wallet * fix: code review * feat: hidde other assets from profile * fix: code review * feat: custom provider * fix: code review * fix: code revew / reversing condition
This commit is contained in:
parent
14567debb0
commit
173db39623
|
@ -43,7 +43,7 @@ contract Escrow is Pausable, MessageSigned, Fees, Arbitrable, RelayRecipient {
|
|||
}
|
||||
|
||||
function setRelayHubAddress(address _relayHub) public onlyOwner {
|
||||
init_relay_hub(RelayHub(_relayHub));
|
||||
set_relay_hub(RelayHub(_relayHub));
|
||||
}
|
||||
|
||||
Arbitration arbitration;
|
||||
|
|
|
@ -260,6 +260,46 @@ module.exports = {
|
|||
dappConnection: ["$WEB3"]
|
||||
},
|
||||
|
||||
ropsten: {
|
||||
tracking: 'shared.ropsten.chains.json',
|
||||
contracts: {
|
||||
Escrow: {
|
||||
args: ["$License", "$Arbitration", "$MetadataStore", "$SNT", BURN_ADDRESS, FEE_AMOUNT],
|
||||
deps: ['RelayHub'],
|
||||
onDeploy: [
|
||||
"Arbitration.methods.setEscrowAddress('$Escrow').send()",
|
||||
"MetadataStore.methods.setEscrowAddress('$Escrow').send()",
|
||||
"Escrow.methods.setRelayHubAddress('$RelayHub').send()",
|
||||
"RelayHub.methods.depositFor('$Escrow').send({value: 300000000000000000})"
|
||||
]
|
||||
},
|
||||
SNT: {
|
||||
address: "0xc55cf4b03948d7ebc8b9e8bad92643703811d162"
|
||||
},
|
||||
"RLPReader": {
|
||||
deploy: false
|
||||
},
|
||||
"RelayHub": {
|
||||
address: "0x1349584869A1C7b8dc8AE0e93D8c15F5BB3B4B87"
|
||||
}
|
||||
},
|
||||
deployment: {
|
||||
accounts: [
|
||||
{
|
||||
mnemonic: secret.mnemonic,
|
||||
hdpath: secret.hdpath || "m/44'/60'/0'/0/",
|
||||
numAddresses: "10"
|
||||
}
|
||||
],
|
||||
host: `ropsten.infura.io/${secret.infuraKey}`,
|
||||
port: false,
|
||||
protocol: 'https',
|
||||
type: "rpc"
|
||||
},
|
||||
afterDeploy: dataMigration.bind(null, LICENSE_PRICE, ARB_LICENSE_PRICE, FEE_AMOUNT),
|
||||
dappConnection: ["$WEB3"]
|
||||
},
|
||||
|
||||
// merges with the settings in default
|
||||
// used with "embark run livenet"
|
||||
livenet: {
|
||||
|
|
|
@ -0,0 +1,46 @@
|
|||
{
|
||||
"0x41941023680923e0fe4d74a34bdac8141f2540e3ae90623718e47d66d1ca4a2d": {
|
||||
"contracts": {
|
||||
"0x3043b04ad856d169c8f0b0509c0bc63192dc7edd92d6933c58708298a0e381be": {
|
||||
"name": "ENSRegistry",
|
||||
"address": "0x112234455c3a32fd11230c42e7bccd4a84e02010"
|
||||
},
|
||||
"0x4f96b534860cd72e9388b7373c14f4d9bdc201a81bdccdc1b2922865de029497": {
|
||||
"name": "RelayHub",
|
||||
"address": "0x1349584869A1C7b8dc8AE0e93D8c15F5BB3B4B87"
|
||||
},
|
||||
"0x573ce922ef30ea27239add0fb9f2af8d008314dc4a0b3eaefa0adaf8963e44fa": {
|
||||
"name": "StandardToken",
|
||||
"address": "0xEAFb5d3c2c79B48896589ec1dfd1E95ed24D6f93"
|
||||
},
|
||||
"0x5cd70a563902729e50887cf8436b89ccf72107e0acf1a98fd78d1b68c0a8edcc": {
|
||||
"name": "MiniMeTokenFactory",
|
||||
"address": "0x1B3748Bdc4aF6f6BE159DDDEA0154fa3717cB516"
|
||||
},
|
||||
"0x90633e0d0e44dedf48012ba2f1f863ad09468d7fb9793830f6e1a8adbeaaf2e7": {
|
||||
"name": "SNT",
|
||||
"address": "0xc55cf4b03948d7ebc8b9e8bad92643703811d162"
|
||||
},
|
||||
"0x823f81eb5239fd857afd6bb050d2d628acddcaf2394ef641cd91cf0b8ff874b9": {
|
||||
"name": "ERC20Receiver",
|
||||
"address": "0xB59B23736D852b854aE0eE6687c2b90B01A02AB4"
|
||||
},
|
||||
"0x2677020cbbcaa18ce69dd8bb8df64aa0e52a0223b292a7a9abb9a9bdef750dd3": {
|
||||
"name": "License",
|
||||
"address": "0x0c7e44b251861a8D4E5E1C81E100CAAd4DCD1DEc"
|
||||
},
|
||||
"0x744d8dd8d4284e8cdebc5adaf2047826cb846f723c7ec842d12ad5b52678a73a": {
|
||||
"name": "Arbitration",
|
||||
"address": "0xaCd119C6049D3cDAe874d73b944a25592233Dd14"
|
||||
},
|
||||
"0xf0e3441440660cc814b11ddb03e1e1f801b6208fe8d821643596e92ac3af2450": {
|
||||
"name": "MetadataStore",
|
||||
"address": "0x72296A3Bd9bdcdE4bCa5fa63920D40388D84cafB"
|
||||
},
|
||||
"0x6736899f25ec619bbd3b81360f73a21009700e238aa3d743aaa8f9456e4ea5d3": {
|
||||
"name": "Escrow",
|
||||
"address": "0xe515E50DeB4280a3C4f57509CCA9310B0D75b501"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
|
@ -19,7 +19,7 @@ import {sortByDate, sortByRating} from '../../utils/sorters';
|
|||
import './index.scss';
|
||||
import {withNamespaces} from "react-i18next";
|
||||
import {addressCompare} from "../../utils/address";
|
||||
import {checkEnoughETH, filterValidGaslessOffers} from "../../utils/transaction";
|
||||
import {checkNotEnoughETH, filterValidGaslessOffers} from "../../utils/transaction";
|
||||
|
||||
class OffersList extends Component {
|
||||
constructor(props) {
|
||||
|
@ -89,7 +89,7 @@ class OffersList extends Component {
|
|||
};
|
||||
|
||||
render() {
|
||||
const notEnoughETH = checkEnoughETH(this.props.gasPrice, this.props.ethBalance);
|
||||
const notEnoughETH = checkNotEnoughETH(this.props.gasPrice, this.props.ethBalance);
|
||||
let filteredOffers = filterValidGaslessOffers(this.props.offers, notEnoughETH);
|
||||
|
||||
if (this.state.locationCoords) {
|
||||
|
|
|
@ -14,7 +14,7 @@ import newBuy from "../../features/newBuy";
|
|||
import network from "../../features/network";
|
||||
|
||||
import {addressCompare} from "../../utils/address";
|
||||
import {checkEnoughETH, filterValidGaslessOffers} from "../../utils/transaction";
|
||||
import {checkNotEnoughETH, filterValidGaslessOffers} from "../../utils/transaction";
|
||||
|
||||
import './index.scss';
|
||||
import Loading from "../../components/Loading";
|
||||
|
@ -39,7 +39,7 @@ class Profile extends Component {
|
|||
const {profile, prices, address} = this.props;
|
||||
if(!profile || !prices) return <Loading page={true} />;
|
||||
|
||||
const notEnoughETH = checkEnoughETH(this.props.gasPrice, this.props.ethBalance);
|
||||
const notEnoughETH = checkNotEnoughETH(this.props.gasPrice, this.props.ethBalance);
|
||||
const filteredOffers = filterValidGaslessOffers(profile.offers, notEnoughETH);
|
||||
|
||||
return (
|
||||
|
|
|
@ -0,0 +1,56 @@
|
|||
/* global web3 */
|
||||
import Escrow from '../embarkArtifacts/contracts/Escrow';
|
||||
import {checkNotEnoughETH} from './utils/transaction';
|
||||
import {addressCompare} from './utils/address';
|
||||
|
||||
const VALID_OPERATIONS = {
|
||||
"cancel(uint256)": "40e58ee5",
|
||||
"create(address,uint256,uint256,uint8,uint256,bytes,string,string)": "a63c5162",
|
||||
"openCase(uint256,string)": "58b67904",
|
||||
"pay(uint256)": "c290d691"
|
||||
};
|
||||
|
||||
class Provider {
|
||||
constructor(origProvider, relayProvider) {
|
||||
this.origProvider = origProvider;
|
||||
this.relayProvider = relayProvider;
|
||||
this.origProviderSend = (this.origProvider['sendAsync'] || this.origProvider['send']).bind(this.origProvider);
|
||||
this.relayProviderSend = (this.relayProvider['sendAsync'] || this.relayProvider['send']).bind(this.relayProvider);
|
||||
}
|
||||
|
||||
send(payload, callback) {
|
||||
const params = payload.params[0];
|
||||
|
||||
if(!(params && params.to && addressCompare(params.to, Escrow.options.address.toLowerCase()) &&
|
||||
payload.method === "eth_sendTransaction" &&
|
||||
Object.values(VALID_OPERATIONS).includes(params.data.substring(2, 10)))){
|
||||
this.origProviderSend(payload, callback);
|
||||
return;
|
||||
}
|
||||
|
||||
(async () => {
|
||||
const balance = await web3.eth.getBalance(web3.eth.defaultAccount);
|
||||
const gasPrice = await web3.eth.getGasPrice();
|
||||
if(checkNotEnoughETH(gasPrice, balance)){
|
||||
// Increase 120%.
|
||||
// Normally we would use gaspriceFactorPercent on tabookey.RelayProvider
|
||||
// but this version of web3 does a getPrice before send() if the gas price is null
|
||||
// to set this gas price as a parameter. Tabookey will then use this value directly
|
||||
// without applying the factor percent
|
||||
const useGasPrice = web3.utils.toBN(gasPrice).mul(web3.utils.toBN("120")).div(web3.utils.toBN("100"));
|
||||
payload.params[0].gasPrice = web3.utils.toHex(useGasPrice);
|
||||
this.relayProviderSend(payload, function (error, result) {
|
||||
callback(error, result);
|
||||
});
|
||||
} else {
|
||||
this.origProviderSend(payload, callback);
|
||||
}
|
||||
})();
|
||||
}
|
||||
|
||||
sendAsync(payload, callback) {
|
||||
return this.send(payload, callback);
|
||||
}
|
||||
}
|
||||
|
||||
export default Provider;
|
|
@ -1,6 +1,8 @@
|
|||
/*global web3*/
|
||||
import EmbarkJS from '../../embarkArtifacts/embarkjs';
|
||||
import {contactCodeRegExp} from '../utils/address';
|
||||
import TellerProvider from '../provider';
|
||||
import tabookey from 'tabookey-gasless';
|
||||
|
||||
export function onReady() {
|
||||
return new Promise((resolve, reject) => {
|
||||
|
@ -9,6 +11,12 @@ export function onReady() {
|
|||
return reject(err);
|
||||
}
|
||||
|
||||
// A relay gets compensated whenever it relays a transaction: whatever the gas usage it pays,
|
||||
// it gets back the same plus the "txFee" precent - that is, it gets back ( (txFee+100)*gasUsed ) / 100
|
||||
const relayProvider = new tabookey.RelayProvider(web3.currentProvider, { txfee: 12 });
|
||||
const customProvider = new TellerProvider(web3.currentProvider, relayProvider);
|
||||
web3.setProvider(customProvider);
|
||||
|
||||
resolve();
|
||||
});
|
||||
});
|
||||
|
|
|
@ -13,7 +13,7 @@ export const calculateEscrowPrice = (escrow, prices) => {
|
|||
|
||||
const toBN = web3.utils.toBN;
|
||||
|
||||
export const checkEnoughETH = (gasPrice, ethBalance) => {
|
||||
export const checkNotEnoughETH = (gasPrice, ethBalance) => {
|
||||
const relayGasPrice = toBN(gasPrice || '0').mul(toBN(120)).div(toBN(100)); // 120%. toBN doesnt like decimals?
|
||||
return toBN(web3.utils.toWei(ethBalance || '0', 'ether')).lt(toBN(500000).mul(relayGasPrice)); // only allow ETH if less than 500000*gasPrice
|
||||
};
|
||||
|
|
Loading…
Reference in New Issue