fix(@browser): move post message async

This commit is contained in:
Anthony Laibe 2022-03-29 12:21:12 +02:00 committed by Anthony Laibe
parent a8e946f602
commit 87da64d70d
11 changed files with 153 additions and 77 deletions

View File

@ -178,7 +178,7 @@ proc newAppController*(statusFoundation: StatusFoundation): AppController =
result.ensService = ens_service.newService(statusFoundation.events, statusFoundation.threadpool,
result.settingsService, result.walletAccountService, result.transactionService, result.ethService,
result.networkService, result.tokenService)
result.providerService = provider_service.newService(result.ensService)
result.providerService = provider_service.newService(statusFoundation.events, statusFoundation.threadpool, result.ensService)
# Modules
result.startupModule = startup_module.newModule[AppController](

View File

@ -41,7 +41,7 @@ proc newModule*(delegate: delegate_interface.AccessInterface,
result.view = view.newView(result)
result.viewVariant = newQVariant(result.view)
result.moduleLoaded = false
result.providerModule = provider_module.newModule(result, settingsService, providerService)
result.providerModule = provider_module.newModule(result, events, settingsService, providerService)
result.bookmarkModule = bookmark_module.newModule(result, bookmarkService)
result.dappsModule = dapps_module.newModule(result, dappPermissionsService, walletAccountService)
result.currentAccountModule = current_account_module.newModule(result, events, walletAccountService)

View File

@ -1,20 +1,25 @@
import strutils
import io_interface
import ../../../../core/eventemitter
import ../../../../../app_service/service/settings/service as settings_service
import ../../../../../app_service/service/provider/service as provider_service
type
Controller* = ref object of RootObj
delegate: io_interface.AccessInterface
events: EventEmitter
settingsService: settings_service.Service
providerService: provider_service.Service
proc newController*(delegate: io_interface.AccessInterface,
settingsService: settings_service.Service,
providerService: provider_service.Service):
Controller =
proc newController*(
delegate: io_interface.AccessInterface,
events: EventEmitter,
settingsService: settings_service.Service,
providerService: provider_service.Service
): Controller =
result = Controller()
result.events = events
result.delegate = delegate
result.settingsService = settingsService
result.providerService = providerService
@ -23,7 +28,9 @@ proc delete*(self: Controller) =
discard
proc init*(self: Controller) =
discard
self.events.on(PROVIDER_SIGNAL_ON_POST_MESSAGE) do(e:Args):
let args = OnPostMessageArgs(e)
self.delegate.onPostMessage(args.payloadMethod, args.result)
proc getDappsAddress*(self: Controller): string =
return self.settingsService.getDappsAddress()
@ -38,8 +45,8 @@ proc getCurrentNetworkId*(self: Controller): int =
proc getCurrentNetwork*(self: Controller): string =
return self.settingsService.getCurrentNetwork()
proc postMessage*(self: Controller, requestType: string, message: string): string =
return self.providerService.postMessage(requestType, message)
proc postMessage*(self: Controller, payloadMethod: string, requestType: string, message: string) =
self.providerService.postMessage(payloadMethod, requestType, message)
proc ensResourceURL*(self: Controller, ens: string, url: string): (string, string, string, string, bool) =
return self.providerService.ensResourceURL(ens, url)

View File

@ -19,11 +19,14 @@ method onDappAddressChanged*(self: AccessInterface, newDappAddress: string) {.ba
method disconnect*(self: AccessInterface, dappName: string, address: string) {.base.} =
raise newException(ValueError, "No implementation available")
method postMessage*(self: AccessInterface, requestType: string, message: string): string {.base.} =
method postMessage*(self: AccessInterface, payloadMethod: string, requestType: string, message: string) {.base.} =
raise newException(ValueError, "No implementation available")
method ensResourceURL*(self: AccessInterface, ens: string, url: string): (string, string, string, string, bool) =
raise newException(ValueError, "No implementation available")
method onPostMessage*(self: AccessInterface, payloadMethod: string, result: string) {.base.} =
raise newException(ValueError, "No implementation available")
method viewDidLoad*(self: AccessInterface) {.base.} =
raise newException(ValueError, "No implementation available")

View File

@ -2,6 +2,8 @@ import NimQml
import io_interface
import view
import controller
import ../../../../core/eventemitter
import ../io_interface as delegate_interface
import ../../../../../app_service/service/settings/service as settings_service
import ../../../../../app_service/service/provider/service as provider_service
@ -16,15 +18,18 @@ type
moduleLoaded: bool
controller: Controller
proc newModule*(delegate: delegate_interface.AccessInterface,
proc newModule*(
delegate: delegate_interface.AccessInterface,
events: EventEmitter,
settingsService: settings_service.Service,
providerService: provider_service.Service): Module =
providerService: provider_service.Service
): Module =
result = Module()
result.delegate = delegate
result.view = newView(result)
result.viewVariant = newQVariant(result.view)
result.moduleLoaded = false
result.controller = controller.newController(result, settingsService, providerService)
result.controller = controller.newController(result, events, settingsService, providerService)
method delete*(self: Module) =
self.controller.delete
@ -37,6 +42,7 @@ method load*(self: Module) =
self.view.networkId = self.controller.getCurrentNetworkId()
self.view.currentNetwork = self.controller.getCurrentNetwork()
self.view.load()
self.controller.init()
method isLoaded*(self: Module): bool =
return self.moduleLoaded
@ -51,8 +57,11 @@ method viewDidLoad*(self: Module) =
self.moduleLoaded = true
self.delegate.providerDidLoad()
method postMessage*(self: Module, requestType: string, message: string): string =
return self.controller.postMessage(requestType, message)
method postMessage*(self: Module, payloadMethod: string, requestType: string, message: string) =
self.controller.postMessage(payloadMethod, requestType, message)
method onPostMessage*(self: Module, payloadMethod: string, result: string) =
self.view.postMessageResult(payloadMethod, result)
method ensResourceURL*(self: Module, ens: string, url: string): (string, string, string, string, bool) =
return self.controller.ensResourceURL(ens, url)

View File

@ -70,8 +70,10 @@ QtObject:
proc getHost*(self: View, url: string): string {.slot.} =
result = url_host(url)
proc postMessage*(self: View, requestType: string, message: string): string {.slot.} =
return self.delegate.postMessage(requestType, message)
proc postMessageResult*(self: View, payloadMethod: string, result: string) {.signal.}
proc postMessage*(self: View, payloadMethod: string, requestType: string, message: string) {.slot.} =
self.delegate.postMessage(payloadMethod, requestType, message)
proc ensResourceURL*(self: View, ens: string, url: string): string {.slot.} =
let (url, base, http_scheme, path_prefix, hasContentHash) = self.delegate.ensResourceURL(ens, url)

View File

@ -6,7 +6,6 @@ proc getLatestVersionJSON(): string =
"version": "",
"url": ""
}
try:
debug "Getting latest version information"

View File

@ -0,0 +1,23 @@
import ../../common/utils
type
PostMessageTaskArg = ref object of QObjectTaskArg
payloadMethod: string
requestType: string
message: string
const postMessageTask: Task = proc(argEncoded: string) {.gcsafe, nimcall.} =
let arg = decode[PostMessageTaskArg](argEncoded)
let jsonMessage = arg.message.parseJson
let password = jsonMessage{"payload"}{"password"}.getStr
if password != "":
let hashedPassword = hashPassword(password)
jsonMessage["payload"]["password"] = newJString(hashedPassword)
let result = status_go_provider.providerRequest(arg.requestType, $jsonMessage).result
let responseJson = %* {
"payloadMethod": arg.payloadMethod,
"result": $result,
}
arg.finish(responseJson)

View File

@ -1,36 +1,70 @@
import json, chronicles
import NimQml, json, chronicles
import ../../../backend/provider as status_go_provider
import ../../../app/core/eventemitter
import ../../../app/core/tasks/[qt, threadpool]
import ../ens/service as ens_service
import ../../common/utils
logScope:
topics = "provider-service"
include ../../common/json_utils
include ./async_tasks
const HTTPS_SCHEME* = "https"
const PROVIDER_SIGNAL_ON_POST_MESSAGE* = "provider-signal-on-post-message"
type
Service* = ref object of RootObj
OnPostMessageArgs* = ref object of Args
payloadMethod*: string
result*: string
QtObject:
type Service* = ref object of QObject
events: EventEmitter
threadpool: ThreadPool
ensService: ens_service.Service
proc delete*(self: Service) =
discard
proc delete*(self: Service) =
self.QObject.delete
proc newService*(ensService: ens_service.Service): Service =
result = Service()
result.ensService = ensService
proc newService*(
events: EventEmitter,
threadpool: ThreadPool,
ensService: ens_service.Service
): Service =
result = Service()
result.QObject.setup
result.events = events
result.threadpool = threadpool
result.ensService = ensService
proc init*(self: Service) =
discard
proc init*(self: Service) =
discard
proc ensResourceURL*(self: Service, username: string, url: string): (string, string, string, string, bool) =
let (scheme, host, path) = self.ensService.resourceUrl(username)
if host == "":
return (url, url, HTTPS_SCHEME, "", false)
return (url, host, scheme, path, true)
proc ensResourceURL*(self: Service, username: string, url: string): (string, string, string, string, bool) =
let (scheme, host, path) = self.ensService.resourceUrl(username)
if host == "":
return (url, url, HTTPS_SCHEME, "", false)
return (url, host, scheme, path, true)
proc postMessage*(self: Service, requestType: string, message: string): string =
try:
return $status_go_provider.providerRequest(requestType, message).result
except Exception as e:
let errDescription = e.msg
error "error: ", errDescription
proc postMessageResolved*(self: Service, response: string) {.slot.} =
let responseObj = response.parseJson
var data = OnPostMessageArgs()
discard responseObj.getProp("payloadMethod", data.payloadMethod)
discard responseObj.getProp("result", data.result)
self.events.emit(PROVIDER_SIGNAL_ON_POST_MESSAGE, data)
proc postMessage*(self: Service, payloadMethod: string, requestType: string, message: string) =
let arg = PostMessageTaskArg(
tptr: cast[ByteAddress](postMessageTask),
vptr: cast[ByteAddress](self.vptr),
slot: "postMessageResolved",
payloadMethod: payloadMethod,
requestType: requestType,
message: message
)
self.threadpool.start(arg)

View File

@ -36,7 +36,7 @@ StatusModal {
if(isAllowed){
Web3ProviderStore.addPermission(request.hostname, request.address, request.permission)
}
browserConnectionModal.web3Response(Web3ProviderStore.web3ProviderInst.postMessage(Constants.api_request, JSON.stringify(request)))
Web3ProviderStore.web3ProviderInst.postMessage("", Constants.api_request, JSON.stringify(request))
}
onClosed: {

View File

@ -27,6 +27,39 @@ QtObject {
return RootStore.getAscii2Hex(input)
}
property Connections conn: Connections {
target: Web3ProviderStore.web3ProviderInst
onPostMessageResult: {
web3Response(result)
const isSign = ["eth_sign", "personal_sign", "eth_signTypedData", "eth_signTypedData_v3"].indexOf(payloadMethod) > -1
const isTx = payloadMethod === "eth_sendTransaction"
try {
let responseObj = JSON.parse(result)
if (responseObj.error) {
throw new Error(responseObj.error)
}
if (isTx) {
showToastMessage(responseObj.result.result)
}
} catch (e) {
if (Utils.isInvalidPasswordMessage(e.message)){
//% "Wrong password"
sendDialog.transactionSigner.validationError = qsTrId("wrong-password")
return
}
if (isTx) {
showSendingError(e.message)
} else if (isSign) {
showSigningError(e.message)
}
}
}
}
function postMessage(requestType, data) {
var request;
try {
@ -53,7 +86,7 @@ QtObject {
dialog.open();
} else {
RootStore.currentTabConnected = true
web3Response(Web3ProviderStore.web3ProviderInst.postMessage(requestType, JSON.stringify(request)));
Web3ProviderStore.web3ProviderInst.postMessage("", requestType, JSON.stringify(request));
}
} else if (requestType === Constants.web3SendAsyncReadOnly &&
request.payload.method === "eth_sendTransaction") {
@ -76,27 +109,7 @@ QtObject {
request.payload.password = enteredPassword
request.payload.params[0] = trx
const response = Web3ProviderStore.web3ProviderInst.postMessage(requestType, JSON.stringify(request))
provider.web3Response(response)
let responseObj
try {
responseObj = JSON.parse(response)
if (responseObj.error) {
throw new Error(responseObj.error)
}
showToastMessage(responseObj.result.result)
} catch (e) {
if (Utils.isInvalidPasswordMessage(e.message)){
//% "Wrong password"
sendDialog.transactionSigner.validationError = qsTrId("wrong-password")
return
}
return showSendingError(e.message)
}
Web3ProviderStore.web3ProviderInst.postMessage(request.payload.method, requestType, JSON.stringify(request))
sendDialog.close()
sendDialog.destroy()
}
@ -115,21 +128,7 @@ QtObject {
case Constants.eth_sign:
request.payload.params[1] = signValue(request.payload.params[1]);
}
const response = Web3ProviderStore.web3ProviderInst.postMessage(requestType, JSON.stringify(request));
provider.web3Response(response);
try {
let responseObj = JSON.parse(response)
if (responseObj.error) {
throw new Error(responseObj.error.message)
}
} catch (e) {
if (Utils.isInvalidPasswordMessage(e.message)){
//% "Wrong password"
signDialog.transactionSigner.validationError = qsTrId("wrong-password")
return
}
return showSigningError(e.message)
}
Web3ProviderStore.web3ProviderInst.postMessage(request.payload.method, requestType, JSON.stringify(request));
signDialog.close()
signDialog.destroy()
}
@ -139,7 +138,7 @@ QtObject {
} else if (request.type === Constants.web3DisconnectAccount) {
web3Response(data);
} else {
web3Response(Web3ProviderStore.web3ProviderInst.postMessage(requestType, data));
Web3ProviderStore.web3ProviderInst.postMessage(request.payload.method, requestType, data);
}
}