chores(@general): remove status-lib deps

This commit is contained in:
Anthony Laibe 2022-02-03 15:23:51 +01:00 committed by Iuri Matias
parent 967fff839b
commit 56340bebd1
80 changed files with 1862 additions and 64 deletions

15
.gitmodules vendored
View File

@ -34,9 +34,6 @@
[submodule "vendor/semver.nim"]
path = vendor/semver.nim
url = https://github.com/euantorano/semver.nim
[submodule "vendor/status-lib"]
path = vendor/status-lib
url = https://github.com/status-im/status-lib
[submodule "spellchecking"]
path = spellchecking
url = https://github.com/status-im/desktop-spellchecking.git
@ -109,3 +106,15 @@
[submodule "vendor/fcitx5-qt"]
path = vendor/fcitx5-qt
url = https://github.com/fcitx/fcitx5-qt
[submodule "vendor/status-go"]
path = vendor/status-go
url = https://github.com/status-im/status-go
[submodule "vendor/nim-status-go"]
path = vendor/nim-status-go
url = https://github.com/status-im/nim-status-go.git
[submodule "vendor/nim-stint"]
path = vendor/nim-stint
url = https://github.com/status-im/nim-stint.git
[submodule "vendor/nim-keycard-go"]
path = vendor/nim-keycard-go
url = https://github.com/status-im/nim-keycard-go

View File

@ -68,7 +68,7 @@ else()
endif()
add_subdirectory(${CMAKE_CURRENT_SOURCE_DIR}/vendor/status-lib/vendor/status-go bin/status-go)
add_subdirectory(${CMAKE_CURRENT_SOURCE_DIR}/vendor/status-go bin/status-go)
# The following are dependencies that do not include CMakeList.txt files
# Create a PR in those projects so we can include them just like it was

View File

@ -208,25 +208,25 @@ $(DOTHERSIDE): | deps
.. $(HANDLE_OUTPUT) && \
$(DOTHERSIDE_BUILD_CMD)
STATUSGO := vendor/status-lib/vendor/status-go/build/bin/libstatus.$(LIBSTATUS_EXT)
STATUSGO := vendor/status-go/build/bin/libstatus.$(LIBSTATUS_EXT)
STATUSGO_LIBDIR := $(shell pwd)/$(shell dirname "$(STATUSGO)")
export STATUSGO_LIBDIR
status-go: $(STATUSGO)
$(STATUSGO): | deps
echo -e $(BUILD_MSG) "status-go"
+ cd vendor/status-lib/vendor/status-go && \
+ cd vendor/status-go && \
$(MAKE) statusgo-shared-library $(HANDLE_OUTPUT)
KEYCARDGO := vendor/status-lib/vendor/nim-keycard-go/go/keycard/build/libkeycard/libkeycard.$(LIBSTATUS_EXT)
KEYCARDGO := vendor/nim-keycard-go/go/keycard/build/libkeycard/libkeycard.$(LIBSTATUS_EXT)
KEYCARDGO_LIBDIR := $(shell pwd)/$(shell dirname "$(KEYCARDGO)")
export KEYCARDGO_LIBDIR
keycard-go: $(KEYCARDGO)
$(KEYCARDGO): | deps
echo -e $(BUILD_MSG) "keycard-go"
+ cd vendor/status-lib/vendor/nim-keycard-go && \
+ cd vendor/nim-keycard-go && \
$(MAKE) build-keycard-go $(HANDLE_OUTPUT)
QRCODEGEN := vendor/QR-Code-generator/c/libqrcodegen.a
@ -385,8 +385,8 @@ $(STATUS_CLIENT_APPIMAGE): nim_status_client $(APPIMAGE_TOOL) nim-status.desktop
cp -P /usr/lib/x86_64-linux-gnu/libgst* tmp/linux/dist/usr/lib/
cp -r /usr/lib/x86_64-linux-gnu/gstreamer-1.0 tmp/linux/dist/usr/lib/
cp -r /usr/lib/x86_64-linux-gnu/gstreamer1.0 tmp/linux/dist/usr/lib/
cp vendor/status-lib/vendor/status-go/build/bin/libstatus.so tmp/linux/dist/usr/lib/
cp vendor/status-lib/vendor/status-go/build/bin/libstatus.so.0 tmp/linux/dist/usr/lib/
cp vendor/status-go/build/bin/libstatus.so tmp/linux/dist/usr/lib/
cp vendor/status-go/build/bin/libstatus.so.0 tmp/linux/dist/usr/lib/
cp $(KEYCARDGO) tmp/linux/dist/usr/lib/
echo -e $(BUILD_MSG) "AppImage"

View File

@ -1,6 +1,6 @@
# Keycard
# TODO: create a PR in that project to build it like we do with status-go ^
set(KEYCARD_ROOT ${CMAKE_CURRENT_SOURCE_DIR}/vendor/status-lib/vendor/nim-keycard-go)
set(KEYCARD_ROOT ${CMAKE_CURRENT_SOURCE_DIR}/vendor/nim-keycard-go)
set(KEYCARD_LIB_DIR ${KEYCARD_ROOT}/go/keycard/build/libkeycard)
ExternalProject_Add(libkeycard
PREFIX ${KEYCARD_ROOT}

View File

@ -5,7 +5,7 @@ import ../../../app/core/tasks/[qt, threadpool]
import ../settings/service as settings_service
import ../network/types
import status/about as status_about
import ../../../backend/about as status_about
import ./update
include async_tasks

View File

@ -4,8 +4,8 @@ import json_serialization, chronicles
import service_interface
import ./dto/accounts
import ./dto/generated_accounts
import status/accounts as status_account
import status/general as status_general
import ../../../backend/accounts as status_account
import ../../../backend/general as status_general
import ../../../app/core/fleets/fleet_configuration
import ../../common/[account_constants, network_constants, utils, string_utils]

View File

@ -9,8 +9,8 @@ import json, tables, json_serialization
import ../chat/service as chat_service
import status/activity_center as status_activity_center
import status/response_type
import ../../../backend/activity_center as status_activity_center
import ../../../backend/response_type
import ./dto/notification
export notification

View File

@ -2,7 +2,7 @@ import Tables, json, sequtils, strformat, chronicles
import result
include ../../common/json_utils
import service_interface, dto/bookmark
import status/bookmarks as status_go
import ../../../backend/bookmarks as status_go
export service_interface

View File

@ -4,8 +4,8 @@ import ./dto/chat as chat_dto
import ../message/dto/message as message_dto
import ../activity_center/dto/notification as notification_dto
import ../contacts/service as contact_service
import status/chat as status_chat
import status/chatCommands as status_chat_commands
import ../../../backend/chat as status_chat
import ../../../backend/chatCommands as status_chat_commands
import ../../../app/global/global_singleton
import ../../../app/core/eventemitter
import ../../../constants

View File

@ -3,7 +3,7 @@ import chronicles, sequtils, json
import ./service_interface, ./dto
import ../settings/service_interface as settings_service
import status/collectibles as collectibles
import ../../../backend/collectibles as collectibles
export service_interface

View File

@ -2,7 +2,7 @@
import json, sequtils
import status/communities
import ../../../../backend/communities
include ../../../common/json_utils
type

View File

@ -7,7 +7,7 @@ import ../chat/service as chat_service
import ../../../app/global/global_singleton
import ../../../app/core/signals/types
import ../../../app/core/eventemitter
import status/communities as status_go
import ../../../backend/communities as status_go
export community_dto

View File

@ -8,10 +8,10 @@ import ../../../app/core/tasks/[qt, threadpool]
import ./dto/contacts as contacts_dto
import ./dto/status_update as status_update_dto
import ./dto/contact_details
import status/contacts as status_contacts
import status/accounts as status_accounts
import status/chat as status_chat
import status/utils as status_utils
import ../../../backend/contacts as status_contacts
import ../../../backend/accounts as status_accounts
import ../../../backend/chat as status_chat
import ../../../backend/utils as status_utils
export contacts_dto, status_update_dto, contact_details

View File

@ -4,7 +4,7 @@ import result
import options
include ../../common/json_utils
import service_interface
import status/permissions as status_go
import ../../../backend/permissions as status_go
import dto/dapp
import dto/permission
export service_interface

View File

@ -5,7 +5,7 @@ import ../settings/service as settings_service
import ../../../app/core/signals/types
import ../../../app/core/eventemitter
import status/installations as status_installations
import ../../../backend/installations as status_installations
export device_dto

View File

@ -6,7 +6,7 @@ import web3/ethtypes
import ../../../app/core/eventemitter
import ../../../app/core/tasks/[qt, threadpool]
import status/eth as status_eth
import ../../../backend/eth as status_eth
import ../../common/conversion as common_conversion
import utils as ens_utils

View File

@ -7,7 +7,7 @@ import ../../common/conversion as common_conversion
import ../eth/dto/transaction as eth_transaction_dto
import ../eth/dto/coder as eth_coder_dto
import ../eth/dto/contract as eth_contract_dto
import status/eth as status_eth
import ../../../backend/eth as status_eth
logScope:
topics = "ens-utils"

View File

@ -7,7 +7,7 @@ import json, tables, json_serialization
import web3/[ethtypes, conversions], stint
import ./method_dto
import status/eth as status_eth
import ../../../../backend/eth as status_eth
export method_dto

View File

@ -4,7 +4,7 @@ import
import
nimcrypto, web3/[encoding, ethtypes]
import status/eth as status_eth
import ../../../../backend/eth as status_eth
import
./transaction,

View File

@ -1,7 +1,7 @@
import json, sequtils, chronicles, macros, sugar, strutils, stint
import web3/ethtypes, json_serialization, chronicles, tables
import status/eth
import ../../../backend/eth
import utils
import ./service_interface

View File

@ -1,8 +1,8 @@
import json, chronicles
import service_interface
import status/general as status_general
import status/keycard as status_keycard
import ../../../backend/general as status_general
import ../../../backend/keycard as status_keycard
import ../../../constants as app_constants

View File

@ -7,7 +7,7 @@ import chronicles
import sequtils
import ../settings/service_interface as settings_service
import status/gif as status_gif
import ../../../backend/gif as status_gif
import ./dto
import ./service_interface

View File

@ -7,7 +7,7 @@ import ../../../app/core/[main]
import ../../../app/core/tasks/[qt, threadpool]
import ../settings/service_interface as settings_service
import ../node_configuration/service_interface as node_configuration_service
import status/mailservers as status_mailservers
import ../../../backend/mailservers as status_mailservers
logScope:
topics = "mailservers-service"

View File

@ -1,7 +1,7 @@
include ../../common/json_utils
include ../../../app/core/tasks/common
import status/chat as status_go_chat
import ../../../backend/chat as status_go_chat
#################################################

View File

@ -3,7 +3,7 @@ import NimQml, tables, json, re, sequtils, strformat, strutils, chronicles
import ../../../app/core/tasks/[qt, threadpool]
import ../../../app/core/signals/types
import ../../../app/core/eventemitter
import status/messages as status_go
import ../../../backend/messages as status_go
import ../contacts/service as contact_service
import ./dto/message as message_dto
import ./dto/pinned_message as pinned_msg_dto

View File

@ -1,7 +1,7 @@
import json, json_serialization, chronicles, atomics
import options
import status/network as status_network
import ../../../backend/network as status_network
import ./service_interface
export service_interface

View File

@ -1,4 +1,4 @@
import status/node as status_node
import ../../../backend/node as status_node
import bitops, stew/byteutils, chronicles
include ../../../app/core/tasks/common

View File

@ -6,7 +6,7 @@ include ../../../common/json_utils
# Important note:
#
# Uppercase letters are used in properties in object types deliberately, cause
# we're following "keys" which are received from `status-lib` (`status-go`)
# we're following "keys" which are received from `status-go`
#
# Why do we do that?
# Cause we're storing node configuration to the settings as JsonNode, and in order to

View File

@ -4,7 +4,7 @@ import service_interface
import ./dto/node_config
import ../settings/service_interface as settings_service
import ../../../app/core/fleets/fleet_configuration
import status/node_config as status_node_config
import ../../../backend/node_config as status_node_config
export service_interface

View File

@ -5,9 +5,9 @@ import ../accounts/service_interface as accounts_service
import ../../../app/core/eventemitter
import status/accounts as status_account
import status/eth as status_eth
import status/privacy as status_privacy
import ../../../backend/accounts as status_account
import ../../../backend/eth as status_eth
import ../../../backend/privacy as status_privacy
logScope:
topics = "privacy-service"

View File

@ -1,7 +1,7 @@
import json, chronicles
import ./service_interface
import status/accounts as status_accounts
import ../../../backend/accounts as status_accounts
export service_interface

View File

@ -7,9 +7,9 @@ import ../dapp_permissions/service as dapp_permissions_service
import ../settings/service_interface as settings_service
import ../ens/utils as ens_utils
import service_interface
import status/permissions as status_go_permissions
import status/core as status_go_core
import status/eth as status_eth
import ../../../backend/permissions as status_go_permissions
import ../../../backend/core as status_go_core
import ../../../backend/eth as status_eth
import ../../common/utils as status_utils
import ../eth/utils as eth_utils
import ../eth/dto/transaction as transaction_data_dto

View File

@ -3,7 +3,7 @@ import chronicles, sequtils, json
import ./service_interface, ./dto
import ../../../app/core/eventemitter
import status/saved_addresses as backend
import ../../../backend/saved_addresses as backend
export service_interface

View File

@ -3,7 +3,7 @@ import chronicles, json, strutils, sequtils, tables, sugar
import ../../common/[network_constants]
import ../../../app/core/fleets/fleet_configuration
import service_interface, ./dto/settings
import status/settings as status_settings
import ../../../backend/settings as status_settings
export service_interface

View File

@ -8,10 +8,10 @@ import ../../../app/core/tasks/[qt, threadpool]
import web3/ethtypes, web3/conversions, stew/byteutils, nimcrypto, json_serialization, chronicles
import json, tables, json_serialization
import status/stickers as status_stickers
import status/chat as status_chat
import status/response_type
import status/eth
import ../../../backend/stickers as status_stickers
import ../../../backend/chat as status_chat
import ../../../backend/response_type
import ../../../backend/eth
import ./dto/stickers
import ../ens/utils as ens_utils
import ../eth/service as eth_service

View File

@ -3,7 +3,7 @@ import NimQml, json, sequtils, chronicles, strformat, strutils
from sugar import `=>`
import web3/ethtypes
from web3/conversions import `$`
import status/custom_tokens as custom_tokens
import ../../../backend/custom_tokens as custom_tokens
import ../settings/service_interface as settings_service
import ../../../app/core/eventemitter

View File

@ -1,7 +1,7 @@
import NimQml, chronicles, sequtils, sugar, stint, strutils, json, strformat
import status/transactions as transactions
import status/wallet as status_wallet
import status/eth
import ../../../backend/transactions as transactions
import ../../../backend/wallet as status_wallet
import ../../../backend/eth
import ../ens/utils as ens_utils
from ../../common/account_constants import ZERO_ADDRESS

View File

@ -9,8 +9,8 @@ import ../../common/account_constants
import ./service_interface, ./dto
import ../../../app/core/eventemitter
import status/accounts as status_go_accounts
import status/eth as status_go_eth
import ../../../backend/accounts as status_go_accounts
import ../../../backend/eth as status_go_eth
export service_interface

8
src/backend/about.nim Normal file
View File

@ -0,0 +1,8 @@
import json
import ./core
import response_type
export response_type
proc getWeb3ClientVersion*(): RpcResponse[JsonNode] {.raises: [Exception].} =
result = callPrivateRPC("web3_clientVersion")

256
src/backend/accounts.nim Normal file
View File

@ -0,0 +1,256 @@
import json, json_serialization, chronicles, nimcrypto
import ./core, ./utils
import ./response_type
import status_go
export response_type
logScope:
topics = "rpc-accounts"
const NUMBER_OF_ADDRESSES_TO_GENERATE = 5
const MNEMONIC_PHRASE_LENGTH = 12
const GENERATED* = "generated"
const SEED* = "seed"
const KEY* = "key"
const WATCH* = "watch"
proc getAccounts*(): RpcResponse[JsonNode] {.raises: [Exception].} =
return core.callPrivateRPC("accounts_getAccounts")
proc deleteAccount*(address: string): RpcResponse[JsonNode] {.raises: [Exception].} =
return core.callPrivateRPC("accounts_deleteAccount", %* [address])
proc updateAccount*(name, address, publicKey, walletType, color: string) {.raises: [Exception].} =
discard core.callPrivateRPC("accounts_saveAccounts", %* [
[{
"color": color,
"name": name,
"address": address,
"public-key": publicKey,
"type": walletType,
"path": "m/44'/60'/0'/0/1" # <--- TODO: fix this. Derivation path is not supposed to change
}]
])
proc generateAddresses*(paths: seq[string]): RpcResponse[JsonNode] {.raises: [Exception].} =
let payload = %* {
"n": NUMBER_OF_ADDRESSES_TO_GENERATE,
"mnemonicPhraseLength": MNEMONIC_PHRASE_LENGTH,
"bip39Passphrase": "",
"paths": paths
}
try:
let response = status_go.multiAccountGenerateAndDeriveAddresses($payload)
result.result = Json.decode(response, JsonNode)
except RpcException as e:
error "error doing rpc request", methodName = "generateAddresses", exception=e.msg
raise newException(RpcException, e.msg)
proc generateAlias*(publicKey: string): RpcResponse[JsonNode] {.raises: [Exception].} =
try:
let response = status_go.generateAlias(publicKey)
result.result = %* response
except RpcException as e:
error "error doing rpc request", methodName = "generateAlias", exception=e.msg
raise newException(RpcException, e.msg)
proc generateIdenticon*(publicKey: string): RpcResponse[JsonNode] {.raises: [Exception].} =
try:
let response = status_go.identicon(publicKey)
result.result = %* response
except RpcException as e:
error "error doing rpc request", methodName = "generateIdenticon", exception=e.msg
raise newException(RpcException, e.msg)
proc multiAccountImportMnemonic*(mnemonic: string): RpcResponse[JsonNode] {.raises: [Exception].} =
let payload = %* {
"mnemonicPhrase": mnemonic,
"Bip39Passphrase": ""
}
try:
let response = status_go.multiAccountImportMnemonic($payload)
result.result = Json.decode(response, JsonNode)
except RpcException as e:
error "error doing rpc request", methodName = "multiAccountImportMnemonic", exception=e.msg
raise newException(RpcException, e.msg)
proc deriveAccounts*(accountId: string, paths: seq[string]): RpcResponse[JsonNode] {.raises: [Exception].} =
let payload = %* {
"accountID": accountId,
"paths": paths
}
try:
let response = status_go.multiAccountDeriveAddresses($payload)
result.result = Json.decode(response, JsonNode)
except RpcException as e:
error "error doing rpc request", methodName = "deriveAccounts", exception=e.msg
raise newException(RpcException, e.msg)
proc openedAccounts*(path: string): RpcResponse[JsonNode] {.raises: [Exception].} =
try:
let response = status_go.openAccounts(path)
result.result = Json.decode(response, JsonNode)
except RpcException as e:
error "error doing rpc request", methodName = "openedAccounts", exception=e.msg
raise newException(RpcException, e.msg)
proc storeDerivedAccounts*(id, hashedPassword: string, paths: seq[string]):
RpcResponse[JsonNode] {.raises: [Exception].} =
let payload = %* {
"accountID": id,
"paths": paths,
"password": hashedPassword
}
try:
let response = status_go.multiAccountStoreDerivedAccounts($payload)
result.result = Json.decode(response, JsonNode)
except RpcException as e:
error "error doing rpc request", methodName = "storeDerivedAccounts", exception=e.msg
raise newException(RpcException, e.msg)
proc storeAccounts*(id, hashedPassword: string): RpcResponse[JsonNode] {.raises: [Exception].} =
let payload = %* {
"accountID": id,
"password": hashedPassword
}
try:
let response = status_go.multiAccountStoreAccount($payload)
result.result = Json.decode(response, JsonNode)
except RpcException as e:
error "error doing rpc request", methodName = "storeAccounts", exception=e.msg
raise newException(RpcException, e.msg)
proc saveAccount*(
address: string,
name: string,
password: string,
color: string,
accountType: string,
isADerivedAccount = true,
walletIndex: int = 0,
id: string = "",
publicKey: string = "",
) {.raises: [Exception].} =
var derivationPath = "m/44'/60'/0'/0/0"
let hashedPassword = hashPassword(password)
if (isADerivedAccount):
let derivationPath = (if accountType == GENERATED: "m/" else: "m/44'/60'/0'/0/") & $walletIndex
discard storeDerivedAccounts(id, hashedPassword, @[derivationPath])
elif accountType == KEY:
discard storeAccounts(id, hashedPassword)
discard callPrivateRPC("accounts_saveAccounts", %* [
[{
"color": color,
"name": name,
"address": address,
"public-key": publicKey,
"type": accountType,
"path": derivationPath
}]
])
proc loadAccount*(address: string, password: string): RpcResponse[JsonNode] {.raises: [Exception].} =
let hashedPassword = hashPassword(password)
let payload = %* {
"address": address,
"password": hashedPassword
}
try:
let response = status_go.multiAccountLoadAccount($payload)
result.result = Json.decode(response, JsonNode)
except RpcException as e:
error "error doing rpc request", methodName = "storeAccounts", exception=e.msg
raise newException(RpcException, e.msg)
proc addPeer*(peer: string): RpcResponse[JsonNode] {.raises: [Exception].} =
try:
let response = status_go.addPeer(peer)
result.result = %* response
except RpcException as e:
error "error doing rpc request", methodName = "addPeer", exception=e.msg
raise newException(RpcException, e.msg)
proc saveAccountAndLogin*(hashedPassword: string, account, subaccounts, settings,
config: JsonNode): RpcResponse[JsonNode] {.raises: [Exception].} =
try:
let response = status_go.saveAccountAndLogin($account, hashedPassword,
$settings, $config, $subaccounts)
result.result = Json.decode(response, JsonNode)
except RpcException as e:
error "error doing rpc request", methodName = "saveAccountAndLogin", exception=e.msg
raise newException(RpcException, e.msg)
proc login*(name, keyUid, hashedPassword, identicon, thumbnail, large: string, nodeCfgObj: string):
RpcResponse[JsonNode]
{.raises: [Exception].} =
try:
var payload = %* {
"name": name,
"key-uid": keyUid,
"identityImage": newJNull(),
"identicon": identicon
}
if(thumbnail.len>0 and large.len > 0):
payload["identityImage"] = %* {"thumbnail": thumbnail, "large": large}
let response = status_go.loginWithConfig($payload, hashedPassword, nodeCfgObj)
result.result = Json.decode(response, JsonNode)
except RpcException as e:
error "error doing rpc request", methodName = "login", exception=e.msg
raise newException(RpcException, e.msg)
proc multiAccountImportPrivateKey*(privateKey: string): RpcResponse[JsonNode] =
let payload = %* {
"privateKey": privateKey
}
try:
let response = status_go.multiAccountImportPrivateKey($payload)
result.result = Json.decode(response, JsonNode)
except RpcException as e:
error "error doing rpc request", methodName = "multiAccountImportPrivateKey", exception=e.msg
raise newException(RpcException, e.msg)
proc verifyAccountPassword*(address: string, password: string, keystoreDir: string):
RpcResponse[JsonNode] {.raises: [Exception].} =
try:
let hashedPassword = hashPassword(password)
let response = status_go.verifyAccountPassword(keystoreDir, address, hashedPassword)
result.result = Json.decode(response, JsonNode)
except RpcException as e:
error "error doing rpc request", methodName = "verifyAccountPassword", exception=e.msg
raise newException(RpcException, e.msg)
proc storeIdentityImage*(keyUID: string, imagePath: string, aX, aY, bX, bY: int):
RpcResponse[JsonNode] {.raises: [Exception].} =
let payload = %* [keyUID, imagePath, aX, aY, bX, bY]
result = core.callPrivateRPC("multiaccounts_storeIdentityImage", payload)
proc deleteIdentityImage*(keyUID: string): RpcResponse[JsonNode] {.raises: [Exception].} =
let payload = %* [keyUID]
result = core.callPrivateRPC("multiaccounts_deleteIdentityImage", payload)

View File

@ -0,0 +1,27 @@
import json
import core, utils
import response_type
export response_type
proc rpcActivityCenterNotifications*(cursorVal: JsonNode, limit: int): RpcResponse[JsonNode] {.raises: [Exception].} =
callPrivateRPC("activityCenterNotifications".prefix, %* [cursorVal, limit])
proc markAllActivityCenterNotificationsRead*(): RpcResponse[JsonNode] {.raises: [Exception].} =
callPrivateRPC("markAllActivityCenterNotificationsRead".prefix, %*[])
proc markActivityCenterNotificationsRead*(ids: seq[string]): RpcResponse[JsonNode] {.raises: [Exception].} =
callPrivateRPC("markActivityCenterNotificationsRead".prefix, %*[ids])
proc markActivityCenterNotificationsUnread*(ids: seq[string]): RpcResponse[JsonNode] {.raises: [Exception].} =
callPrivateRPC("markActivityCenterNotificationsUnread".prefix, %*[ids])
proc acceptActivityCenterNotifications*(ids: seq[string]): RpcResponse[JsonNode] {.raises: [Exception].} =
callPrivateRPC("acceptActivityCenterNotifications".prefix, %*[ids])
proc dismissActivityCenterNotifications*(ids: seq[string]): RpcResponse[JsonNode] {.raises: [Exception].} =
result = callPrivateRPC("dismissActivityCenterNotifications".prefix, %*[ids])
proc unreadActivityCenterNotificationsCount*(): RpcResponse[JsonNode] {.raises: [Exception].} =
callPrivateRPC("unreadActivityCenterNotificationsCount".prefix, %*[])

21
src/backend/bookmarks.nim Normal file
View File

@ -0,0 +1,21 @@
import json, strmisc
import core, utils
import response_type
export response_type
proc getBookmarks*(): RpcResponse[JsonNode] {.raises: [Exception].} =
let payload = %* []
result = callPrivateRPC("browsers_getBookmarks", payload)
proc storeBookmark*(url, name: string): RpcResponse[JsonNode] {.raises: [Exception].} =
let payload = %* [{"url": url, "name": name}]
result = callPrivateRPC("browsers_storeBookmark", payload)
proc deleteBookmark*(url: string): RpcResponse[JsonNode] {.raises: [Exception].} =
let payload = %* [url]
result = callPrivateRPC("browsers_deleteBookmark", payload)
proc updateBookmark*(originalUrl, newUrl, name: string): RpcResponse[JsonNode] {.raises: [Exception].} =
let payload = %* [originalUrl, {"url": newUrl, "name": name}]
result = callPrivateRPC("browsers_updateBookmark", payload)

134
src/backend/chat.nim Normal file
View File

@ -0,0 +1,134 @@
import json, sequtils, sugar
import core, utils
import response_type
export response_type
proc saveChat*(
chatId: string,
chatType: int,
active: bool = true,
color: string = "#000000",
ensName: string = "",
profile: string = "",
joined: int64 = 0
): RpcResponse[JsonNode] {.raises: [Exception].} =
# TODO: ideally status-go/stimbus should handle some of these fields instead of having the client
# send them: lastMessage, unviewedMEssagesCount, timestamp, lastClockValue, name?
return callPrivateRPC("saveChat".prefix, %* [
{
"lastClockValue": 0, # TODO:
"color": color,
"name": (if ensName != "": ensName else: chatId),
"lastMessage": nil, # TODO:
"active": active,
"profile": profile,
"id": chatId,
"unviewedMessagesCount": 0, # TODO:
"chatType": chatType.int,
"timestamp": 1588940692659, # TODO:
"joined": joined
}
])
proc getChats*(): RpcResponse[JsonNode] {.raises: [Exception].} =
let payload = %* []
result = callPrivateRPC("chats".prefix, payload)
proc createPublicChat*(chatId: string): RpcResponse[JsonNode] {.raises: [Exception].} =
let payload = %* [{"ID": chatId}]
result = callPrivateRPC("createPublicChat".prefix, payload)
proc createOneToOneChat*(chatId: string): RpcResponse[JsonNode] {.raises: [Exception].} =
let payload = %* [{"ID": chatId}]
result = callPrivateRPC("createOneToOneChat".prefix, payload)
proc leaveGroupChat*(chatId: string): RpcResponse[JsonNode] {.raises: [Exception].} =
result = callPrivateRPC("leaveGroupChat".prefix, %* [nil, chatId, true])
proc deactivateChat*(chatId: string): RpcResponse[JsonNode] {.raises: [Exception].} =
callPrivateRPC("deactivateChat".prefix, %* [{ "ID": chatId }])
proc clearChatHistory*(chatId: string): RpcResponse[JsonNode] {.raises: [Exception].} =
callPrivateRPC("deleteMessagesByChatID".prefix, %* [chatId])
proc sendChatMessage*(
chatId: string,
msg: string,
replyTo: string,
contentType: int,
preferredUsername: string = "",
communityId: string = "",
stickerHash: string = "",
stickerPack: int = 0,
): RpcResponse[JsonNode] {.raises: [Exception].} =
result = callPrivateRPC("sendChatMessage".prefix, %* [
{
"chatId": chatId,
"text": msg,
"responseTo": replyTo,
"ensName": preferredUsername,
"sticker": {
"hash": stickerHash,
"pack": stickerPack
},
"contentType": contentType,
"communityId": communityId
}
])
proc sendImages*(chatId: string, images: var seq[string]): RpcResponse[JsonNode] {.raises: [Exception].} =
let imagesJson = %* images.map(image => %*
{
"chatId": chatId,
"contentType": 7, # TODO how do we unhardcode this
"imagePath": image,
# TODO is this still needed
# "ensName": preferredUsername,
"text": "Update to latest version to see a nice image here!"
}
)
callPrivateRPC("sendChatMessages".prefix, %* [imagesJson])
proc muteChat*(chatId: string): RpcResponse[JsonNode] {.raises: [Exception].} =
let payload = %* [chatId]
result = callPrivateRPC("muteChat".prefix, payload)
proc unmuteChat*(chatId: string): RpcResponse[JsonNode] {.raises: [Exception].} =
let payload = %* [chatId]
result = callPrivateRPC("unmuteChat".prefix, payload)
proc deleteMessagesByChatId*(chatId: string): RpcResponse[JsonNode] {.raises: [Exception].} =
let payload = %* [chatId]
result = callPrivateRPC("deleteMessagesByChatID".prefix, payload)
proc addGroupMembers*(chatId: string, pubKeys: seq[string]): RpcResponse[JsonNode] {.raises: [Exception].} =
let payload = %* [nil, chatId, pubKeys]
result = callPrivateRPC("addMembersToGroupChat".prefix, payload)
proc removeMembersFromGroupChat*(chatId: string, pubKey: string): RpcResponse[JsonNode] {.raises: [Exception].} =
let payload = %* [nil, chatId, pubKey]
result = callPrivateRPC("removeMemberFromGroupChat".prefix, payload)
proc renameGroupChat*(chatId: string, newName: string): RpcResponse[JsonNode] {.raises: [Exception].} =
let payload = %* [nil, chatId, newName]
result = callPrivateRPC("changeGroupChatName".prefix, payload)
proc makeAdmin*(chatId: string, pubKey: string): RpcResponse[JsonNode] {.raises: [Exception].} =
let payload = %* [nil, chatId, [pubKey]]
result = callPrivateRPC("addAdminsToGroupChat".prefix, payload)
proc createGroupChat*(groupName: string, pubKeys: seq[string]): RpcResponse[JsonNode] {.raises: [Exception].} =
let payload = %* [nil, groupName, pubKeys]
result = callPrivateRPC("createGroupChatWithMembers".prefix, payload)
proc confirmJoiningGroup*(chatId: string): RpcResponse[JsonNode] {.raises: [Exception].} =
let payload = %* [chatId]
result = callPrivateRPC("confirmJoiningGroup".prefix, payload)
proc createGroupChatFromInvitation*(groupName: string, chatId: string, adminPK: string): RpcResponse[JsonNode] {.raises: [Exception].} =
let payload = %* [groupName, chatId, adminPK]
result = callPrivateRPC("createGroupChatFromInvitation".prefix, payload)
proc getLinkPreviewData*(link: string): RpcResponse[JsonNode] {.raises: [Exception].} =
result = callPrivateRPC("getLinkPreviewData".prefix, %* [link])

View File

@ -0,0 +1,21 @@
import json
import core, utils
import response_type
proc acceptRequestAddressForTransaction*(messageId: string, address: string): RpcResponse[JsonNode] {.raises: [Exception].} =
callPrivateRPC("acceptRequestAddressForTransaction".prefix, %* [messageId, address])
proc declineRequestAddressForTransaction*(messageId: string): RpcResponse[JsonNode] {.raises: [Exception].} =
callPrivateRPC("declineRequestAddressForTransaction".prefix, %* [messageId])
proc declineRequestTransaction*(messageId: string): RpcResponse[JsonNode] {.raises: [Exception].} =
callPrivateRPC("declineRequestTransaction".prefix, %* [messageId])
proc requestAddressForTransaction*(chatId: string, fromAddress: string, amount: string, tokenAddress: string): RpcResponse[JsonNode] {.raises: [Exception].} =
callPrivateRPC("requestAddressForTransaction".prefix, %* [chatId, fromAddress, amount, tokenAddress])
proc requestTransaction*(chatId: string, fromAddress: string, amount: string, tokenAddress: string): RpcResponse[JsonNode] {.raises: [Exception].} =
callPrivateRPC("requestTransaction".prefix, %* [chatId, amount, tokenAddress, fromAddress])
proc acceptRequestTransaction*(transactionHash: string, messageId: string, signature: string): RpcResponse[JsonNode] {.raises: [Exception].} =
callPrivateRPC("acceptRequestTransaction".prefix, %* [transactionHash, messageId, signature])

View File

@ -0,0 +1,14 @@
import json
import ./core, ./response_type
export response_type
proc getOpenseaCollections*(chainId: int, address: string): RpcResponse[JsonNode] =
let payload = %* [chainId, address]
return callPrivateRPC("wallet_getOpenseaCollectionsByOwner", payload)
proc getOpenseaAssets*(
chainId: int, address: string, collectionSlug: string, limit: int
): RpcResponse[JsonNode] =
let payload = %* [chainId, address, collectionSlug, limit]
return callPrivateRPC("wallet_getOpenseaAssetsByOwnerAndCollection", payload)

234
src/backend/communities.nim Normal file
View File

@ -0,0 +1,234 @@
import json, strutils
import core, utils
import response_type
export response_type
proc getJoinedComunities*(): RpcResponse[JsonNode] {.raises: [Exception].} =
let payload = %* []
result = callPrivateRPC("joinedCommunities".prefix, payload)
proc getAllCommunities*(): RpcResponse[JsonNode] {.raises: [Exception].} =
result = callPrivateRPC("communities".prefix)
proc joinCommunity*(communityId: string): RpcResponse[JsonNode] {.raises: [Exception].} =
result = callPrivateRPC("joinCommunity".prefix, %*[communityId])
proc requestToJoinCommunity*(communityId: string, ensName: string): RpcResponse[JsonNode] {.raises: [Exception].} =
result = callPrivateRPC("requestToJoinCommunity".prefix, %*[{
"communityId": communityId,
"ensName": ensName
}])
proc myPendingRequestsToJoin*(): RpcResponse[JsonNode] {.raises: [Exception].} =
result = callPrivateRPC("myPendingRequestsToJoin".prefix)
proc pendingRequestsToJoinForCommunity*(communityId: string): RpcResponse[JsonNode] {.raises: [Exception].} =
result = callPrivateRPC("pendingRequestsToJoinForCommunity".prefix, %*[communityId])
proc leaveCommunity*(communityId: string): RpcResponse[JsonNode] {.raises: [Exception].} =
result = callPrivateRPC("leaveCommunity".prefix, %*[communityId])
proc createCommunity*(
name: string,
description: string,
access: int,
ensOnly: bool,
color: string,
imageUrl: string,
aX: int, aY: int, bX: int, bY: int
): RpcResponse[JsonNode] {.raises: [Exception].} =
result = callPrivateRPC("createCommunity".prefix, %*[{
# TODO this will need to be renamed membership (small m)
"Membership": access,
"name": name,
"description": description,
"ensOnly": ensOnly,
"color": color,
"image": imageUrl,
"imageAx": aX,
"imageAy": aY,
"imageBx": bX,
"imageBy": bY
}])
proc editCommunity*(
communityId: string,
name: string,
description: string,
access: int,
ensOnly: bool,
color: string,
imageUrl: string,
aX: int,
aY: int,
bX: int,
bY: int
): RpcResponse[JsonNode] {.raises: [Exception].} =
result = callPrivateRPC("editCommunity".prefix, %*[{
# TODO this will need to be renamed membership (small m)
"CommunityID": communityId,
"Membership": access,
"name": name,
"description": description,
"ensOnly": ensOnly,
"color": color,
"image": imageUrl,
"imageAx": aX,
"imageAy": aY,
"imageBx": bX,
"imageBy": bY
}])
proc createCommunityChannel*(
communityId: string,
name: string,
description: string,
categoryId: string
): RpcResponse[JsonNode] {.raises: [Exception].} =
result = callPrivateRPC("createCommunityChat".prefix, %*[
communityId,
{
"permissions": {
"access": 1 # TODO get this from user selected privacy setting
},
"identity": {
"display_name": name,
"description": description#,
# "color": color#,
# TODO add images once it is supported by Status-Go
# "images": [
# {
# "payload": image,
# # TODO get that from an enum
# "image_type": 1 # 1 is a raw payload
# }
# ]
},
"category_id": categoryId
}])
proc editCommunityChannel*(
communityId: string,
channelId: string,
name: string,
description: string,
categoryId: string,
position: int
): RpcResponse[JsonNode] {.raises: [Exception].} =
result = callPrivateRPC("editCommunityChat".prefix, %*[
communityId,
channelId.replace(communityId, ""),
{
"permissions": {
"access": 1 # TODO get this from user selected privacy setting
},
"identity": {
"display_name": name,
"description": description#,
# "color": color#,
# TODO add images once it is supported by Status-Go
# "images": [
# {
# "payload": image,
# # TODO get that from an enum
# "image_type": 1 # 1 is a raw payload
# }
# ]
},
"category_id": categoryId,
"position": position
}])
proc reorderCommunityChat*(
communityId: string,
categoryId: string,
chatId: string,
position: int
): RpcResponse[JsonNode] {.raises: [Exception].} =
result = callPrivateRPC("reorderCommunityChat".prefix, %*[
{
"communityId": communityId,
"categoryId": categoryId,
"chatId": chatId,
"position": position
}])
proc deleteCommunityChat*(
communityId: string,
chatId: string
): RpcResponse[JsonNode] {.raises: [Exception].} =
result = callPrivateRPC("deleteCommunityChat".prefix, %*[communityId, chatId])
proc createCommunityCategory*(
communityId: string,
name: string,
channels: seq[string]
): RpcResponse[JsonNode] {.raises: [Exception].} =
result = callPrivateRPC("createCommunityCategory".prefix, %*[
{
"communityId": communityId,
"categoryName": name,
"chatIds": channels
}])
proc editCommunityCategory*(
communityId: string,
categoryId: string,
name: string,
channels: seq[string]
): RpcResponse[JsonNode] {.raises: [Exception].} =
result = callPrivateRPC("editCommunityCategory".prefix, %*[
{
"communityId": communityId,
"categoryId": categoryId,
"categoryName": name,
"chatIds": channels
}])
proc deleteCommunityCategory*(
communityId: string,
categoryId: string
): RpcResponse[JsonNode] {.raises: [Exception].} =
result = callPrivateRPC("deleteCommunityCategory".prefix, %*[
{
"communityId": communityId,
"categoryId": categoryId
}])
proc requestCommunityInfo*(communityId: string): RpcResponse[JsonNode] {.raises: [Exception].} =
result = callPrivateRPC("requestCommunityInfoFromMailserver".prefix, %*[communityId])
proc importCommunity*(communityKey: string): RpcResponse[JsonNode] {.raises: [Exception].} =
result = callPrivateRPC("importCommunity".prefix, %*[communityKey])
proc exportCommunity*(communityId: string): RpcResponse[JsonNode] {.raises: [Exception].} =
result = callPrivateRPC("exportCommunity".prefix, %*[communityId])
proc removeUserFromCommunity*(communityId: string, pubKey: string): RpcResponse[JsonNode] {.raises: [Exception].} =
result = callPrivateRPC("removeUserFromCommunity".prefix, %*[communityId, pubKey])
proc acceptRequestToJoinCommunity*(requestId: string): RpcResponse[JsonNode] {.raises: [Exception].} =
return callPrivateRPC("acceptRequestToJoinCommunity".prefix, %*[{
"id": requestId
}])
proc declineRequestToJoinCommunity*(requestId: string): RpcResponse[JsonNode] {.raises: [Exception].} =
return callPrivateRPC("declineRequestToJoinCommunity".prefix, %*[{
"id": requestId
}])
proc banUserFromCommunity*(communityId: string, pubKey: string): RpcResponse[JsonNode] {.raises: [Exception].} =
return callPrivateRPC("banUserFromCommunity".prefix, %*[{
"communityId": communityId,
"user": pubKey
}])
proc setCommunityMuted*(communityId: string, muted: bool): RpcResponse[JsonNode] {.raises: [Exception].} =
return callPrivateRPC("setCommunityMuted".prefix, %*[communityId, muted])
proc inviteUsersToCommunity*(communityId: string, pubKeys: seq[string]): RpcResponse[JsonNode] {.raises: [Exception].} =
return callPrivateRPC("inviteUsersToCommunity".prefix, %*[{
"communityId": communityId,
"users": pubKeys
}])

47
src/backend/contacts.nim Normal file
View File

@ -0,0 +1,47 @@
import json, strmisc
import core, utils
import response_type
export response_type
proc getContacts*(): RpcResponse[JsonNode] {.raises: [Exception].} =
let payload = %* []
result = callPrivateRPC("contacts".prefix, payload)
proc getContactById*(id: string): RpcResponse[JsonNode] {.raises: [Exception].} =
let payload = %* [id]
result = callPrivateRPC("getContactByID".prefix, payload)
proc blockContact*(id: string): RpcResponse[JsonNode] {.raises: [Exception].} =
result = callPrivateRPC("blockContact".prefix, %* [id])
proc unblockContact*(id: string): RpcResponse[JsonNode] {.raises: [Exception].} =
result = callPrivateRPC("unblockContact".prefix, %* [id])
proc removeContact*(id: string): RpcResponse[JsonNode] {.raises: [Exception].} =
result = callPrivateRPC("removeContact".prefix, %* [id])
proc rejectContactRequest*(id: string): RpcResponse[JsonNode] {.raises: [Exception].} =
let payload = %*[{
"id": id
}]
result = callPrivateRPC("rejectContactRequest".prefix, payload)
proc setContactLocalNickname*(id: string, name: string): RpcResponse[JsonNode] {.raises: [Exception].} =
let payload = %* [{
"id": id,
"nickname": name
}]
result = callPrivateRPC("setContactLocalNickname".prefix, payload)
proc addContact*(id: string, ensName: string): RpcResponse[JsonNode] {.raises: [Exception].} =
let payload = %* [{
"id": id,
"ensName": ensName
}]
result = callPrivateRPC("addContact".prefix, payload)
proc sendContactUpdate*(publicKey, ensName, thumbnail: string): RpcResponse[JsonNode] {.raises: [Exception].} =
let payload = %* [publicKey, ensName, thumbnail]
result = callPrivateRPC("sendContactUpdate".prefix, payload)

55
src/backend/core.nim Normal file
View File

@ -0,0 +1,55 @@
import json, json_serialization, strformat, chronicles, nimcrypto
import status_go
import response_type
export response_type
logScope:
topics = "rpc"
proc callRPC*(inputJSON: string): string =
return $status_go.callRPC(inputJSON)
proc callPrivateRPCRaw*(inputJSON: string): string {.raises: [].} =
result = $status_go.callPrivateRPC(inputJSON)
proc callPrivateRPC*(methodName: string, payload = %* []): RpcResponse[JsonNode]
{.raises: [RpcException, ValueError, Defect, SerializationError].} =
try:
let inputJSON = %* {
"jsonrpc": "2.0",
"method": methodName,
"params": %payload
}
debug "NewBE_callPrivateRPC", rpc_method=methodName
let rpcResponseRaw = status_go.callPrivateRPC($inputJSON)
result = Json.decode(rpcResponseRaw, RpcResponse[JsonNode])
if(not result.error.isNil):
var err = "\nstatus-go error ["
err &= fmt"methodName:{methodName}, "
err &= fmt"code:{result.error.code}, "
err &= fmt"message:{result.error.message} "
err &= "]\n"
error "rpc response error", err
raise newException(ValueError, err)
except RpcException as e:
error "error doing rpc request", methodName = methodName, exception=e.msg
raise newException(RpcException, e.msg)
proc signMessage*(rpcParams: string): string =
return $status_go.signMessage(rpcParams)
proc signTypedData*(data: string, address: string, password: string): string =
return $status_go.signTypedData(data, address, password)
proc sendTransaction*(inputJSON: string, password: string): RpcResponse[JsonNode]
{.raises: [RpcException, ValueError, Defect, SerializationError].} =
try:
var hashed_password = "0x" & $keccak_256.digest(password)
let rpcResponseRaw = status_go.sendTransaction(inputJSON, hashed_password)
result = Json.decode(rpcResponseRaw, RpcResponse[JsonNode])
except RpcException as e:
error "error sending tx", inputJSON, exception=e.msg
raise newException(RpcException, e.msg)

View File

@ -0,0 +1,15 @@
import json
import ./core, ./response_type
export response_type
proc getCustomTokens*(): RpcResponse[JsonNode] {.raises: [Exception].} =
return callPrivateRPC("wallet_getCustomTokens", %* [])
proc addCustomToken*(address: string, name: string, symbol: string, decimals: int, color: string) {.raises: [Exception].} =
discard callPrivateRPC("wallet_addCustomToken", %* [
{"address": address, "name": name, "symbol": symbol, "decimals": decimals, "color": color}
])
proc removeCustomToken*(address: string) {.raises: [Exception].} =
discard callPrivateRPC("wallet_deleteCustomToken", %* [address])

216
src/backend/ens.nim Normal file
View File

@ -0,0 +1,216 @@
import sequtils
import strutils
import nimcrypto
import json
import json_serialization
import tables
import stew/byteutils
import web3/[ethtypes, conversions], stint
import chronicles, libp2p/[multihash, multicodec, cid]
import ./statusgo_backend/wallet
import ./statusgo_backend/accounts as status_accounts
import ./statusgo_backend/settings as status_settings
import ./statusgo_backend_new/ens as status_ens
import ./types/[transaction, setting, rpc_response, network_type, network, profile]
import ./utils
import ./transactions
import ./eth/contracts
const domain* = ".stateofus.eth"
proc userName*(ensName: string, removeSuffix: bool = false): string =
if ensName != "" and ensName.endsWith(domain):
if removeSuffix:
result = ensName.split(".")[0]
else:
result = ensName
else:
if ensName.endsWith(".eth") and removeSuffix:
return ensName.split(".")[0]
result = ensName
proc addDomain*(username: string): string =
if username.endsWith(".eth"):
return username
else:
return username & domain
proc hasNickname*(contact: Profile): bool = contact.localNickname != ""
proc userNameOrAlias*(contact: Profile, removeSuffix: bool = false): string =
if(contact.ensName != "" and contact.ensVerified):
result = "@" & userName(contact.ensName, removeSuffix)
elif(contact.localNickname != ""):
result = contact.localNickname
else:
result = contact.alias
proc resolver*(username: string): string =
let chainId = status_settings.getCurrentNetwork().toChainId()
let res = status_ens.resolver(chainId, username)
return res.result.getStr
proc owner*(username: string): string =
let chainId = status_settings.getCurrentNetwork().toChainId()
let res = status_ens.ownerOf(chainId, username)
let address = res.result.getStr
if address == "0x0000000000000000000000000000000000000000":
return ""
return address
proc pubkey*(username: string): string =
try:
let chainId = status_settings.getCurrentNetwork().toChainId()
let res = status_ens.publicKeyOf(chainId, addDomain(username))
var key = res.result.getStr
key.removePrefix("0x")
return "0x04" & key
except:
return ""
proc address*(username: string): string =
let chainId = status_settings.getCurrentNetwork().toChainId()
let res = status_ens.addressOf(chainId, username)
return res.result.getStr
proc contenthash*(username: string): string =
let chainId = status_settings.getCurrentNetwork().toChainId()
let res = status_ens.contentHash(chainId, username)
return res.result.getStr
proc getPrice*(): Stuint[256] =
let chainId = status_settings.getCurrentNetwork().toChainId()
let res = status_ens.price(chainId)
return fromHex(Stuint[256], res.result.getStr)
proc releaseEstimateGas*(username: string, address: string, success: var bool): int =
let
chainId = status_settings.getCurrentNetwork().toChainId()
txData = transactions.buildTransaction(parseAddress(address), 0.u256)
try:
let resp = status_ens.releaseEstimate(chainId, txData, username)
result = resp.result.getInt
success = true
except:
success = false
result = 0
proc release*(username: string, address: string, gas, gasPrice, password: string, success: var bool): string =
let
chainId = status_settings.getCurrentNetwork().toChainId()
txData = transactions.buildTransaction(
parseAddress(address), 0.u256, gas, gasPrice
)
try:
let resp = status_ens.release(chainId, txData, password, username)
result = resp.result.getStr
success = true
let ensUsernamesContract = contracts.findContract(chainId, "ens-usernames")
trackPendingTransaction(result, address, $ensUsernamesContract.address, PendingTransactionType.ReleaseENS, username)
except:
success = false
result = "failed to release the username"
proc getExpirationTime*(username: string, success: var bool): int =
let chainId = status_settings.getCurrentNetwork().toChainId()
let res = status_ens.expireAt(chainId, username)
return fromHex[int](res.result.getStr)
proc registerUsernameEstimateGas*(username: string, address: string, pubKey: string, success: var bool): int =
let
chainId = status_settings.getCurrentNetwork().toChainId()
txData = transactions.buildTransaction(parseAddress(address), 0.u256)
try:
let resp = status_ens.registerEstimate(chainId, txData, username, pubkey)
result = resp.result.getInt
success = true
except:
success = false
result = 0
proc registerUsername*(username, pubKey, address, gas, gasPrice: string, isEIP1559Enabled: bool, maxPriorityFeePerGas: string, maxFeePerGas: string, password: string, success: var bool): string =
let
network = status_settings.getCurrentNetwork().toNetwork()
chainId = network.chainId
txData = transactions.buildTransaction(
parseAddress(address), 0.u256, gas, gasPrice, isEIP1559Enabled, maxPriorityFeePerGas, maxFeePerGas
)
try:
let resp = status_ens.register(chainId, txData, password, username, pubkey)
result = resp.result.getStr
success = true
let sntContract = contracts.findErc20Contract(chainId, network.sntSymbol())
trackPendingTransaction(result, address, $sntContract.address, PendingTransactionType.RegisterEns, username & domain)
except:
success = false
result = "failed to register the username"
proc setPubKeyEstimateGas*(username: string, address: string, pubKey: string, success: var bool): int =
let
chainId = status_settings.getCurrentNetwork().toChainId()
txData = transactions.buildTransaction(parseAddress(address), 0.u256)
try:
let resp = status_ens.setPubKeyEstimate(chainId, txData, username, pubkey)
result = resp.result.getInt
success = true
except:
success = false
result = 0
proc setPubKey*(username, pubKey, address, gas, gasPrice: string, isEIP1559Enabled: bool, maxPriorityFeePerGas: string, maxFeePerGas: string, password: string, success: var bool): string =
let
chainId = status_settings.getCurrentNetwork().toChainId()
txData = transactions.buildTransaction(
parseAddress(address), 0.u256, gas, gasPrice, isEIP1559Enabled, maxPriorityFeePerGas, maxFeePerGas
)
try:
let resp = status_ens.setPubKey(chainId, txData, password, username, pubkey)
result = resp.result.getStr
success = true
let resolverAddress = resolver(username)
trackPendingTransaction(result, $address, resolverAddress, PendingTransactionType.SetPubKey, username)
except:
success = false
result = "failed to set the pubkey"
proc statusRegistrarAddress*():string =
let network = status_settings.getCurrentNetwork().toNetwork()
let contract = contracts.findContract(network.chainId, "ens-usernames")
if contract != nil:
return $contract.address
result = ""
proc validateEnsName*(ens: string, isStatus: bool, usernames: seq[string]): string =
var username = ens & (if(isStatus): domain else: "")
result = ""
if usernames.filter(proc(x: string):bool = x == username).len > 0:
result = "already-connected"
else:
let ownerAddr = owner(username)
if ownerAddr == "" and isStatus:
result = "available"
else:
let userPubKey = status_settings.getSetting[string](Setting.PublicKey, "0x0")
let userWallet = status_accounts.getWalletAccounts()[0].address
let ens_pubkey = pubkey(ens)
if ownerAddr != "":
if ens_pubkey == "" and ownerAddr == userWallet:
result = "owned" # "Continuing will connect this username with your chat key."
elif ens_pubkey == userPubkey:
result = "connected"
elif ownerAddr == userWallet:
result = "connected-different-key" # "Continuing will require a transaction to connect the username with your current chat key.",
else:
result = "taken"
else:
result = "taken"

39
src/backend/eth.nim Normal file
View File

@ -0,0 +1,39 @@
import json, strutils, strformat
import ./core, ./response_type
export response_type
proc getAccounts*(): RpcResponse[JsonNode] {.raises: [Exception].} =
return core.callPrivateRPC("eth_accounts")
proc getBlockByNumber*(blockNumber: string): RpcResponse[JsonNode] {.raises: [Exception].} =
let payload = %* [blockNumber, false]
return core.callPrivateRPC("eth_getBlockByNumber", payload)
proc getEthBalance*(address: string): RpcResponse[JsonNode] {.raises: [Exception].} =
let payload = %* [address, "latest"]
return core.callPrivateRPC("eth_getBalance", payload)
proc getTokenBalance*(tokenAddress: string, accountAddress: string): RpcResponse[JsonNode] {.raises: [Exception].} =
var postfixedAccount: string = accountAddress
postfixedAccount.removePrefix("0x")
let payload = %* [{
"to": tokenAddress, "from": accountAddress, "data": fmt"0x70a08231000000000000000000000000{postfixedAccount}"
}, "latest"]
return core.callPrivateRPC("eth_call", payload)
proc sendTransaction*(transactionData: string, password: string): RpcResponse[JsonNode] {.raises: [Exception].} =
core.sendTransaction(transactionData, password)
# This is the replacement of the `call` function
proc doEthCall*(payload = %* []): RpcResponse[JsonNode] {.raises: [Exception].} =
core.callPrivateRPC("eth_call", payload)
proc estimateGas*(payload = %* []): RpcResponse[JsonNode] {.raises: [Exception].} =
core.callPrivateRPC("eth_estimateGas", payload)
proc getEthAccounts*(): RpcResponse[JsonNode] {.raises: [Exception].} =
return core.callPrivateRPC("eth_accounts")
proc getGasPrice*(payload = %* []): RpcResponse[JsonNode] {.raises: [Exception].} =
return core.callPrivateRPC("eth_gasPrice", payload)

47
src/backend/general.nim Normal file
View File

@ -0,0 +1,47 @@
import json, strutils, json_serialization, chronicles
import core, utils
import response_type
import status_go
export response_type
logScope:
topics = "rpc-general"
proc validateMnemonic*(mnemonic: string): RpcResponse[JsonNode] {.raises: [Exception].} =
try:
let response = status_go.validateMnemonic(mnemonic.strip())
result.result = Json.decode(response, JsonNode)
except RpcException as e:
error "error doing rpc request", methodName = "validateMnemonic", exception=e.msg
raise newException(RpcException, e.msg)
proc startMessenger*(): RpcResponse[JsonNode] {.raises: [Exception].} =
let payload = %* []
result = core.callPrivateRPC("startMessenger".prefix, payload)
proc generateSymKeyFromPassword*(password: string): RpcResponse[JsonNode] {.raises: [Exception].} =
let payload = %* [password]
result = core.callPrivateRPC("waku_generateSymKeyFromPassword", payload)
proc adminPeers*(): RpcResponse[JsonNode] {.raises: [Exception].} =
let payload = %* []
result = core.callPrivateRPC("admin_peers", payload)
proc wakuV2Peers*(): RpcResponse[JsonNode] {.raises: [Exception].} =
let payload = %* []
result = core.callPrivateRPC("peers".prefix, payload)
proc dialPeer*(address: string): RpcResponse[JsonNode] {.raises: [Exception].} =
let payload = %* [address]
result = core.callPrivateRPC("dialPeer".prefix, payload)
proc dropPeerByID*(peer: string): RpcResponse[JsonNode] {.raises: [Exception].} =
let payload = %* [peer]
result = core.callPrivateRPC("dropPeer".prefix, payload)
proc removePeer*(peer: string): RpcResponse[JsonNode] {.raises: [Exception].} =
let payload = %* [peer]
result = core.callPrivateRPC("admin_removePeer", payload)

33
src/backend/gif.nim Normal file
View File

@ -0,0 +1,33 @@
import json, strutils, chronicles, core
import response_type
import status_go
export response_type
logScope:
topics = "rpc-gif"
proc setTenorAPIKey*(key: string): RpcResponse[JsonNode] {.raises: [Exception].} =
let payload = %* [key]
result = core.callPrivateRPC("gif_setTenorAPIKey", payload)
proc fetchGifs*(path: string): RpcResponse[JsonNode] {.raises: [Exception].} =
let payload = %* [path]
result = core.callPrivateRPC("gif_fetchGifs", payload)
proc updateRecentGifs*(recentGifs: JsonNode): RpcResponse[JsonNode] {.raises: [Exception].} =
let payload = %* [recentGifs]
return core.callPrivateRPC("gif_updateRecentGifs", payload)
proc updateFavoriteGifs*(favoriteGifs: JsonNode): RpcResponse[JsonNode] {.raises: [Exception].} =
let payload = %* [favoriteGifs]
return core.callPrivateRPC("gif_updateFavoriteGifs", payload)
proc getRecentGifs*(): RpcResponse[JsonNode] {.raises: [Exception].} =
let payload = %* []
return core.callPrivateRPC("gif_getRecentGifs", payload)
proc getFavoriteGifs*(): RpcResponse[JsonNode] {.raises: [Exception].} =
let payload = %* []
return core.callPrivateRPC("gif_getFavoriteGifs", payload)

View File

@ -0,0 +1,32 @@
import json
import core, utils
import response_type
export response_type
proc setInstallationMetadata*(installationId: string, deviceName: string, deviceType: string):
RpcResponse[JsonNode] {.raises: [Exception].} =
let payload = %* [installationId, {
"name": deviceName,
"deviceType": deviceType
}]
result = callPrivateRPC("setInstallationMetadata".prefix, payload)
proc getOurInstallations*(): RpcResponse[JsonNode] {.raises: [Exception].} =
let payload = %* []
result = callPrivateRPC("getOurInstallations".prefix, payload)
proc syncDevices*(preferredName: string, photoPath: string): RpcResponse[JsonNode] {.raises: [Exception].} =
let payload = %* [preferredName, photoPath]
result = callPrivateRPC("syncDevices".prefix, payload)
proc sendPairInstallation*(): RpcResponse[JsonNode] {.raises: [Exception].} =
result = callPrivateRPC("sendPairInstallation".prefix)
proc enableInstallation*(installationId: string): RpcResponse[JsonNode] {.raises: [Exception].} =
let payload = %* [installationId]
result = callPrivateRPC("enableInstallation".prefix, payload)
proc disableInstallation*(installationId: string): RpcResponse[JsonNode] {.raises: [Exception].} =
let payload = %* [installationId]
result = callPrivateRPC("disableInstallation".prefix, payload)

13
src/backend/keycard.nim Normal file
View File

@ -0,0 +1,13 @@
import json, strutils, chronicles
import core, utils
import response_type
import status_go
export response_type
logScope:
topics = "rpc-keystore"
proc initKeycard*(keystoreDir: string): RpcResponse[JsonNode] {.raises: [Exception].} =
result.result = newJString($status_go.initKeystore(keystoreDir))

View File

@ -0,0 +1,41 @@
import json, chronicles
import core, utils
import response_type
export response_type
logScope:
topics = "mailserver"
proc saveMailserver*(id: string, name: string, enode: string, fleet: string):
RpcResponse[JsonNode] {.raises: [Exception].} =
let payload = %* [{
"id": id,
"name": name,
"address": enode,
"fleet": fleet
}]
result = core.callPrivateRPC("mailservers_addMailserver", payload)
proc getMailservers*(): RpcResponse[JsonNode] {.raises: [Exception].} =
result = core.callPrivateRPC("mailservers_getMailservers")
proc requestAllHistoricMessages*(): RpcResponse[JsonNode] {.raises: [Exception].} =
let payload = %* []
result = core.callPrivateRPC("requestAllHistoricMessages".prefix, payload)
info "requestAllHistoricMessages", topics="mailserver-interaction", rpc_method="mailservers_requestAllHistoricMessages"
proc syncChatFromSyncedFrom*(chatId: string): RpcResponse[JsonNode] {.raises: [Exception].} =
let payload = %*[chatId]
result = core.callPrivateRPC("syncChatFromSyncedFrom".prefix, payload)
info "syncChatFromSyncedFrom", topics="mailserver-interaction", rpc_method="wakuext_syncChatFromSyncedFrom", chatId, result
proc fillGaps*(chatId: string, messageIds: seq[string]): RpcResponse[JsonNode] {.raises: [Exception].} =
let payload = %*[chatId, messageIds]
result = core.callPrivateRPC("fillGaps".prefix, payload)
info "fillGaps", topics="mailserver-interaction", rpc_method="wakuext_fillGaps", chatId, messageIds, result
proc disconnectActiveMailserver*(): RpcResponse[JsonNode] {.raises: [Exception].} =
let payload = %* []
result = core.callPrivateRPC("disconnectActiveMailserver".prefix, payload)
info "delete", topics="mailserver-interaction", rpc_method="wakuext_disconnectActiveMailserver", result

66
src/backend/messages.nim Normal file
View File

@ -0,0 +1,66 @@
import json
import core, utils
import response_type
export response_type
proc fetchMessages*(chatId: string, cursorVal: string, limit: int): RpcResponse[JsonNode] {.raises: [Exception].} =
let payload = %* [chatId, cursorVal, limit]
result = callPrivateRPC("chatMessages".prefix, payload)
proc fetchPinnedMessages*(chatId: string, cursorVal: string, limit: int): RpcResponse[JsonNode] {.raises: [Exception].} =
let payload = %* [chatId, cursorVal, limit]
result = callPrivateRPC("chatPinnedMessages".prefix, payload)
proc fetchReactions*(chatId: string, cursorVal: string, limit: int): RpcResponse[JsonNode] {.raises: [Exception].} =
let payload = %* [chatId, cursorVal, limit]
result = callPrivateRPC("emojiReactionsByChatID".prefix, payload)
proc addReaction*(chatId: string, messageId: string, emojiId: int): RpcResponse[JsonNode] {.raises: [Exception].} =
let payload = %* [chatId, messageId, emojiId]
result = callPrivateRPC("sendEmojiReaction".prefix, payload)
proc removeReaction*(reactionId: string): RpcResponse[JsonNode] {.raises: [Exception].} =
let payload = %* [reactionId]
result = callPrivateRPC("sendEmojiReactionRetraction".prefix, payload)
proc pinUnpinMessage*(chatId: string, messageId: string, pin: bool): RpcResponse[JsonNode] {.raises: [Exception].} =
let payload = %*[{
"message_id": messageId,
"pinned": pin,
"chat_id": chatId
}]
result = callPrivateRPC("sendPinMessage".prefix, payload)
proc fetchMessageByMessageId*(messageId: string): RpcResponse[JsonNode] {.raises: [Exception].} =
let payload = %* [messageId]
result = callPrivateRPC("messageByMessageID".prefix, payload)
proc fetchReactionsForMessageWithId*(chatId: string, messageId: string): RpcResponse[JsonNode] {.raises: [Exception].} =
let payload = %* [chatId, messageId]
result = callPrivateRPC("emojiReactionsByChatIDMessageID".prefix, payload)
proc fetchAllMessagesFromChatWhichMatchTerm*(chatId: string, searchTerm: string, caseSensitive: bool):
RpcResponse[JsonNode] {.raises: [Exception].} =
let payload = %* [chatId, searchTerm, caseSensitive]
result = callPrivateRPC("allMessagesFromChatWhichMatchTerm".prefix, payload)
proc fetchAllMessagesFromChatsAndCommunitiesWhichMatchTerm*(communityIds: seq[string], chatIds: seq[string],
searchTerm: string, caseSensitive: bool): RpcResponse[JsonNode] {.raises: [Exception].} =
let payload = %* [communityIds, chatIds, searchTerm, caseSensitive]
result = callPrivateRPC("allMessagesFromChatsAndCommunitiesWhichMatchTerm".prefix, payload)
proc markAllMessagesFromChatWithIdAsRead*(chatId: string): RpcResponse[JsonNode] {.raises: [Exception].} =
let payload = %* [chatId]
result = callPrivateRPC("markAllRead".prefix, payload)
proc markCertainMessagesFromChatWithIdAsRead*(chatId: string, messageIds: seq[string]):
RpcResponse[JsonNode] {.raises: [Exception].} =
let payload = %* [chatId, messageIds]
result = callPrivateRPC("markMessagesSeen".prefix, payload)
proc deleteMessageAndSend*(messageID: string): RpcResponse[JsonNode] {.raises: [Exception].} =
result = callPrivateRPC("deleteMessageAndSend".prefix, %* [messageID])
proc editMessage*(messageId: string, msg: string): RpcResponse[JsonNode] {.raises: [Exception].} =
result = callPrivateRPC("editMessage".prefix, %* [{"id": messageId, "text": msg}])

12
src/backend/network.nim Normal file
View File

@ -0,0 +1,12 @@
import json
import ./core, ./response_type
proc getNetworks*(payload: JsonNode): RpcResponse[JsonNode] {.raises: [Exception].} =
core.callPrivateRPC("wallet_getEthereumChains", payload)
proc upsertNetwork*(payload: JsonNode): RpcResponse[JsonNode] {.raises: [Exception].} =
core.callPrivateRPC("wallet_addEthereumChain", payload)
proc deleteNetwork*(payload: JsonNode): RpcResponse[JsonNode] {.raises: [Exception].} =
core.callPrivateRPC("wallet_deleteEthereumChain", payload)

20
src/backend/node.nim Normal file
View File

@ -0,0 +1,20 @@
import json
import core, utils
import response_type
export response_type
proc adminPeers*(): RpcResponse[JsonNode] {.raises: [Exception].} =
let payload = %* []
result = callPrivateRPC("admin_peers", payload)
proc wakuV2Peers*(): RpcResponse[JsonNode] {.raises: [Exception].} =
let payload = %* []
result = callPrivateRPC("peers", payload)
proc sendRPCMessageRaw*(inputJSON: string): string {.raises: [Exception].} =
result = callPrivateRPCRaw(inputJSON)
proc getBloomFilter*(): RpcResponse[JsonNode] {.raises: [Exception].} =
let payload = %* []
result = callPrivateRPC("bloomFilter".prefix, payload)

View File

@ -0,0 +1,19 @@
import json, json_serialization, chronicles
import ./core
import ./response_type
import status_go
export response_type
logScope:
topics = "rpc-node-config"
proc getNodeConfig*(): RpcResponse[JsonNode] {.raises: [Exception].} =
try:
let response = status_go.getNodeConfig()
result.result = response.parseJSON()
except RpcException as e:
error "error doing rpc request", methodName = "getNodeConfig", exception=e.msg
raise newException(RpcException, e.msg)

View File

@ -0,0 +1,20 @@
import json, strmisc
import core, utils
import response_type
export response_type
proc getDappPermissions*(): RpcResponse[JsonNode] {.raises: [Exception].} =
let payload = %* []
result = callPrivateRPC("permissions_getDappPermissions", payload)
proc addDappPermissions*(dapp: string, permissions: seq[string]): RpcResponse[JsonNode] {.raises: [Exception].} =
let payload = %*[{
"dapp": dapp,
"permissions": permissions
}]
result = callPrivateRPC("permissions_addDappPermissions", payload)
proc deleteDappPermissions*(dapp: string): RpcResponse[JsonNode] {.raises: [Exception].} =
let payload = %* [dapp]
result = callPrivateRPC("permissions_deleteDappPermissions", payload)

25
src/backend/privacy.nim Normal file
View File

@ -0,0 +1,25 @@
import json, json_serialization, chronicles
import core, utils
import response_type
import status_go
export response_type
logScope:
topics = "rpc-privacy"
proc changeDatabasePassword*(keyUID: string, password: string, newPassword: string): RpcResponse[JsonNode]
{.raises: [Exception].} =
try:
let hashedPassword = hashPassword(password)
let hashedNewPassword = hashPassword(newPassword)
let response = status_go.changeDatabasePassword(keyUID, hashedPassword, hashedNewPassword)
result.result = Json.decode(response, JsonNode)
except RpcException as e:
error "error", methodName = "changeDatabasePassword", exception=e.msg
raise newException(RpcException, e.msg)
proc getLinkPreviewWhitelist*(): RpcResponse[JsonNode] {.raises: [Exception].} =
let payload = %* []
result = callPrivateRPC("getLinkPreviewWhitelist".prefix, payload)

13
src/backend/provider.nim Normal file
View File

@ -0,0 +1,13 @@
import json, json_serialization, strformat, chronicles
import status_go
import ./utils
import ./core
logScope:
topics = "provider"
proc providerRequest*(requestType: string, message:string): RpcResponse[JsonNode] =
let jsonMessage = message.parseJson
if requestType == "web3-send-async-read-only" and jsonMessage.hasKey("payload") and jsonMessage["payload"].hasKey("password"):
jsonMessage["payload"]["password"] = newJString(hashPassword(jsonMessage["payload"]["password"].getStr()))
callPrivateRPC("provider_processRequest", %*[requestType, jsonMessage])

View File

@ -0,0 +1,24 @@
{.used.}
import strformat
type
RpcException* = object of CatchableError
type
RpcError* = ref object
code*: int
message*: string
type
RpcResponse*[T] = object
jsonrpc*: string
result*: T
id*: int
error*: RpcError
proc `$`*(self: RpcError): string =
result = fmt"""RpcError(
code: {self.code},
message: {self.message},
]"""

View File

@ -0,0 +1,16 @@
import json
import ./core, ./response_type
export response_type
proc addSavedAddress*(name, address: string): RpcResponse[JsonNode] {.raises: [Exception].} =
let payload = %* [{"name": name, "address": address}]
return callPrivateRPC("wallet_addSavedAddress", payload)
proc deleteSavedAddress*(address: string): RpcResponse[JsonNode] {.raises: [Exception].} =
let payload = %* [address]
return callPrivateRPC("wallet_deleteSavedAddress", payload)
proc getSavedAddresses*(): RpcResponse[JsonNode] {.raises: [Exception].} =
let payload = %* []
return callPrivateRPC("wallet_getSavedAddresses", payload)

11
src/backend/settings.nim Normal file
View File

@ -0,0 +1,11 @@
import json
import ./core, ./response_type
export response_type
proc getSettings*(): RpcResponse[JsonNode] {.raises: [Exception].} =
return core.callPrivateRPC("settings_getSettings")
proc saveSettings*(key: string, value: string | JsonNode | bool | int): RpcResponse[JsonNode] {.raises: [Exception].} =
let payload = %* [key, value]
result = core.callPrivateRPC("settings_saveSetting", payload)

37
src/backend/signals.nim Normal file
View File

@ -0,0 +1,37 @@
import json, json_serialization, strutils
import signals/[base, chronicles_logs, community, discovery_summary, envelope, expired, mailserver, messages, peerstats, signal_type, stats, wallet, whisper_filter, keycard]
export base, chronicles_logs, community, discovery_summary, envelope, expired, mailserver, messages, peerstats, signal_type, stats, wallet, whisper_filter
proc decode*(jsonSignal: JsonNode): Signal =
let signalString = jsonSignal{"type"}.getStr
var signalType: SignalType
try:
signalType = parseEnum[SignalType](signalString)
except:
raise newException(ValueError, "Unknown signal received: " & signalString)
result = case signalType:
of SignalType.Message: MessageSignal.fromEvent(jsonSignal, true)
of SignalType.EnvelopeSent: EnvelopeSentSignal.fromEvent(jsonSignal)
of SignalType.EnvelopeExpired: EnvelopeExpiredSignal.fromEvent(jsonSignal)
of SignalType.WhisperFilterAdded: WhisperFilterSignal.fromEvent(jsonSignal)
of SignalType.Wallet: WalletSignal.fromEvent(jsonSignal)
of SignalType.NodeLogin: Json.decode($jsonSignal, NodeSignal)
of SignalType.PeerStats: PeerStatsSignal.fromEvent(jsonSignal)
of SignalType.DiscoverySummary: DiscoverySummarySignal.fromEvent(jsonSignal)
of SignalType.MailserverRequestCompleted: MailserverRequestCompletedSignal.fromEvent(jsonSignal)
of SignalType.MailserverRequestExpired: MailserverRequestExpiredSignal.fromEvent(jsonSignal)
of SignalType.CommunityFound: CommunitySignal.fromEvent(jsonSignal)
of SignalType.Stats: StatsSignal.fromEvent(jsonSignal)
of SignalType.ChroniclesLogs: ChroniclesLogsSignal.fromEvent(jsonSignal)
of SignalType.HistoryRequestCompleted: HistoryRequestCompletedSignal.fromEvent(jsonSignal)
of SignalType.HistoryRequestStarted: HistoryRequestStartedSignal.fromEvent(jsonSignal)
of SignalType.HistoryRequestFailed: HistoryRequestFailedSignal.fromEvent(jsonSignal)
of SignalType.HistoryRequestBatchProcessed: HistoryRequestBatchProcessedSignal.fromEvent(jsonSignal)
of SignalType.KeycardConnected: KeycardConnectedSignal.fromEvent(jsonSignal)
of SignalType.MailserverAvailable: MailserverAvailableSignal.fromEvent(jsonSignal)
of SignalType.MailserverChanged: MailserverChangedSignal.fromEvent(jsonSignal)
else: Signal()
result.signalType = signalType

106
src/backend/status.nim Normal file
View File

@ -0,0 +1,106 @@
import statusgo_backend/accounts as statusgo_backend_accounts
import statusgo_backend/core as statusgo_backend_core
import statusgo_backend/settings as statusgo_backend_settings
import chat, accounts, wallet, wallet2, node, network, messages, contacts, profile, stickers, permissions, fleet, settings, mailservers, tokens, provider
import ../eventemitter
import bitops, stew/byteutils, chronicles
import ./types/[setting]
import ./keycard
import ../backends/backend
export chat, accounts, node, messages, contacts, profile, network, permissions, eventemitter
type Status* = ref object
backend*: Backend
events*: EventEmitter
chat*: ChatModel
messages*: MessagesModel
accounts*: AccountModel
wallet*: WalletModel
wallet2*: Wallet2Model
node*: NodeModel
profile*: ProfileModel
contacts*: ContactModel
network*: NetworkModel
stickers*: StickersModel
permissions*: PermissionsModel
settings*: SettingsModel
tokens*: TokensModel
provider*: ProviderModel
keycard*: KeycardModel
proc newStatusInstance*(backendName: string): Status =
result = Status()
result.backend = newBackend(backendName)
result.events = createEventEmitter()
result.chat = chat.newChatModel(result.events)
result.accounts = accounts.newAccountModel(result.events)
result.wallet = wallet.newWalletModel(result.events)
result.wallet.initEvents()
result.wallet2 = wallet2.newWallet2Model(result.events)
result.node = node.newNodeModel()
result.messages = messages.newMessagesModel(result.events)
result.profile = profile.newProfileModel()
result.contacts = contacts.newContactModel(result.events)
result.network = network.newNetworkModel(result.events)
result.stickers = stickers.newStickersModel(result.events)
result.permissions = permissions.newPermissionsModel(result.events)
result.settings = settings.newSettingsModel(result.events)
result.tokens = tokens.newTokensModel(result.events)
result.provider = provider.newProviderModel(result.events, result.permissions, result.wallet)
result.keycard = newKeycardModel(result.backend)
proc initNode*(self: Status, statusGoDir, keystoreDir: string) =
statusgo_backend_accounts.initNode(statusGoDir, keystoreDir)
proc startMessenger*(self: Status) {.exportc, dynlib.} =
statusgo_backend_core.startMessenger()
proc reset*(self: Status) {.exportc, dynlib.} =
# TODO: remove this once accounts are not tracked in the AccountsModel
self.accounts.reset()
# NOT NEEDED self.chat.reset()
# NOT NEEDED self.wallet.reset()
# NOT NEEDED self.node.reset()
# NOT NEEDED self.profile.reset()
# TODO: add all resets here
proc getNodeVersion*(self: Status): string {.exportc, dynlib.} =
statusgo_backend_settings.getWeb3ClientVersion()
# TODO: duplicated??
proc saveSetting*(self: Status, setting: Setting, value: string | bool) =
discard statusgo_backend_settings.saveSetting(setting, value)
proc getBloomFilter*(self: Status): string {.exportc, dynlib.} =
result = statusgo_backend_core.getBloomFilter()
proc getBloomFilterBitsSet*(self: Status): int {.exportc, dynlib.} =
let bloomFilter = statusgo_backend_core.getBloomFilter()
var bitCount = 0;
for b in hexToSeqByte(bloomFilter):
bitCount += countSetBits(b)
return bitCount
# C Helpers
# ==============================================================================
# This creates extra functions with a simpler API for C interop. This is to avoid
# having to manually create nim strings, (we can use cstring) instead, and also
# because functions that accept more than one type for the same parameter are not
# exported correctly
proc newStatusInstance*(): Status {.exportc, dynlib.} =
newStatusInstance("statusgo")
proc initNode*(self: Status, statusGoDir, keystoreDir: cstring) {.exportc, dynlib.} =
self.initNode($statusGoDir, $keystoreDir)
proc saveStringSetting*(self: Status, setting: Setting, value: cstring) {.exportc, dynlib.} =
self.saveSetting(setting, $value)
proc saveBoolSetting*(self: Status, setting: Setting, value: bool) {.exportc, dynlib.} =
self.saveSetting(setting, value)

55
src/backend/stickers.nim Normal file
View File

@ -0,0 +1,55 @@
import json
import ./eth
# Retrieves number of sticker packs owned by user
# See https://notes.status.im/Q-sQmQbpTOOWCQcYiXtf5g#Read-Sticker-Packs-owned-by-a-user
# for more details
proc getBalance*(address: string, data: string): RpcResponse[JsonNode] {.raises: [Exception].} =
let payload = %* [{
"to": address,
"data": data
}, "latest"]
let response = eth.doEthCall(payload)
if not response.error.isNil:
raise newException(RpcException, "Error getting stickers balance: " & response.error.message)
return response
proc tokenOfOwnerByIndex*(address: string, data: string): RpcResponse[JsonNode] {.raises: [Exception].} =
let payload = %* [{
"to": address,
"data": data
}, "latest"]
let response = eth.doEthCall(payload)
if not response.error.isNil:
raise newException(RpcException, "Error getting owned tokens: " & response.error.message)
return response
proc getPackIdFromTokenId*(address: string, data: string): RpcResponse[JsonNode] {.raises: [Exception].} =
let payload = %* [{
"to": address,
"data": data
}, "latest"]
let response = eth.doEthCall(payload)
if not response.error.isNil:
raise newException(RpcException, "Error getting pack id from token id: " & response.error.message)
return response
proc getPackCount*(address: string, data: string): RpcResponse[JsonNode] {.raises: [Exception].} =
let payload = %* [{
"to": address,
"data": data
}, "latest"]
let response = eth.doEthCall(payload)
if not response.error.isNil:
raise newException(RpcException, "Error getting stickers balance: " & response.error.message)
return response

22
src/backend/tokens.nim Normal file
View File

@ -0,0 +1,22 @@
import json
import ./core, ./response_type
export response_type
proc getTokens*(chainId: int): RpcResponse[JsonNode] {.raises: [Exception].} =
return callPrivateRPC("wallet_getTokens", %* [chainId])
proc getBalances*(chainId: int, accounts: seq[string], tokens: seq[string]): RpcResponse[JsonNode] {.raises: [Exception].} =
return callPrivateRPC("wallet_getTokensBalancesForChainIDs", %* [@[chainId], accounts, tokens])
proc getCustomTokens*(): RpcResponse[JsonNode] {.raises: [Exception].} =
return callPrivateRPC("wallet_getCustomTokens", %* [])
proc addCustomToken*(address: string, name: string, symbol: string, decimals: int, color: string) {.raises: [Exception].} =
discard callPrivateRPC("wallet_addCustomToken", %* [
{"address": address, "name": name, "symbol": symbol, "decimals": decimals, "color": color}
])
proc removeCustomToken*(address: string) {.raises: [Exception].} =
discard callPrivateRPC("wallet_deleteCustomToken", %* [address])

View File

@ -0,0 +1,29 @@
import json, stint, chronicles, strutils
import ./core as core
proc checkRecentHistory*(addresses: seq[string]) {.raises: [Exception].} =
let payload = %* [addresses]
discard callPrivateRPC("wallet_checkRecentHistory", payload)
proc getTransfersByAddress*(address: string, toBlock: Uint256, limitAsHexWithoutLeadingZeros: string,
loadMore: bool = false): RpcResponse[JsonNode] {.raises: [Exception].} =
let toBlockParsed = if not loadMore: newJNull() else: %("0x" & stint.toHex(toBlock))
callPrivateRPC("wallet_getTransfersByAddress", %* [address, toBlockParsed, limitAsHexWithoutLeadingZeros, loadMore])
proc trackPendingTransaction*(hash: string, fromAddress: string, toAddress: string, trxType: string, data: string):
RpcResponse[JsonNode] {.raises: [Exception].} =
let payload = %* [{
"hash": hash,
"from": fromAddress,
"to": toAddress,
"type": trxType,
"additionalData": data,
"data": "",
"value": 0,
"timestamp": 0,
"gasPrice": 0,
"gasLimit": 0
}]
callPrivateRPC("wallet_storePendingTransaction", payload)

34
src/backend/updates.nim Normal file
View File

@ -0,0 +1,34 @@
import stew/byteutils
from stew/base32 import nil
from stew/base58 import nil
import ./statusgo_backend_new/ens as status_ens
import chronicles, httpclient, net
import strutils
import json
import semver
import constants
type
VersionInfo* = object
version*: string
url*: string
proc getLatestVersion*(): VersionInfo =
let response = status_ens.resourceUrl(chainId=1, username=APP_UPDATES_ENS)
let host = response.result{"Host"}.getStr
if host == "":
raise newException(ValueError, "ENS does not have a content hash")
let url = "https://" & host & response.result{"Path"}.getStr
# Read version from folder
let secureSSLContext = newContext()
let client = newHttpClient(sslContext = secureSSLContext, timeout = CHECK_VERSION_TIMEOUT_MS)
result.version = client.getContent(url & "/VERSION").strip()
result.url = url
proc isNewer*(currentVersion, versionToCheck: string): bool =
let lastVersion = parseVersion(versionToCheck)
let currVersion = parseVersion(currentVersion)
result = lastVersion > currVersion

12
src/backend/utils.nim Normal file
View File

@ -0,0 +1,12 @@
import nimcrypto
proc isWakuEnabled(): bool =
true # TODO:
proc prefix*(methodName: string, isExt:bool = true): string =
result = if isWakuEnabled(): "waku" else: "shh"
result = result & (if isExt: "ext_" else: "_")
result = result & methodName
proc hashPassword*(password: string): string =
result = "0x" & $keccak_256.digest(password)

12
src/backend/wallet.nim Normal file
View File

@ -0,0 +1,12 @@
import json, chronicles
import core, utils
import response_type
export response_type
logScope:
topics = "rpc-wallet"
proc getPendingTransactions*(): RpcResponse[JsonNode] {.raises: [Exception].} =
let payload = %* []
result = core.callPrivateRPC("wallet_getPendingTransactions", payload)

View File

@ -24,7 +24,7 @@ do
echo "------------------------------------"
((COUNTER=COUNTER+1))
echo "Running the app..."
export LD_LIBRARY_PATH=vendor/status-lib/vendor/status-go/build/bin/libstatus.so &
export LD_LIBRARY_PATH=vendor/status-go/build/bin/libstatus.so &
./bin/nim_status_client &
PID=$!
sleep 4

1
vendor/nim-keycard-go vendored Submodule

@ -0,0 +1 @@
Subproject commit 126fbc9dc2b3d0740f99269753772643ab298a75

1
vendor/nim-status-go vendored Submodule

@ -0,0 +1 @@
Subproject commit d3670390c449f7de0fbce8cf95e67f66441d126e

1
vendor/nim-stint vendored Submodule

@ -0,0 +1 @@
Subproject commit ddfa6c608a6c2a843d7b405f377a22703947267a

1
vendor/status-go vendored Submodule

@ -0,0 +1 @@
Subproject commit 62a0439234c76388e6992647b5599d65ff0b0e24

1
vendor/status-lib vendored

@ -1 +0,0 @@
Subproject commit 33334b9b8a92041c422864b4738f9cd1ba4267e3