Closed joelreymont closed 1 year ago
You have a couple of options of here:
You can either use a Web3 JSON-RPC provider that supports hardware wallets out of the box (e.g., geth
). Then, if you're using the chanterelle deploy
CLI utility, you can just pass in --node-url http://your.mainnet.node.with.a.ledger.plugged.in:8545
.
If you're invoking Chanterelle's deploy
function from a custom PureScript module, then you've probably already noticed that you can pass in a node URL as well. In fact, chanterelle deploy
is more or less a wrapper around exactly that.
Your other option when using a custom PureScript module to run your DeployM
, is to use deployWithProvider
. This is as close to "native" ledger support as it gets. As the name suggests, this lets you specify a web3 provider directly. You can think of deploy
as
module Chanterelle.Deploy where
import Effect.Aff (Aff)
import Effect.Class (liftEffect)
import Network.Ethereum.Web3 (Provider, httpProvider)
deploy :: String -> Int -> (DeployM ~> Aff)
deploy nodeUrl requestTimeout deployScript = do
provider <- liftEffect $ httpProvider nodeUrl
deployWithProvider provider requestTimeout deployScript
deployWithProvider :: Provider -> Int -> (DeployM ~> Aff)
deployWithProvider provider timeout deployScript = ...
-- all the heavy lifting of setting up chanterelle's deploy system and running your script
-- happens here
So, if you can somehow make a web3
provider that supports the ledger, deployWithProvider
becomes your best friend. It's actually fairly similar to how you'd do it in Truffle. In fact, you can even use truffle-ledger-provider
(just don't forget to include it in your package.json
) :)
Some fairly straightforward FFI bindings in a file called LedgerSupport.js
:
"use strict";
var LedgerWalletProvider = require("truffle-ledger-provider");
exports.ledgerHttpProvider = function (providerUrl) {
return function (ledgerOptions) {
return function () {
var provider = new LedgerWalletProvider(ledgerOptions, providerUrl);
return provider.engine;
};
};
};
exports.stopLedgerProvider = function(engine) {
return function () {
engine.stop();
};
};
And some ceremonial foreign imports
in a file called LedgerSupport.purs
module LedgerSupport where
import Prelude (Unit)
import Effect (Effect)
import Network.Ethereum.Web3.Types.Provider (Provider)
type LedgerOptions = { networkId :: Int
, path :: String
, askConfirm :: Boolean
, accountsLength :: Int
, accountsOffset :: Int
}
foreign import ledgerHttpProvider :: String -> LedgerOptions -> Effect Provider
foreign import stopLedgerProvider :: Provider -> Effect Unit
Lets you make quick work of the process:
module Deploy.Mainnet (main) where
import Prelude
import Chanterelle.Deploy (deployWithProvider)
import Deploy.Script (deployScript) as Mainnet
import DApp.LedgerSupport (ledgerHttpProvider, stopLedgerProvider)
import Data.Maybe (fromMaybe)
import Effect (Effect)
import Effect.Aff (launchAff_)
import Node.Process (lookupEnv)
main :: Effect Unit
main = do
let ledgerOptions = { networkId: 1
, path: "44'/60'/0'/0" -- ledger default derivation path
, askConfirm: true
, accountsLength: 1
, accountsOffset: 0
}
nodeUrl <- fromMaybe "http://a.mainnet.node.or.maybe.infura.or.something:8545" <$> lookupEnv "NODE_URL"
provider <- ledgerHttpProvider nodeUrl ledgerOptions
launchAff_ $ deployWithProvider provider 60 Mainnet.deployScript
stopLedgerProvider provider
Hope that helps!
I've actually had a purescript-web3-provider-engine
library of sorts sitting on the backburner for a while. If there's interest in it, I could likely polish it up and release it as well. This would allow you to compose all sorts of provider stacks which can get mighty handy. e.g., Truffle's Ledger provider is essentially a web3-provider-engine
stack. Ganache
is basically glorified provider engine stack, etc.
By the way, right out of the box, purescript-web3
also has metamaskProvider
. So, if you wanna do something silly browserify your deployScript
and deployWithProvider metamaskProvider
using Metamask while looking at log output in your browser's JS console, that's also possible.
(that's mostly a joke, but no reason it shouldn't work :P)
Does Chanterelle let me deploy contracts to mainnet?
What's the best place to plug in signing with the Ledger (or another hardware wallet)?