feat(walletconnect)_: ethereum rpc calls support
Reference: https://docs.walletconnect.com/advanced/rpc-reference/ethereum-rpc
This commit is contained in:
parent
d4ca8616fc
commit
8641ec5dd5
|
@ -1919,7 +1919,7 @@ func (b *GethStatusBackend) SendTransactionWithChainID(chainID uint64, sendArgs
|
||||||
}
|
}
|
||||||
|
|
||||||
func (b *GethStatusBackend) SendTransactionWithSignature(sendArgs transactions.SendTxArgs, sig []byte) (hash types.Hash, err error) {
|
func (b *GethStatusBackend) SendTransactionWithSignature(sendArgs transactions.SendTxArgs, sig []byte) (hash types.Hash, err error) {
|
||||||
hash, err = b.transactor.SendTransactionWithSignature(b.transactor.NetworkID(), sendArgs, sig)
|
hash, err = b.transactor.BuildTransactionAndSendWithSignature(b.transactor.NetworkID(), sendArgs, sig)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
|
@ -6,17 +6,31 @@ const (
|
||||||
// StatusDatabase path relative to DataDir.
|
// StatusDatabase path relative to DataDir.
|
||||||
StatusDatabase = "status-db"
|
StatusDatabase = "status-db"
|
||||||
|
|
||||||
// SendTransactionMethodName defines the name for a giving transaction.
|
// SendTransactionMethodName https://docs.walletconnect.com/advanced/rpc-reference/ethereum-rpc#eth_sendtransaction
|
||||||
SendTransactionMethodName = "eth_sendTransaction"
|
SendTransactionMethodName = "eth_sendTransaction"
|
||||||
|
|
||||||
|
// SendTransactionMethodName https://docs.walletconnect.com/advanced/rpc-reference/ethereum-rpc#eth_sendrawtransaction
|
||||||
|
SendRawTransactionMethodName = "eth_sendRawTransaction"
|
||||||
|
|
||||||
BalanceMethodName = "eth_getBalance"
|
BalanceMethodName = "eth_getBalance"
|
||||||
|
|
||||||
// AccountsMethodName defines the name for listing the currently signed accounts.
|
// AccountsMethodName defines the name for listing the currently signed accounts.
|
||||||
AccountsMethodName = "eth_accounts"
|
AccountsMethodName = "eth_accounts"
|
||||||
|
|
||||||
// PersonalSignMethodName defines the name for `personal.sign` API.
|
// PersonalSignMethodName https://docs.walletconnect.com/advanced/rpc-reference/ethereum-rpc#personal_sign
|
||||||
PersonalSignMethodName = "personal_sign"
|
PersonalSignMethodName = "personal_sign"
|
||||||
|
|
||||||
|
// SignMethodName https://docs.walletconnect.com/advanced/rpc-reference/ethereum-rpc#eth_sign
|
||||||
|
SignMethodName = "eth_sign"
|
||||||
|
|
||||||
|
// SignTransactionMethodName https://docs.walletconnect.com/advanced/rpc-reference/ethereum-rpc#eth_signtransaction
|
||||||
|
SignTransactionMethodName = "eth_signTransaction"
|
||||||
|
|
||||||
|
// SignTypedDataMethodName https://docs.walletconnect.com/advanced/rpc-reference/ethereum-rpc#eth_signtypeddata
|
||||||
|
SignTypedDataMethodName = "eth_signTypedData"
|
||||||
|
|
||||||
|
WalletSwitchEthereumChainMethodName = "wallet_switchEthereumChain"
|
||||||
|
|
||||||
// PersonalRecoverMethodName defines the name for `personal.recover` API.
|
// PersonalRecoverMethodName defines the name for `personal.recover` API.
|
||||||
PersonalRecoverMethodName = "personal_ecRecover"
|
PersonalRecoverMethodName = "personal_ecRecover"
|
||||||
|
|
||||||
|
|
|
@ -26,7 +26,6 @@ import (
|
||||||
"github.com/status-im/status-go/services/wallet/thirdparty"
|
"github.com/status-im/status-go/services/wallet/thirdparty"
|
||||||
"github.com/status-im/status-go/services/wallet/token"
|
"github.com/status-im/status-go/services/wallet/token"
|
||||||
"github.com/status-im/status-go/services/wallet/transfer"
|
"github.com/status-im/status-go/services/wallet/transfer"
|
||||||
"github.com/status-im/status-go/services/wallet/walletconnect"
|
|
||||||
wc "github.com/status-im/status-go/services/wallet/walletconnect"
|
wc "github.com/status-im/status-go/services/wallet/walletconnect"
|
||||||
"github.com/status-im/status-go/services/wallet/walletevent"
|
"github.com/status-im/status-go/services/wallet/walletevent"
|
||||||
"github.com/status-im/status-go/transactions"
|
"github.com/status-im/status-go/transactions"
|
||||||
|
@ -609,16 +608,32 @@ func (api *API) FetchChainIDForURL(ctx context.Context, rpcURL string) (*big.Int
|
||||||
return client.ChainID(ctx)
|
return client.ChainID(ctx)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// WCSignMessage signs a message for the passed address using the provided password and returns the signature
|
||||||
func (api *API) WCSignMessage(ctx context.Context, message types.HexBytes, address common.Address, password string) (string, error) {
|
func (api *API) WCSignMessage(ctx context.Context, message types.HexBytes, address common.Address, password string) (string, error) {
|
||||||
log.Debug("wallet.api.wc.SignMessage", "message", message, "address", address, "password", password)
|
log.Debug("wallet.api.wc.SignMessage", "message", message, "address", address, "password", password)
|
||||||
|
|
||||||
return api.s.walletConnect.SignMessage(message, address, password)
|
return api.s.walletConnect.SignMessage(message, address, password)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (api *API) WCSendTransaction(signature string) (response *walletconnect.SessionRequestResponse, err error) {
|
// WCBuildRawTransaction builds raw transaction using the provided signature and returns the RLP-encoded transaction object
|
||||||
log.Debug("wallet.api.wc.SendTransaction", "signature", signature)
|
func (api *API) WCBuildRawTransaction(signature string) (string, error) {
|
||||||
|
log.Debug("wallet.api.wc.BuildRawTransaction", "signature", signature)
|
||||||
|
|
||||||
return api.s.walletConnect.SendTransaction(signature)
|
return api.s.walletConnect.BuildRawTransaction(signature)
|
||||||
|
}
|
||||||
|
|
||||||
|
// WCSendRawTransaction sends provided raw transaction and returns the transaction hash
|
||||||
|
func (api *API) WCSendRawTransaction(rawTx string) (string, error) {
|
||||||
|
log.Debug("wallet.api.wc.SendRawTransaction", "rawTx", rawTx)
|
||||||
|
|
||||||
|
return api.s.walletConnect.SendRawTransaction(rawTx)
|
||||||
|
}
|
||||||
|
|
||||||
|
// WCSendTransactionWithSignature sends transaction with the provided signature and returns the transaction hash
|
||||||
|
func (api *API) WCSendTransactionWithSignature(signature string) (string, error) {
|
||||||
|
log.Debug("wallet.api.wc.SendTransactionWithSignature", "signature", signature)
|
||||||
|
|
||||||
|
return api.s.walletConnect.SendTransactionWithSignature(signature)
|
||||||
}
|
}
|
||||||
|
|
||||||
// WCPairSessionProposal responds to "session_proposal" event
|
// WCPairSessionProposal responds to "session_proposal" event
|
||||||
|
@ -655,11 +670,11 @@ func (api *API) WCHasActivePairings(ctx context.Context) (bool, error) {
|
||||||
}
|
}
|
||||||
|
|
||||||
// WCSessionRequest responds to "session_request" event
|
// WCSessionRequest responds to "session_request" event
|
||||||
func (api *API) WCSessionRequest(ctx context.Context, sessionRequestJSON string) (response *wc.SessionRequestResponse, err error) {
|
func (api *API) WCSessionRequest(ctx context.Context, sessionRequestJSON string) (*wc.SessionRequestResponse, error) {
|
||||||
log.Debug("wallet.api.wc.SessionRequest", "request.len", len(sessionRequestJSON))
|
log.Debug("wallet.api.wc.SessionRequest", "request.len", len(sessionRequestJSON))
|
||||||
|
|
||||||
var request wc.SessionRequest
|
var request wc.SessionRequest
|
||||||
err = json.Unmarshal([]byte(sessionRequestJSON), &request)
|
err := json.Unmarshal([]byte(sessionRequestJSON), &request)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
|
|
@ -399,7 +399,7 @@ func (tm *TransactionManager) ProceedWithTransactionsSignatures(ctx context.Cont
|
||||||
// send transactions
|
// send transactions
|
||||||
hashes := make(map[uint64][]types.Hash)
|
hashes := make(map[uint64][]types.Hash)
|
||||||
for _, desc := range tm.transactionsForKeycardSingning {
|
for _, desc := range tm.transactionsForKeycardSingning {
|
||||||
hash, err := tm.transactor.SendBuiltTransactionWithSignature(desc.chainID, desc.builtTx, desc.signature)
|
hash, err := tm.transactor.AddSignatureToTransactionAndSend(desc.chainID, desc.builtTx, desc.signature)
|
||||||
if desc.unlock != nil {
|
if desc.unlock != nil {
|
||||||
defer func() {
|
defer func() {
|
||||||
desc.unlock(err == nil, desc.builtTx.Nonce())
|
desc.unlock(err == nil, desc.builtTx.Nonce())
|
||||||
|
|
|
@ -10,7 +10,7 @@ import (
|
||||||
|
|
||||||
"github.com/ethereum/go-ethereum/common"
|
"github.com/ethereum/go-ethereum/common"
|
||||||
ethTypes "github.com/ethereum/go-ethereum/core/types"
|
ethTypes "github.com/ethereum/go-ethereum/core/types"
|
||||||
|
"github.com/ethereum/go-ethereum/signer/core/apitypes"
|
||||||
"github.com/status-im/status-go/eth-node/crypto"
|
"github.com/status-im/status-go/eth-node/crypto"
|
||||||
"github.com/status-im/status-go/eth-node/types"
|
"github.com/status-im/status-go/eth-node/types"
|
||||||
"github.com/status-im/status-go/transactions"
|
"github.com/status-im/status-go/transactions"
|
||||||
|
@ -106,40 +106,41 @@ func (s *Service) buildTransaction(request SessionRequest) (response *SessionReq
|
||||||
txBeingSigned: txBeingSigned,
|
txBeingSigned: txBeingSigned,
|
||||||
}
|
}
|
||||||
|
|
||||||
signer := ethTypes.NewLondonSigner(new(big.Int).SetUint64(s.txSignDetails.chainID))
|
signer := ethTypes.NewLondonSigner(new(big.Int).SetUint64(chainID))
|
||||||
return &SessionRequestResponse{
|
return &SessionRequestResponse{
|
||||||
KeyUID: account.KeyUID,
|
KeyUID: account.KeyUID,
|
||||||
Address: account.Address,
|
Address: account.Address,
|
||||||
AddressPath: account.Path,
|
AddressPath: account.Path,
|
||||||
SignOnKeycard: kp.MigratedToKeycard(),
|
SignOnKeycard: kp.MigratedToKeycard(),
|
||||||
MesageToSign: signer.Hash(s.txSignDetails.txBeingSigned),
|
MesageToSign: signer.Hash(txBeingSigned),
|
||||||
}, nil
|
}, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (s *Service) sendTransaction(signature string) (response *SessionRequestResponse, err error) {
|
func (s *Service) addSignatureToTransaction(signature string) (*ethTypes.Transaction, error) {
|
||||||
if s.txSignDetails.txBeingSigned == nil {
|
if s.txSignDetails.txBeingSigned == nil {
|
||||||
return response, errors.New("no tx to sign")
|
return nil, errors.New("no tx to sign")
|
||||||
}
|
}
|
||||||
|
|
||||||
signatureBytes, _ := hex.DecodeString(signature)
|
signatureBytes, err := hex.DecodeString(signature)
|
||||||
|
|
||||||
hash, err := s.transactor.SendBuiltTransactionWithSignature(s.txSignDetails.chainID, s.txSignDetails.txBeingSigned, signatureBytes)
|
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
|
||||||
return &SessionRequestResponse{
|
return s.transactor.AddSignatureToTransaction(s.txSignDetails.chainID, s.txSignDetails.txBeingSigned, signatureBytes)
|
||||||
SignedMessage: hash,
|
|
||||||
}, nil
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func (s *Service) buildPersonalSingMessage(request SessionRequest) (response *SessionRequestResponse, err error) {
|
func (s *Service) buildMessage(request SessionRequest, addressIndex int, messageIndex int,
|
||||||
|
handleTypedData bool) (response *SessionRequestResponse, err error) {
|
||||||
if len(request.Params.Request.Params) != 2 {
|
if len(request.Params.Request.Params) != 2 {
|
||||||
return nil, ErrorInvalidParamsCount
|
return nil, ErrorInvalidParamsCount
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if addressIndex > 1 || addressIndex < 0 || messageIndex > 1 || messageIndex < 0 {
|
||||||
|
return nil, ErrorInvalidAddressMsgIndex
|
||||||
|
}
|
||||||
|
|
||||||
var address types.Address
|
var address types.Address
|
||||||
if err := json.Unmarshal(request.Params.Request.Params[1], &address); err != nil {
|
if err := json.Unmarshal(request.Params.Request.Params[addressIndex], &address); err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -153,12 +154,29 @@ func (s *Service) buildPersonalSingMessage(request SessionRequest) (response *Se
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
|
||||||
|
var hash []byte
|
||||||
|
if !handleTypedData {
|
||||||
var dBytes types.HexBytes
|
var dBytes types.HexBytes
|
||||||
if err := json.Unmarshal(request.Params.Request.Params[0], &dBytes); err != nil {
|
if err := json.Unmarshal(request.Params.Request.Params[messageIndex], &dBytes); err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
hash = crypto.TextHash(dBytes)
|
||||||
|
} else {
|
||||||
|
var typedDataJSON string
|
||||||
|
if err := json.Unmarshal(request.Params.Request.Params[messageIndex], &typedDataJSON); err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
|
||||||
hash := crypto.TextHash(dBytes)
|
var typedData apitypes.TypedData
|
||||||
|
if err := json.Unmarshal([]byte(typedDataJSON), &typedData); err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
hash, _, err = apitypes.TypedDataAndHash(typedData)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
return &SessionRequestResponse{
|
return &SessionRequestResponse{
|
||||||
KeyUID: account.KeyUID,
|
KeyUID: account.KeyUID,
|
||||||
|
|
|
@ -24,6 +24,7 @@ type txSigningDetails struct {
|
||||||
chainID uint64
|
chainID uint64
|
||||||
from common.Address
|
from common.Address
|
||||||
txBeingSigned *ethTypes.Transaction
|
txBeingSigned *ethTypes.Transaction
|
||||||
|
txHash common.Hash
|
||||||
}
|
}
|
||||||
|
|
||||||
type Service struct {
|
type Service struct {
|
||||||
|
@ -62,8 +63,43 @@ func (s *Service) SignMessage(message types.HexBytes, address common.Address, pa
|
||||||
return types.EncodeHex(signature), err
|
return types.EncodeHex(signature), err
|
||||||
}
|
}
|
||||||
|
|
||||||
func (s *Service) SendTransaction(signature string) (response *SessionRequestResponse, err error) {
|
func (s *Service) BuildRawTransaction(signature string) (string, error) {
|
||||||
return s.sendTransaction(signature)
|
txWithSignature, err := s.addSignatureToTransaction(signature)
|
||||||
|
if err != nil {
|
||||||
|
return "", err
|
||||||
|
}
|
||||||
|
|
||||||
|
data, err := txWithSignature.MarshalBinary()
|
||||||
|
if err != nil {
|
||||||
|
return "", err
|
||||||
|
}
|
||||||
|
|
||||||
|
s.txSignDetails.txHash = txWithSignature.Hash()
|
||||||
|
|
||||||
|
return types.EncodeHex(data), nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (s *Service) SendRawTransaction(rawTx string) (string, error) {
|
||||||
|
err := s.transactor.SendRawTransaction(s.txSignDetails.chainID, rawTx)
|
||||||
|
if err != nil {
|
||||||
|
return "", err
|
||||||
|
}
|
||||||
|
|
||||||
|
return s.txSignDetails.txHash.Hex(), nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (s *Service) SendTransactionWithSignature(signature string) (string, error) {
|
||||||
|
txWithSignature, err := s.addSignatureToTransaction(signature)
|
||||||
|
if err != nil {
|
||||||
|
return "", err
|
||||||
|
}
|
||||||
|
|
||||||
|
hash, err := s.transactor.SendTransactionWithSignature(txWithSignature)
|
||||||
|
if err != nil {
|
||||||
|
return "", err
|
||||||
|
}
|
||||||
|
|
||||||
|
return hash.Hex(), nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (s *Service) PairSessionProposal(proposal SessionProposal) (*PairSessionResponse, error) {
|
func (s *Service) PairSessionProposal(proposal SessionProposal) (*PairSessionResponse, error) {
|
||||||
|
@ -129,7 +165,12 @@ func (s *Service) PairSessionProposal(proposal SessionProposal) (*PairSessionRes
|
||||||
SupportedNamespaces: map[string]Namespace{
|
SupportedNamespaces: map[string]Namespace{
|
||||||
SupportedEip155Namespace: Namespace{
|
SupportedEip155Namespace: Namespace{
|
||||||
Methods: []string{params.SendTransactionMethodName,
|
Methods: []string{params.SendTransactionMethodName,
|
||||||
|
params.SendRawTransactionMethodName,
|
||||||
params.PersonalSignMethodName,
|
params.PersonalSignMethodName,
|
||||||
|
params.SignMethodName,
|
||||||
|
params.SignTransactionMethodName,
|
||||||
|
params.SignTypedDataMethodName,
|
||||||
|
params.WalletSwitchEthereumChainMethodName,
|
||||||
},
|
},
|
||||||
Events: []string{"accountsChanged", "chainChanged"},
|
Events: []string{"accountsChanged", "chainChanged"},
|
||||||
Chains: eipChains,
|
Chains: eipChains,
|
||||||
|
@ -169,8 +210,14 @@ func (s *Service) SessionRequest(request SessionRequest) (response *SessionReque
|
||||||
|
|
||||||
if request.Params.Request.Method == params.SendTransactionMethodName {
|
if request.Params.Request.Method == params.SendTransactionMethodName {
|
||||||
return s.buildTransaction(request)
|
return s.buildTransaction(request)
|
||||||
|
} else if request.Params.Request.Method == params.SignTransactionMethodName {
|
||||||
|
return s.buildTransaction(request)
|
||||||
} else if request.Params.Request.Method == params.PersonalSignMethodName {
|
} else if request.Params.Request.Method == params.PersonalSignMethodName {
|
||||||
return s.buildPersonalSingMessage(request)
|
return s.buildMessage(request, 1, 0, false)
|
||||||
|
} else if request.Params.Request.Method == params.SignMethodName {
|
||||||
|
return s.buildMessage(request, 0, 1, false)
|
||||||
|
} else if request.Params.Request.Method == params.SignTypedDataMethodName {
|
||||||
|
return s.buildMessage(request, 0, 1, true)
|
||||||
}
|
}
|
||||||
|
|
||||||
// TODO #12434: respond async
|
// TODO #12434: respond async
|
||||||
|
|
|
@ -108,7 +108,6 @@ type SessionRequestResponse struct {
|
||||||
AddressPath string `json:"addressPath,omitempty"`
|
AddressPath string `json:"addressPath,omitempty"`
|
||||||
SignOnKeycard bool `json:"signOnKeycard,omitempty"`
|
SignOnKeycard bool `json:"signOnKeycard,omitempty"`
|
||||||
MesageToSign interface{} `json:"messageToSign,omitempty"`
|
MesageToSign interface{} `json:"messageToSign,omitempty"`
|
||||||
SignedMessage interface{} `json:"signedMessage,omitempty"`
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Valid namespace
|
// Valid namespace
|
||||||
|
|
|
@ -55,6 +55,11 @@ func (w *rpcWrapper) EstimateGas(ctx context.Context, msg ethereum.CallMsg) (uin
|
||||||
return uint64(hex), nil
|
return uint64(hex), nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Does the `eth_sendRawTransaction` call with the given raw transaction hex string.
|
||||||
|
func (w *rpcWrapper) SendRawTransaction(ctx context.Context, rawTx string) error {
|
||||||
|
return w.RPCClient.CallContext(ctx, nil, w.chainID, "eth_sendRawTransaction", rawTx)
|
||||||
|
}
|
||||||
|
|
||||||
// SendTransaction injects a signed transaction into the pending pool for execution.
|
// SendTransaction injects a signed transaction into the pending pool for execution.
|
||||||
//
|
//
|
||||||
// If the transaction was a contract creation use the TransactionReceipt method to get the
|
// If the transaction was a contract creation use the TransactionReceipt method to get the
|
||||||
|
@ -64,7 +69,7 @@ func (w *rpcWrapper) SendTransaction(ctx context.Context, tx *gethtypes.Transact
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
return w.RPCClient.CallContext(ctx, nil, w.chainID, "eth_sendRawTransaction", types.EncodeHex(data))
|
return w.SendRawTransaction(ctx, types.EncodeHex(data))
|
||||||
}
|
}
|
||||||
|
|
||||||
func toCallArg(msg ethereum.CallMsg) interface{} {
|
func toCallArg(msg ethereum.CallMsg) interface{} {
|
||||||
|
|
|
@ -116,33 +116,57 @@ func (t *Transactor) ValidateAndBuildTransaction(chainID uint64, sendArgs SendTx
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
func (t *Transactor) SendBuiltTransactionWithSignature(chainID uint64, tx *gethtypes.Transaction, sig []byte) (hash types.Hash, err error) {
|
func (t *Transactor) AddSignatureToTransaction(chainID uint64, tx *gethtypes.Transaction, sig []byte) (*gethtypes.Transaction, error) {
|
||||||
if len(sig) != ValidSignatureSize {
|
if len(sig) != ValidSignatureSize {
|
||||||
return hash, ErrInvalidSignatureSize
|
return nil, ErrInvalidSignatureSize
|
||||||
}
|
}
|
||||||
|
|
||||||
rpcWrapper := newRPCWrapper(t.rpcWrapper.RPCClient, chainID)
|
rpcWrapper := newRPCWrapper(t.rpcWrapper.RPCClient, chainID)
|
||||||
chID := big.NewInt(int64(rpcWrapper.chainID))
|
chID := big.NewInt(int64(rpcWrapper.chainID))
|
||||||
|
|
||||||
signer := gethtypes.NewLondonSigner(chID)
|
signer := gethtypes.NewLondonSigner(chID)
|
||||||
signedTx, err := tx.WithSignature(signer, sig)
|
txWithSignature, err := tx.WithSignature(signer, sig)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return hash, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
|
||||||
|
return txWithSignature, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (t *Transactor) SendRawTransaction(chainID uint64, rawTx string) error {
|
||||||
|
rpcWrapper := newRPCWrapper(t.rpcWrapper.RPCClient, chainID)
|
||||||
|
|
||||||
ctx, cancel := context.WithTimeout(context.Background(), t.rpcCallTimeout)
|
ctx, cancel := context.WithTimeout(context.Background(), t.rpcCallTimeout)
|
||||||
defer cancel()
|
defer cancel()
|
||||||
|
|
||||||
if err := rpcWrapper.SendTransaction(ctx, signedTx); err != nil {
|
return rpcWrapper.SendRawTransaction(ctx, rawTx)
|
||||||
return hash, err
|
|
||||||
}
|
|
||||||
return types.Hash(signedTx.Hash()), nil
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// SendTransactionWithSignature receive a transaction and a signature, serialize them together and propage it to the network.
|
func (t *Transactor) SendTransactionWithSignature(tx *gethtypes.Transaction) (hash types.Hash, err error) {
|
||||||
|
rpcWrapper := newRPCWrapper(t.rpcWrapper.RPCClient, tx.ChainId().Uint64())
|
||||||
|
|
||||||
|
ctx, cancel := context.WithTimeout(context.Background(), t.rpcCallTimeout)
|
||||||
|
defer cancel()
|
||||||
|
|
||||||
|
if err := rpcWrapper.SendTransaction(ctx, tx); err != nil {
|
||||||
|
return hash, err
|
||||||
|
}
|
||||||
|
return types.Hash(tx.Hash()), nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (t *Transactor) AddSignatureToTransactionAndSend(chainID uint64, tx *gethtypes.Transaction, sig []byte) (hash types.Hash, err error) {
|
||||||
|
txWithSignature, err := t.AddSignatureToTransaction(chainID, tx, sig)
|
||||||
|
if err != nil {
|
||||||
|
return hash, err
|
||||||
|
}
|
||||||
|
|
||||||
|
return t.SendTransactionWithSignature(txWithSignature)
|
||||||
|
}
|
||||||
|
|
||||||
|
// BuildTransactionAndSendWithSignature receive a transaction and a signature, serialize them together and propage it to the network.
|
||||||
// It's different from eth_sendRawTransaction because it receives a signature and not a serialized transaction with signature.
|
// It's different from eth_sendRawTransaction because it receives a signature and not a serialized transaction with signature.
|
||||||
// Since the transactions is already signed, we assume it was validated and used the right nonce.
|
// Since the transactions is already signed, we assume it was validated and used the right nonce.
|
||||||
func (t *Transactor) SendTransactionWithSignature(chainID uint64, args SendTxArgs, sig []byte) (hash types.Hash, err error) {
|
func (t *Transactor) BuildTransactionAndSendWithSignature(chainID uint64, args SendTxArgs, sig []byte) (hash types.Hash, err error) {
|
||||||
if !args.Valid() {
|
if !args.Valid() {
|
||||||
return hash, ErrInvalidSendTxArgs
|
return hash, ErrInvalidSendTxArgs
|
||||||
}
|
}
|
||||||
|
@ -167,7 +191,7 @@ func (t *Transactor) SendTransactionWithSignature(chainID uint64, args SendTxArg
|
||||||
return hash, &ErrBadNonce{tx.Nonce(), expectedNonce}
|
return hash, &ErrBadNonce{tx.Nonce(), expectedNonce}
|
||||||
}
|
}
|
||||||
|
|
||||||
return t.SendBuiltTransactionWithSignature(chainID, tx, sig)
|
return t.AddSignatureToTransactionAndSend(chainID, tx, sig)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (t *Transactor) HashTransaction(args SendTxArgs) (validatedArgs SendTxArgs, hash types.Hash, err error) {
|
func (t *Transactor) HashTransaction(args SendTxArgs) (validatedArgs SendTxArgs, hash types.Hash, err error) {
|
||||||
|
|
|
@ -374,7 +374,7 @@ func (s *TransactorSuite) TestSendTransactionWithSignature() {
|
||||||
Return(common.Hash{}, nil)
|
Return(common.Hash{}, nil)
|
||||||
}
|
}
|
||||||
|
|
||||||
_, err = s.manager.SendTransactionWithSignature(s.nodeConfig.NetworkID, args, sig)
|
_, err = s.manager.BuildTransactionAndSendWithSignature(s.nodeConfig.NetworkID, args, sig)
|
||||||
if scenario.expectError {
|
if scenario.expectError {
|
||||||
s.Error(err)
|
s.Error(err)
|
||||||
// local nonce should not be incremented
|
// local nonce should not be incremented
|
||||||
|
@ -393,7 +393,7 @@ func (s *TransactorSuite) TestSendTransactionWithSignature() {
|
||||||
|
|
||||||
func (s *TransactorSuite) TestSendTransactionWithSignature_InvalidSignature() {
|
func (s *TransactorSuite) TestSendTransactionWithSignature_InvalidSignature() {
|
||||||
args := SendTxArgs{}
|
args := SendTxArgs{}
|
||||||
_, err := s.manager.SendTransactionWithSignature(1, args, []byte{})
|
_, err := s.manager.BuildTransactionAndSendWithSignature(1, args, []byte{})
|
||||||
s.Equal(ErrInvalidSignatureSize, err)
|
s.Equal(ErrInvalidSignatureSize, err)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue