feat(wallet): hook sendTransferTokens to the wallet Send

Fixes #4650
This commit is contained in:
Jonathan Rainville 2022-02-02 11:25:06 -05:00
parent 0f5a6d8599
commit b688a5a305
12 changed files with 100 additions and 27 deletions

View File

@ -84,3 +84,9 @@ method transferEth*(self: Controller, from_addr: string, to_addr: string, value:
password: string, uuid: string): bool = password: string, uuid: string): bool =
result = self.transactionService.transferEth(from_addr, to_addr, value, gas, gasPrice, result = self.transactionService.transferEth(from_addr, to_addr, value, gas, gasPrice,
maxPriorityFeePerGas, maxFeePerGas, password, uuid) maxPriorityFeePerGas, maxFeePerGas, password, uuid)
method transferTokens*(self: Controller, from_addr: string, to_addr: string, contractAddress: string,
value: string, gas: string, gasPrice: string, maxPriorityFeePerGas: string,maxFeePerGas: string,
password: string, uuid: string): bool =
result = self.transactionService.transferTokens(from_addr, to_addr, contractAddress, value, gas,
gasPrice, maxPriorityFeePerGas, maxFeePerGas, password, uuid)

View File

@ -37,6 +37,12 @@ method transferEth*(self: AccessInterface, from_addr: string, to_addr: string, v
password: string, uuid: string): bool {.base.} = password: string, uuid: string): bool {.base.} =
raise newException(ValueError, "No implementation available") raise newException(ValueError, "No implementation available")
method transferTokens*(self: AccessInterface, from_addr: string, to_addr: string,
contractAddress: string, value: string, gas: string, gasPrice: string,
maxPriorityFeePerGas: string, maxFeePerGas: string, password: string,
uuid: string): bool {.base.} =
raise newException(ValueError, "No implementation available")
type type
## Abstract class (concept) which must be implemented by object/s used in this ## Abstract class (concept) which must be implemented by object/s used in this
## module. ## module.

View File

@ -48,6 +48,12 @@ method transferEth*(self: AccessInterface, from_addr: string, to_addr: string, v
password: string, uuid: string): bool {.base.} = password: string, uuid: string): bool {.base.} =
raise newException(ValueError, "No implementation available") raise newException(ValueError, "No implementation available")
method transferTokens*(self: AccessInterface, from_addr: string, to_addr: string,
contractAddress: string, value: string, gas: string, gasPrice: string,
maxPriorityFeePerGas: string, maxFeePerGas: string, password: string,
uuid: string): bool {.base.} =
raise newException(ValueError, "No implementation available")
# View Delegate Interface # View Delegate Interface
# Delegate for the view must be declared here due to use of QtObject and multi # Delegate for the view must be declared here due to use of QtObject and multi
# inheritance, which is not well supported in Nim. # inheritance, which is not well supported in Nim.

View File

@ -90,4 +90,10 @@ method transferEth*(self: Module, from_addr: string, to_addr: string, value: str
gasPrice: string, maxPriorityFeePerGas: string, maxFeePerGas: string, password: string, gasPrice: string, maxPriorityFeePerGas: string, maxFeePerGas: string, password: string,
uuid: string): bool = uuid: string): bool =
result = self.controller.transferEth(from_addr, to_addr, value, gas, gasPrice, result = self.controller.transferEth(from_addr, to_addr, value, gas, gasPrice,
maxPriorityFeePerGas, maxFeePerGas, password, uuid)
method transferTokens*(self: Module, from_addr: string, to_addr: string, contractAddress: string,
value: string, gas: string, gasPrice: string, maxPriorityFeePerGas: string,
maxFeePerGas: string, password: string, uuid: string): bool =
result = self.controller.transferTokens(from_addr, to_addr, contractAddress, value, gas, gasPrice,
maxPriorityFeePerGas, maxFeePerGas, password, uuid) maxPriorityFeePerGas, maxFeePerGas, password, uuid)

View File

@ -105,9 +105,16 @@ QtObject:
proc estimateGas*(self: View, from_addr: string, to: string, assetAddress: string, value: string, data: string): string {.slot.} = proc estimateGas*(self: View, from_addr: string, to: string, assetAddress: string, value: string, data: string): string {.slot.} =
result = self.delegate.estimateGas(from_addr, to, assetAddress, value, data) result = self.delegate.estimateGas(from_addr, to, assetAddress, value, data)
result = self.delegate.estimateGas(from_addr, to, assetAddress, value, data)
proc transferEth*(self: View, from_addr: string, to_addr: string, value: string, gas: string, proc transferEth*(self: View, from_addr: string, to_addr: string, value: string, gas: string,
gasPrice: string, maxPriorityFeePerGas: string, maxFeePerGas: string, password: string, gasPrice: string, maxPriorityFeePerGas: string, maxFeePerGas: string, password: string,
uuid: string): bool {.slot.} = uuid: string): bool {.slot.} =
result = self.delegate.transferEth(from_addr, to_addr, value, gas, gasPrice, result = self.delegate.transferEth(from_addr, to_addr, value, gas, gasPrice,
maxPriorityFeePerGas, maxFeePerGas, password, uuid) maxPriorityFeePerGas, maxFeePerGas, password, uuid)
proc transferTokens*(self: View, from_addr: string, to_addr: string, contractAddress: string,
value: string, gas: string, gasPrice: string, maxPriorityFeePerGas: string,
maxFeePerGas: string, password: string, uuid: string): bool {.slot.} =
result = self.delegate.transferTokens(from_addr, to_addr, contractAddress, value, gas, gasPrice,
maxPriorityFeePerGas, maxFeePerGas, password, uuid)

View File

@ -74,4 +74,4 @@ proc tokenSymbol*(contract: ContractDto): string =
getTokenString(contract, "symbol") getTokenString(contract, "symbol")
proc getMethod*(contract: ContractDto, methodName: string): MethodDto = proc getMethod*(contract: ContractDto, methodName: string): MethodDto =
return contract.methods["methodName"] return contract.methods[methodName]

View File

@ -93,7 +93,7 @@ proc send*(self: MethodDto, tx: var TransactionDataDto, methodDescriptor: object
tx.data = self.encodeAbi(methodDescriptor) tx.data = self.encodeAbi(methodDescriptor)
# this call should not be part of this file, we need to move it to appropriate place, or this should not be a DTO class. # this call should not be part of this file, we need to move it to appropriate place, or this should not be a DTO class.
let response = status_eth.sendTransaction($(%tx), password) let response = status_eth.sendTransaction($(%tx), password)
return $response.result return response.result.getStr
proc call[T](self: MethodDto, tx: var TransactionDataDto, methodDescriptor: object, success: var bool): T = proc call[T](self: MethodDto, tx: var TransactionDataDto, methodDescriptor: object, success: var bool): T =
success = true success = true

View File

@ -151,7 +151,8 @@ QtObject:
value: string, value: string,
data: string = "" data: string = ""
): string {.slot.} = ): string {.slot.} =
var response: RpcResponse[JsonNode] var response: RpcResponse[JsonNode]
# TODO make this async
try: try:
if assetAddress != ZERO_ADDRESS and not assetAddress.isEmptyOrWhitespace: if assetAddress != ZERO_ADDRESS and not assetAddress.isEmptyOrWhitespace:
var tx = buildTokenTransaction( var tx = buildTokenTransaction(
@ -160,16 +161,17 @@ QtObject:
) )
let networkType = self.settingsService.getCurrentNetwork().toNetworkType() let networkType = self.settingsService.getCurrentNetwork().toNetworkType()
let network = self.networkService.getNetwork(networkType) let network = self.networkService.getNetwork(networkType)
let contract = self.ethService.findErc20Contract(network.chainId, assetAddress) let contract = self.ethService.findErc20Contract(network.chainId, parseAddress(assetAddress))
if contract == nil: if contract == nil:
raise newException(ValueError, fmt"Could not find ERC-20 contract with address '{assetAddress}' for the current network") raise newException(ValueError, fmt"Could not find ERC-20 contract with address '{assetAddress}' for the current network")
let transfer = Transfer(to: parseAddress(to), value: conversion.eth2Wei(parseFloat(value), contract.decimals)) let transfer = Transfer(to: parseAddress(to), value: conversion.eth2Wei(parseFloat(value), contract.decimals))
let methodThing = contract.getMethod("transfer") let transferMethod = contract.getMethod("transfer")
var success: bool var success: bool
let gas = methodThing.estimateGas(tx, transfer, success) let gas = transferMethod.estimateGas(tx, transfer, success)
result = $(%* { "result": gas, "success": success }) let res = fromHex[int](gas)
result = $(%* { "result": res, "success": success })
else: else:
var tx = ens_utils.buildTransaction( var tx = ens_utils.buildTransaction(
parseAddress(from_addr), parseAddress(from_addr),
@ -217,4 +219,43 @@ QtObject:
except Exception as e: except Exception as e:
error "Error sending eth transfer transaction", msg = e.msg error "Error sending eth transfer transaction", msg = e.msg
return false return false
return true
proc transferTokens*(
self: Service,
from_addr: string,
to_addr: string,
assetAddress: string,
value: string,
gas: string,
gasPrice: string,
maxPriorityFeePerGas: string,
maxFeePerGas: string,
password: string,
uuid: string
): bool =
try:
let eip1559Enabled = self.settingsService.isEIP1559Enabled()
eth_utils.validateTransactionInput(from_addr, to_addr, assetAddress, value, gas,
gasPrice, data = "", eip1559Enabled, maxPriorityFeePerGas, maxFeePerGas, uuid)
# TODO move this to another thread
let networkType = self.settingsService.getCurrentNetwork().toNetworkType()
let network = self.networkService.getNetwork(networkType)
let contract = self.eth_service.findErc20Contract(network.chainId, parseAddress(assetAddress))
var tx = ens_utils.buildTokenTransaction(parseAddress(from_addr), parseAddress(assetAddress),
gas, gasPrice, eip1559Enabled, maxPriorityFeePerGas, maxFeePerGas)
var success: bool
let transfer = Transfer(to: parseAddress(to_addr),
value: conversion.eth2Wei(parseFloat(value), contract.decimals))
let transferMethod = contract.getMethod("transfer")
let response = transferMethod.send(tx, transfer, password, success)
self.trackPendingTransaction(response, from_addr, to_addr,
$PendingTransactionTypeDto.WalletTransfer, data = "")
except Exception as e:
error "Error sending token transfer transaction", msg = e.msg
return false
return true return true

View File

@ -48,6 +48,10 @@ proc fetchPrice(crypto: string, fiat: string): float64 =
client.headers = newHttpHeaders({ "Content-Type": "application/json" }) client.headers = newHttpHeaders({ "Content-Type": "application/json" })
let response = client.request(url) let response = client.request(url)
let parsedResponse = parseJson(response.body)
if (parsedResponse{"Response"} != nil and parsedResponse{"Response"}.getStr == "Error"):
error "Error while getting price", message = parsedResponse["Message"].getStr
return 0.0
result = parsefloat($parseJson(response.body)[fiat.toUpper]) result = parsefloat($parseJson(response.body)[fiat.toUpper])
priceCache[key] = result priceCache[key] = result
except Exception as e: except Exception as e:

View File

@ -73,4 +73,9 @@ QtObject {
return walletSectionTransactions.transferEth(from, to, amount, gasLimit, gasPrice, tipLimit, return walletSectionTransactions.transferEth(from, to, amount, gasLimit, gasPrice, tipLimit,
overallLimit, password, uuid); overallLimit, password, uuid);
} }
function transferTokens(from, to, address, amount, gasLimit, gasPrice, tipLimit, overallLimit, password, uuid) {
return walletSectionTransactions.transferTokens(from, to, address, amount, gasLimit,
gasPrice, tipLimit, overallLimit, password, uuid);
}
} }

View File

@ -51,18 +51,17 @@ ModalPopup {
transactionSigner.enteredPassword, transactionSigner.enteredPassword,
stack.uuid) stack.uuid)
} else { } else {
// Not Refactored Yet success = root.store.transferTokens(
// success = RootStore.transferTokens( selectFromAccount.selectedAccount.address,
// selectFromAccount.selectedAccount.address, selectRecipient.selectedRecipient.address,
// selectRecipient.selectedRecipient.address, txtAmount.selectedAsset.address,
// txtAmount.selectedAsset.address, txtAmount.selectedAmount,
// txtAmount.selectedAmount, gasSelector.selectedGasLimit,
// gasSelector.selectedGasLimit, gasSelector.eip1599Enabled ? "" : gasSelector.selectedGasPrice,
// gasSelector.eip1599Enabled ? "" : gasSelector.selectedGasPrice, gasSelector.selectedTipLimit,
// gasSelector.selectedTipLimit, gasSelector.selectedOverallLimit,
// gasSelector.selectedOverallLimit, transactionSigner.enteredPassword,
// transactionSigner.enteredPassword, stack.uuid)
// stack.uuid)
} }
if(!success){ if(!success){
@ -144,6 +143,7 @@ ModalPopup {
id: txtAmount id: txtAmount
selectedAccount: selectFromAccount.selectedAccount selectedAccount: selectFromAccount.selectedAccount
currentCurrency: root.store.currentCurrency currentCurrency: root.store.currentCurrency
// TODO make those use a debounce
getFiatValue: root.store.getFiatValue getFiatValue: root.store.getFiatValue
// getCryptoValue: RootStore.cryptoValue // getCryptoValue: RootStore.cryptoValue
width: stack.width width: stack.width

View File

@ -62,14 +62,6 @@ QtObject {
localAccountSensitiveSettings.isTenorWarningAccepted = value; localAccountSensitiveSettings.isTenorWarningAccepted = value;
} }
function transferEth(from, to, amount, gasLimit, gasPrice, tipLimit, overallLimit, password, uuid) {
// return walletModelInst.transactionsView.transferEth(from, to, amount, gasLimit, gasPrice, tipLimit, overallLimit, password, uuid);
}
function transferTokens(from, to, address, amount, gasLimit, gasPrice, tipLimit, overallLimit, password, uuid) {
// return walletModelInst.transactionsView.transferTokens(from, to, address, amount, gasLimit, gasPrice, tipLimit, overallLimit, password, uuid);
}
function copyToClipboard(text) { function copyToClipboard(text) {
globalUtils.copyToClipboard(text) globalUtils.copyToClipboard(text)
} }