111 lines
3.6 KiB
Nim
111 lines
3.6 KiB
Nim
import lib/accounts
|
|
import lib/alias
|
|
import lib/alias/data
|
|
import lib/account
|
|
import lib/accounts
|
|
import lib/identicon
|
|
import lib/messages
|
|
import lib/chats
|
|
import lib/permissions
|
|
import lib/util
|
|
|
|
import lib/migration
|
|
import lib/database
|
|
import lib/migrations/sql_scripts_accounts as acc_migration
|
|
import lib/migrations/sql_scripts_app as app_migration
|
|
import sqlcipher
|
|
|
|
import nimcrypto
|
|
import strformat
|
|
import strutils
|
|
import unicode
|
|
import json
|
|
import os
|
|
|
|
export createAccount
|
|
export getAccounts;
|
|
export saveAccount;
|
|
export updateAccount;
|
|
export updateAccountTimestamp;
|
|
export deleteAccount;
|
|
export addPermissions, getPermissions, deletePermission
|
|
|
|
proc hashMessage*(message: string): string =
|
|
## hashMessage calculates the hash of a message to be safely signed by the keycard.
|
|
## The hash is calulcated as
|
|
## keccak256("\x19Ethereum Signed Message:\n"${message length}${message}).
|
|
## This gives context to the signed message and prevents signing of transactions.
|
|
var msg = message
|
|
if isHexString(msg):
|
|
try:
|
|
msg = parseHexStr(msg[2..^1])
|
|
except:
|
|
discard
|
|
const END_OF_MEDIUM = Rune(0x19).toUTF8
|
|
const prefix = END_OF_MEDIUM & "Ethereum Signed Message:\n"
|
|
"0x" & toLower($keccak_256.digest(prefix & $(msg.len) & msg))
|
|
|
|
proc generateAlias*(pubKey: string): string =
|
|
## generateAlias returns a 3-words generated name given a hex encoded (prefixed with 0x) public key.
|
|
## We ignore any error, empty string result is considered an error.
|
|
result = ""
|
|
if isPubKey(pubKey):
|
|
try:
|
|
let seed = truncPubKey(pubKey)
|
|
const poly: uint64 = 0xB8
|
|
let generator = Lsfr(poly: poly, data: seed)
|
|
let adjective1 = adjectives[generator.next mod adjectives.len]
|
|
let adjective2 = adjectives[generator.next mod adjectives.len]
|
|
let animal = animals[generator.next mod animals.len.uint64]
|
|
result = fmt("{adjective1} {adjective2} {animal}")
|
|
except:
|
|
discard
|
|
|
|
proc identicon*(str: string): string =
|
|
## identicon returns a base64 encoded icon given a string.
|
|
## We ignore any error, empty string result is considered an error.
|
|
try:
|
|
result = generateBase64(str)
|
|
except:
|
|
discard
|
|
|
|
|
|
|
|
##### TODO: move to somefile
|
|
|
|
type StatusObject* = ref object
|
|
rootDataDir: string
|
|
accountsDB*: DbConn
|
|
userDB*: DbConn
|
|
|
|
|
|
proc init*(dataDir: string): StatusObject =
|
|
result = new StatusObject
|
|
result.rootDataDir = dataDir
|
|
result.accountsDB = initializeDB(dataDir / "accounts.sql", acc_migration.newMigrationDefinition(), false) # Disabling migrations because we are reusing a status-go DB
|
|
|
|
proc openAccounts*(self: StatusObject): seq[Account] =
|
|
getAccounts(self.accountsDB)
|
|
|
|
proc openUserDB*(self: StatusObject, keyUid: string, password: string) =
|
|
self.userDB = initializeDB(self.rootDataDir / keyUid & ".db", password, app_migration.newMigrationDefinition(), false) # Disabling migrations because we are reusing a status-go DB
|
|
self.userDB.execScript("PRAGMA cipher_page_size = 1024");
|
|
self.userDB.execScript("PRAGMA kdf_iter = 3200");
|
|
self.userDB.execScript("PRAGMA cipher_hmac_algorithm = HMAC_SHA1");
|
|
self.userDB.execScript("PRAGMA cipher_kdf_algorithm = PBKDF2_HMAC_SHA1");
|
|
echo "==============================="
|
|
echo "DB path: " & (self.rootDataDir / keyUid & ".db")
|
|
echo "Password: " & password
|
|
let result = self.userDB.value("SELECT public_key from settings") # check if decryption worked
|
|
echo "Result: "
|
|
echo result.get()
|
|
|
|
proc closeUserDB*(self: StatusObject) =
|
|
self.userDB.close()
|
|
|
|
proc loadChats*(self: StatusObject): seq[Chat] =
|
|
getChats(self.userDB)
|
|
|
|
proc close*(self: StatusObject) =
|
|
self.userDB.close()
|
|
self.accountsDB.close() |