refactor!: provider transactions

This commit is contained in:
Richard Ramos 2021-10-26 10:36:31 -04:00
parent c06c9dbc6d
commit 1989ad7971
20 changed files with 550 additions and 98 deletions

View File

@ -15,6 +15,8 @@ import ../../app_service/service/bookmarks/service as bookmark_service
import ../../app_service/service/dapp_permissions/service as dapp_permissions_service
import ../../app_service/service/mnemonic/service as mnemonic_service
import ../../app_service/service/privacy/service as privacy_service
import ../../app_service/service/provider/service as provider_service
import ../../app_service/service/ens/service as ens_service
import ../core/local_account_settings
import ../../app_service/service/profile/service as profile_service
@ -75,6 +77,8 @@ type
settingService: setting_service.Service
bookmarkService: bookmark_service.Service
dappPermissionsService: dapp_permissions_service.Service
ensService: ens_service.Service
providerService: provider_service.Service
profileService: profile_service.Service
settingsService: settings_service.Service
aboutService: about_service.Service
@ -142,6 +146,8 @@ proc newAppController*(appService: AppService): AppController =
result.languageService = language_service.newService()
result.mnemonicService = mnemonic_service.newService()
result.privacyService = privacy_service.newService()
result.ensService = ens_service.newService()
result.providerService = provider_service.newService(result.dappPermissionsService, result.settingsService, result.ensService)
# Core
result.localAppSettingsVariant = newQVariant(singletonInstance.localAppSettings)
@ -175,7 +181,8 @@ proc newAppController*(appService: AppService): AppController =
result.dappPermissionsService,
result.languageService,
result.mnemonicService,
result.privacyService
result.privacyService,
result.providerService,
)
#################################################
@ -225,6 +232,8 @@ proc delete*(self: AppController) =
self.walletAccountService.delete
self.aboutService.delete
self.dappPermissionsService.delete
self.providerService.delete
self.ensService.delete
proc startupDidLoad*(self: AppController) =
#################################################
@ -269,6 +278,8 @@ proc load*(self: AppController) =
self.tokenService.init()
self.settingsService.init()
self.dappPermissionsService.init()
self.ensService.init()
self.providerService.init()
self.walletAccountService.init()
self.transactionService.init()
self.mainModule.load()

View File

@ -68,11 +68,6 @@ QtObject:
proc revokeAllPermissions(self: View) {.slot.} =
self.delegate.revokeAllPermissions()
proc ensResourceURL*(self: View, ens: string, url: string): string {.slot.} =
discard # TODO:
#let (url, base, http_scheme, path_prefix, hasContentHash) = self.status.provider.ensResourceURL(ens, url)
#result = url_replaceHostAndAddPath(url, (if hasContentHash: base else: url_host(base)), http_scheme, path_prefix)
proc clearDapps*(self: View) =
self.dappsModel.clear()

View File

@ -9,6 +9,7 @@ import dapps/module as dapps_module
import ../../../../app_service/service/bookmarks/service as bookmark_service
import ../../../../app_service/service/settings/service as settings_service
import ../../../../app_service/service/dapp_permissions/service as dapp_permissions_service
import ../../../../app_service/service/provider/service as provider_service
export io_interface
type
@ -21,13 +22,17 @@ type
bookmarkModule: bookmark_module.AccessInterface
dappsModule: dapps_module.AccessInterface
proc newModule*(delegate: delegate_interface.AccessInterface, bookmarkService: bookmark_service.ServiceInterface, settingsService: settings_service.ServiceInterface, dappPermissionsService: dapp_permissions_service.ServiceInterface): Module =
proc newModule*(delegate: delegate_interface.AccessInterface,
bookmarkService: bookmark_service.ServiceInterface,
settingsService: settings_service.ServiceInterface,
dappPermissionsService: dapp_permissions_service.ServiceInterface,
providerService: provider_service.ServiceInterface): Module =
result = Module()
result.delegate = delegate
result.view = view.newView(result)
result.viewVariant = newQVariant(result.view)
result.moduleLoaded = false
result.providerModule = provider_module.newModule(result, settingsService)
result.providerModule = provider_module.newModule(result, settingsService, dappPermissionsService, providerService)
result.bookmarkModule = bookmark_module.newModule(result, bookmarkService)
result.dappsModule = dapps_module.newModule(result, dappPermissionsService)
@ -72,4 +77,3 @@ method dappsDidLoad*(self: Module) =
method viewDidLoad*(self: Module) =
self.checkIfModuleDidLoad()

View File

@ -1,23 +1,29 @@
import Tables
import result
import controller_interface
import io_interface
import ../../../../../app_service/service/settings/service as settings_service
import ../../../../../app_service/service/dapp_permissions/service as dapp_permissions_service
import ../../../../../app_service/service/provider/service as provider_service
export controller_interface
type
Controller* = ref object of controller_interface.AccessInterface
delegate: io_interface.AccessInterface
settingsService: settings_service.ServiceInterface
dappPermissionsService: dapp_permissions_service.ServiceInterface
providerService: provider_service.ServiceInterface
proc newController*(delegate: io_interface.AccessInterface,
settingsService: settings_service.ServiceInterface):
proc newController*(delegate: io_interface.AccessInterface,
settingsService: settings_service.ServiceInterface,
dappPermissionsService: dapp_permissions_service.ServiceInterface,
providerService: provider_service.ServiceInterface):
Controller =
result = Controller()
result.delegate = delegate
result.settingsService = settingsService
result.dappPermissionsService = dappPermissionsService
result.providerService = providerService
method delete*(self: Controller) =
discard
@ -33,4 +39,16 @@ method setDappsAddress*(self: Controller, address: string) =
self.delegate.onDappAddressChanged(address)
method getCurrentNetworkDetails*(self: Controller): NetworkDetails =
return self.settingsService.getCurrentNetworkDetails()
return self.settingsService.getCurrentNetworkDetails()
method disconnect*(self: Controller) =
discard self.dappPermissionsService.revoke("web3".toPermission())
method postMessage*(self: Controller, message: string): string =
return self.providerService.postMessage(message)
method hasPermission*(self: Controller, hostname: string, permission: string): bool =
return self.dappPermissionsService.hasPermission(hostname, permission.toPermission())
method ensResourceURL*(self: Controller, ens: string, url: string): (string, string, string, string, bool) =
return self.providerService.ensResourceURL(ens, url)

View File

@ -18,3 +18,15 @@ method setDappsAddress*(self: AccessInterface, address: string) {.base.} =
method getCurrentNetworkDetails*(self: AccessInterface): NetworkDetails {.base.} =
raise newException(ValueError, "No implementation available")
method disconnect*(self: AccessInterface) {.base.} =
raise newException(ValueError, "No implementation available")
method postMessage*(self: AccessInterface, message: string): string {.base.} =
raise newException(ValueError, "No implementation available")
method hasPermission*(self: AccessInterface, hostname: string, permission: string): bool {.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")

View File

@ -4,6 +4,8 @@ import view
import controller
import ../io_interface as delegate_interface
import ../../../../../app_service/service/settings/service as settings_service
import ../../../../../app_service/service/dapp_permissions/service as dapp_permissions_service
import ../../../../../app_service/service/provider/service as provider_service
import ../../../../core/global_singleton
export io_interface
@ -15,13 +17,16 @@ type
moduleLoaded: bool
controller: controller.AccessInterface
proc newModule*(delegate: delegate_interface.AccessInterface, settingsService: settings_service.ServiceInterface): Module =
proc newModule*(delegate: delegate_interface.AccessInterface,
settingsService: settings_service.ServiceInterface,
dappPermissionsService: dapp_permissions_service.ServiceInterface,
providerService: provider_service.ServiceInterface): Module =
result = Module()
result.delegate = delegate
result.view = newView(result)
result.viewVariant = newQVariant(result.view)
result.moduleLoaded = false
result.controller = controller.newController(result, settingsService)
result.controller = controller.newController(result, settingsService, dappPermissionsService, providerService)
method delete*(self: Module) =
self.controller.delete
@ -49,3 +54,15 @@ proc checkIfModuleDidLoad(self: Module) =
method viewDidLoad*(self: Module) =
self.checkIfModuleDidLoad()
method disconnect*(self: Module) =
self.controller.disconnect()
method postMessage*(self: Module, message: string): string =
return self.controller.postMessage(message)
method hasPermission*(self: Module, hostname: string, permission: string): bool =
return self.controller.hasPermission(hostname, permission)
method ensResourceURL*(self: Module, ens: string, url: string): (string, string, string, string, bool) =
return self.controller.ensResourceURL(ens, url)

View File

@ -1,5 +1,17 @@
method setDappsAddress*(self: AccessInterface, newDappAddress: string) =
method setDappsAddress*(self: AccessInterface, newDappAddress: string) {.base.} =
raise newException(ValueError, "No implementation available")
method onDappAddressChanged*(self: AccessInterface, newDappAddress: string) =
method onDappAddressChanged*(self: AccessInterface, newDappAddress: string) {.base.} =
raise newException(ValueError, "No implementation available")
method disconnect*(self: AccessInterface) {.base.} =
raise newException(ValueError, "No implementation available")
method postMessage*(self: AccessInterface, message: string): string {.base.} =
raise newException(ValueError, "No implementation available")
method hasPermission*(self: AccessInterface, hostname: string, permission: string): bool {.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")

View File

@ -56,3 +56,16 @@ QtObject:
proc getHost*(self: View, url: string): string {.slot.} =
result = url_host(url)
proc disconnect*(self: View) {.slot.} =
self.delegate.disconnect()
proc postMessage*(self: View, message: string): string {.slot.} =
return self.delegate.postMessage(message)
proc hasPermission(self: View, hostname: string, permission: string): bool {.slot.} =
return self.delegate.hasPermission(hostname, permission)
proc ensResourceURL*(self: View, ens: string, url: string): string {.slot.} =
let (url, base, http_scheme, path_prefix, hasContentHash) = self.delegate.ensResourceURL(ens, url)
result = url_replaceHostAndAddPath(url, (if hasContentHash: base else: url_host(base)), http_scheme, path_prefix)

View File

@ -18,4 +18,4 @@ method checkForStoringPassword*(self: AccessInterface) {.base.} =
raise newException(ValueError, "No implementation available")
method storePassword*(self: AccessInterface, password: string) {.base.} =
raise newException(ValueError, "No implementation available")
raise newException(ValueError, "No implementation available")

View File

@ -19,6 +19,7 @@ import ../../../app_service/service/wallet_account/service as wallet_account_ser
import ../../../app_service/service/setting/service as setting_service
import ../../../app_service/service/bookmarks/service as bookmark_service
import ../../../app_service/service/dapp_permissions/service as dapp_permissions_service
import ../../../app_service/service/provider/service as provider_service
import eventemitter
import ../../../app_service/service/profile/service as profile_service
@ -75,7 +76,8 @@ proc newModule*[T](
dappPermissionsService: dapp_permissions_service.ServiceInterface,
languageService: language_service.ServiceInterface,
mnemonicService: mnemonic_service.ServiceInterface,
privacyService: privacy_service.ServiceInterface
privacyService: privacy_service.ServiceInterface,
providerService: provider_service.ServiceInterface
): Module[T] =
result = Module[T]()
result.delegate = delegate
@ -105,8 +107,8 @@ proc newModule*[T](
settingService
)
result.browserSectionModule = browser_section_module.newModule(result, bookmarkService, settingsService, dappPermissionsService)
result.profileSectionModule = profile_section_module.newModule(result,events, accountsService, settingsService, profileService, contactsService, aboutService, languageService, mnemonicService, privacyService)
result.browserSectionModule = browser_section_module.newModule(result, bookmarkService, settingsService, dappPermissionsService, providerService)
result.profileSectionModule = profile_section_module.newModule(result, events, accountsService, settingsService, profileService, contactsService, aboutService, languageService, mnemonicService, privacyService)
method delete*[T](self: Module[T]) =
self.chatSectionModule.delete

View File

@ -1,24 +0,0 @@
import NimQml, chronicles
import status/status
import view
logScope:
topics = "web3-provider"
type Web3ProviderController* = ref object
status*: Status
view*: Web3ProviderView
variant*: QVariant
proc newController*(status: Status): Web3ProviderController =
result = Web3ProviderController()
result.status = status
result.view = newWeb3ProviderView(status)
result.variant = newQVariant(result.view)
proc delete*(self: Web3ProviderController) =
delete self.variant
delete self.view
proc init*(self: Web3ProviderController) =
discard

View File

@ -1,42 +0,0 @@
import NimQml
import status/[status, ens, chat/stickers, wallet, settings, provider]
import status/types/[setting, permission]
import json, json_serialization, sets, strutils
import chronicles
import stew/byteutils
logScope:
topics = "provider-view"
QtObject:
type Web3ProviderView* = ref object of QObject
status*: Status
proc setup(self: Web3ProviderView) =
self.QObject.setup
proc delete*(self: Web3ProviderView) =
self.QObject.delete
proc newWeb3ProviderView*(status: Status): Web3ProviderView =
new(result, delete)
result = Web3ProviderView()
result.status = status
result.setup
proc disconnect*(self: Web3ProviderView) {.slot.} =
self.status.permissions.revoke("web3".toPermission())
proc postMessage*(self: Web3ProviderView, message: string): string {.slot.} =
result = self.status.provider.postMessage(message)
proc hasPermission*(self: Web3ProviderView, hostname: string, permission: string): bool {.slot.} =
result = self.status.permissions.hasPermission(hostname, permission.toPermission())
proc clearPermissions*(self: Web3ProviderView): string {.slot.} =
self.status.permissions.clearPermissions()
proc ensResourceURL*(self: Web3ProviderView, ens: string, url: string): string {.slot.} =
let (url, base, http_scheme, path_prefix, hasContentHash) = self.status.provider.ensResourceURL(ens, url)
result = url_replaceHostAndAddPath(url, (if hasContentHash: base else: url_host(base)), http_scheme, path_prefix)

View File

@ -88,8 +88,10 @@ method revoke*(self: Service, dapp: string, permission: Permission): bool =
method addPermission*(self: Service, dapp: string, permission: Permission): R =
try:
if not self.dapps.hasKey(dapp):
result.err "not found"
return
self.dapps[dapp] = Dapp(
name: dapp,
permissions: initHashSet[Permission]()
)
self.dapps[dapp].permissions.incl(permission)
discard status_go.addDappPermissions(dapp, self.dapps[dapp].permissions.toSeq().mapIt($it))

View File

@ -0,0 +1,75 @@
import Tables, json, chronicles, strutils
import sets
import options
import chronicles, libp2p/[multihash, multicodec, cid]
import nimcrypto
include ../../common/json_utils
import service_interface
import status/statusgo_backend_new/ens as status_go
export service_interface
logScope:
topics = "ens-service"
type
Service* = ref object of ServiceInterface
method delete*(self: Service) =
discard
proc newService*(): Service =
result = Service()
method init*(self: Service) =
discard
method getContentHash*(self: Service, ens: string): Option[string] =
try:
let contentHash = status_go.contenthash(ens)
if contentHash != "":
return some(contentHash)
except Exception as e:
let errDescription = e.msg
error "error: ", errDescription
return none(string)
method decodeENSContentHash*(self: Service, value: string): tuple[ensType: ENSType, output: string] =
if value == "":
return (ENSType.UNKNOWN, "")
if value[0..5] == "e40101":
return (ENSType.SWARM, value.split("1b20")[1])
if value[0..7] == "e3010170":
try:
let defaultCodec = parseHexInt("70") #dag-pb
var codec = defaultCodec # no codec specified
var codecStartIdx = 2 # idx of where codec would start if it was specified
# handle the case when starts with 0xe30170 instead of 0xe3010170
if value[2..5] == "0101":
codecStartIdx = 6
codec = parseHexInt(value[6..7])
elif value[2..3] == "01" and value[4..5] != "12":
codecStartIdx = 4
codec = parseHexInt(value[4..5])
# strip the info we no longer need
var multiHashStr = value[codecStartIdx + 2..<value.len]
# The rest of the hash identifies the multihash algo, length, and digest
# More info: https://multiformats.io/multihash/
# 12 = identifies sha2-256 hash
# 20 = multihash length = 32
# ...rest = multihash digest
let
multiHash = MultiHash.init(nimcrypto.fromHex(multiHashStr)).get()
decoded = Cid.init(CIDv0, MultiCodec.codec(codec), multiHash).get()
return (ENSType.IPFS, $decoded)
except Exception as e:
error "Error decoding ENS contenthash", hash=value, exception=e.msg
raise
if value[0..8] == "e50101700":
return (ENSType.IPNS, parseHexStr(value[12..value.len-1]))
return (ENSType.UNKNOWN, "")

View File

@ -0,0 +1,24 @@
import options
type
ENSType* {.pure.} = enum
IPFS,
SWARM,
IPNS,
UNKNOWN
type
ServiceInterface* {.pure inheritable.} = ref object of RootObj
## Abstract class for this service access.
method delete*(self: ServiceInterface) {.base.} =
raise newException(ValueError, "No implementation available")
method init*(self: ServiceInterface) {.base.} =
raise newException(ValueError, "No implementation available")
method getContentHash*(self: ServiceInterface, ens: string): Option[string] {.base.} =
raise newException(ValueError, "No implementation available")
method decodeENSContentHash*(self: ServiceInterface, value: string): tuple[ensType: ENSType, output: string] =
raise newException(ValueError, "No implementation available")

View File

@ -0,0 +1,324 @@
import Tables, json, sequtils, chronicles
import sets
import options
import strutils
include ../../common/json_utils
import ../dapp_permissions/service as dapp_permissions_service
import ../settings/service as settings_service
import ../ens/service as ens_service
import service_interface
import status/statusgo_backend_new/permissions as status_go_permissions
import status/statusgo_backend_new/accounts as status_go_accounts
import status/statusgo_backend_new/core as status_go_core
from stew/base32 import nil
from stew/base58 import nil
import stew/byteutils
export service_interface
logScope:
topics = "provider-service"
const HTTPS_SCHEME* = "https"
const IPFS_GATEWAY* = ".infura.status.im"
const SWARM_GATEWAY* = "swarm-gateways.net"
type
RequestTypes {.pure.} = enum
Web3SendAsyncReadOnly = "web3-send-async-read-only",
HistoryStateChanged = "history-state-changed",
APIRequest = "api-request"
Unknown = "unknown"
ResponseTypes {.pure.} = enum
Web3SendAsyncCallback = "web3-send-async-callback",
APIResponse = "api-response",
Web3ResponseError = "web3-response-error"
type
Payload = ref object
id: JsonNode
rpcMethod: string
Web3SendAsyncReadOnly = ref object
messageId: JsonNode
payload: Payload
request: string
hostname: string
APIRequest = ref object
isAllowed: bool
messageId: JsonNode
permission: Permission
hostname: string
const AUTH_METHODS = toHashSet(["eth_accounts", "eth_coinbase", "eth_sendTransaction", "eth_sign", "keycard_signTypedData", "eth_signTypedData", "eth_signTypedData_v3", "personal_sign", "personal_ecRecover"])
const SIGN_METHODS = toHashSet(["eth_sign", "personal_sign", "eth_signTypedData", "eth_signTypedData_v3"])
const ACC_METHODS = toHashSet(["eth_accounts", "eth_coinbase"])
proc requestType(message: string): RequestTypes =
let data = message.parseJson
result = RequestTypes.Unknown
try:
result = parseEnum[RequestTypes](data["type"].getStr())
except:
warn "Unknown request type received", value=data["permission"].getStr()
proc toWeb3SendAsyncReadOnly(message: string): Web3SendAsyncReadOnly =
let data = message.parseJson
result = Web3SendAsyncReadOnly(
messageId: data["messageId"],
request: $data["payload"],
hostname: data{"hostname"}.getStr(),
payload: Payload(
id: data["payload"]{"id"},
rpcMethod: data["payload"]["method"].getStr()
)
)
proc toAPIRequest(message: string): APIRequest =
let data = message.parseJson
result = APIRequest(
messageId: data["messageId"],
isAllowed: data{"isAllowed"}.getBool(),
permission: data["permission"].getStr().toPermission(),
hostname: data{"hostname"}.getStr()
)
type
Service* = ref object of service_interface.ServiceInterface
dappPermissionsService: dapp_permissions_service.ServiceInterface
settingsService: settings_service.ServiceInterface
ensService: ens_service.ServiceInterface
method delete*(self: Service) =
discard
proc newService*(dappPermissionsService: dapp_permissions_service.ServiceInterface,
settingsService: settings_service.ServiceInterface,
ensService: ens_service.ServiceInterface): Service =
result = Service()
result.dappPermissionsService = dappPermissionsService
result.settingsService = settingsService
result.ensService = ensService
method init*(self: Service) =
discard
proc process(self: Service, data: Web3SendAsyncReadOnly): string =
if AUTH_METHODS.contains(data.payload.rpcMethod) and not self.dappPermissionsService.hasPermission(data.hostname, Permission.Web3):
return $ %* {
"type": ResponseTypes.Web3SendAsyncCallback,
"messageId": data.messageId,
"error": {
"code": 4100
}
}
if data.payload.rpcMethod == "eth_sendTransaction":
try:
let request = data.request.parseJson
let fromAddress = request["params"][0]["from"].getStr()
let to = request["params"][0]{"to"}.getStr()
let value = if (request["params"][0]["value"] != nil):
request["params"][0]["value"].getStr()
else:
"0"
let password = request["password"].getStr()
let selectedGasLimit = request["selectedGasLimit"].getStr()
let selectedGasPrice = request["selectedGasPrice"].getStr()
let selectedTipLimit = request{"selectedTipLimit"}.getStr()
let selectedOverallLimit = request{"selectedOverallLimit"}.getStr()
let txData = if (request["params"][0].hasKey("data") and request["params"][0]["data"].kind != JNull):
request["params"][0]["data"].getStr()
else:
""
var success: bool
var errorMessage = ""
var response = ""
var validInput: bool = true
# TODO: use the transaction service to send the trx
#[
let eip1559Enabled = self.wallet.isEIP1559Enabled()
try:
validateTransactionInput(fromAddress, to, "", value, selectedGasLimit, selectedGasPrice, txData, eip1559Enabled, selectedTipLimit, selectedOverallLimit, "dummy")
except Exception as e:
validInput = false
success = false
errorMessage = e.msg
if validInput:
# TODO make this async
response = wallet.sendTransaction(fromAddress, to, value, selectedGasLimit, selectedGasPrice, eip1559Enabled, selectedTipLimit, selectedOverallLimit, password, success, txData)
errorMessage = if not success:
if response == "":
"web3-response-error"
else:
response
else:
""
return $ %* {
"type": ResponseTypes.Web3SendAsyncCallback,
"messageId": data.messageId,
"error": errorMessage,
"result": {
"jsonrpc": "2.0",
"id": data.payload.id,
"result": if (success): response else: ""
}
}
]#
# TODO: delete this:
return $ %* {
"type": ResponseTypes.Web3SendAsyncCallback,
"messageId": data.messageId,
"error": "",
"result": {
"jsonrpc": "2.0",
"id": data.payload.id,
"result": ""
}
}
except Exception as e:
error "Error sending the transaction", msg = e.msg
return $ %* {
"type": ResponseTypes.Web3SendAsyncCallback,
"messageId": data.messageId,
"error": {
"code": 4100,
"message": e.msg
}
}
if SIGN_METHODS.contains(data.payload.rpcMethod):
try:
let request = data.request.parseJson
var params = request["params"]
let password = hashPassword(request["password"].getStr())
let dappAddress = self.settingsService.getDappsAddress()
var rpcResult = "{}"
case data.payload.rpcMethod:
of "eth_signTypedData", "eth_signTypedData_v3":
rpcResult = signTypedData(params[1].getStr(), dappAddress, password)
else:
rpcResult = signMessage($ %* {
"data": params[0].getStr(),
"password": password,
"account": dappAddress
})
let jsonRpcResult = rpcResult.parseJson
let success: bool = not jsonRpcResult.hasKey("error")
let errorMessage = if success: "" else: jsonRpcResult["error"]{"message"}.getStr()
let response = if success: jsonRpcResult["result"].getStr() else: ""
return $ %* {
"type": ResponseTypes.Web3SendAsyncCallback,
"messageId": data.messageId,
"error": errorMessage,
"result": {
"jsonrpc": "2.0",
"id": if data.payload.id == nil: newJNull() else: data.payload.id,
"result": if (success): response else: ""
}
}
except Exception as e:
error "Error signing message", msg = e.msg
return $ %* {
"type": ResponseTypes.Web3SendAsyncCallback,
"messageId": data.messageId,
"error": {
"code": 4100,
"message": e.msg
}
}
if ACC_METHODS.contains(data.payload.rpcMethod):
let dappAddress = self.settingsService.getDappsAddress()
return $ %* {
"type": ResponseTypes.Web3SendAsyncCallback,
"messageId": data.messageId,
"result": {
"jsonrpc": "2.0",
"id": data.payload.id,
"result": if data.payload.rpcMethod == "eth_coinbase": newJString(dappAddress) else: %*[dappAddress]
}
}
let rpcResult = callRPC(data.request)
return $ %* {
"type": ResponseTypes.Web3SendAsyncCallback,
"messageId": data.messageId,
"error": (if rpcResult == "": newJString("web3-response-error") else: newJNull()),
"result": rpcResult.parseJson
}
proc process(self: Service, data: APIRequest): string =
var value:JsonNode = case data.permission
of Permission.Web3: %* [self.settingsService.getDappsAddress()]
of Permission.ContactCode: %* self.settingsService.getPubKey()
of Permission.Unknown: newJNull()
let isAllowed = data.isAllowed and data.permission != Permission.Unknown
info "API request received", host=data.hostname, value=data.permission, isAllowed
if isAllowed:
discard self.dappPermissionsService.addPermission(data.hostname, data.permission)
return $ %* {
"type": ResponseTypes.APIResponse,
"isAllowed": isAllowed,
"permission": data.permission,
"messageId": data.messageId,
"data": value
}
method postMessage*(self: Service, message: string): string =
case message.requestType():
of RequestTypes.Web3SendAsyncReadOnly: self.process(message.toWeb3SendAsyncReadOnly())
of RequestTypes.HistoryStateChanged: """{"type":"TODO-IMPLEMENT-THIS"}""" ############# TODO:
of RequestTypes.APIRequest: self.process(message.toAPIRequest())
else: """{"type":"TODO-IMPLEMENT-THIS"}""" ##################### TODO:
method ensResourceURL*(self: Service, ens: string, url: string): (string, string, string, string, bool) =
let contentHash = self.ensService.getContentHash(ens)
if contentHash.isNone(): # ENS does not have a content hash
return (url, url, HTTPS_SCHEME, "", false)
let decodedHash = self.ensService.decodeENSContentHash(contentHash.get())
case decodedHash[0]:
of ENSType.IPFS:
let
base58bytes = base58.decode(base58.BTCBase58, decodedHash[1])
base32Hash = base32.encode(base32.Base32Lower, base58bytes)
result = (url, base32Hash & IPFS_GATEWAY, HTTPS_SCHEME, "", true)
of ENSType.SWARM:
result = (url, SWARM_GATEWAY, HTTPS_SCHEME,
"/bzz:/" & decodedHash[1] & "/", true)
of ENSType.IPNS:
result = (url, decodedHash[1], HTTPS_SCHEME, "", true)
else:
warn "Unknown content for", ens, contentHash

View File

@ -0,0 +1,15 @@
type
ServiceInterface* {.pure inheritable.} = ref object of RootObj
## Abstract class for this service access.
method delete*(self: ServiceInterface) {.base.} =
raise newException(ValueError, "No implementation available")
method init*(self: ServiceInterface) {.base.} =
raise newException(ValueError, "No implementation available")
method postMessage*(self: ServiceInterface, message: string): string {.base.} =
raise newException(ValueError, "No implementation available")
method ensResourceURL*(self: ServiceInterface, ens: string, url: string): (string, string, string, string, bool) =
raise newException(ValueError, "No implementation available")

View File

@ -5,7 +5,6 @@ import app/wallet/v1/core as wallet
import app/wallet/v2/core as walletV2
import app/node/core as node
import app/utilsView/core as utilsView
import app/provider/core as provider
import app/keycard/core as keycard
import status/types/[account]
import status_go
@ -158,10 +157,6 @@ proc mainProc() =
defer: utilsController.delete()
singletonInstance.engine.setRootContextProperty("utilsModel", utilsController.variant)
var provider = provider.newController(status)
defer: provider.delete()
singletonInstance.engine.setRootContextProperty("web3Provider", provider.variant)
var keycard = keycard.newController(status)
defer: keycard.delete()
@ -172,7 +167,6 @@ proc mainProc() =
status.startMessenger()
wallet.init()
wallet2.init()
provider.init()
chat.init()
utilsController.init()
node.init()

View File

@ -12,7 +12,7 @@ QtObject {
var url = RootStore.getUrlFromUserInput(text);
var host = providerModule.getHost(url);
if(host.endsWith(".eth")){
var ensResource = web3Provider.ensResourceURL(host, url);
var ensResource = providerModule.ensResourceURL(host, url);
if(/^https\:\/\/swarm\-gateways\.net\/bzz:\/([0-9a-fA-F]{64}|.+\.eth)(\/?)/.test(ensResource)){
// TODO: populate urlENSDictionary for prettier url instead of swarm-gateway big URL

2
vendor/status-lib vendored

@ -1 +1 @@
Subproject commit fb58ecc10afe13013865163b74563ae762e808f5
Subproject commit 845c29b6be236bf9a0459cff0d2abd57aec8053c