github.com/amazechain/amc@v0.1.3/accounts/external/backend.go (about) 1 // Copyright 2023 The AmazeChain Authors 2 // This file is part of the AmazeChain library. 3 // 4 // The AmazeChain library is free software: you can redistribute it and/or modify 5 // it under the terms of the GNU Lesser General Public License as published by 6 // the Free Software Foundation, either version 3 of the License, or 7 // (at your option) any later version. 8 // 9 // The AmazeChain library is distributed in the hope that it will be useful, 10 // but WITHOUT ANY WARRANTY; without even the implied warranty of 11 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 12 // GNU Lesser General Public License for more details. 13 // 14 // You should have received a copy of the GNU Lesser General Public License 15 // along with the AmazeChain library. If not, see <http://www.gnu.org/licenses/>. 16 17 package external 18 19 //import ( 20 // "fmt" 21 // "math/big" 22 // "sync" 23 // 24 // "github.com/amazechain/amc/accounts" 25 // "github.com/amazechain/amc/common" 26 // types2 "github.com/amazechain/amc/common/types" 27 // "github.com/amazechain/amc/internal/avm/common/hexutil" 28 // "github.com/amazechain/amc/internal/avm/types" 29 // "github.com/amazechain/amc/log" 30 // event "github.com/amazechain/amc/modules/event/v2" 31 // "github.com/amazechain/amc/rpc" 32 // "github.com/amazechain/amc/signer/core/apitypes" 33 //) 34 // 35 //type ExternalBackend struct { 36 // signers []accounts.Wallet 37 //} 38 // 39 //func (eb *ExternalBackend) Wallets() []accounts.Wallet { 40 // return eb.signers 41 //} 42 // 43 //func NewExternalBackend(endpoint string) (*ExternalBackend, error) { 44 // signer, err := NewExternalSigner(endpoint) 45 // if err != nil { 46 // return nil, err 47 // } 48 // return &ExternalBackend{ 49 // signers: []accounts.Wallet{signer}, 50 // }, nil 51 //} 52 // 53 //func (eb *ExternalBackend) Subscribe(sink chan<- accounts.WalletEvent) event.Subscription { 54 // return event.NewSubscription(func(quit <-chan struct{}) error { 55 // <-quit 56 // return nil 57 // }) 58 //} 59 // 60 //// ExternalSigner provides an API to interact with an external signer (clef) 61 //// It proxies request to the external signer while forwarding relevant 62 //// request headers 63 //type ExternalSigner struct { 64 // client *rpc.Client 65 // endpoint string 66 // status string 67 // cacheMu sync.RWMutex 68 // cache []accounts.Account 69 //} 70 // 71 //func NewExternalSigner(endpoint string) (*ExternalSigner, error) { 72 // client, err := rpc.Dial(endpoint) 73 // if err != nil { 74 // return nil, err 75 // } 76 // extsigner := &ExternalSigner{ 77 // client: client, 78 // endpoint: endpoint, 79 // } 80 // // Check if reachable 81 // version, err := extsigner.pingVersion() 82 // if err != nil { 83 // return nil, err 84 // } 85 // extsigner.status = fmt.Sprintf("ok [version=%v]", version) 86 // return extsigner, nil 87 //} 88 // 89 //func (api *ExternalSigner) URL() accounts.URL { 90 // return accounts.URL{ 91 // Scheme: "extapi", 92 // Path: api.endpoint, 93 // } 94 //} 95 // 96 //func (api *ExternalSigner) Status() (string, error) { 97 // return api.status, nil 98 //} 99 // 100 //func (api *ExternalSigner) Open(passphrase string) error { 101 // return fmt.Errorf("operation not supported on external signers") 102 //} 103 // 104 //func (api *ExternalSigner) Close() error { 105 // return fmt.Errorf("operation not supported on external signers") 106 //} 107 // 108 //func (api *ExternalSigner) Accounts() []accounts.Account { 109 // var accnts []accounts.Account 110 // res, err := api.listAccounts() 111 // if err != nil { 112 // log.Error("account listing failed", "error", err) 113 // return accnts 114 // } 115 // for _, addr := range res { 116 // accnts = append(accnts, accounts.Account{ 117 // URL: accounts.URL{ 118 // Scheme: "extapi", 119 // Path: api.endpoint, 120 // }, 121 // Address: addr, 122 // }) 123 // } 124 // api.cacheMu.Lock() 125 // api.cache = accnts 126 // api.cacheMu.Unlock() 127 // return accnts 128 //} 129 // 130 //func (api *ExternalSigner) Contains(account accounts.Account) bool { 131 // api.cacheMu.RLock() 132 // defer api.cacheMu.RUnlock() 133 // if api.cache == nil { 134 // // If we haven't already fetched the accounts, it's time to do so now 135 // api.cacheMu.RUnlock() 136 // api.Accounts() 137 // api.cacheMu.RLock() 138 // } 139 // for _, a := range api.cache { 140 // if a.Address == account.Address && (account.URL == (accounts.URL{}) || account.URL == api.URL()) { 141 // return true 142 // } 143 // } 144 // return false 145 //} 146 // 147 //func (api *ExternalSigner) Derive(path accounts.DerivationPath, pin bool) (accounts.Account, error) { 148 // return accounts.Account{}, fmt.Errorf("operation not supported on external signers") 149 //} 150 // 151 //func (api *ExternalSigner) SelfDerive(bases []accounts.DerivationPath, chain common.ChainStateReader) { 152 // log.Error("operation SelfDerive not supported on external signers") 153 //} 154 // 155 //// SignData signs keccak256(data). The mimetype parameter describes the type of data being signed 156 //func (api *ExternalSigner) SignData(account accounts.Account, mimeType string, data []byte) ([]byte, error) { 157 // var res hexutil.Bytes 158 // var signAddress = common.NewMixedcaseAddress(account.Address) 159 // if err := api.client.Call(&res, "account_signData", 160 // mimeType, 161 // &signAddress, // Need to use the pointer here, because of how MarshalJSON is defined 162 // hexutil.Encode(data)); err != nil { 163 // return nil, err 164 // } 165 // // If V is on 27/28-form, convert to 0/1 for Clique 166 // if mimeType == accounts.MimetypeClique && (res[64] == 27 || res[64] == 28) { 167 // res[64] -= 27 // Transform V from 27/28 to 0/1 for Clique use 168 // } 169 // return res, nil 170 //} 171 // 172 //func (api *ExternalSigner) SignText(account accounts.Account, text []byte) ([]byte, error) { 173 // var signature hexutil.Bytes 174 // var signAddress = common.NewMixedcaseAddress(account.Address) 175 // if err := api.client.Call(&signature, "account_signData", 176 // accounts.MimetypeTextPlain, 177 // &signAddress, // Need to use the pointer here, because of how MarshalJSON is defined 178 // hexutil.Encode(text)); err != nil { 179 // return nil, err 180 // } 181 // if signature[64] == 27 || signature[64] == 28 { 182 // // If clef is used as a backend, it may already have transformed 183 // // the signature to ethereum-type signature. 184 // signature[64] -= 27 // Transform V from Ethereum-legacy to 0/1 185 // } 186 // return signature, nil 187 //} 188 // 189 //// signTransactionResult represents the signinig result returned by clef. 190 //type signTransactionResult struct { 191 // Raw hexutil.Bytes `json:"raw"` 192 // Tx *types.Transaction `json:"tx"` 193 //} 194 // 195 //// SignTx sends the transaction to the external signer. 196 //// If chainID is nil, or tx.ChainID is zero, the chain ID will be assigned 197 //// by the external signer. For non-legacy transactions, the chain ID of the 198 //// transaction overrides the chainID parameter. 199 //func (api *ExternalSigner) SignTx(account accounts.Account, tx *types.Transaction, chainID *big.Int) (*types.Transaction, error) { 200 // data := hexutil.Bytes(tx.Data()) 201 // var to *common.MixedcaseAddress 202 // if tx.To() != nil { 203 // t := common.NewMixedcaseAddress(*tx.To()) 204 // to = &t 205 // } 206 // args := &apitypes.SendTxArgs{ 207 // Data: &data, 208 // Nonce: hexutil.Uint64(tx.Nonce()), 209 // Value: hexutil.Big(*tx.Value()), 210 // Gas: hexutil.Uint64(tx.Gas()), 211 // To: to, 212 // From: common.NewMixedcaseAddress(account.Address), 213 // } 214 // switch tx.Type() { 215 // case types.LegacyTxType, types.AccessListTxType: 216 // args.GasPrice = (*hexutil.Big)(tx.GasPrice()) 217 // case types.DynamicFeeTxType: 218 // args.MaxFeePerGas = (*hexutil.Big)(tx.GasFeeCap()) 219 // args.MaxPriorityFeePerGas = (*hexutil.Big)(tx.GasTipCap()) 220 // default: 221 // return nil, fmt.Errorf("unsupported tx type %d", tx.Type()) 222 // } 223 // // We should request the default chain id that we're operating with 224 // // (the chain we're executing on) 225 // if chainID != nil && chainID.Sign() != 0 { 226 // args.ChainID = (*hexutil.Big)(chainID) 227 // } 228 // if tx.Type() != types.LegacyTxType { 229 // // However, if the user asked for a particular chain id, then we should 230 // // use that instead. 231 // if tx.ChainId().Sign() != 0 { 232 // args.ChainID = (*hexutil.Big)(tx.ChainId()) 233 // } 234 // accessList := tx.AccessList() 235 // args.AccessList = &accessList 236 // } 237 // var res signTransactionResult 238 // if err := api.client.Call(&res, "account_signTransaction", args); err != nil { 239 // return nil, err 240 // } 241 // return res.Tx, nil 242 //} 243 // 244 //func (api *ExternalSigner) SignTextWithPassphrase(account accounts.Account, passphrase string, text []byte) ([]byte, error) { 245 // return []byte{}, fmt.Errorf("password-operations not supported on external signers") 246 //} 247 // 248 //func (api *ExternalSigner) SignTxWithPassphrase(account accounts.Account, passphrase string, tx *types.Transaction, chainID *big.Int) (*types.Transaction, error) { 249 // return nil, fmt.Errorf("password-operations not supported on external signers") 250 //} 251 //func (api *ExternalSigner) SignDataWithPassphrase(account accounts.Account, passphrase, mimeType string, data []byte) ([]byte, error) { 252 // return nil, fmt.Errorf("password-operations not supported on external signers") 253 //} 254 // 255 //func (api *ExternalSigner) listAccounts() ([]types2.Address, error) { 256 // var res []types2.Address 257 // if err := api.client.Call(&res, "account_list"); err != nil { 258 // return nil, err 259 // } 260 // return res, nil 261 //} 262 // 263 //func (api *ExternalSigner) pingVersion() (string, error) { 264 // var v string 265 // if err := api.client.Call(&v, "account_version"); err != nil { 266 // return "", err 267 // } 268 // return v, nil 269 //}