@ -30,7 +30,6 @@ import (
"os/signal"
"os/signal"
"path/filepath"
"path/filepath"
"runtime"
"runtime"
"sort"
"strings"
"strings"
"time"
"time"
@ -55,7 +54,7 @@ import (
"github.com/ethereum/go-ethereum/signer/storage"
"github.com/ethereum/go-ethereum/signer/storage"
"github.com/mattn/go-colorable"
"github.com/mattn/go-colorable"
"github.com/mattn/go-isatty"
"github.com/mattn/go-isatty"
"gopkg.in/urfave/cli.v1 "
"github.com/urfave/cli/v2 "
)
)
const legalWarning = `
const legalWarning = `
@ -73,70 +72,70 @@ PURPOSE. See the GNU General Public License for more details.
`
`
var (
var (
logLevelFlag = cli . IntFlag {
logLevelFlag = & cli . IntFlag {
Name : "loglevel" ,
Name : "loglevel" ,
Value : 4 ,
Value : 4 ,
Usage : "log level to emit to the screen" ,
Usage : "log level to emit to the screen" ,
}
}
advancedMode = cli . BoolFlag {
advancedMode = & cli . BoolFlag {
Name : "advanced" ,
Name : "advanced" ,
Usage : "If enabled, issues warnings instead of rejections for suspicious requests. Default off" ,
Usage : "If enabled, issues warnings instead of rejections for suspicious requests. Default off" ,
}
}
acceptFlag = cli . BoolFlag {
acceptFlag = & cli . BoolFlag {
Name : "suppress-bootwarn" ,
Name : "suppress-bootwarn" ,
Usage : "If set, does not show the warning during boot" ,
Usage : "If set, does not show the warning during boot" ,
}
}
keystoreFlag = cli . StringFlag {
keystoreFlag = & cli . StringFlag {
Name : "keystore" ,
Name : "keystore" ,
Value : filepath . Join ( node . DefaultDataDir ( ) , "keystore" ) ,
Value : filepath . Join ( node . DefaultDataDir ( ) , "keystore" ) ,
Usage : "Directory for the keystore" ,
Usage : "Directory for the keystore" ,
}
}
configdirFlag = cli . StringFlag {
configdirFlag = & cli . StringFlag {
Name : "configdir" ,
Name : "configdir" ,
Value : DefaultConfigDir ( ) ,
Value : DefaultConfigDir ( ) ,
Usage : "Directory for Clef configuration" ,
Usage : "Directory for Clef configuration" ,
}
}
chainIdFlag = cli . Int64Flag {
chainIdFlag = & cli . Int64Flag {
Name : "chainid" ,
Name : "chainid" ,
Value : params . MainnetChainConfig . ChainID . Int64 ( ) ,
Value : params . MainnetChainConfig . ChainID . Int64 ( ) ,
Usage : "Chain id to use for signing (1=mainnet, 3=Ropsten, 4=Rinkeby, 5=Goerli)" ,
Usage : "Chain id to use for signing (1=mainnet, 3=Ropsten, 4=Rinkeby, 5=Goerli)" ,
}
}
rpcPortFlag = cli . IntFlag {
rpcPortFlag = & cli . IntFlag {
Name : "http.port" ,
Name : "http.port" ,
Usage : "HTTP-RPC server listening port" ,
Usage : "HTTP-RPC server listening port" ,
Value : node . DefaultHTTPPort + 5 ,
Value : node . DefaultHTTPPort + 5 ,
Category : flags . APICategory ,
}
}
signerSecretFlag = cli . StringFlag {
signerSecretFlag = & cli . StringFlag {
Name : "signersecret" ,
Name : "signersecret" ,
Usage : "A file containing the (encrypted) master seed to encrypt Clef data, e.g. keystore credentials and ruleset hash" ,
Usage : "A file containing the (encrypted) master seed to encrypt Clef data, e.g. keystore credentials and ruleset hash" ,
}
}
customDBFlag = cli . StringFlag {
customDBFlag = & cli . StringFlag {
Name : "4bytedb-custom" ,
Name : "4bytedb-custom" ,
Usage : "File used for writing new 4byte-identifiers submitted via API" ,
Usage : "File used for writing new 4byte-identifiers submitted via API" ,
Value : "./4byte-custom.json" ,
Value : "./4byte-custom.json" ,
}
}
auditLogFlag = cli . StringFlag {
auditLogFlag = & cli . StringFlag {
Name : "auditlog" ,
Name : "auditlog" ,
Usage : "File used to emit audit logs. Set to \"\" to disable" ,
Usage : "File used to emit audit logs. Set to \"\" to disable" ,
Value : "audit.log" ,
Value : "audit.log" ,
}
}
ruleFlag = cli . StringFlag {
ruleFlag = & cli . StringFlag {
Name : "rules" ,
Name : "rules" ,
Usage : "Path to the rule file to auto-authorize requests with" ,
Usage : "Path to the rule file to auto-authorize requests with" ,
}
}
stdiouiFlag = cli . BoolFlag {
stdiouiFlag = & cli . BoolFlag {
Name : "stdio-ui" ,
Name : "stdio-ui" ,
Usage : "Use STDIN/STDOUT as a channel for an external UI. " +
Usage : "Use STDIN/STDOUT as a channel for an external UI. " +
"This means that an STDIN/STDOUT is used for RPC-communication with a e.g. a graphical user " +
"This means that an STDIN/STDOUT is used for RPC-communication with a e.g. a graphical user " +
"interface, and can be used when Clef is started by an external process." ,
"interface, and can be used when Clef is started by an external process." ,
}
}
testFlag = cli . BoolFlag {
testFlag = & cli . BoolFlag {
Name : "stdio-ui-test" ,
Name : "stdio-ui-test" ,
Usage : "Mechanism to test interface between Clef and UI. Requires 'stdio-ui'." ,
Usage : "Mechanism to test interface between Clef and UI. Requires 'stdio-ui'." ,
}
}
app = cli . NewApp ( )
initCommand = & cli . Command {
initCommand = cli . Command {
Action : initializeSecrets ,
Action : utils . MigrateFlags ( initializeSecrets ) ,
Name : "init" ,
Name : "init" ,
Usage : "Initialize the signer, generate secret storage" ,
Usage : "Initialize the signer, generate secret storage" ,
ArgsUsage : "" ,
ArgsUsage : "" ,
@ -148,8 +147,8 @@ var (
The init command generates a master seed which Clef can use to store credentials and data needed for
The init command generates a master seed which Clef can use to store credentials and data needed for
the rule - engine to work . ` ,
the rule - engine to work . ` ,
}
}
attestCommand = cli . Command {
attestCommand = & cli . Command {
Action : utils . MigrateFlags ( attestFile ) ,
Action : attestFile ,
Name : "attest" ,
Name : "attest" ,
Usage : "Attest that a js-file is to be used" ,
Usage : "Attest that a js-file is to be used" ,
ArgsUsage : "<sha256sum>" ,
ArgsUsage : "<sha256sum>" ,
@ -165,8 +164,8 @@ incoming requests.
Whenever you make an edit to the rule file , you need to use attestation to tell
Whenever you make an edit to the rule file , you need to use attestation to tell
Clef that the file is ' safe ' to execute . ` ,
Clef that the file is ' safe ' to execute . ` ,
}
}
setCredentialCommand = cli . Command {
setCredentialCommand = & cli . Command {
Action : utils . MigrateFlags ( setCredential ) ,
Action : setCredential ,
Name : "setpw" ,
Name : "setpw" ,
Usage : "Store a credential for a keystore file" ,
Usage : "Store a credential for a keystore file" ,
ArgsUsage : "<address>" ,
ArgsUsage : "<address>" ,
@ -178,8 +177,8 @@ Clef that the file is 'safe' to execute.`,
Description : `
Description : `
The setpw command stores a password for a given address ( keyfile ) .
The setpw command stores a password for a given address ( keyfile ) .
` }
` }
delCredentialCommand = cli . Command {
delCredentialCommand = & cli . Command {
Action : utils . MigrateFlags ( removeCredential ) ,
Action : removeCredential ,
Name : "delpw" ,
Name : "delpw" ,
Usage : "Remove a credential for a keystore file" ,
Usage : "Remove a credential for a keystore file" ,
ArgsUsage : "<address>" ,
ArgsUsage : "<address>" ,
@ -191,8 +190,8 @@ The setpw command stores a password for a given address (keyfile).
Description : `
Description : `
The delpw command removes a password for a given address ( keyfile ) .
The delpw command removes a password for a given address ( keyfile ) .
` }
` }
newAccountCommand = cli . Command {
newAccountCommand = & cli . Command {
Action : utils . MigrateFlags ( newAccount ) ,
Action : newAccount ,
Name : "newaccount" ,
Name : "newaccount" ,
Usage : "Create a new account" ,
Usage : "Create a new account" ,
ArgsUsage : "" ,
ArgsUsage : "" ,
@ -207,7 +206,7 @@ The newaccount command creates a new keystore-backed account. It is a convenienc
which can be used in lieu of an external UI . ` ,
which can be used in lieu of an external UI . ` ,
}
}
gendocCommand = cli . Command {
gendocCommand = & cli . Command {
Action : GenDoc ,
Action : GenDoc ,
Name : "gendoc" ,
Name : "gendoc" ,
Usage : "Generate documentation about json-rpc format" ,
Usage : "Generate documentation about json-rpc format" ,
@ -216,39 +215,16 @@ The gendoc generates example structures of the json-rpc communication types.
` }
` }
)
)
// AppHelpFlagGroups is the application flags, grouped by functionality.
var (
var AppHelpFlagGroups = [ ] flags . FlagGroup {
// Git SHA1 commit hash of the release (set via linker flags)
{
gitCommit = ""
Name : "FLAGS" ,
gitDate = ""
Flags : [ ] cli . Flag {
logLevelFlag ,
app = flags . NewApp ( gitCommit , gitDate , "Manage Ethereum account operations" )
keystoreFlag ,
)
configdirFlag ,
chainIdFlag ,
utils . LightKDFFlag ,
utils . NoUSBFlag ,
utils . SmartCardDaemonPathFlag ,
utils . HTTPListenAddrFlag ,
utils . HTTPVirtualHostsFlag ,
utils . IPCDisabledFlag ,
utils . IPCPathFlag ,
utils . HTTPEnabledFlag ,
rpcPortFlag ,
signerSecretFlag ,
customDBFlag ,
auditLogFlag ,
ruleFlag ,
stdiouiFlag ,
testFlag ,
advancedMode ,
acceptFlag ,
} ,
} ,
}
func init ( ) {
func init ( ) {
app . Name = "Clef"
app . Name = "Clef"
app . Usage = "Manage Ethereum account operations"
app . Flags = [ ] cli . Flag {
app . Flags = [ ] cli . Flag {
logLevelFlag ,
logLevelFlag ,
keystoreFlag ,
keystoreFlag ,
@ -273,46 +249,12 @@ func init() {
acceptFlag ,
acceptFlag ,
}
}
app . Action = signer
app . Action = signer
app . Commands = [ ] cli . Command { initCommand ,
app . Commands = [ ] * cli . Command { initCommand ,
attestCommand ,
attestCommand ,
setCredentialCommand ,
setCredentialCommand ,
delCredentialCommand ,
delCredentialCommand ,
newAccountCommand ,
newAccountCommand ,
gendocCommand }
gendocCommand ,
cli . CommandHelpTemplate = flags . CommandHelpTemplate
// Override the default app help template
cli . AppHelpTemplate = flags . ClefAppHelpTemplate
// Override the default app help printer, but only for the global app help
originalHelpPrinter := cli . HelpPrinter
cli . HelpPrinter = func ( w io . Writer , tmpl string , data interface { } ) {
if tmpl == flags . ClefAppHelpTemplate {
// Render out custom usage screen
originalHelpPrinter ( w , tmpl , flags . HelpData { App : data , FlagGroups : AppHelpFlagGroups } )
} else if tmpl == flags . CommandHelpTemplate {
// Iterate over all command specific flags and categorize them
categorized := make ( map [ string ] [ ] cli . Flag )
for _ , flag := range data . ( cli . Command ) . Flags {
if _ , ok := categorized [ flag . String ( ) ] ; ! ok {
categorized [ flags . FlagCategory ( flag , AppHelpFlagGroups ) ] = append ( categorized [ flags . FlagCategory ( flag , AppHelpFlagGroups ) ] , flag )
}
}
// sort to get a stable ordering
sorted := make ( [ ] flags . FlagGroup , 0 , len ( categorized ) )
for cat , flgs := range categorized {
sorted = append ( sorted , flags . FlagGroup { Name : cat , Flags : flgs } )
}
sort . Sort ( flags . ByCategory ( sorted ) )
// add sorted array to data and render with default printer
originalHelpPrinter ( w , tmpl , map [ string ] interface { } {
"cmd" : data ,
"categorizedFlags" : sorted ,
} )
} else {
originalHelpPrinter ( w , tmpl , data )
}
}
}
}
}
@ -329,7 +271,7 @@ func initializeSecrets(c *cli.Context) error {
return err
return err
}
}
// Ensure the master key does not yet exist, we're not willing to overwrite
// Ensure the master key does not yet exist, we're not willing to overwrite
configDir := c . Global String( configdirFlag . Name )
configDir := c . String ( configdirFlag . Name )
if err := os . Mkdir ( configDir , 0700 ) ; err != nil && ! os . IsExist ( err ) {
if err := os . Mkdir ( configDir , 0700 ) ; err != nil && ! os . IsExist ( err ) {
return err
return err
}
}
@ -347,7 +289,7 @@ func initializeSecrets(c *cli.Context) error {
return fmt . Errorf ( "failed to read enough random" )
return fmt . Errorf ( "failed to read enough random" )
}
}
n , p := keystore . StandardScryptN , keystore . StandardScryptP
n , p := keystore . StandardScryptN , keystore . StandardScryptP
if c . Global Bool( utils . LightKDFFlag . Name ) {
if c . Bool ( utils . LightKDFFlag . Name ) {
n , p = keystore . LightScryptN , keystore . LightScryptP
n , p = keystore . LightScryptN , keystore . LightScryptP
}
}
text := "The master seed of clef will be locked with a password.\nPlease specify a password. Do not forget this password!"
text := "The master seed of clef will be locked with a password.\nPlease specify a password. Do not forget this password!"
@ -390,8 +332,9 @@ You should treat 'masterseed.json' with utmost secrecy and make a backup of it!
` )
` )
return nil
return nil
}
}
func attestFile ( ctx * cli . Context ) error {
func attestFile ( ctx * cli . Context ) error {
if len ( ctx . Args ( ) ) < 1 {
if ctx . N Arg( ) < 1 {
utils . Fatalf ( "This command requires an argument." )
utils . Fatalf ( "This command requires an argument." )
}
}
if err := initialize ( ctx ) ; err != nil {
if err := initialize ( ctx ) ; err != nil {
@ -402,7 +345,7 @@ func attestFile(ctx *cli.Context) error {
if err != nil {
if err != nil {
utils . Fatalf ( err . Error ( ) )
utils . Fatalf ( err . Error ( ) )
}
}
configDir := ctx . Global String( configdirFlag . Name )
configDir := ctx . String ( configdirFlag . Name )
vaultLocation := filepath . Join ( configDir , common . Bytes2Hex ( crypto . Keccak256 ( [ ] byte ( "vault" ) , stretchedKey ) [ : 10 ] ) )
vaultLocation := filepath . Join ( configDir , common . Bytes2Hex ( crypto . Keccak256 ( [ ] byte ( "vault" ) , stretchedKey ) [ : 10 ] ) )
confKey := crypto . Keccak256 ( [ ] byte ( "config" ) , stretchedKey )
confKey := crypto . Keccak256 ( [ ] byte ( "config" ) , stretchedKey )
@ -415,7 +358,7 @@ func attestFile(ctx *cli.Context) error {
}
}
func setCredential ( ctx * cli . Context ) error {
func setCredential ( ctx * cli . Context ) error {
if len ( ctx . Args ( ) ) < 1 {
if ctx . N Arg( ) < 1 {
utils . Fatalf ( "This command requires an address to be passed as an argument" )
utils . Fatalf ( "This command requires an address to be passed as an argument" )
}
}
if err := initialize ( ctx ) ; err != nil {
if err := initialize ( ctx ) ; err != nil {
@ -433,7 +376,7 @@ func setCredential(ctx *cli.Context) error {
if err != nil {
if err != nil {
utils . Fatalf ( err . Error ( ) )
utils . Fatalf ( err . Error ( ) )
}
}
configDir := ctx . Global String( configdirFlag . Name )
configDir := ctx . String ( configdirFlag . Name )
vaultLocation := filepath . Join ( configDir , common . Bytes2Hex ( crypto . Keccak256 ( [ ] byte ( "vault" ) , stretchedKey ) [ : 10 ] ) )
vaultLocation := filepath . Join ( configDir , common . Bytes2Hex ( crypto . Keccak256 ( [ ] byte ( "vault" ) , stretchedKey ) [ : 10 ] ) )
pwkey := crypto . Keccak256 ( [ ] byte ( "credentials" ) , stretchedKey )
pwkey := crypto . Keccak256 ( [ ] byte ( "credentials" ) , stretchedKey )
@ -445,7 +388,7 @@ func setCredential(ctx *cli.Context) error {
}
}
func removeCredential ( ctx * cli . Context ) error {
func removeCredential ( ctx * cli . Context ) error {
if len ( ctx . Args ( ) ) < 1 {
if ctx . N Arg( ) < 1 {
utils . Fatalf ( "This command requires an address to be passed as an argument" )
utils . Fatalf ( "This command requires an address to be passed as an argument" )
}
}
if err := initialize ( ctx ) ; err != nil {
if err := initialize ( ctx ) ; err != nil {
@ -461,7 +404,7 @@ func removeCredential(ctx *cli.Context) error {
if err != nil {
if err != nil {
utils . Fatalf ( err . Error ( ) )
utils . Fatalf ( err . Error ( ) )
}
}
configDir := ctx . Global String( configdirFlag . Name )
configDir := ctx . String ( configdirFlag . Name )
vaultLocation := filepath . Join ( configDir , common . Bytes2Hex ( crypto . Keccak256 ( [ ] byte ( "vault" ) , stretchedKey ) [ : 10 ] ) )
vaultLocation := filepath . Join ( configDir , common . Bytes2Hex ( crypto . Keccak256 ( [ ] byte ( "vault" ) , stretchedKey ) [ : 10 ] ) )
pwkey := crypto . Keccak256 ( [ ] byte ( "credentials" ) , stretchedKey )
pwkey := crypto . Keccak256 ( [ ] byte ( "credentials" ) , stretchedKey )
@ -481,8 +424,8 @@ func newAccount(c *cli.Context) error {
var (
var (
ui = core . NewCommandlineUI ( )
ui = core . NewCommandlineUI ( )
pwStorage storage . Storage = & storage . NoStorage { }
pwStorage storage . Storage = & storage . NoStorage { }
ksLoc = c . Global String( keystoreFlag . Name )
ksLoc = c . String ( keystoreFlag . Name )
lightKdf = c . Global Bool( utils . LightKDFFlag . Name )
lightKdf = c . Bool ( utils . LightKDFFlag . Name )
)
)
log . Info ( "Starting clef" , "keystore" , ksLoc , "light-kdf" , lightKdf )
log . Info ( "Starting clef" , "keystore" , ksLoc , "light-kdf" , lightKdf )
am := core . StartClefAccountManager ( ksLoc , true , lightKdf , "" )
am := core . StartClefAccountManager ( ksLoc , true , lightKdf , "" )
@ -500,13 +443,13 @@ func newAccount(c *cli.Context) error {
func initialize ( c * cli . Context ) error {
func initialize ( c * cli . Context ) error {
// Set up the logger to print everything
// Set up the logger to print everything
logOutput := os . Stdout
logOutput := os . Stdout
if c . Global Bool( stdiouiFlag . Name ) {
if c . Bool ( stdiouiFlag . Name ) {
logOutput = os . Stderr
logOutput = os . Stderr
// If using the stdioui, we can't do the 'confirm'-flow
// If using the stdioui, we can't do the 'confirm'-flow
if ! c . Global Bool( acceptFlag . Name ) {
if ! c . Bool ( acceptFlag . Name ) {
fmt . Fprint ( logOutput , legalWarning )
fmt . Fprint ( logOutput , legalWarning )
}
}
} else if ! c . Global Bool( acceptFlag . Name ) {
} else if ! c . Bool ( acceptFlag . Name ) {
if ! confirm ( legalWarning ) {
if ! confirm ( legalWarning ) {
return fmt . Errorf ( "aborted by user" )
return fmt . Errorf ( "aborted by user" )
}
}
@ -545,8 +488,8 @@ func ipcEndpoint(ipcPath, datadir string) string {
func signer ( c * cli . Context ) error {
func signer ( c * cli . Context ) error {
// If we have some unrecognized command, bail out
// If we have some unrecognized command, bail out
if args := c . Args ( ) ; len ( args ) > 0 {
if c . N Arg( ) > 0 {
return fmt . Errorf ( "invalid command: %q" , args [ 0 ] )
return fmt . Errorf ( "invalid command: %q" , c . Args ( ) . First ( ) )
}
}
if err := initialize ( c ) ; err != nil {
if err := initialize ( c ) ; err != nil {
return err
return err
@ -554,7 +497,7 @@ func signer(c *cli.Context) error {
var (
var (
ui core . UIClientAPI
ui core . UIClientAPI
)
)
if c . Global Bool( stdiouiFlag . Name ) {
if c . Bool ( stdiouiFlag . Name ) {
log . Info ( "Using stdin/stdout as UI-channel" )
log . Info ( "Using stdin/stdout as UI-channel" )
ui = core . NewStdIOUI ( )
ui = core . NewStdIOUI ( )
} else {
} else {
@ -562,7 +505,7 @@ func signer(c *cli.Context) error {
ui = core . NewCommandlineUI ( )
ui = core . NewCommandlineUI ( )
}
}
// 4bytedb data
// 4bytedb data
fourByteLocal := c . Global String( customDBFlag . Name )
fourByteLocal := c . String ( customDBFlag . Name )
db , err := fourbyte . NewWithFile ( fourByteLocal )
db , err := fourbyte . NewWithFile ( fourByteLocal )
if err != nil {
if err != nil {
utils . Fatalf ( err . Error ( ) )
utils . Fatalf ( err . Error ( ) )
@ -574,7 +517,7 @@ func signer(c *cli.Context) error {
api core . ExternalAPI
api core . ExternalAPI
pwStorage storage . Storage = & storage . NoStorage { }
pwStorage storage . Storage = & storage . NoStorage { }
)
)
configDir := c . Global String( configdirFlag . Name )
configDir := c . String ( configdirFlag . Name )
if stretchedKey , err := readMasterKey ( c , ui ) ; err != nil {
if stretchedKey , err := readMasterKey ( c , ui ) ; err != nil {
log . Warn ( "Failed to open master, rules disabled" , "err" , err )
log . Warn ( "Failed to open master, rules disabled" , "err" , err )
} else {
} else {
@ -591,7 +534,7 @@ func signer(c *cli.Context) error {
configStorage := storage . NewAESEncryptedStorage ( filepath . Join ( vaultLocation , "config.json" ) , confkey )
configStorage := storage . NewAESEncryptedStorage ( filepath . Join ( vaultLocation , "config.json" ) , confkey )
// Do we have a rule-file?
// Do we have a rule-file?
if ruleFile := c . Global String( ruleFlag . Name ) ; ruleFile != "" {
if ruleFile := c . String ( ruleFlag . Name ) ; ruleFile != "" {
ruleJS , err := os . ReadFile ( ruleFile )
ruleJS , err := os . ReadFile ( ruleFile )
if err != nil {
if err != nil {
log . Warn ( "Could not load rules, disabling" , "file" , ruleFile , "err" , err )
log . Warn ( "Could not load rules, disabling" , "file" , ruleFile , "err" , err )
@ -615,12 +558,12 @@ func signer(c *cli.Context) error {
}
}
}
}
var (
var (
chainId = c . Global Int64( chainIdFlag . Name )
chainId = c . Int64 ( chainIdFlag . Name )
ksLoc = c . Global String( keystoreFlag . Name )
ksLoc = c . String ( keystoreFlag . Name )
lightKdf = c . Global Bool( utils . LightKDFFlag . Name )
lightKdf = c . Bool ( utils . LightKDFFlag . Name )
advanced = c . Global Bool( advancedMode . Name )
advanced = c . Bool ( advancedMode . Name )
nousb = c . Global Bool( utils . NoUSBFlag . Name )
nousb = c . Bool ( utils . NoUSBFlag . Name )
scpath = c . Global String( utils . SmartCardDaemonPathFlag . Name )
scpath = c . String ( utils . SmartCardDaemonPathFlag . Name )
)
)
log . Info ( "Starting signer" , "chainid" , chainId , "keystore" , ksLoc ,
log . Info ( "Starting signer" , "chainid" , chainId , "keystore" , ksLoc ,
"light-kdf" , lightKdf , "advanced" , advanced )
"light-kdf" , lightKdf , "advanced" , advanced )
@ -632,7 +575,7 @@ func signer(c *cli.Context) error {
ui . RegisterUIServer ( core . NewUIServerAPI ( apiImpl ) )
ui . RegisterUIServer ( core . NewUIServerAPI ( apiImpl ) )
api = apiImpl
api = apiImpl
// Audit logging
// Audit logging
if logfile := c . Global String( auditLogFlag . Name ) ; logfile != "" {
if logfile := c . String ( auditLogFlag . Name ) ; logfile != "" {
api , err = core . NewAuditLogger ( logfile , api )
api , err = core . NewAuditLogger ( logfile , api )
if err != nil {
if err != nil {
utils . Fatalf ( err . Error ( ) )
utils . Fatalf ( err . Error ( ) )
@ -650,9 +593,9 @@ func signer(c *cli.Context) error {
Service : api ,
Service : api ,
Version : "1.0" } ,
Version : "1.0" } ,
}
}
if c . Global Bool( utils . HTTPEnabledFlag . Name ) {
if c . Bool ( utils . HTTPEnabledFlag . Name ) {
vhosts := utils . SplitAndTrim ( c . Global String( utils . HTTPVirtualHostsFlag . Name ) )
vhosts := utils . SplitAndTrim ( c . String ( utils . HTTPVirtualHostsFlag . Name ) )
cors := utils . SplitAndTrim ( c . Global String( utils . HTTPCORSDomainFlag . Name ) )
cors := utils . SplitAndTrim ( c . String ( utils . HTTPCORSDomainFlag . Name ) )
srv := rpc . NewServer ( )
srv := rpc . NewServer ( )
err := node . RegisterApis ( rpcAPI , [ ] string { "account" } , srv )
err := node . RegisterApis ( rpcAPI , [ ] string { "account" } , srv )
@ -665,7 +608,7 @@ func signer(c *cli.Context) error {
port := c . Int ( rpcPortFlag . Name )
port := c . Int ( rpcPortFlag . Name )
// start http server
// start http server
httpEndpoint := fmt . Sprintf ( "%s:%d" , c . Global String( utils . HTTPListenAddrFlag . Name ) , port )
httpEndpoint := fmt . Sprintf ( "%s:%d" , c . String ( utils . HTTPListenAddrFlag . Name ) , port )
httpServer , addr , err := node . StartHTTPEndpoint ( httpEndpoint , rpc . DefaultHTTPTimeouts , handler )
httpServer , addr , err := node . StartHTTPEndpoint ( httpEndpoint , rpc . DefaultHTTPTimeouts , handler )
if err != nil {
if err != nil {
utils . Fatalf ( "Could not start RPC api: %v" , err )
utils . Fatalf ( "Could not start RPC api: %v" , err )
@ -679,8 +622,8 @@ func signer(c *cli.Context) error {
log . Info ( "HTTP endpoint closed" , "url" , extapiURL )
log . Info ( "HTTP endpoint closed" , "url" , extapiURL )
} ( )
} ( )
}
}
if ! c . Global Bool( utils . IPCDisabledFlag . Name ) {
if ! c . Bool ( utils . IPCDisabledFlag . Name ) {
givenPath := c . Global String( utils . IPCPathFlag . Name )
givenPath := c . String ( utils . IPCPathFlag . Name )
ipcapiURL = ipcEndpoint ( filepath . Join ( givenPath , "clef.ipc" ) , configDir )
ipcapiURL = ipcEndpoint ( filepath . Join ( givenPath , "clef.ipc" ) , configDir )
listener , _ , err := rpc . StartIPCEndpoint ( ipcapiURL , rpcAPI )
listener , _ , err := rpc . StartIPCEndpoint ( ipcapiURL , rpcAPI )
if err != nil {
if err != nil {
@ -693,7 +636,7 @@ func signer(c *cli.Context) error {
} ( )
} ( )
}
}
if c . Global Bool( testFlag . Name ) {
if c . Bool ( testFlag . Name ) {
log . Info ( "Performing UI test" )
log . Info ( "Performing UI test" )
go testExternalUI ( apiImpl )
go testExternalUI ( apiImpl )
}
}
@ -719,7 +662,7 @@ func signer(c *cli.Context) error {
// persistence requirements.
// persistence requirements.
func DefaultConfigDir ( ) string {
func DefaultConfigDir ( ) string {
// Try to place the data folder in the user's home dir
// Try to place the data folder in the user's home dir
home := util s. HomeDir ( )
home := flag s. HomeDir ( )
if home != "" {
if home != "" {
if runtime . GOOS == "darwin" {
if runtime . GOOS == "darwin" {
return filepath . Join ( home , "Library" , "Signer" )
return filepath . Join ( home , "Library" , "Signer" )
@ -739,10 +682,10 @@ func DefaultConfigDir() string {
func readMasterKey ( ctx * cli . Context , ui core . UIClientAPI ) ( [ ] byte , error ) {
func readMasterKey ( ctx * cli . Context , ui core . UIClientAPI ) ( [ ] byte , error ) {
var (
var (
file string
file string
configDir = ctx . Global String( configdirFlag . Name )
configDir = ctx . String ( configdirFlag . Name )
)
)
if ctx . Global IsSet( signerSecretFlag . Name ) {
if ctx . IsSet ( signerSecretFlag . Name ) {
file = ctx . Global String( signerSecretFlag . Name )
file = ctx . String ( signerSecretFlag . Name )
} else {
} else {
file = filepath . Join ( configDir , "masterseed.json" )
file = filepath . Join ( configDir , "masterseed.json" )
}
}
@ -995,7 +938,7 @@ func decryptSeed(keyjson []byte, auth string) ([]byte, error) {
}
}
// GenDoc outputs examples of all structures used in json-rpc communication
// GenDoc outputs examples of all structures used in json-rpc communication
func GenDoc ( ctx * cli . Context ) {
func GenDoc ( ctx * cli . Context ) error {
var (
var (
a = common . HexToAddress ( "0xdeadbeef000000000000000000000000deadbeef" )
a = common . HexToAddress ( "0xdeadbeef000000000000000000000000deadbeef" )
@ -1145,4 +1088,5 @@ These data types are defined in the channel between clef and the UI`)
for _ , elem := range output {
for _ , elem := range output {
fmt . Println ( elem )
fmt . Println ( elem )
}
}
return nil
}
}