From 315af1e351dca2b842a524d0e1307712233ad015 Mon Sep 17 00:00:00 2001 From: Iuri Matias Date: Fri, 16 Aug 2019 12:32:53 -0400 Subject: [PATCH] add web3 connection --- dapps/tests/app/config/contracts.js | 1 + .../embark-web3/src/contract-artifact.js.ejs | 11 +- packages/embark-web3/src/index.js | 1 + packages/embark-web3/src/web3_init.js.ejs | 157 +++++++++++++++++- 4 files changed, 165 insertions(+), 5 deletions(-) diff --git a/dapps/tests/app/config/contracts.js b/dapps/tests/app/config/contracts.js index 5ce1deda2..23c8a6a7b 100644 --- a/dapps/tests/app/config/contracts.js +++ b/dapps/tests/app/config/contracts.js @@ -1,6 +1,7 @@ module.exports = { default: { dappConnection: [ + "ws://localhost:8556", "ws://localhost:8546", "http://localhost:8550", "http://localhost:8545", diff --git a/packages/embark-web3/src/contract-artifact.js.ejs b/packages/embark-web3/src/contract-artifact.js.ejs index dc0125963..9e2b34bb5 100644 --- a/packages/embark-web3/src/contract-artifact.js.ejs +++ b/packages/embark-web3/src/contract-artifact.js.ejs @@ -1,10 +1,19 @@ -const web3 = require("./web3_init.js") +const web3 = require("./web3_init.js").default let <%- className %>Abi = <%- abi %>; let <%- className %> = new web3.eth.Contract(<%- className %>Abi); <%- className %>.options.address = '<%- contract.deployedAddress %>'; <%- className %>.address = '<%- contract.deployedAddress %>'; <%- className %>.options.from = web3.eth.defaultAccount; + +web3.execWhenReady(() => { + console.dir("running execWhenReady") + <%- className %>.options.from = web3.eth.defaultAccount; + if (!<%- className %>.currentProvider) { + <%- className %>.setProvider(web3.currentProvider); + } +}) + <% if (gasLimit != false) { %> <%- className %>.options.gas = <%- gasLimit %>; <%- className %>.options.gasLimit = <%- gasLimit %>; diff --git a/packages/embark-web3/src/index.js b/packages/embark-web3/src/index.js index 6f182faf3..ae8a3cf4c 100644 --- a/packages/embark-web3/src/index.js +++ b/packages/embark-web3/src/index.js @@ -64,6 +64,7 @@ class EmbarkWeb3 { addWeb3Artifact(_params, cb) { let web3Code = Templates.web3_init({connectionList: this.config.contractsConfig.dappConnection}); + // TODO: generate a .node file this.events.request("pipeline:register", { path: [this.embarkConfig.generationDir, 'contracts'], file: 'web3_init.js', diff --git a/packages/embark-web3/src/web3_init.js.ejs b/packages/embark-web3/src/web3_init.js.ejs index 3c8dfe7ef..a115c84c2 100644 --- a/packages/embark-web3/src/web3_init.js.ejs +++ b/packages/embark-web3/src/web3_init.js.ejs @@ -1,5 +1,154 @@ -// console.dir("connection list TODO") -// console.dir([<%- connectionList %>]) +const {reduce} = require('async') const Web3 = require('web3') -const web3 = new Web3("ws://localhost:8556"); -module.exports = web3; +let web3 = new Web3(); + +let todo = []; +let done = false; + +web3.execWhenReady = function(cb) { + console.dir("adding execWhenReady") + if (done) { + console.dir("already done") + return cb(); + } + todo.push(cb); +} + +let __whenEnvIsLoaded = function(cb) { + if (typeof document !== 'undefined' && document !== null && !(/comp|inter|loaded/).test(document.readyState)) { + document.addEventListener('DOMContentLoaded', cb); + } else { + cb(); + } +}; + +let doConnect = function(connectionList, opts, doneCb) { + const self = this; + + let blockchainConnector = web3; + + const checkConnect = (next) => { + blockchainConnector.eth.getAccounts((error, _a) => { + // const provider = blockchainConnector.getCurrentProvider(); + const provider = blockchainConnector.currentProvider; + const connectionString = provider.host; + + if (error) blockchainConnector.setProvider(null); + + return next(null, { + connectionString, + error, + connected: !error + }); + }); + }; + + const connectWeb3 = async (next) => { + const connectionString = 'web3://'; + + if (typeof window !== 'undefined' && window.ethereum) { + try { + if (Blockchain.autoEnable) { + await ethereum.enable(); + } + blockchainConnector.setProvider(ethereum); + return checkConnect(next); + } catch (error) { + return next(null, { + connectionString, + error, + connected: false + }); + } + } + + return next(null, { + connectionString, + error: new Error("web3 provider not detected"), + connected: false + }); + }; + + const connectWebsocket = (value, next) => { + //blockchainConnector.setProvider(blockchainConnector.getNewProvider('WebsocketProvider', value)); + blockchainConnector.setProvider(new Web3.providers.WebsocketProvider(value)); + checkConnect(next); + }; + + const connectHttp = (value, next) => { + //blockchainConnector.setProvider(blockchainConnector.getNewProvider('HttpProvider', value)); + blockchainConnector.setProvider(new Web3.providers.HttpProvider(value)); + checkConnect(next); + }; + + let connectionErrs = {}; + + reduce(connectionList, false, function(result, connectionString, next) { + if (result.connected) { + return next(null, result); + } else if (result) { + connectionErrs[result.connectionString] = result.error; + } + + if (connectionString === '$WEB3') { + connectWeb3(next); + } else if (connectionString.indexOf('ws://') >= 0) { + console.dir("connectionString") + console.dir(connectionString) + connectWebsocket(connectionString, next); + } else { + connectHttp(connectionString, next); + } + }, async function(_err, result) { + if (!result.connected || result.error) { + // return doneCb(new BlockchainConnectionError(connectionErrs)); + return doneCb(new Error(connectionErrs)); + } + + //blockchainConnector.getAccounts(async (err, accounts) => { + blockchainConnector.eth.getAccounts(async (err, accounts) => { + if (err) { + return doneCb(err); + } + //const currentProv = blockchainConnector.getCurrentProvider(); + const currentProv = blockchainConnector.currentProvider; + if (opts.warnAboutMetamask) { + // if we are using metamask, ask embark to turn on dev_funds + // embark will only do this if geth is our client and we are in + // dev mode + // if (opts.blockchainClient === 'geth') { + // // TODO find a way to share the port number + // console.warn("%cNote: There is a known issue with Geth (when in `--dev` mode) that may cause transactions to get stuck. To enable a workaround, start an Embark console (run command `embark console` in your terminal) or open the dashboard in Cockpit (http://localhost:55555), then type in the console command `devtxs on`. To disable the workaround, type `devtxs off` in the console.", "font-size: 2em"); + // } + if ((currentProv && currentProv.isMetaMask) || + (typeof window !== 'undefined' && window.ethereum && window.ethereum.isMetaMask)) { + console.warn("%cNote: Embark has detected you are in the development environment and using Metamask, please make sure Metamask is connected to your local node", "font-size: 2em"); + // if(opts.blockchainClient === 'parity') { + // console.warn("%cNote: Parity blocks the connection from browser extensions like Metamask. To resolve this problem, go to https://embark.status.im/docs/blockchain_configuration.html#Using-Parity-and-Metamask", "font-size: 2em"); + // } + } + } + if (accounts) { + //blockchainConnector.setDefaultAccount(accounts[0]); + blockchainConnector.eth.defaultAccount = accounts[0]; + } + + doneCb(); + }); + }); +}; + +__whenEnvIsLoaded(() => { + let connectList = [<%- connectionList.map(x => "'" + x + "'").join(",") %>]; + console.dir(connectList); + console.log("test2") + + doConnect(connectList, { + warnAboutMetamask: false, // TODO: can/should be part as the code generation instead... + }, () => { + todo.forEach((x) => x.apply(x)) + done = true; + }) +}) + +export default web3;