refactor(@desktop/general): env variables sorted and CL args introduced
- Necessary env variables to build the app: STATUS_BUILD_INFURA_TOKEN STATUS_BUILD_INFURA_TOKEN_SECRET STATUS_BUILD_POKT_TOKEN STATUS_BUILD_OPENSEA_API_KEY STATUS_BUILD_ALCHEMY_ETHEREUM_MAINNET_TOKEN STATUS_BUILD_ALCHEMY_ETHEREUM_GOERLI_TOKEN STATUS_BUILD_ALCHEMY_ARBITRUM_MAINNET_TOKEN STATUS_BUILD_ALCHEMY_ARBITRUM_GOERLI_TOKEN STATUS_BUILD_ALCHEMY_OPTIMISM_MAINNET_TOKEN STATUS_BUILD_ALCHEMY_OPTIMISM_GOERLI_TOKEN - The list of available env variables as well as CL arguments can be seen running the app providing `--help` argument. All env vars are prefixed with `STATUS_RUNTIME_`.
This commit is contained in:
parent
8caa72c3b5
commit
f88c23dc7b
|
@ -1,5 +1,5 @@
|
||||||
#!/usr/bin/env groovy
|
#!/usr/bin/env groovy
|
||||||
library 'status-jenkins-lib@v1.7.16'
|
library 'status-jenkins-lib@v1.7.17'
|
||||||
|
|
||||||
pipeline {
|
pipeline {
|
||||||
agent { label 'linux' }
|
agent { label 'linux' }
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
#!/usr/bin/env groovy
|
#!/usr/bin/env groovy
|
||||||
library 'status-jenkins-lib@v1.7.16'
|
library 'status-jenkins-lib@v1.7.17'
|
||||||
|
|
||||||
/* Options section can't access functions in objects. */
|
/* Options section can't access functions in objects. */
|
||||||
def isPRBuild = utils.isPRBuild()
|
def isPRBuild = utils.isPRBuild()
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
#!/usr/bin/env groovy
|
#!/usr/bin/env groovy
|
||||||
library 'status-jenkins-lib@v1.7.16'
|
library 'status-jenkins-lib@v1.7.17'
|
||||||
|
|
||||||
/* Options section can't access functions in objects. */
|
/* Options section can't access functions in objects. */
|
||||||
def isPRBuild = utils.isPRBuild()
|
def isPRBuild = utils.isPRBuild()
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
#!/usr/bin/env groovy
|
#!/usr/bin/env groovy
|
||||||
library 'status-jenkins-lib@v1.7.16'
|
library 'status-jenkins-lib@v1.7.17'
|
||||||
|
|
||||||
/* Options section can't access functions in objects. */
|
/* Options section can't access functions in objects. */
|
||||||
def isPRBuild = utils.isPRBuild()
|
def isPRBuild = utils.isPRBuild()
|
||||||
|
@ -97,7 +97,7 @@ pipeline {
|
||||||
|
|
||||||
stage('Client') {
|
stage('Client') {
|
||||||
environment {
|
environment {
|
||||||
GANACHE_NETWORK_RPC_URL = "http://localhost:${env.GANACHE_RPC_PORT}"
|
STATUS_RUNTIME_GANACHE_NETWORK_RPC_URL = "http://localhost:${env.GANACHE_RPC_PORT}"
|
||||||
}
|
}
|
||||||
steps { script {
|
steps { script {
|
||||||
linux.bundle('nim_status_client')
|
linux.bundle('nim_status_client')
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
#!/usr/bin/env groovy
|
#!/usr/bin/env groovy
|
||||||
library 'status-jenkins-lib@v1.7.16'
|
library 'status-jenkins-lib@v1.7.17'
|
||||||
|
|
||||||
/* Options section can't access functions in objects. */
|
/* Options section can't access functions in objects. */
|
||||||
def isPRBuild = utils.isPRBuild()
|
def isPRBuild = utils.isPRBuild()
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
#!/usr/bin/env groovy
|
#!/usr/bin/env groovy
|
||||||
library 'status-jenkins-lib@v1.7.16'
|
library 'status-jenkins-lib@v1.7.17'
|
||||||
|
|
||||||
/* Options section can't access functions in objects. */
|
/* Options section can't access functions in objects. */
|
||||||
def isPRBuild = utils.isPRBuild()
|
def isPRBuild = utils.isPRBuild()
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
#!/usr/bin/env groovy
|
#!/usr/bin/env groovy
|
||||||
library 'status-jenkins-lib@v1.7.16'
|
library 'status-jenkins-lib@v1.7.17'
|
||||||
|
|
||||||
/* Options section can't access functions in objects. */
|
/* Options section can't access functions in objects. */
|
||||||
def isPRBuild = utils.isPRBuild()
|
def isPRBuild = utils.isPRBuild()
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
#!/usr/bin/env groovy
|
#!/usr/bin/env groovy
|
||||||
library 'status-jenkins-lib@v1.7.16'
|
library 'status-jenkins-lib@v1.7.17'
|
||||||
|
|
||||||
/* Options section can't access functions in objects. */
|
/* Options section can't access functions in objects. */
|
||||||
def isPRBuild = utils.isPRBuild()
|
def isPRBuild = utils.isPRBuild()
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
#!/usr/bin/env groovy
|
#!/usr/bin/env groovy
|
||||||
library 'status-jenkins-lib@v1.7.16'
|
library 'status-jenkins-lib@v1.7.17'
|
||||||
|
|
||||||
/* Options section can't access functions in objects. */
|
/* Options section can't access functions in objects. */
|
||||||
def isPRBuild = utils.isPRBuild()
|
def isPRBuild = utils.isPRBuild()
|
||||||
|
|
|
@ -135,10 +135,10 @@ proc connect(self: AppController) =
|
||||||
if not existsEnv("LOG_LEVEL"):
|
if not existsEnv("LOG_LEVEL"):
|
||||||
self.statusFoundation.events.on(node_configuration_service.SIGNAL_NODE_LOG_LEVEL_UPDATE) do(a: Args):
|
self.statusFoundation.events.on(node_configuration_service.SIGNAL_NODE_LOG_LEVEL_UPDATE) do(a: Args):
|
||||||
let args = NodeLogLevelUpdatedArgs(a)
|
let args = NodeLogLevelUpdatedArgs(a)
|
||||||
if args.logLevel == LogLevel.DEBUG:
|
if args.logLevel == chronicles.LogLevel.DEBUG:
|
||||||
setLogLevel(LogLevel.DEBUG)
|
setLogLevel(chronicles.LogLevel.DEBUG)
|
||||||
elif defined(production):
|
elif defined(production):
|
||||||
setLogLevel(LogLevel.INFO)
|
setLogLevel(chronicles.LogLevel.INFO)
|
||||||
|
|
||||||
proc newAppController*(statusFoundation: StatusFoundation): AppController =
|
proc newAppController*(statusFoundation: StatusFoundation): AppController =
|
||||||
result = AppController()
|
result = AppController()
|
||||||
|
@ -440,7 +440,7 @@ proc load(self: AppController) =
|
||||||
# Apply runtime log level settings
|
# Apply runtime log level settings
|
||||||
if not existsEnv("LOG_LEVEL"):
|
if not existsEnv("LOG_LEVEL"):
|
||||||
if self.nodeConfigurationService.isDebugEnabled():
|
if self.nodeConfigurationService.isDebugEnabled():
|
||||||
setLogLevel(LogLevel.DEBUG)
|
setLogLevel(chronicles.LogLevel.DEBUG)
|
||||||
|
|
||||||
# load main module
|
# load main module
|
||||||
self.mainModule.load(
|
self.mainModule.load(
|
||||||
|
|
|
@ -1,74 +1,6 @@
|
||||||
import json, os, chronicles, strutils
|
import json, os, strutils
|
||||||
import ../../constants as main_constants
|
import ../../constants as main_constants
|
||||||
|
|
||||||
proc resolveEnvVar(envVar: string, defaultValue: string): string =
|
|
||||||
let envVarValue = $getEnv(envVar)
|
|
||||||
if envVarValue != "":
|
|
||||||
return envVarValue
|
|
||||||
else:
|
|
||||||
return defaultValue
|
|
||||||
|
|
||||||
# provider Tokens
|
|
||||||
# allow runtime override via environment variable; core contributors can set a
|
|
||||||
# release token in this way for local development
|
|
||||||
|
|
||||||
# set via `nim c` param `-d:POKT_TOKEN:[token]`; should be set in CI/release builds
|
|
||||||
const POKT_TOKEN {.strdefine.} = ""
|
|
||||||
let POKT_TOKEN_RESOLVED* = resolveEnvVar("POKT_TOKEN", POKT_TOKEN)
|
|
||||||
|
|
||||||
# set via `nim c` param `-d:INFURA_TOKEN:[token]`; should be set in CI/release builds
|
|
||||||
const INFURA_TOKEN {.strdefine.} = ""
|
|
||||||
let INFURA_TOKEN_RESOLVED* = resolveEnvVar("INFURA_TOKEN", INFURA_TOKEN)
|
|
||||||
|
|
||||||
# set via `nim c` param `-d:INFURA_TOKEN_SECRET:[token]`; should be set in CI/release builds
|
|
||||||
const INFURA_TOKEN_SECRET {.strdefine.} = ""
|
|
||||||
let INFURA_TOKEN_SECRET_RESOLVED* = resolveEnvVar("INFURA_TOKEN_SECRET", INFURA_TOKEN_SECRET)
|
|
||||||
|
|
||||||
# set via `nim c` param `-d:ALCHEMY_ETHEREUM_MAINNET_TOKEN:[token]`; should be set in CI/release builds
|
|
||||||
const ALCHEMY_ETHEREUM_MAINNET_TOKEN {.strdefine.} = ""
|
|
||||||
let ALCHEMY_ETHEREUM_MAINNET_TOKEN_RESOLVED* = resolveEnvVar("ALCHEMY_ETHEREUM_MAINNET_TOKEN", ALCHEMY_ETHEREUM_MAINNET_TOKEN)
|
|
||||||
|
|
||||||
# set via `nim c` param `-d:ALCHEMY_ETHEREUM_GOERLI_TOKEN:[token]`; should be set in CI/release builds
|
|
||||||
const ALCHEMY_ETHEREUM_GOERLI_TOKEN {.strdefine.} = ""
|
|
||||||
let ALCHEMY_ETHEREUM_GOERLI_TOKEN_RESOLVED* = resolveEnvVar("ALCHEMY_ETHEREUM_GOERLI_TOKEN", ALCHEMY_ETHEREUM_GOERLI_TOKEN)
|
|
||||||
|
|
||||||
# set via `nim c` param `-d:ALCHEMY_ARBITRUM_MAINNET_TOKEN:[token]`; should be set in CI/release builds
|
|
||||||
const ALCHEMY_ARBITRUM_MAINNET_TOKEN {.strdefine.} = ""
|
|
||||||
let ALCHEMY_ARBITRUM_MAINNET_TOKEN_RESOLVED* = resolveEnvVar("ALCHEMY_ARBITRUM_MAINNET_TOKEN", ALCHEMY_ARBITRUM_MAINNET_TOKEN)
|
|
||||||
|
|
||||||
# set via `nim c` param `-d:ALCHEMY_ARBITRUM_GOERLI_TOKEN:[token]`; should be set in CI/release builds
|
|
||||||
const ALCHEMY_ARBITRUM_GOERLI_TOKEN {.strdefine.} = ""
|
|
||||||
let ALCHEMY_ARBITRUM_GOERLI_TOKEN_RESOLVED* = resolveEnvVar("ALCHEMY_ARBITRUM_GOERLI_TOKEN", ALCHEMY_ARBITRUM_GOERLI_TOKEN)
|
|
||||||
|
|
||||||
# set via `nim c` param `-d:ALCHEMY_OPTIMISM_MAINNET_TOKEN:[token]`; should be set in CI/release builds
|
|
||||||
const ALCHEMY_OPTIMISM_MAINNET_TOKEN {.strdefine.} = ""
|
|
||||||
let ALCHEMY_OPTIMISM_MAINNET_TOKEN_RESOLVED* = resolveEnvVar("ALCHEMY_OPTIMISM_MAINNET_TOKEN", ALCHEMY_OPTIMISM_MAINNET_TOKEN)
|
|
||||||
|
|
||||||
# set via `nim c` param `-d:ALCHEMY_OPTIMISM_GOERLI_TOKEN:[token]`; should be set in CI/release builds
|
|
||||||
const ALCHEMY_OPTIMISM_GOERLI_TOKEN {.strdefine.} = ""
|
|
||||||
let ALCHEMY_OPTIMISM_GOERLI_TOKEN_RESOLVED* = resolveEnvVar("ALCHEMY_OPTIMISM_GOERLI_TOKEN", ALCHEMY_OPTIMISM_GOERLI_TOKEN)
|
|
||||||
|
|
||||||
# set via `nim c` param `-d:OPENSEA_API_KEY:[token]`; should be set in CI/release builds
|
|
||||||
const OPENSEA_API_KEY {.strdefine.} = ""
|
|
||||||
let OPENSEA_API_KEY_RESOLVED* = resolveEnvVar("OPENSEA_API_KEY", OPENSEA_API_KEY)
|
|
||||||
|
|
||||||
const GANACHE_NETWORK_RPC_URL = $getEnv("GANACHE_NETWORK_RPC_URL")
|
|
||||||
|
|
||||||
const DEFAULT_TORRENT_CONFIG_PORT = 0 # Random
|
|
||||||
let TORRENT_CONFIG_PORT* = if (existsEnv("TORRENT_PORT")):
|
|
||||||
parseInt($getEnv("TORRENT_PORT"))
|
|
||||||
else:
|
|
||||||
DEFAULT_TORRENT_CONFIG_PORT
|
|
||||||
|
|
||||||
const DEFAULT_WAKU_V2_PORT = 0 # Random
|
|
||||||
let WAKU_V2_PORT* = if (existsEnv("WAKU_PORT")):
|
|
||||||
parseInt($getEnv("WAKU_PORT"))
|
|
||||||
else:
|
|
||||||
DEFAULT_WAKU_V2_PORT
|
|
||||||
|
|
||||||
let DEFAULT_TORRENT_CONFIG_DATADIR* = joinPath(main_constants.defaultDataDir(), "data", "archivedata")
|
|
||||||
let DEFAULT_TORRENT_CONFIG_TORRENTDIR* = joinPath(main_constants.defaultDataDir(), "data", "torrents")
|
|
||||||
|
|
||||||
var NETWORKS* = %* [
|
var NETWORKS* = %* [
|
||||||
{
|
{
|
||||||
"chainId": 1,
|
"chainId": 1,
|
||||||
|
@ -344,7 +276,7 @@ var NODE_CONFIG* = %* {
|
||||||
# Docs: https://pkg.go.dev/gopkg.in/natefinch/lumberjack.v2@v2.0.0#readme-cleaning-up-old-log-files
|
# Docs: https://pkg.go.dev/gopkg.in/natefinch/lumberjack.v2@v2.0.0#readme-cleaning-up-old-log-files
|
||||||
"LogMaxBackups": 1,
|
"LogMaxBackups": 1,
|
||||||
"LogMaxSize": 100, # MB
|
"LogMaxSize": 100, # MB
|
||||||
"LogLevel": $LogLevel.INFO,
|
"LogLevel": main_constants.DEFAULT_LOG_LEVEL,
|
||||||
"MailserversConfig": {
|
"MailserversConfig": {
|
||||||
"Enabled": true
|
"Enabled": true
|
||||||
},
|
},
|
||||||
|
|
|
@ -277,7 +277,7 @@ QtObject:
|
||||||
"wallet-root-address": account.derivedAccounts.walletRoot.address,
|
"wallet-root-address": account.derivedAccounts.walletRoot.address,
|
||||||
"preview-privacy?": true,
|
"preview-privacy?": true,
|
||||||
"signing-phrase": generateSigningPhrase(3),
|
"signing-phrase": generateSigningPhrase(3),
|
||||||
"log-level": $LogLevel.INFO,
|
"log-level": main_constants.LOG_LEVEL,
|
||||||
"latest-derived-path": 0,
|
"latest-derived-path": 0,
|
||||||
"currency": "usd",
|
"currency": "usd",
|
||||||
"networks/networks": @[],
|
"networks/networks": @[],
|
||||||
|
@ -308,7 +308,7 @@ QtObject:
|
||||||
if(self.importedAccount.id == accountId):
|
if(self.importedAccount.id == accountId):
|
||||||
return self.prepareAccountSettingsJsonObject(self.importedAccount, installationId, displayName)
|
return self.prepareAccountSettingsJsonObject(self.importedAccount, installationId, displayName)
|
||||||
|
|
||||||
proc getDefaultNodeConfig*(self: Service, installationId: string, recoverAccount: bool, login: bool = false): JsonNode =
|
proc getDefaultNodeConfig*(self: Service, installationId: string, recoverAccount: bool): JsonNode =
|
||||||
let fleet = Fleet.StatusProd
|
let fleet = Fleet.StatusProd
|
||||||
let dnsDiscoveryURL = @["enrtree://AL65EKLJAUXKKPG43HVTML5EFFWEZ7L4LOKTLZCLJASG4DSESQZEC@prod.status.nodes.status.im"]
|
let dnsDiscoveryURL = @["enrtree://AL65EKLJAUXKKPG43HVTML5EFFWEZ7L4LOKTLZCLJASG4DSESQZEC@prod.status.nodes.status.im"]
|
||||||
|
|
||||||
|
@ -339,26 +339,69 @@ QtObject:
|
||||||
result["ClusterConfig"]["DiscV5BootstrapNodes"] = %* (@[])
|
result["ClusterConfig"]["DiscV5BootstrapNodes"] = %* (@[])
|
||||||
result["Rendezvous"] = newJBool(false)
|
result["Rendezvous"] = newJBool(false)
|
||||||
|
|
||||||
# Source the connection port from the environment for debugging or if default port not accessible
|
result["LogLevel"] = newJString(main_constants.LOG_LEVEL)
|
||||||
if existsEnv("STATUS_PORT"):
|
|
||||||
let wV1Port = $getEnv("STATUS_PORT")
|
|
||||||
# Waku V1 config
|
|
||||||
result["ListenAddr"] = newJString("0.0.0.0:" & wV1Port)
|
|
||||||
|
|
||||||
# Don't override log level on login. For onboarding it is required, nothing to override
|
if STATUS_PORT != 0:
|
||||||
if login:
|
result["ListenAddr"] = newJString("0.0.0.0:" & $main_constants.STATUS_PORT)
|
||||||
result.delete("LogLevel")
|
|
||||||
|
|
||||||
if existsEnv("LOG_LEVEL"):
|
|
||||||
let logLvl = getEnv("LOG_LEVEL")
|
|
||||||
if logLvl in @["ERROR", "WARN", "INFO", "DEBUG", "TRACE"]:
|
|
||||||
result["LogLevel"] = newJString($logLvl)
|
|
||||||
|
|
||||||
result["KeyStoreDir"] = newJString(self.keyStoreDir.replace(main_constants.STATUSGODIR, ""))
|
result["KeyStoreDir"] = newJString(self.keyStoreDir.replace(main_constants.STATUSGODIR, ""))
|
||||||
result["RootDataDir"] = newJString(main_constants.STATUSGODIR)
|
result["RootDataDir"] = newJString(main_constants.STATUSGODIR)
|
||||||
result["KeycardPairingDataFile"] = newJString(main_constants.KEYCARDPAIRINGDATAFILE)
|
result["KeycardPairingDataFile"] = newJString(main_constants.KEYCARDPAIRINGDATAFILE)
|
||||||
result["ProcessBackedupMessages"] = newJBool(recoverAccount)
|
result["ProcessBackedupMessages"] = newJBool(recoverAccount)
|
||||||
|
|
||||||
|
proc getLoginNodeConfig(self: Service): JsonNode =
|
||||||
|
# To create appropriate NodeConfig for Login we set only params that maybe be set via env variables or cli flags
|
||||||
|
result = %*{}
|
||||||
|
|
||||||
|
# mandatory params
|
||||||
|
result["NetworkId"] = NETWORKS[0]{"chainId"}
|
||||||
|
result["DataDir"] = %* "./ethereum/mainnet"
|
||||||
|
result["KeyStoreDir"] = %* "./keystore"
|
||||||
|
result["KeycardPairingDataFile"] = %* main_constants.KEYCARDPAIRINGDATAFILE
|
||||||
|
|
||||||
|
# other params
|
||||||
|
result["Networks"] = NETWORKS
|
||||||
|
|
||||||
|
result["UpstreamConfig"] = %* {
|
||||||
|
"URL": NETWORKS[0]{"rpcUrl"},
|
||||||
|
"Enabled": true,
|
||||||
|
}
|
||||||
|
|
||||||
|
result["ShhextConfig"] = %* {
|
||||||
|
"VerifyENSURL": NETWORKS[0]{"fallbackUrl"},
|
||||||
|
"VerifyTransactionURL": NETWORKS[0]{"fallbackUrl"}
|
||||||
|
}
|
||||||
|
|
||||||
|
result["WakuV2Config"] = %* {
|
||||||
|
"Port": WAKU_V2_PORT,
|
||||||
|
"UDPPort": WAKU_V2_PORT
|
||||||
|
}
|
||||||
|
|
||||||
|
result["WalletConfig"] = %* {
|
||||||
|
"OpenseaAPIKey": OPENSEA_API_KEY_RESOLVED,
|
||||||
|
"InfuraAPIKey": INFURA_TOKEN_RESOLVED,
|
||||||
|
"InfuraAPIKeySecret": INFURA_TOKEN_SECRET_RESOLVED,
|
||||||
|
"AlchemyAPIKeys": %* {
|
||||||
|
"1": ALCHEMY_ETHEREUM_MAINNET_TOKEN_RESOLVED,
|
||||||
|
"5": ALCHEMY_ETHEREUM_GOERLI_TOKEN_RESOLVED,
|
||||||
|
"42161": ALCHEMY_ARBITRUM_MAINNET_TOKEN_RESOLVED,
|
||||||
|
"421613": ALCHEMY_ARBITRUM_GOERLI_TOKEN_RESOLVED,
|
||||||
|
"10": ALCHEMY_OPTIMISM_MAINNET_TOKEN_RESOLVED,
|
||||||
|
"420": ALCHEMY_OPTIMISM_GOERLI_TOKEN_RESOLVED
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
result["TorrentConfig"] = %* {
|
||||||
|
"Port": TORRENT_CONFIG_PORT,
|
||||||
|
"DataDir": DEFAULT_TORRENT_CONFIG_DATADIR,
|
||||||
|
"TorrentDir": DEFAULT_TORRENT_CONFIG_TORRENTDIR
|
||||||
|
}
|
||||||
|
|
||||||
|
result["LogLevel"] = newJString(main_constants.LOG_LEVEL)
|
||||||
|
|
||||||
|
if STATUS_PORT != 0:
|
||||||
|
result["ListenAddr"] = newJString("0.0.0.0:" & $main_constants.STATUS_PORT)
|
||||||
|
|
||||||
proc setLocalAccountSettingsFile(self: Service) =
|
proc setLocalAccountSettingsFile(self: Service) =
|
||||||
if(main_constants.IS_MACOS and self.getLoggedInAccount.isValid()):
|
if(main_constants.IS_MACOS and self.getLoggedInAccount.isValid()):
|
||||||
singletonInstance.localAccountSettings.setFileName(self.getLoggedInAccount.name)
|
singletonInstance.localAccountSettings.setFileName(self.getLoggedInAccount.name)
|
||||||
|
@ -484,7 +527,7 @@ QtObject:
|
||||||
"wallet-root-address": walletRootAddress,
|
"wallet-root-address": walletRootAddress,
|
||||||
"preview-privacy?": true,
|
"preview-privacy?": true,
|
||||||
"signing-phrase": generateSigningPhrase(3),
|
"signing-phrase": generateSigningPhrase(3),
|
||||||
"log-level": $LogLevel.INFO,
|
"log-level": main_constants.LOG_LEVEL,
|
||||||
"latest-derived-path": 0,
|
"latest-derived-path": 0,
|
||||||
"currency": "usd",
|
"currency": "usd",
|
||||||
"networks/networks": @[],
|
"networks/networks": @[],
|
||||||
|
@ -624,7 +667,7 @@ QtObject:
|
||||||
error "error: ", procName="verifyDatabasePassword", errName = e.name, errDesription = e.msg
|
error "error: ", procName="verifyDatabasePassword", errName = e.name, errDesription = e.msg
|
||||||
|
|
||||||
proc doLogin(self: Service, account: AccountDto, hashedPassword, thumbnailImage, largeImage: string) =
|
proc doLogin(self: Service, account: AccountDto, hashedPassword, thumbnailImage, largeImage: string) =
|
||||||
let nodeConfigJson = self.getDefaultNodeConfig(installationId = "", recoverAccount = false, login = true)
|
let nodeConfigJson = self.getDefaultNodeConfig(installationId = "", recoverAccount = false)
|
||||||
let response = status_account.login(
|
let response = status_account.login(
|
||||||
account.name,
|
account.name,
|
||||||
account.keyUid,
|
account.keyUid,
|
||||||
|
@ -706,7 +749,7 @@ QtObject:
|
||||||
"key-uid": accToBeLoggedIn.keyUid,
|
"key-uid": accToBeLoggedIn.keyUid,
|
||||||
}
|
}
|
||||||
|
|
||||||
let nodeConfigJson = self.getDefaultNodeConfig(installationId = "", recoverAccount = false, login = true)
|
let nodeConfigJson = self.getDefaultNodeConfig(installationId = "", recoverAccount = false)
|
||||||
|
|
||||||
let response = status_account.loginWithKeycard(keycardData.whisperKey.privateKey,
|
let response = status_account.loginWithKeycard(keycardData.whisperKey.privateKey,
|
||||||
keycardData.encryptionKey.publicKey,
|
keycardData.encryptionKey.publicKey,
|
||||||
|
|
|
@ -1,69 +1,27 @@
|
||||||
import os, sequtils, strutils, strformat
|
include env_cli_vars
|
||||||
|
|
||||||
import # vendor libs
|
## Added a constant here cause it's easier to check the app how it behaves
|
||||||
confutils
|
|
||||||
|
|
||||||
const DEFAULT_WALLET_ENABLED = true
|
|
||||||
let WALLET_ENABLED* = if (existsEnv("ENABLE_WALLET")):
|
|
||||||
parseInt($getEnv("ENABLE_WALLET")) != 0
|
|
||||||
else:
|
|
||||||
DEFAULT_WALLET_ENABLED
|
|
||||||
|
|
||||||
## Added a constant here cause it's easier to check the app how it behaves
|
|
||||||
## on other platform if we just change the value here
|
## on other platform if we just change the value here
|
||||||
const IS_MACOS* = defined(macosx)
|
const IS_MACOS* = defined(macosx)
|
||||||
|
|
||||||
# For future supporting fingerprints on other platforms
|
# For future supporting fingerprints on other platforms
|
||||||
const SUPPORTS_FINGERPRINT* = IS_MACOS
|
const SUPPORTS_FINGERPRINT* = IS_MACOS
|
||||||
|
# This is changed during compilation by reading the VERSION file
|
||||||
|
const DESKTOP_VERSION {.strdefine.} = "0.0.0"
|
||||||
|
const STATUSGO_VERSION* {.strdefine.} = "0.0.0"
|
||||||
|
# This is changed during compilation by executing git command
|
||||||
|
const GIT_COMMIT* {.strdefine.} = ""
|
||||||
|
|
||||||
|
const APP_VERSION* = if defined(production): DESKTOP_VERSION else: fmt("{GIT_COMMIT}")
|
||||||
|
|
||||||
const sep* = when defined(windows): "\\" else: "/"
|
const sep* = when defined(windows): "\\" else: "/"
|
||||||
|
|
||||||
proc defaultDataDir*(): string =
|
################################################################################
|
||||||
let homeDir = getHomeDir()
|
# The following variables are set:
|
||||||
let parentDir =
|
#
|
||||||
if defined(development):
|
# - via CL arguments, if they are provided
|
||||||
parentDir(getAppDir())
|
# - otherwise via env variables, if they are provided
|
||||||
elif homeDir == "":
|
# - otherwise the default values are used
|
||||||
getCurrentDir()
|
################################################################################
|
||||||
elif IS_MACOS:
|
|
||||||
joinPath(homeDir, "Library", "Application Support")
|
|
||||||
elif defined(windows):
|
|
||||||
let targetDir = getEnv("LOCALAPPDATA").string
|
|
||||||
if targetDir == "":
|
|
||||||
joinPath(homeDir, "AppData", "Local")
|
|
||||||
else:
|
|
||||||
targetDir
|
|
||||||
else:
|
|
||||||
let targetDir = getEnv("XDG_CONFIG_HOME").string
|
|
||||||
if targetDir == "":
|
|
||||||
joinPath(homeDir, ".config")
|
|
||||||
else:
|
|
||||||
targetDir
|
|
||||||
absolutePath(joinPath(parentDir, "Status"))
|
|
||||||
|
|
||||||
type StatusDesktopConfig = object
|
|
||||||
dataDir* {.
|
|
||||||
defaultValue: defaultDataDir()
|
|
||||||
desc: "Status Desktop data directory"
|
|
||||||
abbr: "d" .}: string
|
|
||||||
uri* {.
|
|
||||||
defaultValue: ""
|
|
||||||
desc: "status-app:// URI to open a chat or other"
|
|
||||||
name: "uri" .}: string
|
|
||||||
|
|
||||||
|
|
||||||
# On macOS the first time when a user gets the "App downloaded from the
|
|
||||||
# internet" warning, and clicks the Open button, the OS passes a unique process
|
|
||||||
# serial number (PSN) as -psn_... command-line argument, which we remove before
|
|
||||||
# processing the arguments with nim-confutils.
|
|
||||||
# Credit: https://github.com/bitcoin/bitcoin/blame/b6e34afe9735faf97d6be7a90fafd33ec18c0cbb/src/util/system.cpp#L383-L389
|
|
||||||
|
|
||||||
var cliParams = commandLineParams()
|
|
||||||
if IS_MACOS:
|
|
||||||
cliParams.keepIf(proc(p: string): bool = not p.startsWith("-psn_"))
|
|
||||||
|
|
||||||
let desktopConfig = StatusDesktopConfig.load(cliParams)
|
|
||||||
|
|
||||||
let
|
let
|
||||||
baseDir = absolutePath(expandTilde(desktopConfig.dataDir))
|
baseDir = absolutePath(expandTilde(desktopConfig.dataDir))
|
||||||
OPENURI* = desktopConfig.uri
|
OPENURI* = desktopConfig.uri
|
||||||
|
@ -73,22 +31,26 @@ let
|
||||||
TMPDIR* = joinPath(baseDir, "tmp") & sep
|
TMPDIR* = joinPath(baseDir, "tmp") & sep
|
||||||
LOGDIR* = joinPath(baseDir, "logs") & sep
|
LOGDIR* = joinPath(baseDir, "logs") & sep
|
||||||
KEYCARDPAIRINGDATAFILE* = joinPath(baseDir, "data", "keycard/pairings.json")
|
KEYCARDPAIRINGDATAFILE* = joinPath(baseDir, "data", "keycard/pairings.json")
|
||||||
|
DEFAULT_TORRENT_CONFIG_DATADIR* = joinPath(baseDir, "data", "archivedata")
|
||||||
|
DEFAULT_TORRENT_CONFIG_TORRENTDIR* = joinPath(baseDir, "data", "torrents")
|
||||||
|
|
||||||
proc ensureDirectories*(dataDir, tmpDir, logDir: string) =
|
# runtime variables
|
||||||
createDir(dataDir)
|
TEST_MODE_ENABLED* = desktopConfig.testMode
|
||||||
createDir(tmpDir)
|
WALLET_ENABLED* = desktopConfig.enableWallet
|
||||||
createDir(logDir)
|
GANACHE_NETWORK_RPC_URL* = desktopConfig.genacheNetworkRpcUrl
|
||||||
|
TORRENT_CONFIG_PORT* = desktopConfig.defaultTorentConfigPort
|
||||||
|
WAKU_V2_PORT* = desktopConfig.defaultWakuV2Port
|
||||||
|
STATUS_PORT* = desktopConfig.statusPort
|
||||||
|
LOG_LEVEL* = desktopConfig.logLevel
|
||||||
|
|
||||||
# This is changed during compilation by reading the VERSION file
|
# build variables
|
||||||
const DESKTOP_VERSION {.strdefine.} = "0.0.0"
|
POKT_TOKEN_RESOLVED* = desktopConfig.poktToken
|
||||||
const STATUSGO_VERSION* {.strdefine.} = "0.0.0"
|
INFURA_TOKEN_RESOLVED* = desktopConfig.infuraToken
|
||||||
# This is changed during compilation by executing git command
|
INFURA_TOKEN_SECRET_RESOLVED* = desktopConfig.infuraTokenSecret
|
||||||
const GIT_COMMIT* {.strdefine.} = ""
|
ALCHEMY_ETHEREUM_MAINNET_TOKEN_RESOLVED* = desktopConfig.alchemyEthereumMainnetToken
|
||||||
|
ALCHEMY_ETHEREUM_GOERLI_TOKEN_RESOLVED* = desktopConfig.alchemyEthereumGoerliToken
|
||||||
const APP_VERSION* = if defined(production): DESKTOP_VERSION else: fmt("{GIT_COMMIT}")
|
ALCHEMY_ARBITRUM_MAINNET_TOKEN_RESOLVED* = desktopConfig.alchemyArbitrumMainnetToken
|
||||||
|
ALCHEMY_ARBITRUM_GOERLI_TOKEN_RESOLVED* = desktopConfig.alchemyArbitrumGoerliToken
|
||||||
# Name of the test environment var to check for
|
ALCHEMY_OPTIMISM_MAINNET_TOKEN_RESOLVED* = desktopConfig.alchemyOptimismMainnetToken
|
||||||
const STATUS_RUNTIME_TEST_MODE_VAR* = "STATUS_RUNTIME_TEST_MODE"
|
ALCHEMY_OPTIMISM_GOERLI_TOKEN_RESOLVED* = desktopConfig.alchemyOptimismGoerliToken
|
||||||
|
OPENSEA_API_KEY_RESOLVED* = desktopConfig.openseaApiKey
|
||||||
let TEST_MODE_ENABLED* = getEnv(STATUS_RUNTIME_TEST_MODE_VAR).toUpperAscii() == "TRUE" or
|
|
||||||
getEnv(STATUS_RUNTIME_TEST_MODE_VAR) == "1"
|
|
|
@ -0,0 +1,180 @@
|
||||||
|
import os, sequtils, strutils, strformat, chronicles
|
||||||
|
|
||||||
|
import # vendor libs
|
||||||
|
confutils
|
||||||
|
|
||||||
|
const BUILD_TIME_PREFIX = "STATUS_BUILD_"
|
||||||
|
const RUN_TIME_PREFIX = "STATUS_RUNTIME"
|
||||||
|
|
||||||
|
# default log level value
|
||||||
|
const DEFAULT_LOG_LEVEL* = if defined(production): $LogLevel.INFO else: $LogLevel.DEBUG
|
||||||
|
|
||||||
|
# build vars base name
|
||||||
|
const BASE_NAME_INFURA_TOKEN = "INFURA_TOKEN"
|
||||||
|
const BASE_NAME_INFURA_TOKEN_SECRET = "INFURA_TOKEN_SECRET"
|
||||||
|
const BASE_NAME_POKT_TOKEN = "POKT_TOKEN"
|
||||||
|
const BASE_NAME_OPENSEA_API_KEY = "OPENSEA_API_KEY"
|
||||||
|
const BASE_NAME_ALCHEMY_ETHEREUM_MAINNET_TOKEN = "ALCHEMY_ETHEREUM_MAINNET_TOKEN"
|
||||||
|
const BASE_NAME_ALCHEMY_ETHEREUM_GOERLI_TOKEN = "ALCHEMY_ETHEREUM_GOERLI_TOKEN"
|
||||||
|
const BASE_NAME_ALCHEMY_ARBITRUM_MAINNET_TOKEN = "ALCHEMY_ARBITRUM_MAINNET_TOKEN"
|
||||||
|
const BASE_NAME_ALCHEMY_ARBITRUM_GOERLI_TOKEN = "ALCHEMY_ARBITRUM_GOERLI_TOKEN"
|
||||||
|
const BASE_NAME_ALCHEMY_OPTIMISM_MAINNET_TOKEN = "ALCHEMY_OPTIMISM_MAINNET_TOKEN"
|
||||||
|
const BASE_NAME_ALCHEMY_OPTIMISM_GOERLI_TOKEN = "ALCHEMY_OPTIMISM_GOERLI_TOKEN"
|
||||||
|
|
||||||
|
|
||||||
|
################################################################################
|
||||||
|
# Build time evaluated variables
|
||||||
|
################################################################################
|
||||||
|
|
||||||
|
const BUILD_INFURA_TOKEN = getEnv(BUILD_TIME_PREFIX & BASE_NAME_INFURA_TOKEN)
|
||||||
|
const BUILD_INFURA_TOKEN_SECRET = getEnv(BUILD_TIME_PREFIX & BASE_NAME_INFURA_TOKEN_SECRET)
|
||||||
|
const BUILD_POKT_TOKEN = getEnv(BUILD_TIME_PREFIX & BASE_NAME_POKT_TOKEN)
|
||||||
|
const BUILD_OPENSEA_API_KEY = getEnv(BUILD_TIME_PREFIX & BASE_NAME_OPENSEA_API_KEY)
|
||||||
|
const BUILD_ALCHEMY_ETHEREUM_MAINNET_TOKEN = getEnv(BUILD_TIME_PREFIX & BASE_NAME_ALCHEMY_ETHEREUM_MAINNET_TOKEN)
|
||||||
|
const BUILD_ALCHEMY_ETHEREUM_GOERLI_TOKEN = getEnv(BUILD_TIME_PREFIX & BASE_NAME_ALCHEMY_ETHEREUM_GOERLI_TOKEN)
|
||||||
|
const BUILD_ALCHEMY_ARBITRUM_MAINNET_TOKEN = getEnv(BUILD_TIME_PREFIX & BASE_NAME_ALCHEMY_ARBITRUM_MAINNET_TOKEN)
|
||||||
|
const BUILD_ALCHEMY_ARBITRUM_GOERLI_TOKEN = getEnv(BUILD_TIME_PREFIX & BASE_NAME_ALCHEMY_ARBITRUM_GOERLI_TOKEN)
|
||||||
|
const BUILD_ALCHEMY_OPTIMISM_MAINNET_TOKEN = getEnv(BUILD_TIME_PREFIX & BASE_NAME_ALCHEMY_OPTIMISM_MAINNET_TOKEN)
|
||||||
|
const BUILD_ALCHEMY_OPTIMISM_GOERLI_TOKEN = getEnv(BUILD_TIME_PREFIX & BASE_NAME_ALCHEMY_OPTIMISM_GOERLI_TOKEN)
|
||||||
|
|
||||||
|
################################################################################
|
||||||
|
# Run time evaluated variables
|
||||||
|
################################################################################
|
||||||
|
|
||||||
|
proc defaultDataDir*(): string =
|
||||||
|
try:
|
||||||
|
let homeDir = getHomeDir()
|
||||||
|
let parentDir =
|
||||||
|
if defined(development):
|
||||||
|
parentDir(getAppDir())
|
||||||
|
elif homeDir == "":
|
||||||
|
getCurrentDir()
|
||||||
|
elif defined(macosx):
|
||||||
|
joinPath(homeDir, "Library", "Application Support")
|
||||||
|
elif defined(windows):
|
||||||
|
let targetDir = getEnv("LOCALAPPDATA").string
|
||||||
|
if targetDir == "":
|
||||||
|
joinPath(homeDir, "AppData", "Local")
|
||||||
|
else:
|
||||||
|
targetDir
|
||||||
|
else:
|
||||||
|
let targetDir = getEnv("XDG_CONFIG_HOME").string
|
||||||
|
if targetDir == "":
|
||||||
|
joinPath(homeDir, ".config")
|
||||||
|
else:
|
||||||
|
targetDir
|
||||||
|
return absolutePath(joinPath(parentDir, "Status"))
|
||||||
|
except OSError:
|
||||||
|
echo "Error: Unable to determine home directory."
|
||||||
|
|
||||||
|
type StatusDesktopConfig = object
|
||||||
|
# runtime counterparts vars of build vars
|
||||||
|
infuraToken* {.
|
||||||
|
defaultValue: BUILD_INFURA_TOKEN
|
||||||
|
desc: "Sets infura token"
|
||||||
|
name: $BASE_NAME_INFURA_TOKEN
|
||||||
|
abbr: "infura-token" .}: string
|
||||||
|
infuraTokenSecret* {.
|
||||||
|
defaultValue: BUILD_INFURA_TOKEN_SECRET
|
||||||
|
desc: "Sets infura token secret"
|
||||||
|
name: $BASE_NAME_INFURA_TOKEN_SECRET
|
||||||
|
abbr: "infura-token-secret" .}: string
|
||||||
|
poktToken* {.
|
||||||
|
defaultValue: BUILD_POKT_TOKEN
|
||||||
|
desc: "Sets pokt token"
|
||||||
|
name: $BASE_NAME_POKT_TOKEN
|
||||||
|
abbr: "pokt-token" .}: string
|
||||||
|
openSeaApiKey* {.
|
||||||
|
defaultValue: BUILD_OPENSEA_API_KEY
|
||||||
|
desc: "Sets open sea api key"
|
||||||
|
name: $BASE_NAME_OPENSEA_API_KEY
|
||||||
|
abbr: "open-sea-api-key" .}: string
|
||||||
|
alchemyEthereumMainnetToken* {.
|
||||||
|
defaultValue: BUILD_ALCHEMY_ETHEREUM_MAINNET_TOKEN
|
||||||
|
desc: "Sets alchemy ethereum mainnet token"
|
||||||
|
name: $BASE_NAME_ALCHEMY_ETHEREUM_MAINNET_TOKEN
|
||||||
|
abbr: "alchemy-ethereum-mainnet-token" .}: string
|
||||||
|
alchemyEthereumGoerliToken* {.
|
||||||
|
defaultValue: BUILD_ALCHEMY_ETHEREUM_GOERLI_TOKEN
|
||||||
|
desc: "Sets alchemy ethereum goerli token"
|
||||||
|
name: $BASE_NAME_ALCHEMY_ETHEREUM_GOERLI_TOKEN
|
||||||
|
abbr: "alchemy-ethereum-goerli-token" .}: string
|
||||||
|
alchemyArbitrumMainnetToken* {.
|
||||||
|
defaultValue: BUILD_ALCHEMY_ARBITRUM_MAINNET_TOKEN
|
||||||
|
desc: "Sets alchemy arbitrum mainnet token"
|
||||||
|
name: $BASE_NAME_ALCHEMY_ARBITRUM_MAINNET_TOKEN
|
||||||
|
abbr: "alchemy-arbitrum-mainnet-token" .}: string
|
||||||
|
alchemyArbitrumGoerliToken* {.
|
||||||
|
defaultValue: BUILD_ALCHEMY_ARBITRUM_GOERLI_TOKEN
|
||||||
|
desc: "Sets alchemy arbitrum goerli token"
|
||||||
|
name: $BASE_NAME_ALCHEMY_ARBITRUM_GOERLI_TOKEN
|
||||||
|
abbr: "alchemy-arbitrum-goerli-token" .}: string
|
||||||
|
alchemyOptimismMainnetToken* {.
|
||||||
|
defaultValue: BUILD_ALCHEMY_OPTIMISM_MAINNET_TOKEN
|
||||||
|
desc: "Sets alchemy optimism mainnet token"
|
||||||
|
name: $BASE_NAME_ALCHEMY_OPTIMISM_MAINNET_TOKEN
|
||||||
|
abbr: "alchemy-optimism-mainnet-token" .}: string
|
||||||
|
alchemyOptimismGoerliToken* {.
|
||||||
|
defaultValue: BUILD_ALCHEMY_OPTIMISM_GOERLI_TOKEN
|
||||||
|
desc: "Sets alchemy optimism goerli token"
|
||||||
|
name: $BASE_NAME_ALCHEMY_OPTIMISM_GOERLI_TOKEN
|
||||||
|
abbr: "alchemy-optimism-goerli-token" .}: string
|
||||||
|
|
||||||
|
# runtime vars
|
||||||
|
dataDir* {.
|
||||||
|
defaultValue: defaultDataDir()
|
||||||
|
desc: "Status Desktop data directory"
|
||||||
|
abbr: "d" .}: string
|
||||||
|
uri* {.
|
||||||
|
defaultValue: ""
|
||||||
|
desc: "status-app:// URI to open a chat or other"
|
||||||
|
name: "uri" .}: string
|
||||||
|
testMode* {.
|
||||||
|
defaultValue: false
|
||||||
|
desc: "Determines if the app should be run in test mode"
|
||||||
|
name: "TEST_MODE"
|
||||||
|
abbr: "test-mode" .}: bool
|
||||||
|
enableWallet* {.
|
||||||
|
defaultValue: true
|
||||||
|
desc: "Determines if the wallet section is enabled"
|
||||||
|
name: "ENABLE_WALLET"
|
||||||
|
abbr: "enable-wallet" .}: bool
|
||||||
|
genacheNetworkRpcUrl* {.
|
||||||
|
defaultValue: ""
|
||||||
|
desc: "Sets ganache network rpc url"
|
||||||
|
name: "GANACHE_NETWORK_RPC_URL"
|
||||||
|
abbr: "ganache-network-rpc-url" .}: string
|
||||||
|
defaultTorentConfigPort* {.
|
||||||
|
defaultValue: 0
|
||||||
|
desc: "Sets default torrent config port"
|
||||||
|
name: "DEFAULT_TORRENT_CONFIG_PORT"
|
||||||
|
abbr: "default-torrent-config-port" .}: int
|
||||||
|
defaultWakuV2Port* {.
|
||||||
|
defaultValue: 0
|
||||||
|
desc: "Sets default waku v2 port"
|
||||||
|
name: "DEFAULT_WAKU_V2_PORT"
|
||||||
|
abbr: "default-waku-v2-port" .}: int
|
||||||
|
statusPort* {.
|
||||||
|
defaultValue: 0
|
||||||
|
desc: "Sets Waku V1 config port"
|
||||||
|
name: "PORT"
|
||||||
|
abbr: "status-port" .}: int
|
||||||
|
logLevel* {.
|
||||||
|
defaultValue: DEFAULT_LOG_LEVEL
|
||||||
|
desc: "Sets log level"
|
||||||
|
longdesc: "Can be one of: \"ERROR\", \"WARN\", \"INFO\", \"DEBUG\", \"TRACE\". \"INFO\" in production build, otherwise \"DEBUG\""
|
||||||
|
name: "LOG_LEVEL"
|
||||||
|
abbr: "log-level" .}: string
|
||||||
|
|
||||||
|
|
||||||
|
# On macOS the first time when a user gets the "App downloaded from the
|
||||||
|
# internet" warning, and clicks the Open button, the OS passes a unique process
|
||||||
|
# serial number (PSN) as -psn_... command-line argument, which we remove before
|
||||||
|
# processing the arguments with nim-confutils.
|
||||||
|
# Credit: https://github.com/bitcoin/bitcoin/blame/b6e34afe9735faf97d6be7a90fafd33ec18c0cbb/src/util/system.cpp#L383-L389
|
||||||
|
|
||||||
|
var cliParams = commandLineParams()
|
||||||
|
if defined(macosx):
|
||||||
|
cliParams.keepIf(proc(p: string): bool = not p.startsWith("-psn_"))
|
||||||
|
|
||||||
|
let desktopConfig = StatusDesktopConfig.load(cmdLine = cliParams, envVarsPrefix = RUN_TIME_PREFIX)
|
|
@ -55,9 +55,9 @@ proc prepareLogging() =
|
||||||
except:
|
except:
|
||||||
logLoggingFailure(cstring(msg), getCurrentException())
|
logLoggingFailure(cstring(msg), getCurrentException())
|
||||||
|
|
||||||
let defaultLogLvl = if defined(production): LogLevel.INFO else: LogLevel.DEBUG
|
let defaultLogLvl = if defined(production): chronicles.LogLevel.INFO else: chronicles.LogLevel.DEBUG
|
||||||
# default log level can be overriden by LOG_LEVEL env parameter
|
# default log level can be overriden by LOG_LEVEL env parameter
|
||||||
let logLvl = try: parseEnum[LogLevel](getEnv("LOG_LEVEL"))
|
let logLvl = try: parseEnum[chronicles.LogLevel](main_constants.LOG_LEVEL)
|
||||||
except: defaultLogLvl
|
except: defaultLogLvl
|
||||||
|
|
||||||
setLogLevel(logLvl)
|
setLogLevel(logLvl)
|
||||||
|
@ -80,6 +80,11 @@ proc setupRemoteSignalsHandling() =
|
||||||
signal_handler(keycardServiceQObjPointer, p0, "receiveKeycardSignal")
|
signal_handler(keycardServiceQObjPointer, p0, "receiveKeycardSignal")
|
||||||
keycard_go.setSignalEventCallback(callbackKeycardGo)
|
keycard_go.setSignalEventCallback(callbackKeycardGo)
|
||||||
|
|
||||||
|
proc ensureDirectories*(dataDir, tmpDir, logDir: string) =
|
||||||
|
createDir(dataDir)
|
||||||
|
createDir(tmpDir)
|
||||||
|
createDir(logDir)
|
||||||
|
|
||||||
proc mainProc() =
|
proc mainProc() =
|
||||||
|
|
||||||
when defined(macosx) and defined(arm64):
|
when defined(macosx) and defined(arm64):
|
||||||
|
|
|
@ -1 +1 @@
|
||||||
Subproject commit 38dfeaaabdc6792d0f4d701621cbe34001978456
|
Subproject commit 674c9e4c8e0cad2b7193cc9a59c12d39a397750f
|
Loading…
Reference in New Issue