feat: dynamic library - pt1 (#9)

* feat: statuslib dynamic library

* fix: library versions
This commit is contained in:
RichΛrd 2021-09-10 11:29:10 -04:00 committed by GitHub
parent 7058328bb3
commit efe2790db6
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
42 changed files with 332 additions and 68 deletions

3
.gitignore vendored Normal file
View File

@ -0,0 +1,3 @@
.update.timestamp
nimcache
vendor/.nimble

87
.gitmodules vendored Normal file
View File

@ -0,0 +1,87 @@
[submodule "vendor/nimbus-build-system"]
path = vendor/nimbus-build-system
url = https://github.com/status-im/nimbus-build-system
[submodule "vendor/status-go"]
path = vendor/status-go
url = https://github.com/status-im/status-go
[submodule "vendor/nimcrypto"]
path = vendor/nimcrypto
url = https://github.com/cheatfate/nimcrypto.git
[submodule "vendor/uuids"]
path = vendor/uuids
url = https://github.com/pragmagic/uuids.git
[submodule "vendor/isaac"]
path = vendor/isaac
url = https://github.com/pragmagic/isaac.git
[submodule "vendor/nim-json-serialization"]
path = vendor/nim-json-serialization
url = https://github.com/status-im/nim-json-serialization.git
[submodule "vendor/nim-serialization"]
path = vendor/nim-serialization
url = https://github.com/status-im/nim-serialization.git
[submodule "vendor/nim-stew"]
path = vendor/nim-stew
url = https://github.com/status-im/nim-stew.git
[submodule "vendor/nim-faststreams"]
path = vendor/nim-faststreams
url = https://github.com/status-im/nim-faststreams.git
[submodule "vendor/nim-chronicles"]
path = vendor/nim-chronicles
url = https://github.com/status-im/nim-chronicles.git
[submodule "vendor/nim-status-go"]
path = vendor/nim-status-go
url = https://github.com/status-im/nim-status-go.git
[submodule "vendor/nim-stint"]
path = vendor/nim-stint
url = https://github.com/status-im/nim-stint.git
[submodule "vendor/nim-web3"]
path = vendor/nim-web3
url = https://github.com/status-im/nim-web3.git
[submodule "vendor/nim-http-utils"]
path = vendor/nim-http-utils
url = https://github.com/status-im/nim-http-utils
[submodule "vendor/nim-chronos"]
path = vendor/nim-chronos
url = https://github.com/status-im/nim-chronos.git
[submodule "vendor/nim-json-rpc"]
path = vendor/nim-json-rpc
url = https://github.com/status-im/nim-json-rpc
[submodule "vendor/news"]
path = vendor/news
url = https://github.com/Tormund/news
[submodule "vendor/nim-websock"]
path = vendor/nim-websock
url = https://github.com/status-im/nim-websock
[submodule "vendor/nim-bearssl"]
path = vendor/nim-bearssl
url = https://github.com/status-im/nim-bearssl
[submodule "vendor/nim-zlib"]
path = vendor/nim-zlib
url = https://github.com/status-im/nim-zlib
[submodule "vendor/nim-eth"]
path = vendor/nim-eth
url = https://github.com/status-im/nim-eth
[submodule "vendor/nim-secp256k1"]
path = vendor/nim-secp256k1
url = https://github.com/status-im/nim-secp256k1
[submodule "vendor/nim-metrics"]
path = vendor/nim-metrics
url = https://github.com/status-im/nim-metrics
[submodule "vendor/nim-confutils"]
path = vendor/nim-confutils
url = https://github.com/status-im/nim-confutils.git
[submodule "vendor/nim-libp2p"]
path = vendor/nim-libp2p
url = https://github.com/status-im/nim-libp2p
[submodule "vendor/nim-task-runner"]
path = vendor/nim-task-runner
url = https://github.com/status-im/nim-task-runner.git
[submodule "vendor/nbaser"]
path = vendor/nbaser
url = https://github.com/D-Nice/nbaser/
[submodule "vendor/nim-base32"]
path = vendor/nim-base32
url = https://github.com/elktree/nim-base32
[submodule "vendor/edn.nim"]
path = vendor/edn.nim
url = https://github.com/status-im/edn.nim

130
Makefile Normal file
View File

@ -0,0 +1,130 @@
# Copyright (c) 2021 Status Research & Development GmbH. Licensed under
# either of:
# - Apache License, version 2.0
# - MIT license
# at your option. This file may not be copied, modified, or distributed except
# according to those terms.
SHELL := bash # the shell used internally by Make
# used inside the included makefiles
BUILD_SYSTEM_DIR := vendor/nimbus-build-system
# we don't want an error here, so we can handle things later, in the ".DEFAULT" target
-include $(BUILD_SYSTEM_DIR)/makefiles/variables.mk
.PHONY: \
all \
bottles \
clean \
deps \
libstatuslib \
status-go \
update \
build_ctest \
ctest
ifeq ($(NIM_PARAMS),)
# "variables.mk" was not included, so we update the submodules.
GIT_SUBMODULE_UPDATE := git submodule update --init --recursive
.DEFAULT:
+@ echo -e "Git submodules not found. Running '$(GIT_SUBMODULE_UPDATE)'.\n"; \
$(GIT_SUBMODULE_UPDATE); \
echo
# Now that the included *.mk files appeared, and are newer than this file, Make will restart itself:
# https://www.gnu.org/software/make/manual/make.html#Remaking-Makefiles
#
# After restarting, it will execute its original goal, so we don't have to start a child Make here
# with "$(MAKE) $(MAKECMDGOALS)". Isn't hidden control flow great?
else # "variables.mk" was included. Business as usual until the end of this file.
all: libstatuslib
# must be included after the default target
-include $(BUILD_SYSTEM_DIR)/makefiles/targets.mk
ifeq ($(OS),Windows_NT) # is Windows_NT on XP, 2000, 7, Vista, 10...
detected_OS := Windows
else
detected_OS := $(strip $(shell uname))
endif
ifeq ($(detected_OS),Darwin)
CFLAGS := -mmacosx-version-min=10.14
export CFLAGS
CGO_CFLAGS := -mmacosx-version-min=10.14
export CGO_CFLAGS
LIBSTATUS_EXT := dylib
MACOSX_DEPLOYMENT_TARGET := 10.14
export MACOSX_DEPLOYMENT_TARGET
else ifeq ($(detected_OS),Windows)
LIBSTATUS_EXT := dll
else
LIBSTATUS_EXT := so
endif
ifeq ($(detected_OS),Darwin)
bottles/openssl:
./scripts/fetch-brew-bottle.sh openssl
bottles/pcre: bottles/openssl
./scripts/fetch-brew-bottle.sh pcre
bottles: bottles/openssl bottles/pcre
endif
deps: | deps-common bottles
update: | update-common
RELEASE ?= false
ifeq ($(RELEASE),false)
# We need `-d:debug` to get Nim's default stack traces
NIM_PARAMS += -d:debug
# Enable debugging symbols in DOtherSide, in case we need GDB backtraces
CFLAGS += -g
CXXFLAGS += -g
else
# Additional optimization flags for release builds are not included at present;
# adding them will involve refactoring config.nims in the root of this repo
NIM_PARAMS += -d:release
endif
NIM_PARAMS += --outdir:./build
STATUSGO := vendor/status-go/build/bin/libstatus.$(LIBSTATUS_EXT)
STATUSGO_LIBDIR := $(shell pwd)/$(shell dirname "$(STATUSGO)")
export STATUSGO_LIBDIR
status-go: $(STATUSGO)
$(STATUSGO): | deps
echo -e $(BUILD_MSG) "status-go"
+ cd vendor/status-go && \
$(MAKE) statusgo-shared-library $(HANDLE_OUTPUT)
libstatuslib: | $(STATUSGO)
echo -e $(BUILD_MSG) "$@" && \
$(ENV_SCRIPT) nim c $(NIM_PARAMS) $(NIM_EXTRA_PARAMS) -o:build/$@.$(LIBSTATUS_EXT).0 -d:ssl --app:lib --noMain --header --nimcache:nimcache/libstatuslib statuslib.nim && \
rm -f build/$@.$(LIBSTATUS_EXT) && \
ln -s $@.$(LIBSTATUS_EXT).0 build/$@.so && \
cp nimcache/libstatuslib/*.h build/. && \
[[ $$? = 0 ]]
# libraries for dynamic linking of non-Nim objects
EXTRA_LIBS_DYNAMIC := -L"$(CURDIR)/build" -lstatuslib -lm -L"$(STATUSGO_LIBDIR)" -lstatus
build_ctest: | libstatuslib build deps
echo -e $(BUILD_MSG) "build/ctest" && \
$(CC) test/main.c -Wl,-rpath,'$$ORIGIN' -I./vendor/nimbus-build-system/vendor/Nim/lib $(EXTRA_LIBS_DYNAMIC) -g -o build/ctest
ctest: | build_ctest
echo -e "Running ctest:" && \
LD_LIBRARY_PATH="$(STATUSGO_LIBDIR)" \
./build/ctest
clean: | clean-common
rm -rf bin/* node_modules bottles/* pkg/* tmp/* $(STATUSGO)
endif # "variables.mk" was not included

2
build/.gitignore vendored Normal file
View File

@ -0,0 +1,2 @@
*
!.gitignore

View File

@ -25,8 +25,8 @@ proc generateAddresses*(self: AccountModel): seq[GeneratedAccount] =
self.generatedAddresses.add(account)
result = self.generatedAddresses
proc openAccounts*(self: AccountModel): seq[NodeAccount] =
result = status_accounts.openAccounts()
proc openAccounts*(self: AccountModel, statusGoDir: string): seq[NodeAccount] =
result = status_accounts.openAccounts(statusGoDir)
proc login*(self: AccountModel, selectedAccountIndex: int, password: string): NodeAccount =
let currentNodeAccount = self.nodeAccounts[selectedAccountIndex]

View File

@ -1,11 +1,4 @@
import libstatus/accounts/constants
export OPENURI
export DATADIR
export STATUSGODIR
export KEYSTOREDIR
export TMPDIR
export LOGDIR
const APP_UPDATES_ENS* = "desktop.status.eth"
const CHECK_VERSION_TIMEOUT_MS* = 5000

View File

@ -58,10 +58,10 @@ proc generateAlias*(publicKey: string): string =
proc generateIdenticon*(publicKey: string): string =
result = $status_go.identicon(publicKey)
proc initNode*() =
createDir(STATUSGODIR)
createDir(KEYSTOREDIR)
discard $status_go.initKeystore(KEYSTOREDIR)
proc initNode*(statusGoDir, keystoreDir: string) =
createDir(statusGoDir)
createDir(keystoreDir)
discard $status_go.initKeystore(keystoreDir)
proc parseIdentityImage*(images: JsonNode): IdentityImage =
result = IdentityImage()
@ -73,7 +73,7 @@ proc parseIdentityImage*(images: JsonNode): IdentityImage =
elif (image["type"].getStr == "large"):
result.large = image["uri"].getStr
proc openAccounts*(): seq[NodeAccount] =
proc openAccounts*(STATUSGODIR: string): seq[NodeAccount] =
let strNodeAccounts = status_go.openAccounts(STATUSGODIR).parseJson
# FIXME fix serialization
result = @[]
@ -226,9 +226,9 @@ proc loadAccount*(address: string, password: string): GeneratedAccount =
raise newException(StatusGoException, "Error loading wallet account: " & error)
proc verifyAccountPassword*(address: string, password: string): bool =
proc verifyAccountPassword*(address: string, password: string, keystoreDir: string): bool =
let hashedPassword = hashPassword(password)
let verifyResult = $status_go.verifyAccountPassword(KEYSTOREDIR, address, hashedPassword)
let verifyResult = $status_go.verifyAccountPassword(keystoreDir, address, hashedPassword)
let error = parseJson(verifyResult)["error"].getStr
if error == "":

View File

@ -1,9 +1,6 @@
import # std libs
json, os, sequtils, strutils
import # vendor libs
confutils
const GENERATED* = "generated"
const SEED* = "seed"
const KEY* = "key"
@ -271,37 +268,13 @@ proc defaultDataDir(): string =
targetDir
absolutePath(joinPath(parentDir, "Status"))
type StatusDesktopConfig = object
dataDir* {.
defaultValue: defaultDataDir()
desc: "Status Desktop data directory"
abbr: "d" .}: string
uri* {.
defaultValue: ""
desc: "status-im:// URI to open a chat or other"
name: "uri" .}: string
# On macOS the first time when a user gets the "App downloaded from the
# internet" warning, and clicks the Open button, the OS passes a unique process
# serial number (PSN) as -psn_... command-line argument, which we remove before
# processing the arguments with nim-confutils.
# Credit: https://github.com/bitcoin/bitcoin/blame/b6e34afe9735faf97d6be7a90fafd33ec18c0cbb/src/util/system.cpp#L383-L389
proc ensureDirectories*(dataDir, tmpDir, logDir: string) =
createDir(dataDir)
createDir(tmpDir)
createDir(logDir)
var cliParams = commandLineParams()
if defined(macosx):
cliParams.keepIf(proc(p: string): bool = not p.startsWith("-psn_"))
let desktopConfig = StatusDesktopConfig.load(cliParams)
let
baseDir = absolutePath(expandTilde(desktopConfig.dataDir))
OPENURI* = desktopConfig.uri
DATADIR* = baseDir & sep
STATUSGODIR* = joinPath(baseDir, "data") & sep
KEYSTOREDIR* = joinPath(baseDir, "data", "keystore") & sep
TMPDIR* = joinPath(baseDir, "tmp") & sep
LOGDIR* = joinPath(baseDir, "logs") & sep
createDir(DATADIR)
createDir(TMPDIR)
createDir(LOGDIR)
# C Helpers
# ==============================================================================
proc ensureDirectories*(dataDir, tmpDir, logDir: cstring) {.exportc, dynlib.} =
ensureDirectories($dataDir, $tmpDir, $logDir)

View File

@ -53,13 +53,13 @@ proc newStatusInstance*(fleetConfig: string): Status =
result.provider = provider.newProviderModel(result.events, result.permissions)
result.osnotifications = newOsNotifications(result.events)
proc initNode*(self: Status) =
libstatus_accounts.initNode()
proc initNode*(self: Status, statusGoDir, keystoreDir: string) =
libstatus_accounts.initNode(statusGoDir, keystoreDir)
proc startMessenger*(self: Status) =
proc startMessenger*(self: Status) {.exportc, dynlib.} =
libstatus_core.startMessenger()
proc reset*(self: Status) =
proc reset*(self: Status) {.exportc, dynlib.} =
# TODO: remove this once accounts are not tracked in the AccountsModel
self.accounts.reset()
@ -71,19 +71,39 @@ proc reset*(self: Status) =
# TODO: add all resets here
proc getNodeVersion*(self: Status): string =
proc getNodeVersion*(self: Status): string {.exportc, dynlib.} =
libstatus_settings.getWeb3ClientVersion()
# TODO: duplicated??
proc saveSetting*(self: Status, setting: Setting, value: string | bool) =
discard libstatus_settings.saveSetting(setting, value)
proc getBloomFilter*(self: Status): string =
proc getBloomFilter*(self: Status): string {.exportc, dynlib.} =
result = libstatus_core.getBloomFilter()
proc getBloomFilterBitsSet*(self: Status): int =
proc getBloomFilterBitsSet*(self: Status): int {.exportc, dynlib.} =
let bloomFilter = libstatus_core.getBloomFilter()
var bitCount = 0;
for b in hexToSeqByte(bloomFilter):
bitCount += countSetBits(b)
return bitCount
# C Helpers
# ==============================================================================
# This creates extra functions with a simpler API for C interop. This is to avoid
# having to manually create nim strings, (we can use cstring) instead, and also
# because functions that accept more than one type for the same parameter are not
# exported correctly
proc newStatusInstance*(fleetConfig: cstring): Status {.exportc, dynlib.} =
newStatusInstance($fleetConfig)
proc initNode*(self: Status, statusGoDir, keystoreDir: cstring) {.exportc, dynlib.} =
self.initNode($statusGoDir, $keystoreDir)
proc saveStringSetting*(self: Status, setting: Setting, value: cstring) {.exportc, dynlib.} =
self.saveSetting(setting, $value)
proc saveBoolSetting*(self: Status, setting: Setting, value: bool) {.exportc, dynlib.} =
self.saveSetting(setting, value)

View File

@ -281,24 +281,24 @@ proc generateNewAccount*(self: WalletModel, password: string, accountName: strin
if statusGoResult.error != "":
error "Error storing the latest wallet index", msg=statusGoResult.error
proc addAccountsFromSeed*(self: WalletModel, seed: string, password: string, accountName: string, color: string) =
proc addAccountsFromSeed*(self: WalletModel, seed: string, password: string, accountName: string, color: string, keystoreDir: string) =
let mnemonic = replace(seed, ',', ' ')
var generatedAccount = status_accounts.multiAccountImportMnemonic(mnemonic)
generatedAccount.derived = status_accounts.deriveAccounts(generatedAccount.id)
let
defaultAccount = status_accounts.getDefaultAccount()
isPasswordOk = status_accounts.verifyAccountPassword(defaultAccount, password)
isPasswordOk = status_accounts.verifyAccountPassword(defaultAccount, password, keystoreDir)
if not isPasswordOk:
raise newException(StatusGoException, "Error generating new account: invalid password")
self.addNewGeneratedAccount(generatedAccount, password, accountName, color, constants.SEED)
proc addAccountsFromPrivateKey*(self: WalletModel, privateKey: string, password: string, accountName: string, color: string) =
proc addAccountsFromPrivateKey*(self: WalletModel, privateKey: string, password: string, accountName: string, color: string, keystoreDir: string) =
let
generatedAccount = status_accounts.MultiAccountImportPrivateKey(privateKey)
defaultAccount = status_accounts.getDefaultAccount()
isPasswordOk = status_accounts.verifyAccountPassword(defaultAccount, password)
isPasswordOk = status_accounts.verifyAccountPassword(defaultAccount, password, keystoreDir)
if not isPasswordOk:
raise newException(StatusGoException, "Error generating new account: invalid password")

View File

@ -158,24 +158,24 @@ proc generateNewAccount*(self: StatusWalletController, password: string, account
if statusGoResult.error != "":
error "Error storing the latest wallet index", msg=statusGoResult.error
proc addAccountsFromSeed*(self: StatusWalletController, seed: string, password: string, accountName: string, color: string) =
proc addAccountsFromSeed*(self: StatusWalletController, seed: string, password: string, accountName: string, color: string, keystoreDir: string) =
let mnemonic = replace(seed, ',', ' ')
var generatedAccount = status_accounts.multiAccountImportMnemonic(mnemonic)
generatedAccount.derived = status_accounts.deriveAccounts(generatedAccount.id)
let
defaultAccount = status_accounts.getDefaultAccount()
isPasswordOk = status_accounts.verifyAccountPassword(defaultAccount, password)
isPasswordOk = status_accounts.verifyAccountPassword(defaultAccount, password, keystoreDir)
if not isPasswordOk:
raise newException(StatusGoException, "Error generating new account: invalid password")
self.addNewGeneratedAccount(generatedAccount, password, accountName, color, constants.SEED)
proc addAccountsFromPrivateKey*(self: StatusWalletController, privateKey: string, password: string, accountName: string, color: string) =
proc addAccountsFromPrivateKey*(self: StatusWalletController, privateKey: string, password: string, accountName: string, color: string, keystoreDir: string) =
let
generatedAccount = status_accounts.MultiAccountImportPrivateKey(privateKey)
defaultAccount = status_accounts.getDefaultAccount()
isPasswordOk = status_accounts.verifyAccountPassword(defaultAccount, password)
isPasswordOk = status_accounts.verifyAccountPassword(defaultAccount, password, keystoreDir)
if not isPasswordOk:
raise newException(StatusGoException, "Error generating new account: invalid password")

6
statuslib.nim Normal file
View File

@ -0,0 +1,6 @@
# TODO: Import all the files that contain {.exportc.}
import status/status
proc helloWorld() {.exportc, dynlib.} =
echo "hello world"

21
test/main.c Normal file
View File

@ -0,0 +1,21 @@
#include <stdio.h>
#include <stddef.h>
#include "../build/statuslib.h"
void NimMain();
int main(int argc, char *argv[])
{
NimMain();
helloWorld();
ensureDirectories("./build/A", "./build/B", "./build/C");
char fleetConfigStr[] = "{\"fleets\":{\"eth.prod\":{\"boot\":{\"boot-01.ac-cn-hongkong-c.eth.prod\":\"enode://6e6554fb3034b211398fcd0f0082cbb6bd13619e1a7e76ba66e1809aaa0c5f1ac53c9ae79cf2fd4a7bacb10d12010899b370c75fed19b991d9c0cdd02891abad@47.75.99.169:443\"},\"mail\":{\"mail-01.ac-cn-hongkong-c.eth.prod\":\"enode://606ae04a71e5db868a722c77a21c8244ae38f1bd6e81687cc6cfe88a3063fa1c245692232f64f45bd5408fed5133eab8ed78049332b04f9c110eac7f71c1b429@47.75.247.214:443\"},\"rendezvous\":{\"boot-01.ac-cn-hongkong-c.eth.prod\":\"/ip4/47.75.99.169/tcp/30703/ethv4/16Uiu2HAmV8Hq9e3zm9TMVP4zrVHo3BjqW5D6bDVV6VQntQd687e4\"},\"whisper\":{\"node-01.ac-cn-hongkong-c.eth.prod\":\"enode://b957e51f41e4abab8382e1ea7229e88c6e18f34672694c6eae389eac22dab8655622bbd4a08192c321416b9becffaab11c8e2b7a5d0813b922aa128b82990dab@47.75.222.178:443\"}}},\"meta\":{\"hostname\":\"node-01.do-ams3.proxy.misc\",\"timestamp\":\"2021-09-09T00:00:14.760436\"}}";
void *statusObj = newStatusInstance(fleetConfigStr);
initNode(statusObj, "./build/A", "./build/B");
}

1
vendor/edn.nim vendored Submodule

@ -0,0 +1 @@
Subproject commit 3305e41f9da3f2f21c56bd23b74b0a3589f3bf3e

1
vendor/isaac vendored Submodule

@ -0,0 +1 @@
Subproject commit 45a5cbbd54ff59ba3ed94242620c818b9aad1b5b

1
vendor/nbaser vendored Submodule

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

1
vendor/news vendored Submodule

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

1
vendor/nim-base32 vendored Submodule

@ -0,0 +1 @@
Subproject commit 660680c1cbdf6b1294b669fdb8b6e9c89794cb5b

1
vendor/nim-bearssl vendored Submodule

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

1
vendor/nim-chronicles vendored Submodule

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

1
vendor/nim-chronos vendored Submodule

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

1
vendor/nim-confutils vendored Submodule

@ -0,0 +1 @@
Subproject commit 7176de4ddb3a628a5c3abfcd430010bf0229deb1

1
vendor/nim-eth vendored Submodule

@ -0,0 +1 @@
Subproject commit 3ddb498f2a41e1e470d780757faeedc0b8cb3a21

1
vendor/nim-faststreams vendored Submodule

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

1
vendor/nim-http-utils vendored Submodule

@ -0,0 +1 @@
Subproject commit 33d70b9f378591e074838d6608a4468940137357

1
vendor/nim-json-rpc vendored Submodule

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

1
vendor/nim-json-serialization vendored Submodule

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

1
vendor/nim-libp2p vendored Submodule

@ -0,0 +1 @@
Subproject commit 70deac9e0d16f7d00a0d4404ed191042dbf079be

1
vendor/nim-metrics vendored Submodule

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

1
vendor/nim-secp256k1 vendored Submodule

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

1
vendor/nim-serialization vendored Submodule

@ -0,0 +1 @@
Subproject commit 474bdbf49cf1634ba504888ad1a1927a2703bd3f

1
vendor/nim-status-go vendored Submodule

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

1
vendor/nim-stew vendored Submodule

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

1
vendor/nim-stint vendored Submodule

@ -0,0 +1 @@
Subproject commit 9e49b00148884a01d61478ae5d2c69b543b93ceb

1
vendor/nim-task-runner vendored Submodule

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

1
vendor/nim-web3 vendored Submodule

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

1
vendor/nim-websock vendored Submodule

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

1
vendor/nim-zlib vendored Submodule

@ -0,0 +1 @@
Subproject commit 6bbc67d09e624d69052d62b2353878f491186942

1
vendor/nimbus-build-system vendored Submodule

@ -0,0 +1 @@
Subproject commit 6589cedffa2eb083f838d15c70c45ce000596859

1
vendor/nimcrypto vendored Submodule

@ -0,0 +1 @@
Subproject commit 30d0ceaba02c0b966515f98873a0404786fbf796

1
vendor/status-go vendored Submodule

@ -0,0 +1 @@
Subproject commit 07651d4d0696a2810666d49baaebcebc308c992a

1
vendor/uuids vendored Submodule

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