¿La forma más sencilla de integrar Infura con una aplicación Web3/Truffle?

Tengo una aplicación Truffle/Web3 que tiene este código en app.js (de forma predeterminada) que se ejecuta cuando se carga la página:

$(document).ready(function () {
  if (typeof web3 !== 'undefined') {
    console.warn('Using web3 detected from external source like Metamask')
    window.web3 = new Web3(web3.currentProvider)
  } else {
    console.warn("No web3 detected. Falling back to http://localhost:8545. You should remove this fallback when you deploy live, as it's inherently insecure. Consider switching to Metamask for development. More info here: http://truffleframework.com/tutorials/truffle-and-metamask")
    window.web3 = new Web3(new Web3.providers.HttpProvider('http://localhost:8545'))
  }

Mi archivo truffle.js se ve así:

require('babel-register')

module.exports = {
  networks: {
    "ropsten": {
      host: 'localhost',
      port: 8545,
      network_id: 3, // Ropsten
      gas: 500000
    }
  }
}

También me registré en Infura, que me dio una "URL de proveedor" como https://ropsten.infura.io/xxxxxxxxxxxxxxxxxxxxx

¿Cómo debo configurar correctamente mi truffle.js y app.js para usar Infura? Me gustaría usar Infura con el fin de mostrar a los usuarios que no están usando datos de MetaMask/Parity/Mist de la cadena de bloques (para que la aplicación aún pueda llamar a funciones de mi contrato), mientras que Infura debe ignorarse si se detecta que el usuario está usando MetaMask/Parity/Mist.

Intenté usar la URL de mi proveedor de ropsten de esta manera: window.web3 = new Web3(new Web3.providers.HttpProvider(' ropsten.infura.io/xxxxxxxxxxxxxxxxxxxxx' )) Esto da como resultado errores de "nuevo BigNumber() no un número base 16" que rompen la aplicación, creo que porque el nodo Infura no está actualizado (tal vez retrasado unos minutos). Se agradecería cualquier aporte de alguien que haya usado Infura con éxito con el fin de poder recuperar datos de la cadena de bloques para usuarios sin MetaMask.

Respuestas (2)

Este es un ejemplo de cómo configurar un proveedor de infura usando truffle-hdwallet-provider con una billetera personalizada:

const HDWalletProvider = require('truffle-hdwallet-provider')
const fs = require('fs')

const mnemonic = process.env.MNEMONIC

module.exports = {
  networks: {
    development: {
      host: 'localhost',
      port: 8545,
      gas: 4500000,
      gasPrice: 25000000000,
      network_id: '*' 
    },
    kovan: {
      provider: new HDWalletProvider(mnemonic, 'https://kovan.infura.io'),
      network_id: '*',
      gas: 4500000,
      gasPrice: 25000000000
    },
    rinkeby: {
      provider: new HDWalletProvider(mnemonic, 'https://rinkeby.infura.io'),
      network_id: '*',
      gas: 4500000,
      gasPrice: 25000000000
    },
    mainnet: {
      provider: new HDWalletProvider(mnemonic, 'https://mainnet.infura.io'),
      network_id: '*',
      gas: 4500000,
      gasPrice: 25000000000
    }
  }
}

Luego simplemente configure la opción de red al implementar:

truffle migrate --reset --network=rinkeby

En la interfaz de usuario, aquí se explica cómo configurar el proveedor HTTP de Web3 en infura:

if (typeof web3 !== 'undefined') {
    window.web3 = new Web3(web3.currentProvider)
} else {
    window.web3 = new Web3(new Web3.providers.HttpProvider('https://rinkeby.infura.io:443'))
}
¿No necesita agregar su código infura api a la URL?
@Andrey al momento de escribir esta publicación no era obligatorio, pero puede que tengas razón

Aquí hay un tutorial de truffle sobre esto: https://truffleframework.com/tutorials/using-infura-custom-provider

Sin embargo, me imagino que almacenar y manejar el mnemotécnico es bastante arriesgado (ya que le dará control total sobre toda la billetera)

Para mí, usar Infura como HTTPProvider como se sugiere en la respuesta anterior no funcionó, así que también tuve que:

var HDWalletProvider = require("truffle-hdwallet-provider");
var mnemonic = 'xxx xxx xxx... ';

var hd = new HDWalletProvider(mnemonic, "https://ropsten.infura.io/v3/xxxxyyyzzz");    
window.web3 = new Web3(hd); 
Dos sugerencias para hacer de esta la mejor respuesta. Primero, use dotenv para guardar la clave API mnemotécnica e infura en un archivo no confirmado .env. En segundo lugar, solo funcionó para mí después de cambiar a v1 en lugar de v3.