Refactor/wallet part 2 (#91)
* refactor: add save account * refactor: add account generation * refactor: save settings * refactor: add update account in new be * add getTransfersByAddress (#93) Co-authored-by: Jonathan Rainville <rainville.jonathan@gmail.com>
This commit is contained in:
parent
ad9af00340
commit
76e867f1d8
|
@ -1,4 +1,4 @@
|
|||
import json, json_serialization, chronicles
|
||||
import json, json_serialization, chronicles, nimcrypto
|
||||
import ./core, ./utils
|
||||
import ./response_type
|
||||
|
||||
|
@ -12,9 +12,29 @@ logScope:
|
|||
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,
|
||||
|
@ -102,6 +122,69 @@ proc storeDerivedAccounts*(id, hashedPassword: string, paths: seq[string]):
|
|||
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 hashPassword*(password: string): string =
|
||||
result = "0x" & $keccak_256.digest(password)
|
||||
|
||||
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)
|
||||
|
@ -142,3 +225,26 @@ proc login*(name, keyUid, hashedPassword, identicon, thumbnail, large: string):
|
|||
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): bool =
|
||||
let hashedPassword = hashPassword(password)
|
||||
let verifyResult = status_go.verifyAccountPassword(keystoreDir, address, hashedPassword)
|
||||
let error = parseJson(verifyResult)["error"].getStr
|
||||
|
||||
if error == "":
|
||||
return true
|
||||
|
||||
return false
|
||||
|
|
@ -0,0 +1,35 @@
|
|||
import
|
||||
json, options, strutils
|
||||
|
||||
import
|
||||
web3/[conversions, ethtypes], stint
|
||||
|
||||
import ../types/transaction
|
||||
|
||||
# TODO: make this public in nim-web3 lib
|
||||
template stripLeadingZeros*(value: string): string =
|
||||
var cidx = 0
|
||||
# ignore the last character so we retain '0' on zero value
|
||||
while cidx < value.len - 1 and value[cidx] == '0':
|
||||
cidx.inc
|
||||
value[cidx .. ^1]
|
||||
|
||||
proc `%`*(x: TransactionData): JsonNode =
|
||||
result = newJobject()
|
||||
result["from"] = %x.source
|
||||
result["type"] = %x.txType
|
||||
if x.to.isSome:
|
||||
result["to"] = %x.to.unsafeGet
|
||||
if x.gas.isSome:
|
||||
result["gas"] = %x.gas.unsafeGet
|
||||
if x.gasPrice.isSome:
|
||||
result["gasPrice"] = %("0x" & x.gasPrice.unsafeGet.toHex.stripLeadingZeros)
|
||||
if x.maxFeePerGas.isSome:
|
||||
result["maxFeePerGas"] = %("0x" & x.maxFeePerGas.unsafeGet.toHex)
|
||||
if x.maxPriorityFeePerGas.isSome:
|
||||
result["maxPriorityFeePerGas"] = %("0x" & x.maxPriorityFeePerGas.unsafeGet.toHex)
|
||||
if x.value.isSome:
|
||||
result["value"] = %("0x" & x.value.unsafeGet.toHex)
|
||||
result["data"] = %x.data
|
||||
if x.nonce.isSome:
|
||||
result["nonce"] = %x.nonce.unsafeGet
|
|
@ -3,6 +3,9 @@ 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)
|
||||
|
|
|
@ -4,4 +4,7 @@ import ./core, ./response_type
|
|||
export response_type
|
||||
|
||||
proc getSettings*(): RpcResponse[JsonNode] {.raises: [Exception].} =
|
||||
return core.callPrivateRPC("settings_getSettings")
|
||||
return core.callPrivateRPC("settings_getSettings")
|
||||
|
||||
proc saveSettings*(key: string, value: string | JsonNode | bool | int) {.raises: [Exception].} =
|
||||
discard core.callPrivateRPC("settings_saveSetting", %* [key, value])
|
|
@ -1,7 +1,17 @@
|
|||
import json
|
||||
import json, stint, chronicles, strutils, conversions
|
||||
|
||||
import ./core
|
||||
|
||||
import ../types/transaction
|
||||
import ./core as core
|
||||
|
||||
proc checkRecentHistory*(addresses: seq[string]) {.raises: [Exception].} =
|
||||
let payload = %* [addresses]
|
||||
discard callPrivateRPC("wallet_checkRecentHistory", payload)
|
||||
discard callPrivateRPC("wallet_checkRecentHistory", payload)
|
||||
|
||||
proc getTransfersByAddress*(address: string, toBlock: Uint256, limit: int, loadMore: bool = false): RpcResponse[JsonNode] {.raises: [Exception].} =
|
||||
let
|
||||
toBlockParsed = if not loadMore: newJNull() else: %("0x" & stint.toHex(toBlock))
|
||||
limitParsed = "0x" & limit.toHex.stripLeadingZeros
|
||||
|
||||
callPrivateRPC("wallet_getTransfersByAddress", %* [address, toBlockParsed, limitParsed, loadMore])
|
||||
|
Loading…
Reference in New Issue