code.vegaprotocol.io/vega@v0.79.0/core/nodewallets/ethereum_handler.go (about) 1 // Copyright (C) 2023 Gobalsky Labs Limited 2 // 3 // This program is free software: you can redistribute it and/or modify 4 // it under the terms of the GNU Affero General Public License as 5 // published by the Free Software Foundation, either version 3 of the 6 // License, or (at your option) any later version. 7 // 8 // This program is distributed in the hope that it will be useful, 9 // but WITHOUT ANY WARRANTY; without even the implied warranty of 10 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 11 // GNU Affero General Public License for more details. 12 // 13 // You should have received a copy of the GNU Affero General Public License 14 // along with this program. If not, see <http://www.gnu.org/licenses/>. 15 16 package nodewallets 17 18 import ( 19 "fmt" 20 "path/filepath" 21 22 "code.vegaprotocol.io/vega/core/nodewallets/eth" 23 "code.vegaprotocol.io/vega/core/nodewallets/eth/clef" 24 "code.vegaprotocol.io/vega/core/nodewallets/eth/keystore" 25 "code.vegaprotocol.io/vega/core/nodewallets/registry" 26 "code.vegaprotocol.io/vega/paths" 27 28 ethcommon "github.com/ethereum/go-ethereum/common" 29 "github.com/ethereum/go-ethereum/rpc" 30 ) 31 32 func GetEthereumWallet(vegaPaths paths.Paths, registryPassphrase string) (*eth.Wallet, error) { 33 registryLoader, err := registry.NewLoader(vegaPaths, registryPassphrase) 34 if err != nil { 35 return nil, fmt.Errorf("couldn't initialise node wallet registry: %v", err) 36 } 37 38 registry, err := registryLoader.Get(registryPassphrase) 39 if err != nil { 40 return nil, fmt.Errorf("couldn't load node wallet registry: %v", err) 41 } 42 43 if registry.Ethereum == nil { 44 return nil, ErrEthereumWalletIsMissing 45 } 46 47 return GetEthereumWalletWithRegistry(vegaPaths, registry) 48 } 49 50 func GetEthereumWalletWithRegistry(vegaPaths paths.Paths, reg *registry.Registry) (*eth.Wallet, error) { 51 switch walletRegistry := reg.Ethereum.Details.(type) { 52 case registry.EthereumClefWallet: 53 ethAddress := ethcommon.HexToAddress(walletRegistry.AccountAddress) 54 55 client, err := rpc.Dial(walletRegistry.ClefAddress) 56 if err != nil { 57 return nil, fmt.Errorf("failed to dial Clef daemon: %w", err) 58 } 59 60 w, err := clef.NewWallet(client, walletRegistry.ClefAddress, ethAddress) 61 if err != nil { 62 return nil, fmt.Errorf("couldn't initialise Ethereum Clef node wallet: %w", err) 63 } 64 65 return eth.NewWallet(w), nil 66 case registry.EthereumKeyStoreWallet: 67 walletLoader, err := keystore.InitialiseWalletLoader(vegaPaths) 68 if err != nil { 69 return nil, fmt.Errorf("couldn't initialise Ethereum key store node wallet loader: %w", err) 70 } 71 72 w, err := walletLoader.Load(walletRegistry.Name, walletRegistry.Passphrase) 73 if err != nil { 74 return nil, fmt.Errorf("couldn't load Ethereum key store node wallet: %w", err) 75 } 76 77 return eth.NewWallet(w), nil 78 default: 79 return nil, fmt.Errorf("could not create unknown Ethereum wallet type %q", reg.Ethereum.Type) 80 } 81 } 82 83 func GenerateEthereumWallet( 84 vegaPaths paths.Paths, 85 registryPassphrase, 86 walletPassphrase string, 87 clefAddress string, 88 overwrite bool, 89 ) (map[string]string, error) { 90 registryLoader, err := registry.NewLoader(vegaPaths, registryPassphrase) 91 if err != nil { 92 return nil, fmt.Errorf("couldn't initialise node wallet registry: %v", err) 93 } 94 95 reg, err := registryLoader.Get(registryPassphrase) 96 if err != nil { 97 return nil, fmt.Errorf("couldn't load node wallet registry: %v", err) 98 } 99 100 if !overwrite && reg.Ethereum != nil { 101 return nil, ErrEthereumWalletAlreadyExists 102 } 103 104 var data map[string]string 105 106 if clefAddress != "" { 107 client, err := rpc.Dial(clefAddress) 108 if err != nil { 109 return nil, fmt.Errorf("failed to dial Clef daemon: %w", err) 110 } 111 112 w, err := clef.GenerateNewWallet(client, clefAddress) 113 if err != nil { 114 return nil, fmt.Errorf("couldn't generate Ethereum clef node wallet: %w", err) 115 } 116 117 data = map[string]string{ 118 "clefAddress": clefAddress, 119 "accountAddress": w.PubKey().Hex(), 120 } 121 122 reg.Ethereum = ®istry.RegisteredEthereumWallet{ 123 Type: registry.EthereumWalletTypeClef, 124 Details: registry.EthereumClefWallet{ 125 Name: w.Name(), 126 AccountAddress: w.PubKey().Hex(), 127 ClefAddress: clefAddress, 128 }, 129 } 130 } else { 131 keyStoreLoader, err := keystore.InitialiseWalletLoader(vegaPaths) 132 if err != nil { 133 return nil, fmt.Errorf("couldn't initialise Ethereum key store node wallet loader: %w", err) 134 } 135 136 w, d, err := keyStoreLoader.Generate(walletPassphrase) 137 if err != nil { 138 return nil, fmt.Errorf("couldn't generate Ethereum key store node wallet: %w", err) 139 } 140 141 data = d 142 143 reg.Ethereum = ®istry.RegisteredEthereumWallet{ 144 Type: registry.EthereumWalletTypeKeyStore, 145 Details: registry.EthereumKeyStoreWallet{ 146 Name: w.Name(), 147 Passphrase: walletPassphrase, 148 }, 149 } 150 } 151 152 if err := registryLoader.Save(reg, registryPassphrase); err != nil { 153 return nil, fmt.Errorf("couldn't save registry: %w", err) 154 } 155 156 data["registryFilePath"] = registryLoader.RegistryFilePath() 157 return data, nil 158 } 159 160 func ImportEthereumWallet( 161 vegaPaths paths.Paths, 162 registryPassphrase, 163 walletPassphrase, 164 clefAccount, 165 clefAddress, 166 sourceFilePath string, 167 overwrite bool, 168 ) (map[string]string, error) { 169 registryLoader, err := registry.NewLoader(vegaPaths, registryPassphrase) 170 if err != nil { 171 return nil, fmt.Errorf("couldn't initialise node wallet registry: %v", err) 172 } 173 174 reg, err := registryLoader.Get(registryPassphrase) 175 if err != nil { 176 return nil, fmt.Errorf("couldn't load node wallet registry: %v", err) 177 } 178 179 if !overwrite && reg.Ethereum != nil { 180 return nil, ErrEthereumWalletAlreadyExists 181 } 182 183 var data map[string]string 184 185 if clefAddress != "" { 186 if !ethcommon.IsHexAddress(clefAccount) { 187 return nil, fmt.Errorf("invalid Ethereum hex address %q", clefAccount) 188 } 189 190 ethAddress := ethcommon.HexToAddress(clefAccount) 191 192 client, err := rpc.Dial(clefAddress) 193 if err != nil { 194 return nil, fmt.Errorf("failed to dial Clef daemon: %w", err) 195 } 196 197 w, err := clef.NewWallet(client, clefAddress, ethAddress) 198 if err != nil { 199 return nil, fmt.Errorf("couldn't initialise Ethereum Clef node wallet: %w", err) 200 } 201 202 data = map[string]string{ 203 "clefAddress": clefAddress, 204 "accountAddress": w.PubKey().Hex(), 205 } 206 207 reg.Ethereum = ®istry.RegisteredEthereumWallet{ 208 Type: registry.EthereumWalletTypeClef, 209 Details: registry.EthereumClefWallet{ 210 Name: w.Name(), 211 AccountAddress: w.PubKey().Hex(), 212 ClefAddress: clefAddress, 213 }, 214 } 215 } else { 216 if !filepath.IsAbs(sourceFilePath) { 217 return nil, fmt.Errorf("path to the wallet file need to be absolute") 218 } 219 220 ethWalletLoader, err := keystore.InitialiseWalletLoader(vegaPaths) 221 if err != nil { 222 return nil, fmt.Errorf("couldn't initialise Ethereum node wallet loader: %w", err) 223 } 224 225 w, d, err := ethWalletLoader.Import(sourceFilePath, walletPassphrase) 226 if err != nil { 227 return nil, fmt.Errorf("couldn't import Ethereum node wallet: %w", err) 228 } 229 230 data = d 231 232 reg.Ethereum = ®istry.RegisteredEthereumWallet{ 233 Type: registry.EthereumWalletTypeKeyStore, 234 Details: registry.EthereumKeyStoreWallet{ 235 Name: w.Name(), 236 Passphrase: walletPassphrase, 237 }, 238 } 239 } 240 241 if err := registryLoader.Save(reg, registryPassphrase); err != nil { 242 return nil, fmt.Errorf("couldn't save registry: %w", err) 243 } 244 245 data["registryFilePath"] = registryLoader.RegistryFilePath() 246 return data, nil 247 }