Truffle: Add subscription support for @truffle/hdwallet-provider

Created on 7 Nov 2019  路  8Comments  路  Source: trufflesuite/truffle

  • [ ] I've asked for help in the Truffle Gitter before filing this issue.

Issue

What the issue is, in broad strokes.

Steps to Reproduce

Add HDWalletProvider to drizzle store

Expected Behavior

Drizzle successful subscribed to events

Actual Results

subscriptions problem

Environment

  • Operating System: Win 10
  • Ethereum client: N/A
  • Truffle version (truffle version): v5.0.43
  • node version (node --version): 10.17.0
  • npm version (npm --version): 6.11.3
bug help wanted needs investigated needs reproduced priority6 馃挱

Most helpful comment

The issue is that HDWalletProvider does not have an on() function, so web3 assumes no subscription support and throws an error. Web3.providers.WebsocketProvider implements .on() and supports subscription callbacks. HDWalletProvider uses WebsocketProvider when rpcUrl has ws: or wss:, but it's added via web3-provider-engine, which also doesn't support subscriptions by implementing on(). web3 looks for the on() function on the top level provider (HDWalletProvider) and can't find it.

Here's the monkey patched workaround I'm using:

const Web3 = require('web3')
const HDWalletProvider = require('@truffle/hdwallet-provider')

const rpcUrl = 'http://localhost:8545'
const mnemonic = 'monkey patch bad ...'

const wsProvider = new Web3.providers.WebsocketProvider(rpcUrl)
HDWalletProvider.prototype.on = wsProvider.on.bind(wsProvider)
const provider = new HDWalletProvider(mnemonic, wsProvider)

const web3 = new Web3(provider)

// subscribe callbacks should work now
web3.eth.subscribe('newBlockHeaders', (error, block) => console.log(error || block))

All 8 comments

Hm, sounds like this is a Drizzle issue, for https://github.com/trufflesuite/drizzle/issues

I am afraid that if I inherit from ProviderEngine this problem will be solved

Hi @MrRefactoring! I don't totally understand what you mean about ProviderEngine, can you clarify? Do you mean instead of accessing HDWalletProvider directly?

I think that HDWalletProvider should inherit ProviderEngine, and not write an adapter for it

I'm generally opposed to inheritance in favor of composition, but that seems like an implementation detail. Is there more information about what is causing this not to work? Thanks!

Hey @MrRefactoring or maybe @adrianmcli, could either of you lend any clarity to this issue? Thanks in advance!

@gnidan I'm busy at work so far, I can鈥檛 see this issue, sorry :(

The issue is that HDWalletProvider does not have an on() function, so web3 assumes no subscription support and throws an error. Web3.providers.WebsocketProvider implements .on() and supports subscription callbacks. HDWalletProvider uses WebsocketProvider when rpcUrl has ws: or wss:, but it's added via web3-provider-engine, which also doesn't support subscriptions by implementing on(). web3 looks for the on() function on the top level provider (HDWalletProvider) and can't find it.

Here's the monkey patched workaround I'm using:

const Web3 = require('web3')
const HDWalletProvider = require('@truffle/hdwallet-provider')

const rpcUrl = 'http://localhost:8545'
const mnemonic = 'monkey patch bad ...'

const wsProvider = new Web3.providers.WebsocketProvider(rpcUrl)
HDWalletProvider.prototype.on = wsProvider.on.bind(wsProvider)
const provider = new HDWalletProvider(mnemonic, wsProvider)

const web3 = new Web3(provider)

// subscribe callbacks should work now
web3.eth.subscribe('newBlockHeaders', (error, block) => console.log(error || block))
Was this page helpful?
0 / 5 - 0 ratings

Related issues

abcoathup picture abcoathup  路  3Comments

mezrin picture mezrin  路  3Comments

arunmitteam picture arunmitteam  路  3Comments

maximilianh picture maximilianh  路  3Comments

tcurdt picture tcurdt  路  3Comments