refactor: remove status-go and shim/related modules in nim_status

Also adjust Makefile, GitHub Actions workflow, etc.
This commit is contained in:
Michael Bradley, Jr 2021-03-15 10:55:19 -05:00 committed by Michael Bradley
parent ace63694ad
commit 21aebe41be
43 changed files with 77 additions and 2037 deletions

View File

@ -73,7 +73,6 @@ jobs:
git
unzip
mingw-w64-x86_64-toolchain
mingw-w64-x86_64-go
mingw-w64-x86_64-openssl
mingw-w64-x86_64-pcre
@ -89,9 +88,7 @@ jobs:
- uses: actions/cache@v2
with:
path: |
vendor/nimbus-build-system/vendor/Nim/bin
vendor/status-go/build/bin
path: vendor/nimbus-build-system/vendor/Nim/bin
key: ${{ matrix.platform.os }}-${{ steps.calc-cache-key.outputs.hash }}
- name: Install and build dependencies
@ -108,9 +105,7 @@ jobs:
mkdir -p "${HOME}/.local/bin" && \
ln -f -s /usr/local/Cellar/llvm/*/bin/llvm-ar "${HOME}/.local/bin/ar") || true)
export PATH="${HOME}/.local/bin:${PATH}"
# test-nim and test-c can interfere with each other if run in
# parallel so use `-j1` instead of `-j${NPROC}`
make -j1 \
make \
NIMFLAGS="--parallelBuild:${NPROC}" \
PCRE_INCLUDE_DIR="${{ matrix.platform.pcre_include }}" \
PCRE_LIB_DIR="${{ matrix.platform.pcre_lib }}" \
@ -127,9 +122,7 @@ jobs:
# specify `C:/msys64/` include/lib paths (via `cygpath -m`) to avoid
# problems with msys2 path conversion
run: |
# test-nim and test-c can interfere with each other if run in
# parallel so use `-j1` instead of `-j${NPROC}`
make -j1 \
make \
NIMFLAGS="--parallelBuild:${NPROC}" \
PCRE_INCLUDE_DIR="$(cygpath -m ${{ matrix.platform.pcre_include }})" \
PCRE_LIB_DIR="$(cygpath -m ${{ matrix.platform.pcre_lib }})" \

10
.gitignore vendored
View File

@ -1,16 +1,10 @@
.DS_Store
.idea
.vscode
/build
/data
/keystore
/nim_status.a
/.update.timestamp
/nim_status.nims
/nimcache
/noBackup
/shims.a
/test/c/build
/test/nim/build
/test/build
/vendor/.nimble
TODO
sql_generate

3
.gitmodules vendored
View File

@ -1,9 +1,6 @@
[submodule "vendor/nimbus-build-system"]
path = vendor/nimbus-build-system
url = https://github.com/status-im/nimbus-build-system.git
[submodule "vendor/status-go"]
path = vendor/status-go
url = https://github.com/status-im/status-go.git
[submodule "vendor/nimcrypto"]
path = vendor/nimcrypto
url = https://github.com/cheatfate/nimcrypto.git

203
Makefile
View File

@ -21,23 +21,13 @@ export LINK_PCRE := 0
all \
clean \
clean-build-dirs \
clean-data-dirs \
clean-migration-files \
clean-sqlcipher \
clean-status-go \
clean-migration-file \
create-data-dirs \
deps \
migrations \
nat-libs-sub \
nim_status \
nim_status_go \
shims-for-test-c \
status-go \
sqlcipher \
test \
test-c \
test-c-template \
test-nim \
update
ifeq ($(NIM_PARAMS),)
@ -55,7 +45,7 @@ GIT_SUBMODULE_UPDATE := git submodule update --init --recursive
else # "variables.mk" was included. Business as usual until the end of this file.
all: nim_status
all: sqlcipher
# must be included after the default target
-include $(BUILD_SYSTEM_DIR)/makefiles/targets.mk
@ -69,33 +59,21 @@ else
detected_OS := $(strip $(shell uname))
endif
clean: | clean-common clean-build-dirs clean-data-dirs clean-sqlcipher clean-status-go
clean: | clean-common clean-build-dirs clean-migration-files clean-sqlcipher
clean-build-dirs:
rm -rf \
build \
test/c/build \
test/nim/build
test/build
clean-data-dirs:
rm -rf \
data \
keystore \
noBackup
clean-migration-files:
rm -f \
nim_status/migrations/sql_scripts_accounts.nim \
nim_status/migrations/sql_scripts_app.nim
clean-sqlcipher:
cd vendor/nim-sqlcipher && $(MAKE) clean-build-dirs
cd vendor/nim-sqlcipher && $(MAKE) clean-sqlcipher
clean-status-go:
rm -rf $(shell dirname $(STATUSGO))/*
create-data-dirs:
mkdir -p \
data \
keystore \
noBackup
# nat-libs target assumes libs are in vendor subdir of working directory;
# also, in msys2 environment miniupnpc's Makefile.mingw's invocation of
# `wingenminiupnpcstrings.exe` will fail if containing directory is not in PATH
@ -118,21 +96,6 @@ ifndef SHARED_LIB_EXT
endif
endif
# should be an absolute path when supplied by user
ifndef STATUSGO
STATUSGO := vendor/status-go/build/bin/libstatus.$(SHARED_LIB_EXT)
STATUSGO_LIB_DIR := $(shell pwd)/$(shell dirname $(STATUSGO))
else
STATUSGO_LIB_DIR := $(shell dirname $(STATUSGO))
endif
$(STATUSGO): | deps
echo -e $(BUILD_MSG) "$@"
+ cd vendor/status-go && \
$(MAKE) statusgo-shared-library $(HANDLE_OUTPUT)
status-go: $(STATUSGO)
# These SSL variables and logic work like those in nim-sqlcipher's Makefile
SSL_STATIC ?= true
SSL_INCLUDE_DIR ?= /usr/include
@ -214,97 +177,36 @@ $(MIGRATIONS): | deps
nim_status/migrations/sql_generate nim_status/migrations/accounts > nim_status/migrations/sql_scripts_accounts.nim
nim_status/migrations/sql_generate nim_status/migrations/app > nim_status/migrations/sql_scripts_app.nim
clean-migration-file:
rm -f nim_status/migrations/sql_scripts_accounts.nim
rm -f nim_status/migrations/sql_scripts_app.nim
migrations: clean-migration-file $(MIGRATIONS)
NIMSTATUS ?= build/nim_status.a
$(NIMSTATUS): $(SQLCIPHER) $(MIGRATIONS)
echo -e $(BUILD_MSG) "$@"
+ mkdir -p build
$(ENV_SCRIPT) nim c $(NIM_PARAMS) \
--app:staticLib \
--header \
--nimcache:nimcache/nim_status \
--noMain \
--threads:on \
--tlsEmulation:off \
-o:$@ \
nim_status/c/shim.nim
cp nimcache/nim_status/shim.h build/nim_status.h
mv nim_status.a build/
nim_status: $(NIMSTATUS)
NIMSTATUS_GO ?= build/nim_status_go.a
$(NIMSTATUS_GO):
echo -e $(BUILD_MSG) "$@"
+ mkdir -p build
$(ENV_SCRIPT) nim c $(NIM_PARAMS) \
--app:staticLib \
--header \
--nimcache:nimcache/nim_status_go \
--noMain \
--threads:on \
--tlsEmulation:off \
-o:$@ \
nim_status/c/go/shim.nim
cp nimcache/nim_status_go/shim.h build/nim_status_go.h
mv nim_status_go.a build/
nim_status_go: $(NIMSTATUS_GO)
SHIMS_FOR_TEST_C ?= test/c/build/shims.a
$(SHIMS_FOR_TEST_C): $(SQLCIPHER)
echo -e $(BUILD_MSG) "$@"
+ mkdir -p test/c/build
$(ENV_SCRIPT) nim c $(NIM_PARAMS) \
--app:staticLib \
--header \
--nimcache:nimcache/shims \
--noMain \
--threads:on \
--tlsEmulation:off \
-o:$@ \
test/c/shims.nim
cp nimcache/shims/shims.h test/c/build/shims.h
mv shims.a test/c/build/
shims-for-test-c: $(SHIMS_FOR_TEST_C)
migrations: clean-migration-files $(MIGRATIONS)
ifeq ($(SQLCIPHER_STATIC),false)
PATH_TEST ?= $(shell pwd)/$(shell dirname $(SQLCIPHER)):$(STATUSGO_LIB_DIR):$${PATH}
PATH_TEST ?= $(shell pwd)/$(shell dirname $(SQLCIPHER)):$${PATH}
ifeq ($(PCRE_STATIC),false)
ifeq ($(SSL_STATIC),false)
LD_LIBRARY_PATH_TEST ?= $(shell pwd)/$(shell dirname $(SQLCIPHER)):$(PCRE_LIB_DIR):$(SSL_LIB_DIR):$(STATUSGO_LIB_DIR)$${LD_LIBRARY_PATH:+:$${LD_LIBRARY_PATH}}
LD_LIBRARY_PATH_TEST ?= $(shell pwd)/$(shell dirname $(SQLCIPHER)):$(PCRE_LIB_DIR):$(SSL_LIB_DIR)$${LD_LIBRARY_PATH:+:$${LD_LIBRARY_PATH}}
else
LD_LIBRARY_PATH_TEST ?= $(shell pwd)/$(shell dirname $(SQLCIPHER)):$(PCRE_LIB_DIR):$(STATUSGO_LIB_DIR)$${LD_LIBRARY_PATH:+:$${LD_LIBRARY_PATH}}
LD_LIBRARY_PATH_TEST ?= $(shell pwd)/$(shell dirname $(SQLCIPHER)):$(PCRE_LIB_DIR)$${LD_LIBRARY_PATH:+:$${LD_LIBRARY_PATH}}
endif
else
ifeq ($(SSL_STATIC),false)
LD_LIBRARY_PATH_TEST ?= $(shell pwd)/$(shell dirname $(SQLCIPHER)):$(SSL_LIB_DIR):$(STATUSGO_LIB_DIR)$${LD_LIBRARY_PATH:+:$${LD_LIBRARY_PATH}}
LD_LIBRARY_PATH_TEST ?= $(shell pwd)/$(shell dirname $(SQLCIPHER)):$(SSL_LIB_DIR)$${LD_LIBRARY_PATH:+:$${LD_LIBRARY_PATH}}
else
LD_LIBRARY_PATH_TEST ?= $(shell pwd)/$(shell dirname $(SQLCIPHER)):$(STATUSGO_LIB_DIR)$${LD_LIBRARY_PATH:+:$${LD_LIBRARY_PATH}}
LD_LIBRARY_PATH_TEST ?= $(shell pwd)/$(shell dirname $(SQLCIPHER))$${LD_LIBRARY_PATH:+:$${LD_LIBRARY_PATH}}
endif
endif
else
PATH_TEST ?= $(STATUSGO_LIB_DIR):$${PATH}
PATH_TEST ?= $${PATH}
ifeq ($(PCRE_STATIC),false)
ifeq ($(SSL_STATIC),false)
LD_LIBRARY_PATH_TEST ?= $(PCRE_LIB_DIR):$(SSL_LIB_DIR):$(STATUSGO_LIB_DIR)$${LD_LIBRARY_PATH:+:$${LD_LIBRARY_PATH}}
LD_LIBRARY_PATH_TEST ?= $(PCRE_LIB_DIR):$(SSL_LIB_DIR)$${LD_LIBRARY_PATH:+:$${LD_LIBRARY_PATH}}
else
LD_LIBRARY_PATH_TEST ?= $(PCRE_LIB_DIR):$(STATUSGO_LIB_DIR)$${LD_LIBRARY_PATH:+:$${LD_LIBRARY_PATH}}
LD_LIBRARY_PATH_TEST ?= $(PCRE_LIB_DIR)$${LD_LIBRARY_PATH:+:$${LD_LIBRARY_PATH}}
endif
else
ifeq ($(SSL_STATIC),false)
LD_LIBRARY_PATH_TEST ?= $(SSL_LIB_DIR):$(STATUSGO_LIB_DIR)$${LD_LIBRARY_PATH:+:$${LD_LIBRARY_PATH}}
LD_LIBRARY_PATH_TEST ?= $(SSL_LIB_DIR)$${LD_LIBRARY_PATH:+:$${LD_LIBRARY_PATH}}
else
LD_LIBRARY_PATH_TEST ?= :$(STATUSGO_LIB_DIR)$${LD_LIBRARY_PATH:+:$${LD_LIBRARY_PATH}}
LD_LIBRARY_PATH_TEST ?= $${LD_LIBRARY_PATH}}
endif
endif
endif
@ -323,73 +225,13 @@ else
endif
endif
ifeq ($(detected_OS),Windows)
STATUSGO_SQLCIPHER_LDFLAGS_TEST := -L$(STATUSGO_LIB_DIR) -lstatus $(SQLCIPHER_LDFLAGS_TEST)
else
STATUSGO_SQLCIPHER_LDFLAGS_TEST := $(SQLCIPHER_LDFLAGS_TEST) -L$(STATUSGO_LIB_DIR) -lstatus
endif
ifeq ($(detected_OS),Linux)
PLATFORM_FLAGS_TEST_C ?= -ldl
else ifeq ($(detected_OS),macOS)
PLATFORM_FLAGS_TEST_C ?= -Wl,-headerpad_max_install_names
endif
test-c-template: $(STATUSGO) clean-data-dirs create-data-dirs
echo "Compiling 'test/c/$(TEST_NAME)'"
+ mkdir -p test/c/build
$(ENV_SCRIPT) $(CC) \
$(TEST_INCLUDES) \
-I$(shell pwd)/vendor/nimbus-build-system/vendor/Nim/lib \
test/c/$(TEST_NAME).c \
$(TEST_DEPS) \
$(PCRE_LDFLAGS) \
$(STATUSGO_SQLCIPHER_LDFLAGS_TEST) \
$(SSL_LDFLAGS) \
-lm \
-pthread \
$(PLATFORM_FLAGS_TEST_C) \
-o test/c/build/$(TEST_NAME) $(HANDLE_OUTPUT)
[[ $$? = 0 ]] && \
(([[ $(detected_OS) = macOS ]] && \
install_name_tool -add_rpath \
$(STATUSGO_LIB_DIR) \
test/c/build/$(TEST_NAME) $(HANDLE_OUTPUT) && \
install_name_tool -change \
libstatus.dylib \
@rpath/libstatus.dylib \
test/c/build/$(TEST_NAME) $(HANDLE_OUTPUT)) || true)
echo "Executing 'test/c/build/$(TEST_NAME)'"
ifeq ($(detected_OS),macOS)
./test/c/build/$(TEST_NAME)
else ifeq ($(detected_OS),Windows)
PATH="$(PATH_TEST)" \
./test/c/build/$(TEST_NAME)
else
LD_LIBRARY_PATH="$(LD_LIBRARY_PATH_TEST)" \
./test/c/build/$(TEST_NAME)
endif
SHIMS_FOR_TEST_C_INCLUDES ?= -I$(shell pwd)/test/c/build
LOGIN_TEST_INCLUDES ?= -I$(shell pwd)/build
test-c:
rm -rf test/c/build
$(MAKE) $(SHIMS_FOR_TEST_C)
$(MAKE) TEST_DEPS=$(SHIMS_FOR_TEST_C) \
TEST_INCLUDES=$(SHIMS_FOR_TEST_C_INCLUDES) \
TEST_NAME=shims \
test-c-template
rm -rf test/c/build
$(MAKE) $(NIMSTATUS_GO)
$(MAKE) TEST_DEPS=$(NIMSTATUS_GO) \
TEST_INCLUDES=$(LOGIN_TEST_INCLUDES) \
TEST_NAME=login \
test-c-template
test-nim: $(STATUSGO) $(SQLCIPHER) $(MIGRATIONS)
test: $(SQLCIPHER) $(MIGRATIONS)
ifeq ($(detected_OS),macOS)
NIMSTATUS_CFLAGS="$(NIMSTATUS_CFLAGS)" \
PCRE_LDFLAGS="$(PCRE_LDFLAGS)" \
@ -397,7 +239,6 @@ ifeq ($(detected_OS),macOS)
SQLCIPHER_LDFLAGS="$(SQLCIPHER_LDFLAGS_TEST)" \
SSL_LDFLAGS="$(SSL_LDFLAGS)" \
SSL_STATIC="$(SSL_STATIC)" \
STATUSGO_LIB_DIR="$(STATUSGO_LIB_DIR)" \
$(ENV_SCRIPT) nimble tests
else ifeq ($(detected_OS),Windows)
NIMSTATUS_CFLAGS="$(NIMSTATUS_CFLAGS)" \
@ -407,7 +248,6 @@ else ifeq ($(detected_OS),Windows)
SQLCIPHER_LDFLAGS="$(SQLCIPHER_LDFLAGS_TEST)" \
SSL_LDFLAGS="$(SSL_LDFLAGS)" \
SSL_STATIC="$(SSL_STATIC)" \
STATUSGO_LIB_DIR="$(STATUSGO_LIB_DIR)" \
$(ENV_SCRIPT) nimble tests
else
LD_LIBRARY_PATH="$(LD_LIBRARY_PATH_TEST)" \
@ -417,10 +257,7 @@ else
SQLCIPHER_LDFLAGS="$(SQLCIPHER_LDFLAGS_TEST)" \
SSL_LDFLAGS="$(SSL_LDFLAGS)" \
SSL_STATIC="$(SSL_STATIC)" \
STATUSGO_LIB_DIR="$(STATUSGO_LIB_DIR)" \
$(ENV_SCRIPT) nimble tests
endif
test: test-nim test-c
endif # "variables.mk" was not included

View File

@ -3,46 +3,28 @@
![Stability: experimental](https://img.shields.io/badge/Stability-experimental-orange.svg)
[![Tests (GitHub Actions)](https://github.com/status-im/nim-status/workflows/Tests/badge.svg?branch=master)](https://github.com/status-im/nim-status/actions?query=workflow%3ATests+branch%3Amaster)
Nim implementation of the Status protocol: https://github.com/status-im/specs
Nim implementation of the [Status protocol](https://github.com/status-im/specs).
Corresponds roughly to status-go: https://github.com/status-im/status-go which is consumed by status-react: https://github.com/status-im/status-react/
Corresponds roughly to [status-go](https://github.com/status-im/status-go), which is consumed by [status-react](https://github.com/status-im/status-react/).
### Requirements
* Go - (used to build status-go)
```
# Linux
<TODO>
# macOS
brew install go
```
### Installation
## Installation
```
git clone https://github.com/status-im/nim-status
cd nim-status
make update
make
make PCRE_INCLUDE_DIR=... PCRE_LIB_DIR=... SSL_INCLUDE_DIR=... SSL_LIB_DIR=...
```
For more output use `make V=1 ...`.
Use 4 CPU cores with `make -j4 ...`.
### Usage
- Include `build/nim_status.a`, `build/nim_status.h` in your project
- Before any of the API calls are done, NimMain() needs to be run.
## Usage
### Troubleshooting
If the `make` command fails due to already installed Homebrew packages, such as:
```
Error: protobuf 3.11.4 is already installed
To upgrade to 3.11.4_1, run `brew upgrade protobuf`.
make[1]: *** [install-os-dependencies] Error 1
make: *** [vendor/status-go/build/bin/libstatus.a] Error 2
```nim
import nim_status
```
This can be fixed by uninstalling the package e.g. `brew uninstall protobuf` followed by rerunning `make`.
## License
Licensed and distributed under the [MIT License](https://github.com/status-im/nim-status/blob/master/LICENSE).

View File

@ -22,17 +22,11 @@ requires "nim >= 1.2.0",
import strutils
proc buildAndRunTest(name: string,
srcDir = "test/nim/",
outDir = "test/nim/build/",
srcDir = "test/",
outDir = "test/build/",
params = "",
cmdParams = "",
lang = "c") =
rmDir "data"
rmDir "keystore"
rmDir "noBackup"
mkDir "data"
mkDir "keystore"
mkDir "noBackup"
rmDir outDir
mkDir outDir
# allow something like "nim test --verbosity:0 --hints:off beacon_chain.nims"
@ -52,7 +46,7 @@ proc buildAndRunTest(name: string,
" --out:" & outDir & name &
(if getEnv("NIMSTATUS_CFLAGS").strip != "": " --passC:\"" & getEnv("NIMSTATUS_CFLAGS") & "\"" else: "") &
(if getEnv("PCRE_LDFLAGS").strip != "": " --passL:\"" & getEnv("PCRE_LDFLAGS") & "\"" else: "") &
(if defined(windows): " --passL:\"-L" & getEnv("STATUSGO_LIB_DIR") & " -lstatus" & "\"" & (if getEnv("SQLCIPHER_LDFLAGS").strip != "": " --passL:\"" & getEnv("SQLCIPHER_LDFLAGS") & "\"" else: "") else: (if getEnv("SQLCIPHER_LDFLAGS").strip != "": " --passL:\"" & getEnv("SQLCIPHER_LDFLAGS") & "\"" else: "") & " --passL:\"-L" & getEnv("STATUSGO_LIB_DIR") & " -lstatus" & "\"") &
(if getEnv("SQLCIPHER_LDFLAGS").strip != "": " --passL:\"" & getEnv("SQLCIPHER_LDFLAGS") & "\"" else: "") &
(if getEnv("SSL_LDFLAGS").strip != "": " --passL:\"" & getEnv("SSL_LDFLAGS") & "\"" else: "") &
(if defined(macosx): " --passL:-headerpad_max_install_names" else: "") &
" --stacktrace:on" &
@ -64,14 +58,7 @@ proc buildAndRunTest(name: string,
srcDir & name & ".nim" &
" " &
cmdParams
if defined(macosx):
exec "install_name_tool -add_rpath " & getEnv("STATUSGO_LIB_DIR") & " " & outDir & name
exec "install_name_tool -change libstatus.dylib @rpath/libstatus.dylib " & outDir & name
exec outDir & name
if defined(windows):
rmDir "data"
rmDir "keystore"
rmDir "noBackup"
task tests, "Run all tests":
buildAndRunTest "test_all"

View File

@ -1,71 +0,0 @@
# This module (see also `./shim_impl.nim`) wraps the API supplied by status-go
# when it is compiled into `libstatus.a` or `libstatus.dll|dylib|so`.
# It is expected that this module will be compiled into an archive so that it
# can be consumed as a C library (see the `nim_status_go` target in this repo's
# Makefile, which compiles this module into `build/nim_status_go.a`). It is the
# responsibility of the user to link status-go compiled to `libstatus` into the
# final executable.
import ./shim_impl as go_shim
let hashMessage {.exportc.} = go_shim.hashMessage
let initKeystore {.exportc.} = go_shim.initKeystore
let openAccounts {.exportc.} = go_shim.openAccounts
let multiAccountGenerateAndDeriveAddresses {.exportc.} = go_shim.multiAccountGenerateAndDeriveAddresses
let multiAccountStoreDerivedAccounts {.exportc.} = go_shim.multiAccountStoreDerivedAccounts
let multiAccountImportMnemonic {.exportc.} = go_shim.multiAccountImportMnemonic
let multiAccountImportPrivateKey {.exportc.} = go_shim.multiAccountImportPrivateKey
let multiAccountDeriveAddresses {.exportc.} = go_shim.multiAccountDeriveAddresses
let saveAccountAndLogin {.exportc.} = go_shim.saveAccountAndLogin
let deleteMultiAccount {.exportc.} = go_shim.deleteMultiAccount
let callRPC {.exportc.} = go_shim.callRPC
let callPrivateRPC {.exportc.} = go_shim.callPrivateRPC
let addPeer {.exportc.} = go_shim.addPeer
let sendTransaction {.exportc.} = go_shim.sendTransaction
let generateAlias {.exportc.} = go_shim.generateAlias
let identicon {.exportc.} = go_shim.identicon
let login {.exportc.} = go_shim.login
let logout {.exportc.} = go_shim.logout
let verifyAccountPassword {.exportc.} = go_shim.verifyAccountPassword
let validateMnemonic {.exportc.} = go_shim.validateMnemonic
let saveAccountAndLoginWithKeycard {.exportc.} = go_shim.saveAccountAndLoginWithKeycard
let hashTransaction {.exportc.} = go_shim.hashTransaction
let extractGroupMembershipSignatures {.exportc.} = go_shim.extractGroupMembershipSignatures
let connectionChange {.exportc.} = go_shim.connectionChange
let multiformatSerializePublicKey {.exportc.} = go_shim.multiformatSerializePublicKey
let multiformatDeserializePublicKey {.exportc.} = go_shim.multiformatDeserializePublicKey
let validateNodeConfig {.exportc.} = go_shim.validateNodeConfig
let loginWithKeycard {.exportc.} = go_shim.loginWithKeycard
let recover {.exportc.} = go_shim.recover
let writeHeapProfile {.exportc.} = go_shim.writeHeapProfile
let hashTypedData {.exportc.} = go_shim.hashTypedData
let resetChainData {.exportc.} = go_shim.resetChainData
let signMessage {.exportc.} = go_shim.signMessage
let signTypedData {.exportc.} = go_shim.signTypedData
let stopCPUProfiling {.exportc.} = go_shim.stopCPUProfiling
let getNodesFromContract {.exportc.} = go_shim.getNodesFromContract
let exportNodeLogs {.exportc.} = go_shim.exportNodeLogs
let chaosModeUpdate {.exportc.} = go_shim.chaosModeUpdate
let signHash {.exportc.} = go_shim.signHash
let sendTransactionWithSignature {.exportc.} = go_shim.sendTransactionWithSignature
let startCPUProfile {.exportc.} = go_shim.startCPUProfile
let appStateChange {.exportc.} = go_shim.appStateChange
let signGroupMembership {.exportc.} = go_shim.signGroupMembership
let multiAccountStoreAccount {.exportc.} = go_shim.multiAccountStoreAccount
let multiAccountLoadAccount {.exportc.} = go_shim.multiAccountLoadAccount
let multiAccountGenerate {.exportc.} = go_shim.multiAccountGenerate
let multiAccountReset {.exportc.} = go_shim.multiAccountReset
let migrateKeyStoreDir {.exportc.} = go_shim.migrateKeyStoreDir
let startWallet {.exportc.} = go_shim.startWallet
let stopWallet {.exportc.} = go_shim.stopWallet
let startLocalNotifications {.exportc.} = go_shim.startLocalNotifications
let stopLocalNotifications {.exportc.} = go_shim.stopLocalNotifications
type SignalCallback {.exportc: "SignalCallback".} = proc(eventMessage: cstring): void {.cdecl.}
proc setSignalEventCallback(callback: SignalCallback) {.exportc.} =
go_shim.setSignalEventCallback(callback)
let setupForeignThreadGc {.exportc.} = setupForeignThreadGc
let tearDownForeignThreadGc {.exportc.} = tearDownForeignThreadGc

View File

@ -1,110 +0,0 @@
import ./signals
# All procs start with lowercase because the compiler will also need to import
# status-go, and it will complain of duplication of function names
proc hashMessage*(message: cstring): cstring {.importc: "HashMessage".}
proc initKeystore*(keydir: cstring): cstring {.importc: "InitKeystore".}
proc openAccounts*(datadir: cstring): cstring {.importc: "OpenAccounts".}
proc multiAccountGenerateAndDeriveAddresses*(paramsJSON: cstring): cstring {.importc: "MultiAccountGenerateAndDeriveAddresses".}
proc multiAccountStoreDerivedAccounts*(paramsJSON: cstring): cstring {.importc: "MultiAccountStoreDerivedAccounts".}
proc multiAccountImportMnemonic*(paramsJSON: cstring): cstring {.importc: "MultiAccountImportMnemonic".}
proc multiAccountImportPrivateKey*(paramsJSON: cstring): cstring {.importc: "MultiAccountImportPrivateKey".}
proc multiAccountDeriveAddresses*(paramsJSON: cstring): cstring {.importc: "MultiAccountDeriveAddresses".}
proc saveAccountAndLogin*(accountData: cstring, password: cstring, settingsJSON: cstring, configJSON: cstring, subaccountData: cstring): cstring {.importc: "SaveAccountAndLogin".}
proc deleteMultiAccount*(keyUID: cstring, keyStoreDir: cstring): cstring {.importc: "DeleteMultiaccount".}
proc callRPC*(inputJSON: cstring): cstring {.importc: "CallRPC".}
proc callPrivateRPC*(inputJSON: cstring): cstring {.importc: "CallPrivateRPC".}
proc addPeer*(peer: cstring): cstring {.importc: "AddPeer".}
proc setSignalEventCallback*(callback: SignalCallback) {.importc: "SetSignalEventCallback".}
proc sendTransaction*(jsonArgs: cstring, password: cstring): cstring {.importc: "SendTransaction".}
proc generateAlias*(pk: cstring): cstring {.importc: "GenerateAlias".}
proc identicon*(pk: cstring): cstring {.importc: "Identicon".}
proc login*(accountData: cstring, password: cstring): cstring {.importc: "Login".}
proc logout*(): cstring {.importc: "Logout".}
proc verifyAccountPassword*(keyStoreDir: cstring, address: cstring, password: cstring): cstring {.importc: "VerifyAccountPassword".}
proc validateMnemonic*(mnemonic: cstring): cstring {.importc: "ValidateMnemonic".}
proc saveAccountAndLoginWithKeycard*(accountData: cstring, password: cstring, settingsJSON: cstring, configJSON: cstring, subaccountData: cstring, keyHex: cstring): cstring {.importc: "SaveAccountAndLoginWithKeycard".}
proc hashTransaction*(txArgsJSON: cstring): cstring {.importc: "HashTransaction".}
proc extractGroupMembershipSignatures*(signaturePairsStr: cstring): cstring {.importc: "ExtractGroupMembershipSignatures".}
proc connectionChange*(typ: cstring, expensive: cstring) {.importc: "ConnectionChange".}
proc multiformatSerializePublicKey*(key: cstring, outBase: cstring): cstring {.importc: "MultiformatSerializePublicKey".}
proc multiformatDeserializePublicKey*(key: cstring, outBase: cstring): cstring {.importc: "MultiformatDeserializePublicKey".}
proc validateNodeConfig*(configJSON: cstring): cstring {.importc: "ValidateNodeConfig".}
proc loginWithKeycard*(accountData: cstring, password: cstring, keyHex: cstring): cstring {.importc: "LoginWithKeycard".}
proc recover*(rpcParams: cstring): cstring {.importc: "Recover".}
proc writeHeapProfile*(dataDir: cstring): cstring {.importc: "WriteHeapProfile".}
proc hashTypedData*(data: cstring): cstring {.importc: "HashTypedData".}
proc resetChainData*(): cstring {.importc: "ResetChainData".}
proc signMessage*(rpcParams: cstring): cstring {.importc: "SignMessage".}
proc signTypedData*(data: cstring, address: cstring, password: cstring): cstring {.importc: "SignTypedData".}
proc stopCPUProfiling*(): cstring {.importc: "StopCPUProfiling".}
proc getNodesFromContract*(rpcEndpoint: cstring, contractAddress: cstring): cstring {.importc: "GetNodesFromContract".}
proc exportNodeLogs*(): cstring {.importc: "ExportNodeLogs".}
proc chaosModeUpdate*(on: cint): cstring {.importc: "ChaosModeUpdate".}
proc signHash*(hexEncodedHash: cstring): cstring {.importc: "SignHash".}
proc sendTransactionWithSignature*(txtArgsJSON: cstring, sigString: cstring): cstring {.importc: "SendTransactionWithSignature".}
proc startCPUProfile*(dataDir: cstring): cstring {.importc: "StartCPUProfile".}
proc appStateChange*(state: cstring) {.importc: "AppStateChange".}
proc signGroupMembership*(content: cstring): cstring {.importc: "SignGroupMembership".}
proc multiAccountStoreAccount*(paramsJSON: cstring): cstring {.importc: "MultiAccountStoreAccount".}
proc multiAccountLoadAccount*(paramsJSON: cstring): cstring {.importc: "MultiAccountLoadAccount".}
proc multiAccountGenerate*(paramsJSON: cstring): cstring {.importc: "MultiAccountGenerate".}
proc multiAccountReset*(): cstring {.importc: "MultiAccountReset".}
proc migrateKeyStoreDir*(accountData: cstring, password: cstring, oldKeystoreDir: cstring, multiaccountKeystoreDir: cstring): cstring {.importc: "MigrateKeyStoreDir".}
proc startWallet*(watchNewBlocks: bool): cstring {.importc: "StartWallet".}
proc stopWallet*(): cstring {.importc: "StopWallet".}
proc startLocalNotifications*(): cstring {.importc: "StartLocalNotifications".}
proc stopLocalNotifications*(): cstring {.importc: "StopLocalNotifications".}

View File

@ -1 +0,0 @@
type SignalCallback* = proc(eventMessage: cstring): void {.cdecl.}

View File

@ -1,82 +0,0 @@
# The goal of this module (see also `./shim_impl.nim`) is to wrap the APIs
# re-exported by this library's root `nim_status.nim` such that the function
# names, parameter types, return types, and overall behavior match the API of
# status-go when it is compiled into `libstatus.a`.
# NOTE: this module is completely independent of status-go and is intended
# primarily as a means for consumers of status-go (e.g. status-react) to
# transition from status-go's API to nim-status' own APIs.
# It is expected that this module will be compiled into an archive so that it
# can be consumed as a C library (see the `nim_status` target in this repo's
# Makefile, which compiles this module into `build/nim_status.a`). If this
# module is successfully implemented in full, `nim_status.a` will be able to
# serve as a drop-in replacement for `libstatus.a`.
# In the future there may be a module in `nim_status/c/` that is intended to be
# compiled into an archive (consumable as a C library) providing nim-status'
# own APIs *without* a status-go compatibility wrapper, but at present there is
# no such module since those APIs are still taking shape.
import ./shim_impl as nim_shim
let HashMessage {.exportc.} = nim_shim.hashMessage
let InitKeystore {.exportc.} = nim_shim.initKeystore
let OpenAccounts {.exportc.} = nim_shim.openAccounts
let MultiAccountGenerateAndDeriveAddresses {.exportc.} = nim_shim.multiAccountGenerateAndDeriveAddresses
let MultiAccountStoreDerivedAccounts {.exportc.} = nim_shim.multiAccountStoreDerivedAccounts
let MultiAccountImportMnemonic {.exportc.} = nim_shim.multiAccountImportMnemonic
let MultiAccountImportPrivateKey {.exportc.} = nim_shim.multiAccountImportPrivateKey
let MultiAccountDeriveAddresses {.exportc.} = nim_shim.multiAccountDeriveAddresses
let SaveAccountAndLogin {.exportc.} = nim_shim.saveAccountAndLogin
let DeleteMultiAccount {.exportc.} = nim_shim.deleteMultiAccount
let CallRPC {.exportc.} = nim_shim.callRPC
let CallPrivateRPC {.exportc.} = nim_shim.callPrivateRPC
let AddPeer {.exportc.} = nim_shim.addPeer
let SendTransaction {.exportc.} = nim_shim.sendTransaction
let GenerateAlias {.exportc.} = nim_shim.generateAlias
let Identicon {.exportc.} = nim_shim.identicon
let Login {.exportc.} = nim_shim.login
let Logout {.exportc.} = nim_shim.logout
let VerifyAccountPassword {.exportc.} = nim_shim.verifyAccountPassword
let ValidateMnemonic {.exportc.} = nim_shim.validateMnemonic
let SaveAccountAndLoginWithKeycard {.exportc.} = nim_shim.saveAccountAndLoginWithKeycard
let HashTransaction {.exportc.} = nim_shim.hashTransaction
let ExtractGroupMembershipSignatures {.exportc.} = nim_shim.extractGroupMembershipSignatures
let ConnectionChange {.exportc.} = nim_shim.connectionChange
let MultiformatSerializePublicKey {.exportc.} = nim_shim.multiformatSerializePublicKey
let MultiformatDeserializePublicKey {.exportc.} = nim_shim.multiformatDeserializePublicKey
let ValidateNodeConfig {.exportc.} = nim_shim.validateNodeConfig
let LoginWithKeycard {.exportc.} = nim_shim.loginWithKeycard
let Recover {.exportc.} = nim_shim.recover
let WriteHeapProfile {.exportc.} = nim_shim.writeHeapProfile
let HashTypedData {.exportc.} = nim_shim.hashTypedData
let ResetChainData {.exportc.} = nim_shim.resetChainData
let SignMessage {.exportc.} = nim_shim.signMessage
let SignTypedData {.exportc.} = nim_shim.signTypedData
let StopCPUProfiling {.exportc.} = nim_shim.stopCPUProfiling
let GetNodesFromContract {.exportc.} = nim_shim.getNodesFromContract
let ExportNodeLogs {.exportc.} = nim_shim.exportNodeLogs
let ChaosModeUpdate {.exportc.} = nim_shim.chaosModeUpdate
let SignHash {.exportc.} = nim_shim.signHash
let SendTransactionWithSignature {.exportc.} = nim_shim.sendTransactionWithSignature
let StartCPUProfile {.exportc.} = nim_shim.startCPUProfile
let AppStateChange {.exportc.} = nim_shim.appStateChange
let SignGroupMembership {.exportc.} = nim_shim.signGroupMembership
let MultiAccountStoreAccount {.exportc.} = nim_shim.multiAccountStoreAccount
let MultiAccountLoadAccount {.exportc.} = nim_shim.multiAccountLoadAccount
let MultiAccountGenerate {.exportc.} = nim_shim.multiAccountGenerate
let MultiAccountReset {.exportc.} = nim_shim.multiAccountReset
let MigrateKeyStoreDir {.exportc.} = nim_shim.migrateKeyStoreDir
let StartWallet {.exportc.} = nim_shim.startWallet
let StopWallet {.exportc.} = nim_shim.stopWallet
let StartLocalNotifications {.exportc.} = nim_shim.startLocalNotifications
let StopLocalNotifications {.exportc.} = nim_shim.stopLocalNotifications
type SignalCallback {.exportc: "SignalCallback".} = proc(eventMessage: cstring): void {.cdecl.}
proc SetSignalEventCallback(callback: SignalCallback) {.exportc.} =
nim_shim.setSignalEventCallback(callback)
let setupForeignThreadGc {.exportc.} = setupForeignThreadGc
let tearDownForeignThreadGc {.exportc.} = tearDownForeignThreadGc

View File

@ -1,181 +0,0 @@
import strformat
import ../../nim_status as nim_status
import ./go/signals
import ./sys
export SignalCallback
proc notImplemented() =
writeStackTrace()
raise newException(Defect, "NOT IMPLEMENTED")
proc hashMessage*(message: cstring): cstring =
var hash = nim_status.hashMessage($message)
# status-go compatible formatting
hash = fmt("{{\"result\":\"{hash}\"}}")
result = cast[cstring](c_malloc(csize_t hash.len + 1))
copyMem(result, hash.cstring, hash.len)
result[hash.len] = '\0'
proc initKeystore*(keydir: cstring): cstring =
notImplemented()
proc openAccounts*(datadir: cstring): cstring =
notImplemented()
proc multiAccountGenerateAndDeriveAddresses*(paramsJSON: cstring): cstring =
notImplemented()
proc multiAccountStoreDerivedAccounts*(paramsJSON: cstring): cstring =
notImplemented()
proc multiAccountImportMnemonic*(paramsJSON: cstring): cstring =
notImplemented()
proc multiAccountImportPrivateKey*(paramsJSON: cstring): cstring =
notImplemented()
proc multiAccountDeriveAddresses*(paramsJSON: cstring): cstring =
notImplemented()
proc saveAccountAndLogin*(accountData: cstring, password: cstring, settingsJSON: cstring, configJSON: cstring, subaccountData: cstring): cstring =
notImplemented()
proc deleteMultiAccount*(keyUID: cstring, keyStoreDir: cstring): cstring =
notImplemented()
proc callRPC*(inputJSON: cstring): cstring =
notImplemented()
proc callPrivateRPC*(inputJSON: cstring): cstring =
notImplemented()
proc addPeer*(peer: cstring): cstring =
notImplemented()
proc setSignalEventCallback*(callback: SignalCallback) =
notImplemented()
proc sendTransaction*(jsonArgs: cstring, password: cstring): cstring =
notImplemented()
proc generateAlias*(pubKey: cstring): cstring =
let alias = nim_status.generateAlias($pubKey)
result = cast[cstring](c_malloc(csize_t alias.len + 1))
copyMem(result, alias.cstring, alias.len)
result[alias.len] = '\0'
proc identicon*(pubKey: cstring): cstring =
let icon = nim_status.identicon($pubKey)
result = cast[cstring](c_malloc(csize_t icon.len + 1))
copyMem(result, icon.cstring, icon.len)
result[icon.len] = '\0'
proc login*(accountData: cstring, password: cstring): cstring =
notImplemented()
proc logout*(): cstring =
notImplemented()
proc verifyAccountPassword*(keyStoreDir: cstring, address: cstring, password: cstring): cstring =
notImplemented()
proc validateMnemonic*(mnemonic: cstring): cstring =
notImplemented()
proc saveAccountAndLoginWithKeycard*(accountData: cstring, password: cstring, settingsJSON: cstring, configJSON: cstring, subaccountData: cstring, keyHex: cstring): cstring =
notImplemented()
proc hashTransaction*(txArgsJSON: cstring): cstring =
notImplemented()
proc extractGroupMembershipSignatures*(signaturePairsStr: cstring): cstring =
notImplemented()
proc connectionChange*(typ: cstring, expensive: cstring) =
notImplemented()
proc multiformatSerializePublicKey*(key: cstring, outBase: cstring): cstring =
notImplemented()
proc multiformatDeserializePublicKey*(key: cstring, outBase: cstring): cstring =
notImplemented()
proc validateNodeConfig*(configJSON: cstring): cstring =
notImplemented()
proc loginWithKeycard*(accountData: cstring, password: cstring, keyHex: cstring): cstring =
notImplemented()
proc recover*(rpcParams: cstring): cstring =
notImplemented()
proc writeHeapProfile*(dataDir: cstring): cstring =
notImplemented()
proc hashTypedData*(data: cstring): cstring =
notImplemented()
proc resetChainData*(): cstring =
notImplemented()
proc signMessage*(rpcParams: cstring): cstring =
notImplemented()
proc signTypedData*(data: cstring, address: cstring, password: cstring): cstring =
notImplemented()
proc stopCPUProfiling*(): cstring =
notImplemented()
proc getNodesFromContract*(rpcEndpoint: cstring, contractAddress: cstring): cstring =
notImplemented()
proc exportNodeLogs*(): cstring =
notImplemented()
proc chaosModeUpdate*(on: cint): cstring =
notImplemented()
proc signHash*(hexEncodedHash: cstring): cstring =
notImplemented()
proc sendTransactionWithSignature*(txtArgsJSON: cstring, sigString: cstring): cstring =
notImplemented()
proc startCPUProfile*(dataDir: cstring): cstring =
notImplemented()
proc appStateChange*(state: cstring) =
notImplemented()
proc signGroupMembership*(content: cstring): cstring =
notImplemented()
proc multiAccountStoreAccount*(paramsJSON: cstring): cstring =
notImplemented()
proc multiAccountLoadAccount*(paramsJSON: cstring): cstring =
notImplemented()
proc multiAccountGenerate*(paramsJSON: cstring): cstring =
notImplemented()
proc multiAccountReset*(): cstring =
notImplemented()
proc migrateKeyStoreDir*(accountData: cstring, password: cstring, oldKeystoreDir: cstring, multiaccountKeystoreDir: cstring): cstring =
notImplemented()
proc startWallet*(watchNewBlocks: bool): cstring =
notImplemented()
proc stopWallet*(): cstring =
notImplemented()
proc startLocalNotifications*(): cstring =
notImplemented()
proc stopLocalNotifications*(): cstring =
notImplemented()

View File

@ -1 +0,0 @@
proc c_malloc*(size: csize_t): pointer {.importc: "malloc", header: "<stdlib.h>".}

View File

@ -1,174 +0,0 @@
# This module (see also `../c/go/shim_impl.nim`) wraps the API supplied by
# status-go when it is compiled into `libstatus.a` or `libstatus.dll|dylib|so`.
# It is expected that this module will be consumed as an import in another Nim
# module; when doing so, it is not necessary to separately compile
# `../c/go/shim.nim` but it is the responsibility of the user to link status-go
# compiled to `libstatus` into the final executable.
import ../c/go/shim_impl as go_shim
import ../c/go/signals
export SignalCallback
# All procs start with lowercase because the compiler will also need to import
# status-go, and it will complain of duplication of function names
proc hashMessage*(message: string): string =
$go_shim.hashMessage(message.cstring)
proc initKeystore*(keydir: string): string =
$go_shim.initKeystore(keydir.cstring)
proc openAccounts*(datadir: string): string =
$go_shim.openAccounts(datadir.cstring)
proc multiAccountGenerateAndDeriveAddresses*(paramsJSON: string): string =
$go_shim.multiAccountGenerateAndDeriveAddresses(paramsJSON.cstring)
proc multiAccountStoreDerivedAccounts*(paramsJSON: string): string =
$go_shim.multiAccountStoreDerivedAccounts(paramsJSON.cstring)
proc multiAccountImportMnemonic*(paramsJSON: string): string =
$go_shim.multiAccountImportMnemonic(paramsJSON.cstring)
proc multiAccountImportPrivateKey*(paramsJSON: string): string =
$go_shim.multiAccountImportPrivateKey(paramsJSON.cstring)
proc multiAccountDeriveAddresses*(paramsJSON: string): string =
$go_shim.multiAccountDeriveAddresses(paramsJSON.cstring)
proc saveAccountAndLogin*(accountData: string, password: string, settingsJSON: string, configJSON: string, subaccountData: string): string =
$go_shim.saveAccountAndLogin(accountData.cstring, password.cstring, settingsJSON.cstring, configJSON.cstring, subaccountData.cstring)
proc deleteMultiAccount*(keyUID: string, keyStoreDir: string): string =
$go_shim.deleteMultiAccount(keyUID.cstring, keyStoreDir.cstring)
proc callRPC*(inputJSON: string): string =
$go_shim.callRPC(inputJSON.cstring)
proc callPrivateRPC*(inputJSON: string): string =
$go_shim.callPrivateRPC(inputJSON.cstring)
proc addPeer*(peer: string): string =
$go_shim.addPeer(peer.cstring)
proc setSignalEventCallback*(callback: SignalCallback) =
go_shim.setSignalEventCallback(callback)
proc sendTransaction*(jsonArgs: string, password: string): string =
$go_shim.sendTransaction(jsonArgs.cstring, password.cstring)
proc generateAlias*(pk: string): string =
$go_shim.generateAlias(pk)
proc identicon*(pk: string): string =
$go_shim.identicon(pk)
proc login*(accountData: string, password: string): string =
$go_shim.login(accountData.cstring, password.cstring)
proc logout*(): string =
$go_shim.logout()
proc verifyAccountPassword*(keyStoreDir: string, address: string, password: string): string =
$go_shim.verifyAccountPassword(keyStoreDir.cstring, address.cstring, password.cstring)
proc validateMnemonic*(mnemonic: string): string =
$go_shim.validateMnemonic(mnemonic.cstring)
proc saveAccountAndLoginWithKeycard*(accountData: string, password: string, settingsJSON: string, configJSON: string, subaccountData: string, keyHex: string): string =
$go_shim.saveAccountAndLoginWithKeycard(accountData.cstring, password.cstring, settingsJSON.cstring, configJSON.cstring, subaccountData.cstring, keyHex.cstring)
proc hashTransaction*(txArgsJSON: string): string =
$go_shim.hashTransaction(txArgsJSON.cstring)
proc extractGroupMembershipSignatures*(signaturePairsStr: string): string =
$go_shim.extractGroupMembershipSignatures(signaturePairsStr.cstring)
proc connectionChange*(typ: string, expensive: string) =
go_shim.connectionChange(typ.cstring, expensive.cstring)
proc multiformatSerializePublicKey*(key: string, outBase: string): string =
$go_shim.multiformatSerializePublicKey(key.cstring, outBase.cstring)
proc multiformatDeserializePublicKey*(key: string, outBase: string): string =
$go_shim.multiformatDeserializePublicKey(key.cstring, outBase.cstring)
proc validateNodeConfig*(configJSON: string): string =
$go_shim.validateNodeConfig(configJSON.cstring)
proc loginWithKeycard*(accountData: string, password: string, keyHex: string): string =
$go_shim.loginWithKeycard(accountData.cstring, password.cstring, keyHex.cstring)
proc recover*(rpcParams: string): string =
$go_shim.recover(rpcParams.cstring)
proc writeHeapProfile*(dataDir: string): string =
$go_shim.writeHeapProfile(dataDir.cstring)
proc hashTypedData*(data: string): string =
$go_shim.hashTypedData(data.cstring)
proc resetChainData*(): string =
$go_shim.resetChainData()
proc signMessage*(rpcParams: string): string =
$go_shim.signMessage(rpcParams.cstring)
proc signTypedData*(data: string, address: string, password: string): string =
$go_shim.signTypedData(data.cstring, address.cstring, password.cstring)
proc stopCPUProfiling*(): string =
$go_shim.stopCPUProfiling()
proc getNodesFromContract*(rpcEndpoint: string, contractAddress: string): string =
$go_shim.getNodesFromContract(rpcEndpoint.cstring, contractAddress.cstring)
proc exportNodeLogs*(): string =
$go_shim.exportNodeLogs()
proc chaosModeUpdate*(on: int): string =
$go_shim.chaosModeUpdate(on.cint)
proc signHash*(hexEncodedHash: string): string =
$go_shim.signHash(hexEncodedHash.cstring)
proc sendTransactionWithSignature*(txtArgsJSON: string, sigString: string): string =
$go_shim.sendTransactionWithSignature(txtArgsJSON.cstring, sigString.cstring)
proc startCPUProfile*(dataDir: string): string =
$go_shim.startCPUProfile(dataDir.cstring)
proc appStateChange*(state: string) =
go_shim.appStateChange(state.cstring)
proc signGroupMembership*(content: string): string =
$go_shim.signGroupMembership(content.cstring)
proc multiAccountStoreAccount*(paramsJSON: string): string =
$go_shim.multiAccountStoreAccount(paramsJSON.cstring)
proc multiAccountLoadAccount*(paramsJSON: string): string =
$go_shim.multiAccountLoadAccount(paramsJSON.cstring)
proc multiAccountGenerate*(paramsJSON: string): string =
$go_shim.multiAccountGenerate(paramsJSON.cstring)
proc multiAccountReset*(): string =
$go_shim.multiAccountReset()
proc migrateKeyStoreDir*(accountData: string, password: string, oldKeystoreDir: string, multiaccountKeystoreDir: string): string =
$go_shim.migrateKeyStoreDir(accountData.cstring, password.cstring, oldKeystoreDir.cstring, multiaccountKeystoreDir.cstring)
proc startWallet*(watchNewBlocks: bool): string =
$go_shim.startWallet(watchNewBlocks)
proc stopWallet*(): string =
$go_shim.stopWallet()
proc startLocalNotifications*(): string =
$go_shim.startLocalNotifications()
proc stopLocalNotifications*(): string =
$go_shim.stopLocalNotifications()

View File

@ -1,197 +0,0 @@
# This module (see also `./go/shim.nim` and `./c/go/shim_impl.nim`) wraps the
# API supplied by status-go when it is compiled into `libstatus.a` or
# `libstatus.dll|dylib|so`. Unlike `./go/shim.nim`, individual proc wrappers
# here are expected to be *hybrids* that combine existing status-go
# functionality with Nim code implemented elsewhere in this library. For
# example, the `callRPC` proc in this module could redirect some calls to procs
# in other modules in this library while passing other calls to
# status-go. Individual procs in this module may also be complete replacements
# for their status-go counterparts (e.g. `hashMessage` and `identicon`), in
# which case it is expected the replacements will behave identically with their
# counterparts. The hybrids may exhibit behavior incompatible with status-go
# while they are a work-in-progress.
# Hybrids implemented here may all eventually become complete replacements for
# their status-go counterparts, at which time this module would be renamed
# `shim.nim` and have close correspondence with the code in `./c/shim.nim` and
# `./c/shim_impl.nim`, i.e. the latter can make use of the replacement procs in
# this module as appropriate.
# It is expected that this module will be consumed as an import in another Nim
# module; when doing so, it is not necessary to separately compile
# `./c/go/shim.nim` but it is the responsibility of the user to link status-go
# compiled to `libstatus` into the final executable.
import strformat
from ../../nim_status as nim_status import nil
from ../go/shim as go_shim import nil
import ../c/go/signals
export SignalCallback
proc notImplemented() =
writeStackTrace()
raise newException(Defect, "NOT IMPLEMENTED")
# `hashMessage` is a complete replacement, not a hybrid
proc hashMessage*(message: string): string =
let hash = nim_status.hashMessage(message)
# status-go compatible formatting
fmt("{{\"result\":\"{hash}\"}}")
proc initKeystore*(keydir: string): string =
notImplemented()
proc openAccounts*(datadir: string): string =
notImplemented()
proc multiAccountGenerateAndDeriveAddresses*(paramsJSON: string): string =
notImplemented()
proc multiAccountStoreDerivedAccounts*(paramsJSON: string): string =
notImplemented()
proc multiAccountImportMnemonic*(paramsJSON: string): string =
notImplemented()
proc multiAccountImportPrivateKey*(paramsJSON: string): string =
notImplemented()
proc multiAccountDeriveAddresses*(paramsJSON: string): string =
notImplemented()
proc saveAccountAndLogin*(accountData: string, password: string, settingsJSON: string, configJSON: string, subaccountData: string): string =
notImplemented()
proc deleteMultiAccount*(keyUID: string, keyStoreDir: string): string =
notImplemented()
proc callRPC*(inputJSON: string): string =
notImplemented()
proc callPrivateRPC*(inputJSON: string): string =
notImplemented()
proc addPeer*(peer: string): string =
notImplemented()
proc setSignalEventCallback*(callback: SignalCallback) =
notImplemented()
proc sendTransaction*(jsonArgs: string, password: string): string =
notImplemented()
# `generateAlias` is a complete replacement, not a hybrid
export nim_status.generateAlias
# `identicon` is a complete replacement, not a hybrid
export nim_status.identicon
proc login*(accountData: string, password: string): string =
notImplemented()
proc logout*(): string =
notImplemented()
proc verifyAccountPassword*(keyStoreDir: string, address: string, password: string): string =
notImplemented()
proc validateMnemonic*(mnemonic: string): string =
notImplemented()
proc saveAccountAndLoginWithKeycard*(accountData: string, password: string, settingsJSON: string, configJSON: string, subaccountData: string, keyHex: string): string =
notImplemented()
proc hashTransaction*(txArgsJSON: string): string =
notImplemented()
proc extractGroupMembershipSignatures*(signaturePairsStr: string): string =
notImplemented()
proc connectionChange*(typ: string, expensive: string) =
notImplemented()
proc multiformatSerializePublicKey*(key: string, outBase: string): string =
notImplemented()
proc multiformatDeserializePublicKey*(key: string, outBase: string): string =
notImplemented()
proc validateNodeConfig*(configJSON: string): string =
notImplemented()
proc loginWithKeycard*(accountData: string, password: string, keyHex: string): string =
notImplemented()
proc recover*(rpcParams: string): string =
notImplemented()
proc writeHeapProfile*(dataDir: string): string =
notImplemented()
proc hashTypedData*(data: string): string =
notImplemented()
proc resetChainData*(): string =
notImplemented()
proc signMessage*(rpcParams: string): string =
notImplemented()
proc signTypedData*(data: string, address: string, password: string): string =
notImplemented()
proc stopCPUProfiling*(): string =
notImplemented()
proc getNodesFromContract*(rpcEndpoint: string, contractAddress: string): string =
notImplemented()
proc exportNodeLogs*(): string =
notImplemented()
proc chaosModeUpdate*(on: int): string =
notImplemented()
proc signHash*(hexEncodedHash: string): string =
notImplemented()
proc sendTransactionWithSignature*(txtArgsJSON: string, sigString: string): string =
notImplemented()
proc startCPUProfile*(dataDir: string): string =
notImplemented()
proc appStateChange*(state: string) =
notImplemented()
proc signGroupMembership*(content: string): string =
notImplemented()
proc multiAccountStoreAccount*(paramsJSON: string): string =
notImplemented()
proc multiAccountLoadAccount*(paramsJSON: string): string =
notImplemented()
proc multiAccountGenerate*(paramsJSON: string): string =
notImplemented()
proc multiAccountReset*(): string =
notImplemented()
proc migrateKeyStoreDir*(accountData: string, password: string, oldKeystoreDir: string, multiaccountKeystoreDir: string): string =
notImplemented()
proc startWallet*(watchNewBlocks: bool): string =
notImplemented()
proc stopWallet*(): string =
notImplemented()
proc startLocalNotifications*(): string =
notImplemented()
proc stopLocalNotifications*(): string =
notImplemented()

View File

View File

@ -5,7 +5,7 @@ import # vednor libs
chronos, eth/[keys, p2p]
import # nim-status libs
../../nim_status/account,
../nim_status/account,
./test_helpers, ./test_utils
procSuite "account":

View File

@ -5,8 +5,8 @@ import # vendor libs
chronos, json_serialization, sqlcipher, web3/conversions as web3_conversions
import # nim-status libs
../../nim_status/[accounts, database, conversions],
../../nim_status/migrations/sql_scripts_accounts,
../nim_status/[accounts, database, conversions],
../nim_status/migrations/sql_scripts_accounts,
./test_helpers
procSuite "accounts":

View File

@ -5,7 +5,7 @@ import # vendor libs
chronos, byteutils, eth/keys, secp256k1, stew/[results]
import # nim-status libs
../../nim_status/account,
../nim_status/account,
./test_helpers
procSuite "bip32":

View File

@ -1,112 +0,0 @@
#include <stdbool.h>
#include <stdio.h>
#include <string.h>
#include <unistd.h>
#include "nim_status_go.h"
#include "nxjson.c"
bool success = false;
void eventCallback(char *event) {
printf("SIGNAL RECEIVED:\n%s\n", event);
if (strcmp(event, "{\"type\":\"node.login\",\"event\":{}}") == 0) {
success = true;
}
}
int main(int argc, char* argv[]) {
// NimMain initializes Nim's garbage collector and runs top level statements
// in the compiled library
NimMain();
printf("Create an account, login and receive signals:\n");
char* initKeystoreResult = initKeystore("./data");
printf("1. InitKeystore:\n%s\n\n", initKeystoreResult);
char* openAccountsResults = openAccounts("./noBackup");
printf("2. OpenAccounts:\n%s\n\n", openAccountsResults);
char* multiAccountGenerateAndDeriveAddressesResult = multiAccountGenerateAndDeriveAddresses("{\"n\":5,\"mnemonicPhraseLength\":12,\"bip39Passphrase\":\"\",\"paths\":[\"m/43'/60'/1581'/0'/0\",\"m/44'/60'/0'/0/0\"]}");
printf("3. MultiAccountGenerateAndDeriveAddresses:\n%s\n\n", multiAccountGenerateAndDeriveAddressesResult);
const nx_json* MultiAccountGenerateAndDeriveAddresses = nx_json_parse(multiAccountGenerateAndDeriveAddressesResult, 0);
char* accountID = nx_json_get(nx_json_item(MultiAccountGenerateAndDeriveAddresses, 0), "id")->text_value;
char p2[300];
char* password = "0x2cd9bf92c5e20b1b410f5ace94d963a96e89156fbe65b70365e8596b37f1f165"; // qwerty
sprintf(p2, "{\"accountID\": \"%s\", \"paths\": [\"m/44'/60'/0'/0\", \"m/43'/60'/1581'\", \"m/43'/60'/1581'/0'/0\", \"m/44'/60'/0'/0/0\"], \"password\": \"%s\"}", accountID, password);
char* multiAccountStoreDerivedAccountsResult = multiAccountStoreDerivedAccounts(p2);
printf("4. MultiAccountStoreDerivedAccounts:\n%s\n\n", multiAccountStoreDerivedAccountsResult);
const nx_json* MultiAccountStoreDerivedAccounts = nx_json_parse(multiAccountStoreDerivedAccountsResult, 0);
char* m4460publicKey = nx_json_get(nx_json_get(MultiAccountStoreDerivedAccounts, "m/44'/60'/0'/0/0"), "publicKey")->text_value;
char* m4460address = nx_json_get(nx_json_get(MultiAccountStoreDerivedAccounts, "m/44'/60'/0'/0/0"), "address")->text_value;
char* m4360publicKey = nx_json_get(nx_json_get(MultiAccountStoreDerivedAccounts, "m/43'/60'/1581'/0'/0"), "publicKey")->text_value;
char* m4360address = nx_json_get(nx_json_get(MultiAccountStoreDerivedAccounts, "m/43'/60'/1581'/0'/0"), "address")->text_value;
char accountsData[2000];
sprintf(accountsData, "[{\"public-key\":\"%s\",\"address\":\"%s\",\"color\":\"#4360df\",\"wallet\":true,\"path\":\"m/44'/60'/0'/0/0\",\"name\":\"Status account\"},{\"public-key\":\"%s\",\"address\":\"%s\",\"name\":\"Delectable Overjoyed Nauplius\",\"photo-path\":\"data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAADIAAAAyCAYAAAAeP4ixAAAAmElEQVR4nOzX4QmAIBBA4Yp2aY52aox2ao6mqf+SoajwON73M0J4HBy6TEEYQmMIjSE0htCECVlbDziv+/n6fuzb3OP/UmEmYgiNITRNm+LPqO2UE2YihtAYQlN818ptoZzau1btOakwEzGExhCa5hdi7d2p1zZLhZmIITSG0PhCpDGExhANEmYihtAYQmMIjSE0bwAAAP//kHQdRIWYzToAAAAASUVORK5CYII=\",\"path\":\"m/43'/60'/1581'/0'/0\",\"chat\":true}]",
m4460publicKey, m4460address, m4360publicKey, m4360address);
char* finalConfig = "{\"BrowsersConfig\":{\"Enabled\":true},\"ClusterConfig\":{\"BootNodes\":[\"enode://23d0740b11919358625d79d4cac7d50a34d79e9c69e16831c5c70573757a1f5d7d884510bc595d7ee4da3c1508adf87bbc9e9260d804ef03f8c1e37f2fb2fc69@47.52.106.107:443\",\"enode://5395aab7833f1ecb671b59bf0521cf20224fe8162fc3d2675de4ee4d5636a75ec32d13268fc184df8d1ddfa803943906882da62a4df42d4fccf6d17808156a87@178.128.140.188:443\",\"enode://6e6554fb3034b211398fcd0f0082cbb6bd13619e1a7e76ba66e1809aaa0c5f1ac53c9ae79cf2fd4a7bacb10d12010899b370c75fed19b991d9c0cdd02891abad@47.75.99.169:443\",\"enode://5405c509df683c962e7c9470b251bb679dd6978f82d5b469f1f6c64d11d50fbd5dd9f7801c6ad51f3b20a5f6c7ffe248cc9ab223f8bcbaeaf14bb1c0ef295fd0@35.223.215.156:443\"],\"Enabled\":true,\"Fleet\":\"eth.prod\",\"RendezvousNodes\":[\"/ip4/34.70.75.208/tcp/30703/ethv4/16Uiu2HAm6ZsERLx2BwVD2UM9SVPnnMU6NBycG8XPtu8qKys5awsU\",\"/ip4/178.128.140.188/tcp/30703/ethv4/16Uiu2HAmLqTXuY4Sb6G28HNooaFUXUKzpzKXCcgyJxgaEE2i5vnf\",\"/ip4/47.52.106.107/tcp/30703/ethv4/16Uiu2HAmEHiptiDDd9gqNY8oQqo8hHUWMHJzfwt5aLRdD6W2zcXR\"],\"StaticNodes\":[\"enode://887cbd92d95afc2c5f1e227356314a53d3d18855880ac0509e0c0870362aee03939d4074e6ad31365915af41d34320b5094bfcc12a67c381788cd7298d06c875@178.128.141.0:443\",\"enode://fbeddac99d396b91d59f2c63a3cb5fc7e0f8a9f7ce6fe5f2eed5e787a0154161b7173a6a73124a4275ef338b8966dc70a611e9ae2192f0f2340395661fad81c0@34.67.230.193:443\"],\"TrustedMailServers\":[\"enode://2c8de3cbb27a3d30cbb5b3e003bc722b126f5aef82e2052aaef032ca94e0c7ad219e533ba88c70585ebd802de206693255335b100307645ab5170e88620d2a81@47.244.221.14:443\",\"enode://ee2b53b0ace9692167a410514bca3024695dbf0e1a68e1dff9716da620efb195f04a4b9e873fb9b74ac84de801106c465b8e2b6c4f0d93b8749d1578bfcaf03e@104.197.238.144:443\",\"enode://8a64b3c349a2e0ef4a32ea49609ed6eb3364be1110253c20adc17a3cebbc39a219e5d3e13b151c0eee5d8e0f9a8ba2cd026014e67b41a4ab7d1d5dd67ca27427@178.128.142.94:443\",\"enode://7aa648d6e855950b2e3d3bf220c496e0cae4adfddef3e1e6062e6b177aec93bc6cdcf1282cb40d1656932ebfdd565729da440368d7c4da7dbd4d004b1ac02bf8@178.128.142.26:443\",\"enode://c42f368a23fa98ee546fd247220759062323249ef657d26d357a777443aec04db1b29a3a22ef3e7c548e18493ddaf51a31b0aed6079bd6ebe5ae838fcfaf3a49@178.128.142.54:443\",\"enode://30211cbd81c25f07b03a0196d56e6ce4604bb13db773ff1c0ea2253547fafd6c06eae6ad3533e2ba39d59564cfbdbb5e2ce7c137a5ebb85e99dcfc7a75f99f55@23.236.58.92:443\"]},\"DataDir\":\"./data\",\"EnableNTPSync\":true,\"KeyStoreDir\":\"./keystore\",\"ListenAddr\":\":30304\",\"LogEnabled\":true,\"LogFile\":\"./geth.log\",\"LogLevel\":\"INFO\",\"MailserversConfig\":{\"Enabled\":true},\"Name\":\"StatusIM\",\"NetworkId\":1,\"NoDiscovery\":false,\"PermissionsConfig\":{\"Enabled\":true},\"Rendezvous\":true,\"RequireTopics\":{\"whisper\":{\"Max\":2,\"Min\":2}},\"ShhExtConfig\":{\"BackupDisabledDataDir\":\"./\",\"DataSyncEnabled\":true,\"InstallationID\":\"aef27732-8d86-5039-a32e-bdbe094d8791\",\"MailServerConfirmations\":true,\"MaxMessageDeliveryAttempts\":6,\"PFSEnabled\":true,\"VerifyENSContractAddress\":\"0x00000000000C2E074eC69A0dFb2997BA6C7d2e1e\",\"VerifyENSURL\":\"https://mainnet.infura.io/v3/f315575765b14720b32382a61a89341a\",\"VerifyTransactionChainID\":1,\"VerifyTransactionURL\":\"https://mainnet.infura.io/v3/f315575765b14720b32382a61a89341a\"},\"ShhextConfig\":{\"BackupDisabledDataDir\":null,\"DataSyncEnabled\":true,\"InstallationID\":\"aef27732-8d86-5039-a32e-bdbe094d8791\",\"MailServerConfirmations\":true,\"MaxMessageDeliveryAttempts\":6,\"PFSEnabled\":true,\"VerifyENSContractAddress\":\"0x00000000000C2E074eC69A0dFb2997BA6C7d2e1e\",\"VerifyENSURL\":\"https://mainnet.infura.io/v3/f315575765b14720b32382a61a89341a\",\"VerifyTransactionChainID\":1,\"VerifyTransactionURL\":\"https://mainnet.infura.io/v3/f315575765b14720b32382a61a89341a\"},\"StatusAccountsConfig\":{\"Enabled\":true},\"UpstreamConfig\":{\"Enabled\":true,\"URL\":\"https://mainnet.infura.io/v3/f315575765b14720b32382a61a89341a\"},\"WakuConfig\":{\"BloomFilterMode\":null,\"Enabled\":true,\"LightClient\":true,\"MinimumPoW\":0.001},\"WalletConfig\":{\"Enabled\":true}}";
char* multiAccountGenerateAndDeriveAddresses0address = nx_json_get(nx_json_item(MultiAccountGenerateAndDeriveAddresses, 0), "address")->text_value;
char* multiAccountGenerateAndDeriveAddresses0keyUid = nx_json_get(nx_json_item(MultiAccountGenerateAndDeriveAddresses, 0), "keyUid")->text_value;
char multiAccountData[2000];
sprintf(multiAccountData, "{\"name\":\"Delectable Overjoyed Nauplius\",\"address\":\"%s\",\"photo-path\":\"data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAADIAAAAyCAYAAAAeP4ixAAAAmElEQVR4nOzX4QmAIBBA4Yp2aY52aox2ao6mqf+SoajwON73M0J4HBy6TEEYQmMIjSE0htCECVlbDziv+/n6fuzb3OP/UmEmYgiNITRNm+LPqO2UE2YihtAYQlN818ptoZzau1btOakwEzGExhCa5hdi7d2p1zZLhZmIITSG0PhCpDGExhANEmYihtAYQmMIjSE0bwAAAP//kHQdRIWYzToAAAAASUVORK5CYII=\",\"key-uid\":\"%s\",\"keycard-pairing\":null}", multiAccountGenerateAndDeriveAddresses0address, multiAccountGenerateAndDeriveAddresses0keyUid);
// multiAccountGenerateAndDeriveAddresses0keyUid
char* multiAccountGenerateAndDeriveAddresses0mnemonic = nx_json_get(nx_json_item(MultiAccountGenerateAndDeriveAddresses, 0), "mnemonic")->text_value;
// m4360publicKey
// multiAccountGenerateAndDeriveAddresses0address
char* eip1581Address = nx_json_get(nx_json_get(MultiAccountStoreDerivedAccounts, "m/43'/60'/1581'"), "address")->text_value;
// m4460address
char* walletRootAddress = nx_json_get(nx_json_get(MultiAccountStoreDerivedAccounts, "m/44'/60'/0'/0"), "address")->text_value;
char settings[5000];
sprintf(settings, "{\"key-uid\":\"%s\",\"mnemonic\":\"%s\",\"public-key\":\"%s\",\"name\":\"Delectable Overjoyed Nauplius\",\"address\":\"%s\",\"eip1581-address\":\"%s\",\"dapps-address\":\"%s\",\"wallet-root-address\":\"%s\",\"preview-privacy?\":true,\"signing-phrase\":\"dust gear boss\",\"log-level\":\"INFO\",\"latest-derived-path\":0,\"networks/networks\":[{\"id\":\"testnet_rpc\",\"etherscan-link\":\"https://ropsten.etherscan.io/address/\",\"name\":\"Ropsten with upstream RPC\",\"config\":{\"NetworkId\":3,\"DataDir\":\"/ethereum/testnet_rpc\",\"UpstreamConfig\":{\"Enabled\":true,\"URL\":\"https://ropsten.infura.io/v3/f315575765b14720b32382a61a89341a\"}}},{\"id\":\"rinkeby_rpc\",\"etherscan-link\":\"https://rinkeby.etherscan.io/address/\",\"name\":\"Rinkeby with upstream RPC\",\"config\":{\"NetworkId\":4,\"DataDir\":\"/ethereum/rinkeby_rpc\",\"UpstreamConfig\":{\"Enabled\":true,\"URL\":\"https://rinkeby.infura.io/v3/f315575765b14720b32382a61a89341a\"}}},{\"id\":\"goerli_rpc\",\"etherscan-link\":\"https://goerli.etherscan.io/address/\",\"name\":\"Goerli with upstream RPC\",\"config\":{\"NetworkId\":5,\"DataDir\":\"/ethereum/goerli_rpc\",\"UpstreamConfig\":{\"Enabled\":true,\"URL\":\"https://goerli.blockscout.com/\"}}},{\"id\":\"mainnet_rpc\",\"etherscan-link\":\"https://etherscan.io/address/\",\"name\":\"Mainnet with upstream RPC\",\"config\":{\"NetworkId\":1,\"DataDir\":\"/ethereum/mainnet_rpc\",\"UpstreamConfig\":{\"Enabled\":true,\"URL\":\"https://mainnet.infura.io/v3/f315575765b14720b32382a61a89341a\"}}},{\"id\":\"xdai_rpc\",\"name\":\"xDai Chain\",\"config\":{\"NetworkId\":100,\"DataDir\":\"/ethereum/xdai_rpc\",\"UpstreamConfig\":{\"Enabled\":true,\"URL\":\"https://dai.poa.network\"}}},{\"id\":\"poa_rpc\",\"name\":\"POA Network\",\"config\":{\"NetworkId\":99,\"DataDir\":\"/ethereum/poa_rpc\",\"UpstreamConfig\":{\"Enabled\":true,\"URL\":\"https://core.poa.network\"}}}],\"currency\":\"usd\",\"photo-path\":\"data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAADIAAAAyCAYAAAAeP4ixAAAAmElEQVR4nOzX4QmAIBBA4Yp2aY52aox2ao6mqf+SoajwON73M0J4HBy6TEEYQmMIjSE0htCECVlbDziv+/n6fuzb3OP/UmEmYgiNITRNm+LPqO2UE2YihtAYQlN818ptoZzau1btOakwEzGExhCa5hdi7d2p1zZLhZmIITSG0PhCpDGExhANEmYihtAYQmMIjSE0bwAAAP//kHQdRIWYzToAAAAASUVORK5CYII=\",\"waku-enabled\":true,\"wallet/visible-tokens\":{\"mainnet\":[\"SNT\"]},\"appearance\":0,\"networks/current-network\":\"mainnet_rpc\",\"installation-id\":\"5d6bc316-a97e-5b89-9541-ad01f8eb7397\"}",
multiAccountGenerateAndDeriveAddresses0keyUid, multiAccountGenerateAndDeriveAddresses0mnemonic, m4360publicKey, multiAccountGenerateAndDeriveAddresses0address,
eip1581Address, m4460address, walletRootAddress);
char* loginResult = saveAccountAndLogin(multiAccountData, password, settings, finalConfig, accountsData);
printf("5. saveAccountAndLogin:\n%s\n\n", loginResult);
setSignalEventCallback(&eventCallback);
int seconds = 0;
while(seconds < 300) {
fflush(stdout);
if (success) {
return 0;
}
printf("...\n");
sleep(1);
seconds += 1;
}
return 1;
}

View File

@ -1,387 +0,0 @@
/*
* Copyright (c) 2013 Yaroslav Stavnichiy <yarosla@gmail.com>
*
* This file is part of NXJSON.
*
* NXJSON is free software: you can redistribute it and/or modify
* it under the terms of the GNU Lesser General Public License
* as published by the Free Software Foundation, either version 3
* of the License, or (at your option) any later version.
*
* NXJSON is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with NXJSON. If not, see <http://www.gnu.org/licenses/>.
*/
// this file can be #included in your code
#ifndef NXJSON_C
#define NXJSON_C
#ifdef __cplusplus
extern "C" {
#endif
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include <assert.h>
#include <errno.h>
#include "nxjson.h"
// redefine NX_JSON_CALLOC & NX_JSON_FREE to use custom allocator
#ifndef NX_JSON_CALLOC
#define NX_JSON_CALLOC() calloc(1, sizeof(nx_json))
#define NX_JSON_FREE(json) free((void*)(json))
#endif
// redefine NX_JSON_REPORT_ERROR to use custom error reporting
#ifndef NX_JSON_REPORT_ERROR
#define NX_JSON_REPORT_ERROR(msg, p) fprintf(stderr, "NXJSON PARSE ERROR (%d): " msg " at %s\n", __LINE__, p)
#endif
#define IS_WHITESPACE(c) ((unsigned char)(c)<=(unsigned char)' ')
static const nx_json dummy={ NX_JSON_NULL };
static nx_json* create_json(nx_json_type type, const char* key, nx_json* parent) {
nx_json* js=NX_JSON_CALLOC();
assert(js);
js->type=type;
js->key=key;
if (!parent->last_child) {
parent->child=parent->last_child=js;
}
else {
parent->last_child->next=js;
parent->last_child=js;
}
parent->length++;
return js;
}
void nx_json_free(const nx_json* js) {
nx_json* p=js->child;
nx_json* p1;
while (p) {
p1=p->next;
nx_json_free(p);
p=p1;
}
NX_JSON_FREE(js);
}
static int unicode_to_utf8(unsigned int codepoint, char* p, char** endp) {
// code from http://stackoverflow.com/a/4609989/697313
if (codepoint<0x80) *p++=codepoint;
else if (codepoint<0x800) *p++=192+codepoint/64, *p++=128+codepoint%64;
else if (codepoint-0xd800u<0x800) return 0; // surrogate must have been treated earlier
else if (codepoint<0x10000) *p++=224+codepoint/4096, *p++=128+codepoint/64%64, *p++=128+codepoint%64;
else if (codepoint<0x110000) *p++=240+codepoint/262144, *p++=128+codepoint/4096%64, *p++=128+codepoint/64%64, *p++=128+codepoint%64;
else return 0; // error
*endp=p;
return 1;
}
nx_json_unicode_encoder nx_json_unicode_to_utf8=unicode_to_utf8;
static inline int hex_val(char c) {
if (c>='0' && c<='9') return c-'0';
if (c>='a' && c<='f') return c-'a'+10;
if (c>='A' && c<='F') return c-'A'+10;
return -1;
}
static char* unescape_string(char* s, char** end, nx_json_unicode_encoder encoder) {
char* p=s;
char* d=s;
char c;
while ((c=*p++)) {
if (c=='"') {
*d='\0';
*end=p;
return s;
}
else if (c=='\\') {
switch (*p) {
case '\\':
case '/':
case '"':
*d++=*p++;
break;
case 'b':
*d++='\b'; p++;
break;
case 'f':
*d++='\f'; p++;
break;
case 'n':
*d++='\n'; p++;
break;
case 'r':
*d++='\r'; p++;
break;
case 't':
*d++='\t'; p++;
break;
case 'u': // unicode
if (!encoder) {
// leave untouched
*d++=c;
break;
}
char* ps=p-1;
int h1, h2, h3, h4;
if ((h1=hex_val(p[1]))<0 || (h2=hex_val(p[2]))<0 || (h3=hex_val(p[3]))<0 || (h4=hex_val(p[4]))<0) {
NX_JSON_REPORT_ERROR("invalid unicode escape", p-1);
return 0;
}
unsigned int codepoint=h1<<12|h2<<8|h3<<4|h4;
if ((codepoint & 0xfc00)==0xd800) { // high surrogate; need one more unicode to succeed
p+=6;
if (p[-1]!='\\' || *p!='u' || (h1=hex_val(p[1]))<0 || (h2=hex_val(p[2]))<0 || (h3=hex_val(p[3]))<0 || (h4=hex_val(p[4]))<0) {
NX_JSON_REPORT_ERROR("invalid unicode surrogate", ps);
return 0;
}
unsigned int codepoint2=h1<<12|h2<<8|h3<<4|h4;
if ((codepoint2 & 0xfc00)!=0xdc00) {
NX_JSON_REPORT_ERROR("invalid unicode surrogate", ps);
return 0;
}
codepoint=0x10000+((codepoint-0xd800)<<10)+(codepoint2-0xdc00);
}
if (!encoder(codepoint, d, &d)) {
NX_JSON_REPORT_ERROR("invalid codepoint", ps);
return 0;
}
p+=5;
break;
default:
// leave untouched
*d++=c;
break;
}
}
else {
*d++=c;
}
}
NX_JSON_REPORT_ERROR("no closing quote for string", s);
return 0;
}
static char* skip_block_comment(char* p) {
// assume p[-2]=='/' && p[-1]=='*'
char* ps=p-2;
if (!*p) {
NX_JSON_REPORT_ERROR("endless comment", ps);
return 0;
}
REPEAT:
p=strchr(p+1, '/');
if (!p) {
NX_JSON_REPORT_ERROR("endless comment", ps);
return 0;
}
if (p[-1]!='*') goto REPEAT;
return p+1;
}
static char* parse_key(const char** key, char* p, nx_json_unicode_encoder encoder) {
// on '}' return with *p=='}'
char c;
while ((c=*p++)) {
if (c=='"') {
*key=unescape_string(p, &p, encoder);
if (!*key) return 0; // propagate error
while (*p && IS_WHITESPACE(*p)) p++;
if (*p==':') return p+1;
NX_JSON_REPORT_ERROR("unexpected chars", p);
return 0;
}
else if (IS_WHITESPACE(c) || c==',') {
// continue
}
else if (c=='}') {
return p-1;
}
else if (c=='/') {
if (*p=='/') { // line comment
char* ps=p-1;
p=strchr(p+1, '\n');
if (!p) {
NX_JSON_REPORT_ERROR("endless comment", ps);
return 0; // error
}
p++;
}
else if (*p=='*') { // block comment
p=skip_block_comment(p+1);
if (!p) return 0;
}
else {
NX_JSON_REPORT_ERROR("unexpected chars", p-1);
return 0; // error
}
}
else {
NX_JSON_REPORT_ERROR("unexpected chars", p-1);
return 0; // error
}
}
NX_JSON_REPORT_ERROR("unexpected chars", p-1);
return 0; // error
}
static char* parse_value(nx_json* parent, const char* key, char* p, nx_json_unicode_encoder encoder) {
nx_json* js;
while (1) {
switch (*p) {
case '\0':
NX_JSON_REPORT_ERROR("unexpected end of text", p);
return 0; // error
case ' ': case '\t': case '\n': case '\r':
case ',':
// skip
p++;
break;
case '{':
js=create_json(NX_JSON_OBJECT, key, parent);
p++;
while (1) {
const char* new_key;
p=parse_key(&new_key, p, encoder);
if (!p) return 0; // error
if (*p=='}') return p+1; // end of object
p=parse_value(js, new_key, p, encoder);
if (!p) return 0; // error
}
case '[':
js=create_json(NX_JSON_ARRAY, key, parent);
p++;
while (1) {
p=parse_value(js, 0, p, encoder);
if (!p) return 0; // error
if (*p==']') return p+1; // end of array
}
case ']':
return p;
case '"':
p++;
js=create_json(NX_JSON_STRING, key, parent);
js->text_value=unescape_string(p, &p, encoder);
if (!js->text_value) return 0; // propagate error
return p;
case '-': case '0': case '1': case '2': case '3': case '4': case '5': case '6': case '7': case '8': case '9':
{
js=create_json(NX_JSON_INTEGER, key, parent);
char* pe;
js->int_value=strtoll(p, &pe, 0);
if (pe==p || errno==ERANGE) {
NX_JSON_REPORT_ERROR("invalid number", p);
return 0; // error
}
if (*pe=='.' || *pe=='e' || *pe=='E') { // double value
js->type=NX_JSON_DOUBLE;
js->dbl_value=strtod(p, &pe);
if (pe==p || errno==ERANGE) {
NX_JSON_REPORT_ERROR("invalid number", p);
return 0; // error
}
}
else {
js->dbl_value=js->int_value;
}
return pe;
}
case 't':
if (!strncmp(p, "true", 4)) {
js=create_json(NX_JSON_BOOL, key, parent);
js->int_value=1;
return p+4;
}
NX_JSON_REPORT_ERROR("unexpected chars", p);
return 0; // error
case 'f':
if (!strncmp(p, "false", 5)) {
js=create_json(NX_JSON_BOOL, key, parent);
js->int_value=0;
return p+5;
}
NX_JSON_REPORT_ERROR("unexpected chars", p);
return 0; // error
case 'n':
if (!strncmp(p, "null", 4)) {
create_json(NX_JSON_NULL, key, parent);
return p+4;
}
NX_JSON_REPORT_ERROR("unexpected chars", p);
return 0; // error
case '/': // comment
if (p[1]=='/') { // line comment
char* ps=p;
p=strchr(p+2, '\n');
if (!p) {
NX_JSON_REPORT_ERROR("endless comment", ps);
return 0; // error
}
p++;
}
else if (p[1]=='*') { // block comment
p=skip_block_comment(p+2);
if (!p) return 0;
}
else {
NX_JSON_REPORT_ERROR("unexpected chars", p);
return 0; // error
}
break;
default:
NX_JSON_REPORT_ERROR("unexpected chars", p);
return 0; // error
}
}
}
const nx_json* nx_json_parse_utf8(char* text) {
return nx_json_parse(text, unicode_to_utf8);
}
const nx_json* nx_json_parse(char* text, nx_json_unicode_encoder encoder) {
nx_json js={0};
if (!parse_value(&js, 0, text, encoder)) {
if (js.child) nx_json_free(js.child);
return 0;
}
return js.child;
}
const nx_json* nx_json_get(const nx_json* json, const char* key) {
if (!json || !key) return &dummy; // never return null
nx_json* js;
for (js=json->child; js; js=js->next) {
if (js->key && !strcmp(js->key, key)) return js;
}
return &dummy; // never return null
}
const nx_json* nx_json_item(const nx_json* json, int idx) {
if (!json) return &dummy; // never return null
nx_json* js;
for (js=json->child; js; js=js->next) {
if (!idx--) return js;
}
return &dummy; // never return null
}
#ifdef __cplusplus
}
#endif
#endif /* NXJSON_C */

View File

@ -1,65 +0,0 @@
/*
* Copyright (c) 2013 Yaroslav Stavnichiy <yarosla@gmail.com>
*
* This file is part of NXJSON.
*
* NXJSON is free software: you can redistribute it and/or modify
* it under the terms of the GNU Lesser General Public License
* as published by the Free Software Foundation, either version 3
* of the License, or (at your option) any later version.
*
* NXJSON is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with NXJSON. If not, see <http://www.gnu.org/licenses/>.
*/
#ifndef NXJSON_H
#define NXJSON_H
#ifdef __cplusplus
extern "C" {
#endif
typedef enum nx_json_type {
NX_JSON_NULL, // this is null value
NX_JSON_OBJECT, // this is an object; properties can be found in child nodes
NX_JSON_ARRAY, // this is an array; items can be found in child nodes
NX_JSON_STRING, // this is a string; value can be found in text_value field
NX_JSON_INTEGER, // this is an integer; value can be found in int_value field
NX_JSON_DOUBLE, // this is a double; value can be found in dbl_value field
NX_JSON_BOOL // this is a boolean; value can be found in int_value field
} nx_json_type;
typedef struct nx_json {
nx_json_type type; // type of json node, see above
const char* key; // key of the property; for object's children only
const char* text_value; // text value of STRING node
long long int_value; // the value of INTEGER or BOOL node
double dbl_value; // the value of DOUBLE node
int length; // number of children of OBJECT or ARRAY
struct nx_json* child; // points to first child
struct nx_json* next; // points to next child
struct nx_json* last_child;
} nx_json;
typedef int (*nx_json_unicode_encoder)(unsigned int codepoint, char* p, char** endp);
extern nx_json_unicode_encoder nx_json_unicode_to_utf8;
const nx_json* nx_json_parse(char* text, nx_json_unicode_encoder encoder);
const nx_json* nx_json_parse_utf8(char* text);
void nx_json_free(const nx_json* js);
const nx_json* nx_json_get(const nx_json* json, const char* key); // get object's property by key
const nx_json* nx_json_item(const nx_json* json, int idx); // get array element by index
#ifdef __cplusplus
}
#endif
#endif /* NXJSON_H */

View File

@ -1,193 +0,0 @@
#include <assert.h>
#include <stdbool.h>
#include <stdio.h>
#include <string.h>
#include <unistd.h>
#include "shims.h"
void hashCmp(char* str1, char* str2, bool testSame) {
if (testSame) {
assert(strcmp(nim_hashMessage(str1), go_hashMessage(str2)) == 0);
} else {
assert(strcmp(nim_hashMessage(str1), go_hashMessage(str2)) != 0);
}
}
void generateAliasCmp(char* pubKey) {
assert(strcmp(nim_generateAlias(pubKey), go_generateAlias(pubKey)) == 0);
}
void identiconCmp(char* key, char* go_b64, char* nim_b64) {
assert(strcmp(go_identicon(key), go_b64) == 0);
assert(strcmp(nim_identicon(key), nim_b64) == 0);
}
int main(int argc, char* argv[]) {
// NimMain initializes Nim's garbage collector and runs top level statements
// in the compiled library
NimMain();
// hashMessage
hashCmp("", "", true);
hashCmp("a", "a", true);
hashCmp("ab", "ab", true);
hashCmp("abc", "abc", true);
hashCmp("aBc", "aBc", true);
hashCmp("Abc", "abC", false);
hashCmp("0xffffff", "0xffffff", true);
hashCmp("0xFFFFFF", "0xffffff", true);
hashCmp("0xffffff", "0xFFFFFF", true);
hashCmp("0x616263", "abc", true);
hashCmp("abc", "0x616263", true);
hashCmp("0xabc", "0xabc", true);
hashCmp("0xaBc", "0xaBc", true);
hashCmp("0xAbc", "0xabC", false);
hashCmp("0xabcd", "0xabcd", true);
hashCmp("0xaBcd", "0xaBcd", true);
hashCmp("0xAbcd", "0xabcD", true);
hashCmp("0xverybadhex", "0xverybadhex", true);
hashCmp("0Xabcd", "0Xabcd", true);
hashCmp("0xabcd", "0Xabcd", false);
hashCmp("0Xabcd", "0xabcd", false);
assert(strcmp(nim_hashMessage("0Xabcd"), nim_hashMessage("0xabcd")) != 0);
assert(strcmp(go_hashMessage("0Xabcd"), go_hashMessage("0xabcd")) != 0);
char* pubKey_01 = "0x0441ccda1563d69ac6b2e53718973c4e7280b4a5d8b3a09bb8bce9ebc5f082778243f1a04ec1f7995660482ca4b966ab0044566141ca48d7cdef8b7375cd5b7af5";
char* pubKey_02 = "0x04ee10b0d66ccb9e3da3a74f73f880e829332f2a649e759d7c82f08b674507d498d7837279f209444092625b2be691e607c5dc3da1c198d63e430c9c7810516a8f";
char* pubKey_03 = "0x046ffe9547ebceda7696ef5a67dc28e330b6fc3911eb6b1996c9622b2d7f0e8493c46fbd07ab591d62244e36c0d051863f86b1d656361d347a830c4239ef8877f5";
char* pubKey_04 = "0x049bdc0016c51ec7b788db9ab0c63a1fbf3f873d2f3e3b85bf1cf034ab5370858ff31894017f56705de03dbaabf3f9811193fd5323376ec38a688cc306a5bf3ef7";
char* pubKey_05 = "0x04ffdb0fef8f8e3bd899250538bc3c651090aa5b579e9cefa38f6896d599dcd1f1326ec5cd8f749e0a7d3c0ce1c8f9126bd4be985004319769de1e83cbca9301bf";
char* pubKey_06 = "0x0488371505c57c1232fa821ba6963b1f250ac0fb72bf0519ada8f36a36cf8020c69d4a94432252d1e4d75997681381705c06b5fed61213d123cab092197e1f933a";
char* pubKey_07 = "0x0406416d94cf8c8398966dca9eedb0cb485b18e2dd718e39f706be159d09b43896717be11e0610f62eca255526b832f9499c640ead09a38bd9ffde0a2dcf07313a";
char* pubKey_08 = "0x040011a1ce61cb8ce22555442ef540f3b355a4d09d922e5a7e94c8c67265d3369a5ccbd0cce6861d8544ed561b25967d34a332ade61dc2c933655ecdee0cee484c";
char* pubKey_09 = "0x0461717f5e30da90b0e5b024d7b92519226747fcbc0dc52d20b6f4f98f249f719eba1bb126bc1a925aec3186d3c3b4e74b42885a369e0ca34676848ef04605a180";
char* pubKey_10 = "0x04cd43f8afaf4ccd3aeaa79547d259c2cd0e5db699ba7fa0bb3dd5b75b8805d1aed1cd12e69d29aeffe0bf77574c420339f913639fc1ac880ddf08b99e247bb358";
char* pubKey_11 = "0x04335623d65400f122259e6221dda570e7c12e48711e8d22869a179c19665bfcdbf6a2a034fdcfd03a13bbaf5fa5ef5e607d224f4785a74a3e4256bc043e652097";
char* pubKey_12 = "0x049263876e11372628c4d69dc51bd42fe6be5211128654d617e70c73f669d5192b672851d6f420efc8c5ebdade79c298c9b0dbd83c00084dbb8cb3c8ccc259f2f2";
char* pubKey_13 = "0x0469932af292fd008fb6c4c74146a744c52815c3e3878d7a054a93693fbc4c26b48bc56267e01e9b12e5f4116d06df638ea74964bb9c7a86dc78e812fc768c9215";
char* pubKey_14 = "0x0408ca2799cf3648324a9ef6f1e2103732b219e2326295a593ea9a91ac252e4368ce498c768f0bc42949c528b93f9498bba4349586e6f35faf6f13aaf24e5ad295";
char* pubKey_15 = "0x0483c81ec1ae54f77c13eab798d526291d5664a26e8e91aaa8544008ed3c2960f9e243a45141fd56a7c5942e081945db993f372150853feb71a3d3d22d5e493401";
char* pubKey_16 = "0x045463b67aba3b32f7fe8bfdea5fe28a53ee02fd0b5ce979122d40f4a8504f4fbbd101f276b9853eadffadab3baa2c94b852e75763498b67474d3333368b513fdc";
char* pubKey_17 = "0x045350e6cac56e9d8a3528f5ebfba171d993de8b4e5c6134eb9b62b4c87f9cb910f85b9b1407f7da2607c330cd055557cd85957b18f0585fabbf83ff190f2da58d";
char* pubKey_18 = "0x04ed045c2dc3472a8adc169797bc57fd582f39550746f161f215bac2e371bbcf78006d9a7239be8e5bed2d8ad3bed52c900bf10804712ca34e371f16d7d9dfd6d8";
char* pubKey_19 = "0x0455f596c4d177bd59495bfd4fb94d27b0b5db8ca9043fb2241e753baa1824860b11c525f5570936aeaada7c1c6f318efe59039578e0b41a4e49962ed82b59ac3f";
char* pubKey_20 = "0x04252dc037c147fbe39cb650d1f68fce098821ededa4f3785a446d428ec193374d65c3e468e2cbed3308be77e68bd243044cd2e6e27829123a30c612d10524d778";
char* badKey_01 = "xyz";
char* badKey_02 = "0x06abcd";
char* badKey_03 = "0x06ffdb0fef8f8e3bd899250538bc3c651090aa5b579e9cefa38f6896d599dcd1f1326ec5cd8f749e0a7d3c0ce1c8f9126bd4be985004319769de1e83cbca9301bf";
char* badKey_04 = "0x04ffdb0fef8f8e3bd899250538bc3c651090aa5b579e9cefa38f6896d599dcd1f1326ec5cd8f749e0a7d3c0ce1c8f9126bd4be985004319769de1e83cbca930xyz";
// generateAlias
generateAliasCmp(pubKey_01);
generateAliasCmp(pubKey_02);
generateAliasCmp(pubKey_03);
generateAliasCmp(pubKey_04);
generateAliasCmp(pubKey_05);
generateAliasCmp(pubKey_06);
generateAliasCmp(pubKey_07);
generateAliasCmp(pubKey_08);
generateAliasCmp(pubKey_09);
generateAliasCmp(pubKey_10);
generateAliasCmp(pubKey_11);
generateAliasCmp(pubKey_12);
generateAliasCmp(pubKey_13);
generateAliasCmp(pubKey_14);
generateAliasCmp(pubKey_15);
generateAliasCmp(pubKey_16);
generateAliasCmp(pubKey_17);
generateAliasCmp(pubKey_18);
generateAliasCmp(pubKey_19);
generateAliasCmp(pubKey_20);
generateAliasCmp(badKey_01);
generateAliasCmp(badKey_02);
generateAliasCmp(badKey_03);
generateAliasCmp(badKey_04);
// identicon
// The real test is performed in ../nim/shims.nim, which compares the decoded
// PNGs pixel by pixel since the encodings are slightly different, which
// results in different base64 encoded strings. Here it's simply checked that
// the expected base64 values are returned.
char* go_b64_01 = "data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAADIAAAAyCAYAAAAeP4ixAAAAk0lEQVR4nOzYwQmEMBQG4exiL1ZjN5ZhN1ZjNXrxaCCQBIaf+Y4iwvAgvPgvIQyhMYTGEBpDaGJClt4PHOd1fz3ft/U34v1WMRMxhMYQGkNoDKExhKZ5v6ntSLO17mAxEzGExhCarltZGXiaeUN8GUJjCE33qVUz6/9VTcxEDKExRJPETMQQGkNoDKExhOYJAAD//7VPFGKMHGOVAAAAAElFTkSuQmCC";
char* nim_b64_01 = "data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAADIAAAAyCAYAAAAeP4ixAAAAZ0lEQVR4Ae3UMQ6AIAxAUeP5uQ2n4TQ6ukjCAFrre0k3Bj5N2AAALqW2425mnR+1v/0QswiJRkg0QqIREo2Qzyq1HW/M6P3SbERINELSefp36kmzESHRCPmNVb9TT5qNCIlGCADAOifdFswjU3SRrgAAAABJRU5ErkJggg==";
char* go_b64_02 = "data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAADIAAAAyCAYAAAAeP4ixAAAAk0lEQVR4nOzYwQnCQBQGYRV78WxvKSO95ZxqknvIwsLbDcPPfEcRYfjhsfh5hTCExhAaQ2gMoYkJ+VZ/YN234+7z5fd/j/h+r5hFDKExhKb7arWuzSjVaxaziCE0htCU31ots6/cVcwihtAYokliFjGExhCax99a1f+vWmIWMYTGEE0Ss4ghNIbQGEJjCM0ZAAD//0Z8Fs/Oqls7AAAAAElFTkSuQmCC";
char* nim_b64_02 = "data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAADIAAAAyCAYAAAAeP4ixAAAAaUlEQVR4Ae3VQQqAIBAF0IiO791cdxpbtjEoGmmS92B2onyF7wIAcCp7bb2JWn/X+vVFRBEkG0F+66ptolrrbZtN8yKCZCNINtuojZ80ToRpXkSQbAQBIKWy19abUedN848Iko0gAADjHHD8ib7huqEAAAAAAElFTkSuQmCC";
char* go_b64_03 = "data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAADIAAAAyCAYAAAAeP4ixAAAAlklEQVR4nOzX0QmDUBAF0SSklxSTdlJG2rEYq9F/UXiyK4yXOf+RDAsX3usRwhAaQ2gMoTGEJibkXf3Af5qXjj/y+36eld/HXMQQGkNohlfraJ2qa9P1/ZiLGEJjCE3L4uy5euW2Yi5iCI0hNOUF8YXYzBAaQ2iGl6Jrnc7yhXhXhtDEhMSIuYghNIbQGEJjCM0aAAD//5bkGGRhA5HWAAAAAElFTkSuQmCC";
char* nim_b64_03 = "data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAADIAAAAyCAYAAAAeP4ixAAAAbElEQVR4Ae3UwQmAMAxAUXF+13EYp9GjIHgQE0zje9Br6W8gEwDAaVm3PeK8fcf89UdEEVKNkGFlbZuo+9tMREg1Qn4je8tdtZmIkGqEtHO3nZ6et+9oMxEh1QgZVtR2ytpmbSYipBohAAB5DmWTBHaeBJQGAAAAAElFTkSuQmCC";
char* go_b64_04 = "data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAADIAAAAyCAYAAAAeP4ixAAAAg0lEQVR4nOzWwQmAMBQEURV7sRFLsgxLshGr0QZyCCQfhmXeUSQwLIRsSwhDaAyhMYTGEBpDaAyhMYQmJmQfPeB+3q/1/TqPdcb/vWIWMYTGEJrum6Lqtpl1fswihtAYQoN5a42KWcQQGkNoDKExhMYQFYlZxBAaQ2gMoTGE5g8AAP//St0XhgBe61AAAAAASUVORK5CYII=";
char* nim_b64_04 = "data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAADIAAAAyCAYAAAAeP4ixAAAAYElEQVR4Ae3UUQqAIBBFUWn9LamNtJr6j4KCkZ5yDvgnA1dhGgAAwKjWbT/uTtX9t5a/H6KKkDRChtVr21TNn+ZHhKQRMqynrfJ121TNuZrmR4SkEZJGSBohaYQAAPRzAp/ZliudjXNFAAAAAElFTkSuQmCC";
char* go_b64_05 = "data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAADIAAAAyCAYAAAAeP4ixAAAAnUlEQVR4nOzY0QmDMBRG4bZ0l+7TWRzDWdzHafQ9EDHcCIef870bPFy4RD+vEIbQGEJjCI0hNDEh3+oB67YfM15k+f/eledjJmIIjSE0pU1xpbfNqtupJ2YihtAYQnP7rjV6p+ptp1nntGImYgiNITTlL8TRu9OsbdaKmYghNIbQYP5rVcVMxBAaQ/SQmIkYQmMIjSE0htCcAQAA///dlxhq1Y4r+AAAAABJRU5ErkJggg==";
char* nim_b64_05 = "data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAADIAAAAyCAYAAAAeP4ixAAAAcElEQVR4Ae3UwQmAMAxAURHHdxb3cRo9CoIHSYppfQ96DX4DmQAALuu2Hxkv+h3z1z8ii5BqhPxGq+v0ZJiNCKlGSLeertDb65Q1526YjQipRki3olel9fxhNiKkGiHVLNEBmZcrYpiNCKlGCABAOydUs7uBcVGURQAAAABJRU5ErkJggg==";
char* go_b64_06 = "data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAADIAAAAyCAYAAAAeP4ixAAAAmElEQVR4nOzYwQmFMBAA0f/FXizA1izD1izAavSSk0SIJAvDMu8oEhgWFpLpl4QhNIbQGEJjCE2akLn3gP04r9r3bV3+I/5vlWYihtAYQtO8KaK2zajz00zEEBpDaIZsnJroLfeUZiKG0BhC071B3rbTV94QC0NoDKFpfteKfr/yhlgYQmOIgqSZiCE0htAYQmMIzR0AAP//lSkkZN3k4WYAAAAASUVORK5CYII=";
char* nim_b64_06 = "data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAADIAAAAyCAYAAAAeP4ixAAAAcElEQVR4Ae3UUQqEMAxAQfH8e7U9wJ5m/RSKgsUG0zgD/SvFZyALAMDu8/39j86o+1etT/+IUYRkI2RaUdtm1PtlJiIkGyGvEb3lWmUmIiQbIeWcbafec/c7ykxESDZCptW7baLvt8pMREg2QgAA4mwbaNLVS2NWgwAAAABJRU5ErkJggg==";
char* go_b64_07 = "data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAADIAAAAyCAYAAAAeP4ixAAAAo0lEQVR4nOzXwQkCMRBGYRV7sQMrswwrswOr0ZOXQCTDbODx877zEngMDLOXUwhDaAyhMYTGEJqYkOvqh8/X+1N5+HG/nXe+M4qZiCE0htAsbYR/qltoZnU7zcRMxBAaQ2jat1b1pjrq+1HMRAyhMYRmeWvNVG+to26zUcxEDKExhKa9tbp/dj/dbRYzEUNoDNEmMRMxhMYQGkNoDKH5BgAA///jZyLG3MhBiAAAAABJRU5ErkJggg==";
char* nim_b64_07 = "data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAADIAAAAyCAYAAAAeP4ixAAAAfElEQVR4Ae3U0QmAMAxF0Sru4gZO5hhO5gZOo/8FwZiGPuM90L9SuA2kAACAP9r247Sc6HdqY+8PaoUQNYSkY91C3u10J81ECFFDyGdZt030/VqaiRCihhA1k/cBy2Z5c/+pNBMhRA0hatwh6zIPLU73EBWEqCEEAAAgzgW2GNQhQvtAFwAAAABJRU5ErkJggg==";
char* go_b64_08 = "data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAADIAAAAyCAYAAAAeP4ixAAAAlElEQVR4nOzYwQmDQBBG4SSkl9STXlJGerEeq9G7KIzsDjx+3neeg4+BYfH1CGEIjSE0htAYQhMT8q4O/pd16/2Uc7/v51mZi9mIITSGqEnMRgyhMYRm+K119Rbqnj+K2YghNIbQlK/WXdVrM0vMRgyhMYRm+LLM+t81euViNmIIjSFqErMRQ2gMoTGExhCaPQAA///EKxVT1czzbgAAAABJRU5ErkJggg==";
char* nim_b64_08 = "data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAADIAAAAyCAYAAAAeP4ixAAAAcUlEQVR4Ae3VwQ2DMAxAUVp1l87TXTpGdsk8mSa9VxyQIIll3pN8Q8gfH9gAgDsqtfUVc3S/5+oPdBUh0QgBYIpSW9+bVc//S/MfERKNkGheo178/bwfM0PSXERINELSKbX1K+bsHmkuIiQaIQAA4/wAYsvMAPtP9jAAAAAASUVORK5CYII=";
char* go_b64_09 = "data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAADIAAAAyCAYAAAAeP4ixAAAAmUlEQVR4nOzXwQkCQRAFURVz0QANwwA1Gr0vOzBDT0PxqXeURSwaPu7tEsIQGkNoDKExhCYm5D774Pf9+Z19/ng9rzt+SPX7Yy5iCI0hNOXFGa3Nqur6xVzEEBpDaNr+a3U/fxRzEUNoDKGZXq2RXetUFXMRQ2gMoSmv1uqbXdeaxVzEEBpD1CTmIobQGEJjCI0hNP8AAAD//8jNJGr/ACdeAAAAAElFTkSuQmCC";
char* nim_b64_09 = "data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAADIAAAAyCAYAAAAeP4ixAAAAbUlEQVR4Ae3UQQqAMAwEQPH9PlBfo3exB2mDaZyB3ErpNrALAPBHx7afT5Pl/vXrDxpFkGwEKafVNm+n9x1lNiJINoJM623bRJ+/K7MRQbIRZFqtVhnVTlpLkKQEmVZvq0TfX2YjgmQjCABAnAv83Q/yHiavrwAAAABJRU5ErkJggg==";
char* go_b64_10 = "data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAADIAAAAyCAYAAAAeP4ixAAAAlUlEQVR4nOzXwQmEQAxA0d1le7ERS7IMS7IRq9G7GInMiJ/w31Fy+QTC+PsUYQiNITSG0BhCYwiNITSG0JQJ+WcH52Xdzr5P4/B9Y/6ozEYMoTGEJn21ItG16TWfVWYjhtAYQpN6x1zpdYWyb6pImY0YQmMITfPVirT+8d1VZiOG0Biih5TZiCE0htAYQmMIzR4AAP//6dUapcA17BkAAAAASUVORK5CYII=";
char* nim_b64_10 = "data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAADIAAAAyCAYAAAAeP4ixAAAAZ0lEQVR4Ae3U0QmAMAxAQRHHdyQXcRrFX1FQ29IQ76B/pfgMZAAAAIhuXtbt6vS6fzb2/kG1CIlGSDRT6QNvNsuX+0+lmYiQaISkc2yhGqf0O9JMREg0Qn6j1Xa6k2YiQqIRAgDQzg4qkomtDuNHlgAAAABJRU5ErkJggg==";
char* go_b64_11 = "data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAADIAAAAyCAYAAAAeP4ixAAAAk0lEQVR4nOzY0QmEMBAG4TuxF8uwKcuwKcuwGm3AQCCuDD/zPYqIw8ISnX4hDKExhMYQGkNoYkLm3hv347yerm/r8n/jRUafHzMRQ2gMoeneWi2tbfO1mIkYQmMIzfDWqj5r9YqZiCE0hqhIzEQMoTGEpuwLsXUGq/o/FjMRQ2gMUZGYiRhCYwiNITSG0NwBAAD//4h2F47hoXg5AAAAAElFTkSuQmCC";
char* nim_b64_11 = "data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAADIAAAAyCAYAAAAeP4ixAAAAbklEQVR4Ae3V4QmFIBiG0e6lXRqjpRqjpRrDaWqBfgQavtg58P0T4VHQCQD4ov0o592k7P/vfUCtCEkjJM1cu0HLl6vGMDciJI2QNNUh27r8Wkz3kBRC0ggBoKv9KOfdtFr/1DD/iJA0QgAA3nMBjkheMqlJ9soAAAAASUVORK5CYII=";
char* go_b64_12 = "data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAADIAAAAyCAYAAAAeP4ixAAAAjElEQVR4nOzXUQmAQBAGYRW72MgkxjCJjUyjBTzYQw6Gn/me98Fh4ViXKYQhNIbQGEJjCI0hNIbQGEITE7JWB6/7fMZ+yrd9O+bKXMxGDKExhMYQGkNoDKEp31otrVuodZv1zlfFbMQQGkNofr9ava/NqD/NmI0YQmOIBonZiCE0htAYQmMIzRsAAP//eckShReeRAYAAAAASUVORK5CYII=";
char* nim_b64_12 = "data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAADIAAAAyCAYAAAAeP4ixAAAAZElEQVR4Ae3UTQrDIBRG0VK6fFfijlyNnYcMzB9+kXPA2SPk+sAPAABAutpKn3FG/+87+4LuIiSNkDRC0ghJI+S1ait978ya31pmI0LSCEnzu/qBIy/LmflRy2xESBohAADP+QMbOZjrEGpysgAAAABJRU5ErkJggg==";
char* go_b64_13 = "data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAADIAAAAyCAYAAAAeP4ixAAAAg0lEQVR4nOzWUQmAQBAGYRW7mMkexrCHmUyjBRSUvYPhZ75HkeOGheWmIYQhNIbQGEJjCI0hNIbQGEJjCI0hNIbQxITMX3/cz+N6+r4t69jiItXzYyZiCI0hNOWN87Zt/qpuv5iJGEJjCI1vLRpDaAxRJzETMYTGEBpDaAyhuQMAAP//VwQUZomgpuQAAAAASUVORK5CYII=";
char* nim_b64_13 = "data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAADIAAAAyCAYAAAAeP4ixAAAAVklEQVR4Ae3U0QnAMAgFwND5u0dn6jTtAu1HiCFG7sBf8SnYAAAAAIh03tfzVVn6H6sXFEWQbAQp5+/b9NboHGUuIkg2gmxr1reJ6l/mIoJkIwgAwDwvwQ9/7bhniAEAAAAASUVORK5CYII=";
char* go_b64_14 = "data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAADIAAAAyCAYAAAAeP4ixAAAAiElEQVR4nOzYsQmEUBQF0V2xF3NrswxrM7caTQz9oHwfDJc5oYgwvOTi8AthCI0hNIbQGEITEzL2fmDd9uPu+TJP/y/efyrmIobQGKIiMRcxhMYQmu6t1VK1qVpiLmIIjSE0htAYQmMITffuaW2qt/yvdTGExhAVibmIITSG0BhCYwjNGQAA///dkRBklltN8wAAAABJRU5ErkJggg==";
char* nim_b64_14 = "data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAADIAAAAyCAYAAAAeP4ixAAAAXklEQVR4Ae3VMQrAIBQFQcn5PZu9pzFlGotAlDxkBn4n6GphAQB41NbHbFatf+v6+yJWEZJGCACRautjNrv2O+YfEZJGSBohaYSkEXKc2vpYMV/PccyLCEkjBABgnxuynHMz+ACdOwAAAABJRU5ErkJggg==";
char* go_b64_15 = "data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAADIAAAAyCAYAAAAeP4ixAAAAkUlEQVR4nOzW0QmAMAwAURV3cQFHcwxHcwGn0X+pUGkDZ7j3KSIegZBpSMIQGkNoDKExhCZNyFz74n4eV+n5tqxjjx9p/X6aiRhCYwhNl41TEr3lntJMxBAaQ2iqN8jbFormrfVXhtCkCWm+e77eVFE3WJqJGEJjCI0hNIbQGKIgaSZiCI0hNIbQGEJzBwAA//+xuRhi5JHvewAAAABJRU5ErkJggg==";
char* nim_b64_15 = "data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAADIAAAAyCAYAAAAeP4ixAAAAaElEQVR4Ae3UwQmAMBBFQbF+S7MBq9G7GFA0+F1nINeQl4UdAIA/mpZ5PTop949vf9BThKQR8hu9t9xemYkISSPks1pbqPc5+74yExGSRkg5V7fN3e3UUmYiQtIISSMkjZA0QgAA+tkAqZi/dScnT28AAAAASUVORK5CYII=";
char* go_b64_16 = "data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAADIAAAAyCAYAAAAeP4ixAAAAlElEQVR4nOzXwQmDQBBG4SSkl7SWAizDAmzNavQuLq6M4uPnfUeZy2NgcD+vEIbQGEJjCI0hNDEh397BcZ6Wve/D7/9+Yn4rZiOG0BhC0321Wq66TlUxGzGExhCa8tXq/Rc6mq9es5iNGEJjCE35arVUX3xnxWzEEBpDdJOYjRhCYwiNITSG0BhCYwiNITRrAAAA//+mxBxrInMMoAAAAABJRU5ErkJggg==";
char* nim_b64_16 = "data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAADIAAAAyCAYAAAAeP4ixAAAAYUlEQVR4Ae3UwQmAMBREQbF+C7A1q9G76Ml8sokz4E0CL4FdAIA/2o79fPp6/X+39r6gVoSkETKst1VptU5WS0goIcP6uirV50/zIkLSCElTFlK9cl4knZA004QAAAD0cgEiELM7LkPipAAAAABJRU5ErkJggg==";
char* go_b64_17 = "data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAADIAAAAyCAYAAAAeP4ixAAAAgklEQVR4nOzXsQmAQBAFURV7sTZzyzC3NqvRXDxZA3H4zAuPTYaFhRu6EIbQGEJjCI0hNIbQGEJjCE1MyFgdXLf9uHtf5qn/Y/4qZiOG0BhCU7oIT1rX5q3qdWqJ2YghNIbQGEJjCI0hNP4QaQyhMUQfidmIITSG0BhCYwjNGQAA///omBxmOuGhKAAAAABJRU5ErkJggg==";
char* nim_b64_17 = "data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAADIAAAAyCAYAAAAeP4ixAAAAX0lEQVR4Ae3UsQqAIBSG0ej53X02n8Z2qSEq/JNz4G538FNwAwAASFdq62cza3+0z76gtwhJI2Q5V7/N3Xl6jmVeREgaIWmEpBGSRshvldr62czaHy3zIkLSCAEA+M4B64+hHeAhkrsAAAAASUVORK5CYII=";
char* go_b64_18 = "data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAADIAAAAyCAYAAAAeP4ixAAAAlElEQVR4nOzW0QmEMBAG4TuxF/uwJsuwJvuwGn0XhYQkMPzM93iEw2Fh2ekXwhAaQ2gMoTGEJiZkLn24n8f19vu2rP8eH9L6/zETMYTGEJrirVVr9JZ7ipmIITSG0DRvra/t1Ot9qZiJGEJjCE3z3VN7U426wWImYgiNIRokZiKG0BhCYwiNITSG0BhCYwjNHQAA///YzhqsKhq2mAAAAABJRU5ErkJggg==";
char* nim_b64_18 = "data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAADIAAAAyCAYAAAAeP4ixAAAAZklEQVR4Ae3UwQmAMBBFQRHLtyb7sBpFvOagaPCzzkBuIfCysAMA8Efzumytk/L++PUHvUVIGiFpuoX03nImkk5ImjIh09MH7m6iXpurzESEpBFSzrGFWuet+1eVmYiQNEIAAAA47RhjZG+9Rh+XAAAAAElFTkSuQmCC";
char* go_b64_19 = "data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAADIAAAAyCAYAAAAeP4ixAAAAiklEQVR4nOzYsQmAQBAFURV7MbE8y7A8E6vRBhRXjoPhMy++wGGTj9MQwhAaQ2gMoTGEJiZkrj7cj/Pq+ynPtnUZK+9iLmIIjSE0htAYQmMITXlr/fW2kXpttpiLGEJjCI0hNIbQGELTvLWq/52+3rdusJiLGEJjiDqJuYghNIbQGEJjCM0dAAD//xTSDTE4YY+HAAAAAElFTkSuQmCC";
char* nim_b64_19 = "data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAADIAAAAyCAYAAAAeP4ixAAAAa0lEQVR4Ae3RsRECIQBFQbGZSyiPMizPxGq0AQJnxOPD7c78jIAHNwDgih7P13vGvr3fffYDjSIkjZA0QtIISSMkzd9CWj1Kb8uFnE1IGiFphKQRkkZImp9DWj1Kb6PO+5FVCUmzTQgAsJMPXdlu2xSxgz0AAAAASUVORK5CYII=";
char* go_b64_20 = "data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAADIAAAAyCAYAAAAeP4ixAAAAkklEQVR4nOzYwQmFMBAA0f/FXqzMDizDDqzMavTiSQxs1OCwzDuGvQwLIaT7JWEIjSE0htAYQpMmpI8OLuu8XZ2Pw/T/Yv4szUYMoTGEJnxrlZRum7fmo9JsxBAaQ2hC75g7nr6daqXZiCE0htAYQmMIjSE0zf61avmvdTCExhA1kmYjhtAYQmMIjSE0ewAAAP//pjweZgztcigAAAAASUVORK5CYII=";
char* nim_b64_20 = "data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAADIAAAAyCAYAAAAeP4ixAAAAcklEQVR4Ae3USwrAIAxFUSldvjtwZa7G0qlk0I+SZ7wHMguWW8EEAAB2VGpu1njt9w7vHzQKIWoIUXP+PeDNy/Jl/6kwN0KIGkK2cb9O1sz6XpgbIUQNIWoIUUOIGkKWVWpu1njt98LcCCFqCAEAAJjnAv4FhA0qj5T5AAAAAElFTkSuQmCC";
char* go_b64_21 = "data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAADIAAAAyCAYAAAAeP4ixAAAAiklEQVR4nOzUwQmAMBAFURV70QItwwK1Gr0HQnYPgWGZdw6BYeFvSxGG0BhCYwiNITSG0BhCYwiNITSG0BhCUyZkjz683+fLfHwd5zrzn1aZixhCYwhNeLV6oqsyep9ds1aZixhCYwhNanEyeiuUXbmoMhcxhMYQTVLmIobQGEJjCI0hNH8AAAD//yusESocCiZuAAAAAElFTkSuQmCC";
char* nim_b64_21 = "data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAADIAAAAyCAYAAAAeP4ixAAAAUklEQVR4Ae3UQQqAMAxFQfH8HlBPo/vuxH5M2xnoNvAayAYAAABAT8d13m9eek5r//uDehFSjZBhfb0q6fnTbERINUKWkb5yrWk2IqQaIQAAOQ/Nr4f3HldRAgAAAABJRU5ErkJggg==";
char* go_b64_22 = "data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAADIAAAAyCAYAAAAeP4ixAAAAh0lEQVR4nOzYwQmEQBAF0V0xFzMzAsMwAjMzGr0LAz2HhuJT7ywDxb80Lr8QhtAYQmMIjSE0MSFr9cPzvp6Zh49t/3e+8xWziCE0hqhJzCKG0BhCU761Rka30+ytVb2pRmIWMYTGEDWJWcQQGkNo/K9FYwiNIWoSs4ghNIbQGEJjCM0bAAD//yatGGXKTxImAAAAAElFTkSuQmCC";
char* nim_b64_22 = "data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAADIAAAAyCAYAAAAeP4ixAAAAW0lEQVR4Ae3VMQrAIAxA0dLze4LcLKexu3RoQavY9yCbBL5LDgDgj0pGfTOj97TO2R/Ui5DVCAFgqpJR76bX+6e2uSNCViMEgE+UjPpmRu9pbXNHhKxGCADAOBedWbOn+OO/yQAAAABJRU5ErkJggg==";
char* go_b64_23 = "data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAADIAAAAyCAYAAAAeP4ixAAAAkklEQVR4nOzYwQmAMBAFURV7sTfPluHZ3qxGGzCghJXhM+8oEhkWwuI0hDCExhAaQ2gMoYkJmasO3o/zenq+rctY8b2YiRhCYwjN61ur+hbqPT9mIobQGEJTtmtV7VQtMRMxhMYQmu5b6+uO1Hq/V8xEDKExhOb3/1pVYiZiCI0hKhIzEUNoDKExhMYQmjsAAP//EQkXZy2G+AYAAAAASUVORK5CYII=";
char* nim_b64_23 = "data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAADIAAAAyCAYAAAAeP4ixAAAAeklEQVR4Ae3UQQqAIBRF0Qr30t4atwzH7s3V2FyCEnr1+twDzuTL5YMTAADAtVxqOzuq95avgwkhxFyYkNtGfyH1/V6YjRDihhA3STV439b5zZAwGyHEDSG/lUttI0c9pxdmI4S4IcRNUg0e+XGeEGYjhLghBAAAQOcAqCSTGzD+2xcAAAAASUVORK5CYII=";
char* go_b64_24 = "data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAADIAAAAyCAYAAAAeP4ixAAAAnUlEQVR4nOzYwQmEMBBA0d1le7E275bh3dqsRi+exEjCJPAZ/juKBD4DQ/T3ScIQGkNoDKExhCZNyD96wLrtx9PzZZ6+Pd6vlWYihtAYQhPeWiWl7TRKmokYQmMITeh+82bUnaokzUQMoTGEJrxBet2p/EK8GEJjCE31pmjdTq3/tVrPuUszEUNoDNEgaSZiCI0hNIbQGEJzBgAA///luRtfuq1hLQAAAABJRU5ErkJggg==";
char* nim_b64_24 = "data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAADIAAAAyCAYAAAAeP4ixAAAAb0lEQVR4Ae3UMQqAMAxAUfH87p7N0+joYkBpizG+B9kc+g1kAgA4Leu2X02v7++a3/4RvQjJRkg50RV6Oq3vKLMRIdkI+Y1R1ylSZiNCshFSTnSdnk7rO8psREg2Qj6r1xUadc3KbERINkIAAMY5AGw76K1Ynwl+AAAAAElFTkSuQmCC";
identiconCmp(pubKey_01, go_b64_01, nim_b64_01);
identiconCmp(pubKey_02, go_b64_02, nim_b64_02);
identiconCmp(pubKey_03, go_b64_03, nim_b64_03);
identiconCmp(pubKey_04, go_b64_04, nim_b64_04);
identiconCmp(pubKey_05, go_b64_05, nim_b64_05);
identiconCmp(pubKey_06, go_b64_06, nim_b64_06);
identiconCmp(pubKey_07, go_b64_07, nim_b64_07);
identiconCmp(pubKey_08, go_b64_08, nim_b64_08);
identiconCmp(pubKey_09, go_b64_09, nim_b64_09);
identiconCmp(pubKey_10, go_b64_10, nim_b64_10);
identiconCmp(pubKey_11, go_b64_11, nim_b64_11);
identiconCmp(pubKey_12, go_b64_12, nim_b64_12);
identiconCmp(pubKey_13, go_b64_13, nim_b64_13);
identiconCmp(pubKey_14, go_b64_14, nim_b64_14);
identiconCmp(pubKey_15, go_b64_15, nim_b64_15);
identiconCmp(pubKey_16, go_b64_16, nim_b64_16);
identiconCmp(pubKey_17, go_b64_17, nim_b64_17);
identiconCmp(pubKey_18, go_b64_18, nim_b64_18);
identiconCmp(pubKey_19, go_b64_19, nim_b64_19);
identiconCmp(pubKey_20, go_b64_20, nim_b64_20);
identiconCmp(badKey_01, go_b64_21, nim_b64_21);
identiconCmp(badKey_02, go_b64_22, nim_b64_22);
identiconCmp(badKey_03, go_b64_23, nim_b64_23);
identiconCmp(badKey_04, go_b64_24, nim_b64_24);
return 0;
}

View File

@ -1,11 +0,0 @@
import ../../nim_status/c/shim_impl as nim_shim
let nim_hashMessage {.exportc.} = nim_shim.hashMessage
let nim_generateAlias {.exportc.} = nim_shim.generateAlias
let nim_identicon {.exportc.} = nim_shim.identicon
import ../../nim_status/c/go/shim_impl as go_shim
let go_hashMessage {.exportc.} = go_shim.hashMessage
let go_generateAlias {.exportc.} = go_shim.generateAlias
let go_identicon {.exportc.} = go_shim.identicon

View File

@ -6,8 +6,8 @@ import # vendor libs
options, sqlcipher, web3/conversions
import # nim-status libs
../../nim_status/[callrpc, database, settings],
../../nim_status/migrations/sql_scripts_app,
../nim_status/[callrpc, database, settings],
../nim_status/migrations/sql_scripts_app,
./test_helpers
procSuite "callrpc":

View File

@ -5,8 +5,8 @@ import # vendor libs
chronos, json_serialization, sqlcipher, web3/conversions as web3_conversions
import # nim-status libs
../../nim_status/[chats, contacts, conversions, database, messages],
../../nim_status/migrations/sql_scripts_app,
../nim_status/[chats, contacts, conversions, database, messages],
../nim_status/migrations/sql_scripts_app,
./test_helpers
procSuite "chats":

View File

@ -6,8 +6,8 @@ import # vendor libs
web3/ethtypes
import # nim-status libs
../../nim_status/[contacts, conversions, database],
../../nim_status/migrations/sql_scripts_app,
../nim_status/[contacts, conversions, database],
../nim_status/migrations/sql_scripts_app,
./test_helpers
procSuite "contacts":

View File

@ -5,7 +5,7 @@ import # vendor libs
chronos, sqlcipher
import # nim-status libs
../../nim_status/database,
../nim_status/database,
./test_helpers
procSuite "db_smoke":

View File

@ -5,7 +5,7 @@ import # vendor libs
chronos, json_serialization, sqlcipher, web3/conversions
import # nim-status libs
../../nim_status/[accounts, callrpc, database, settings],
../nim_status/[accounts, callrpc, database, settings],
./test_helpers
procSuite "login_and_logout":

View File

@ -5,8 +5,8 @@ import # vendor libs
chronos, json_serialization, sqlcipher
import # nim-status libs
../../nim_status/[database, mailservers],
../../nim_status/migrations/sql_scripts_app,
../nim_status/[database, mailservers],
../nim_status/migrations/sql_scripts_app,
./test_helpers
procSuite "mailservers":

View File

@ -5,8 +5,8 @@ import # vendor libs
json_serialization, sqlcipher, web3/conversions as web3_conversions
import # nim-status libs
../../nim_status/[conversions, chats, database, messages],
../../nim_status/migrations/sql_scripts_app,
../nim_status/[conversions, chats, database, messages],
../nim_status/migrations/sql_scripts_app,
./test_helpers
procSuite "messages":

View File

@ -5,8 +5,8 @@ import # vendor libs
chronos, results, sqlcipher, stew/byteutils
import # nim-status libs
../../nim_status/migration,
../../nim_status/migrations/sql_scripts_accounts as migration_accounts,
../nim_status/migration,
../nim_status/migrations/sql_scripts_accounts as migration_accounts,
./test_helpers
procSuite "migrations":

View File

@ -1,15 +0,0 @@
import ../../nim_status/go/shim as go_shim
import ../../nim_status/hybrid/shim as hybrid
const chatKey = "0x04e3b648524ca528588527ff8ea71d8b60e43bbd85f7983fa5f12b3fa27446e66f46c7c88329b2229cfbef3daa5fc6b65a385eac405c610ec285a21a5fd4034690"
echo hybrid.generateAlias(chatKey)
echo go_shim.generateAlias(chatKey)
echo hybrid.hashMessage("test")
echo go_shim.hashMessage("test")
# the base64 encodings are not expected to match though visually re: pixels and
# colors they're an exact match
echo hybrid.identicon(chatKey)
echo go_shim.identicon(chatKey)

View File

@ -1,154 +0,0 @@
import # nim libs
base64, strutils, unittest
import # vendor libs
chronos, nimPNG
import # nim-status libs
../../nim_status/c/shim_impl as nim_shim,
../../nim_status/go/shim as go_shim,
./test_helpers
const pubKey_01 = "0x0441ccda1563d69ac6b2e53718973c4e7280b4a5d8b3a09bb8bce9ebc5f082778243f1a04ec1f7995660482ca4b966ab0044566141ca48d7cdef8b7375cd5b7af5"
const pubKey_02 = "0x04ee10b0d66ccb9e3da3a74f73f880e829332f2a649e759d7c82f08b674507d498d7837279f209444092625b2be691e607c5dc3da1c198d63e430c9c7810516a8f"
const pubKey_03 = "0x046ffe9547ebceda7696ef5a67dc28e330b6fc3911eb6b1996c9622b2d7f0e8493c46fbd07ab591d62244e36c0d051863f86b1d656361d347a830c4239ef8877f5"
const pubKey_04 = "0x049bdc0016c51ec7b788db9ab0c63a1fbf3f873d2f3e3b85bf1cf034ab5370858ff31894017f56705de03dbaabf3f9811193fd5323376ec38a688cc306a5bf3ef7"
const pubKey_05 = "0x04ffdb0fef8f8e3bd899250538bc3c651090aa5b579e9cefa38f6896d599dcd1f1326ec5cd8f749e0a7d3c0ce1c8f9126bd4be985004319769de1e83cbca9301bf"
const pubKey_06 = "0x0488371505c57c1232fa821ba6963b1f250ac0fb72bf0519ada8f36a36cf8020c69d4a94432252d1e4d75997681381705c06b5fed61213d123cab092197e1f933a"
const pubKey_07 = "0x0406416d94cf8c8398966dca9eedb0cb485b18e2dd718e39f706be159d09b43896717be11e0610f62eca255526b832f9499c640ead09a38bd9ffde0a2dcf07313a"
const pubKey_08 = "0x040011a1ce61cb8ce22555442ef540f3b355a4d09d922e5a7e94c8c67265d3369a5ccbd0cce6861d8544ed561b25967d34a332ade61dc2c933655ecdee0cee484c"
const pubKey_09 = "0x0461717f5e30da90b0e5b024d7b92519226747fcbc0dc52d20b6f4f98f249f719eba1bb126bc1a925aec3186d3c3b4e74b42885a369e0ca34676848ef04605a180"
const pubKey_10 = "0x04cd43f8afaf4ccd3aeaa79547d259c2cd0e5db699ba7fa0bb3dd5b75b8805d1aed1cd12e69d29aeffe0bf77574c420339f913639fc1ac880ddf08b99e247bb358"
const pubKey_11 = "0x04335623d65400f122259e6221dda570e7c12e48711e8d22869a179c19665bfcdbf6a2a034fdcfd03a13bbaf5fa5ef5e607d224f4785a74a3e4256bc043e652097"
const pubKey_12 = "0x049263876e11372628c4d69dc51bd42fe6be5211128654d617e70c73f669d5192b672851d6f420efc8c5ebdade79c298c9b0dbd83c00084dbb8cb3c8ccc259f2f2"
const pubKey_13 = "0x0469932af292fd008fb6c4c74146a744c52815c3e3878d7a054a93693fbc4c26b48bc56267e01e9b12e5f4116d06df638ea74964bb9c7a86dc78e812fc768c9215"
const pubKey_14 = "0x0408ca2799cf3648324a9ef6f1e2103732b219e2326295a593ea9a91ac252e4368ce498c768f0bc42949c528b93f9498bba4349586e6f35faf6f13aaf24e5ad295"
const pubKey_15 = "0x0483c81ec1ae54f77c13eab798d526291d5664a26e8e91aaa8544008ed3c2960f9e243a45141fd56a7c5942e081945db993f372150853feb71a3d3d22d5e493401"
const pubKey_16 = "0x045463b67aba3b32f7fe8bfdea5fe28a53ee02fd0b5ce979122d40f4a8504f4fbbd101f276b9853eadffadab3baa2c94b852e75763498b67474d3333368b513fdc"
const pubKey_17 = "0x045350e6cac56e9d8a3528f5ebfba171d993de8b4e5c6134eb9b62b4c87f9cb910f85b9b1407f7da2607c330cd055557cd85957b18f0585fabbf83ff190f2da58d"
const pubKey_18 = "0x04ed045c2dc3472a8adc169797bc57fd582f39550746f161f215bac2e371bbcf78006d9a7239be8e5bed2d8ad3bed52c900bf10804712ca34e371f16d7d9dfd6d8"
const pubKey_19 = "0x0455f596c4d177bd59495bfd4fb94d27b0b5db8ca9043fb2241e753baa1824860b11c525f5570936aeaada7c1c6f318efe59039578e0b41a4e49962ed82b59ac3f"
const pubKey_20 = "0x04252dc037c147fbe39cb650d1f68fce098821ededa4f3785a446d428ec193374d65c3e468e2cbed3308be77e68bd243044cd2e6e27829123a30c612d10524d778"
const badKey_01 = "xyz"
const badKey_02 = "0x06abcd"
const badKey_03 = "0x06ffdb0fef8f8e3bd899250538bc3c651090aa5b579e9cefa38f6896d599dcd1f1326ec5cd8f749e0a7d3c0ce1c8f9126bd4be985004319769de1e83cbca9301bf"
const badKey_04 = "0x04ffdb0fef8f8e3bd899250538bc3c651090aa5b579e9cefa38f6896d599dcd1f1326ec5cd8f749e0a7d3c0ce1c8f9126bd4be985004319769de1e83cbca930xyz"
proc hashCmp(str1: string, str2: string, testSame: bool): void =
{.gcsafe.}:
if testSame:
check:
$nim_shim.hashMessage(str1.cstring) == go_shim.hashMessage(str2)
else:
check:
$nim_shim.hashMessage(str1.cstring) != go_shim.hashMessage(str2)
proc generateAliasCmp(pubKey: string): void =
{.gcsafe.}:
check:
$nim_shim.generateAlias(pubKey.cstring) == go_shim.generateAlias(pubKey)
proc identiconCmp(key: string): void =
# Here it's checked that the decoded PNGs are an exact match in terms of their
# pixel by pixel RGBA values represented as sequences of uint8 values. It's not
# possible to compare the base64 encoded strings directly since the PNG
# encodings are slightly different, which results in different strings.
let go_b64 = go_shim.identicon(key)
let nim_b64 = $nim_shim.identicon(key.cstring)
check: (go_b64 != "" and nim_b64 != "") or (go_b64 == "" and nim_b64 == "")
if go_b64 == "" and nim_b64 == "":
return
let go_png_bytes = cast[seq[uint8]](decode(go_b64[22..^1]))
let nim_png_bytes = cast[seq[uint8]](decode(nim_b64[22..^1]))
let go_png = decodePNG32(go_png_bytes)
let nim_png = decodePNG32(nim_png_bytes)
check: go_png.get.data.len == nim_png.get.data.len
var i = 0
while i < nim_png.get.data.len:
check: nim_png.get.data[i] == gopng.get.data[i]
i += 1
procSuite "shims":
asyncTest "hashMessage":
hashCmp("", "", true)
hashCmp("a", "a", true)
hashCmp("ab", "ab", true)
hashCmp("abc", "abc", true)
hashCmp("aBc", "aBc", true)
hashCmp("Abc", "abC", false)
hashCmp("0xffffff", "0xffffff", true)
hashCmp("0xFFFFFF", "0xffffff", true)
hashCmp("0xffffff", "0xFFFFFF", true)
hashCmp("0x" & "abc".toHex, "abc", true)
hashCmp("0x616263", "abc", true)
hashCmp("abc", "0x" & "abc".toHex, true)
hashCmp("abc", "0x616263", true)
hashCmp("0xabc", "0xabc", true)
hashCmp("0xaBc", "0xaBc", true)
hashCmp("0xAbc", "0xabC", false)
hashCmp("0xabcd", "0xabcd", true)
hashCmp("0xaBcd", "0xaBcd", true)
hashCmp("0xAbcd", "0xabcD", true)
hashCmp("0xverybadhex", "0xverybadhex", true)
hashCmp("0Xabcd", "0Xabcd", true)
hashCmp("0xabcd", "0Xabcd", false)
hashCmp("0Xabcd", "0xabcd", false)
{.gcsafe.}:
check:
nim_shim.hashMessage("0Xabcd") != nim_shim.hashMessage("0xabcd")
go_shim.hashMessage("0Xabcd") != go_shim.hashMessage("0xabcd")
asyncTest "generateAlias":
generateAliasCmp(pubKey_01)
generateAliasCmp(pubKey_02)
generateAliasCmp(pubKey_03)
generateAliasCmp(pubKey_04)
generateAliasCmp(pubKey_05)
generateAliasCmp(pubKey_06)
generateAliasCmp(pubKey_07)
generateAliasCmp(pubKey_08)
generateAliasCmp(pubKey_09)
generateAliasCmp(pubKey_10)
generateAliasCmp(pubKey_11)
generateAliasCmp(pubKey_12)
generateAliasCmp(pubKey_13)
generateAliasCmp(pubKey_14)
generateAliasCmp(pubKey_15)
generateAliasCmp(pubKey_16)
generateAliasCmp(pubKey_17)
generateAliasCmp(pubKey_18)
generateAliasCmp(pubKey_19)
generateAliasCmp(pubKey_20)
generateAliasCmp(badKey_01)
generateAliasCmp(badKey_02)
generateAliasCmp(badKey_03)
generateAliasCmp(badKey_04)
asyncTest "identicon":
identiconCmp(pubKey_01)
identiconCmp(pubKey_02)
identiconCmp(pubKey_03)
identiconCmp(pubKey_04)
identiconCmp(pubKey_05)
identiconCmp(pubKey_06)
identiconCmp(pubKey_07)
identiconCmp(pubKey_08)
identiconCmp(pubKey_09)
identiconCmp(pubKey_10)
identiconCmp(pubKey_11)
identiconCmp(pubKey_12)
identiconCmp(pubKey_13)
identiconCmp(pubKey_14)
identiconCmp(pubKey_15)
identiconCmp(pubKey_16)
identiconCmp(pubKey_17)
identiconCmp(pubKey_18)
identiconCmp(pubKey_19)
identiconCmp(pubKey_20)
identiconCmp(badKey_01)
identiconCmp(badKey_02)
identiconCmp(badKey_03)
identiconCmp(badKey_04)

View File

@ -5,8 +5,8 @@ import # vendor libs
chronos, json_serialization, sqlcipher, web3/conversions as web3_conversions
import # nim-status libs
../../nim_status/[conversions, database, pendingtxs],
../../nim_status/migrations/sql_scripts_app,
../nim_status/[conversions, database, pendingtxs],
../nim_status/migrations/sql_scripts_app,
./test_helpers
procSuite "pendingtxs":

View File

@ -5,8 +5,8 @@ import # vendor libs
chronos, json_serialization, sqlcipher
import # nim-status libs
../../nim_status/[database, permissions],
../../nim_status/migrations/sql_scripts_app,
../nim_status/[database, permissions],
../nim_status/migrations/sql_scripts_app,
./test_helpers
procSuite "permissions":

View File

@ -6,8 +6,8 @@ import # vendor libs
sqlcipher, web3/conversions as web3_conversions, web3/ethtypes
import # nim-status libs
../../nim_status/[conversions, database, settings],
../../nim_status/migrations/sql_scripts_app,
../nim_status/[conversions, database, settings],
../nim_status/migrations/sql_scripts_app,
./test_helpers
procSuite "settings":

View File

@ -1,14 +1,17 @@
import
./account,
# `test/account.nim` is presently disabled because it relies on
# `test/test_utils.nim`, which relies on `nim_status/go/shim.nim`, which has
# been removed from this repo
# ./account,
./accounts,
./bip32,
./callrpc,
./chats,
./contacts,
./db_smoke,
./hybrid_smoke,
# `test/nim/login_and_logout.nim` is presently disabled because
# `test/login_and_logout.nim` is presently disabled because
# `nim_status/accounts.nim` uses a global mutable variable for `web3_conn`
# (which can't be referenced within a chronos async function, e.g. an
# `asyncTest`); it should instead be a property of an init'd Status object
@ -21,6 +24,5 @@ import
./pendingtxs,
./permissions,
./settings,
./shims,
./tokens,
./waku_smoke

View File

@ -3,8 +3,11 @@ import nimcrypto
import chronicles
import os
import ../../nim_status
import ../../nim_status/go/shim as go_shim
import ../nim_status
# The module `nim_status/go/shim.nim` has been removed from this repo, so this
# test_utils module is not usable and will eventually be removed
import ../nim_status/go/shim as go_shim
proc hashPassword(password: string): string =
result = "0x" & $keccak_256.digest(password)

View File

@ -5,8 +5,8 @@ import # vendor libs
chronos, json_serialization, sqlcipher, web3/conversions
import # nim-status libs
../../nim_status/[database, tokens],
../../nim_status/migrations/sql_scripts_app,
../nim_status/[database, tokens],
../nim_status/migrations/sql_scripts_app,
./test_helpers
procSuite "tokens":

View File

@ -6,7 +6,7 @@ import # vendor libs
waku/v2/node/[config, wakunode2], waku/v2/protocol/waku_message
import # nim-status libs
../../nim_status/waku,
../nim_status/waku,
./test_helpers
# This test suite is essentially a "smoke test" for using nim-waku v2 from

@ -1 +1 @@
Subproject commit 92e5042667b747d22106f085eaa9b5e9766ba474
Subproject commit e7694f16ceccd7c98ecb6870263025018b7d37b3

1
vendor/status-go vendored

@ -1 +0,0 @@
Subproject commit 7387049d4b524d3371966fa07ccba3e08b6c652a