diff --git a/.dockerignore b/.dockerignore index 1f9ca954ba..3d1d7cfbad 100644 --- a/.dockerignore +++ b/.dockerignore @@ -28,7 +28,7 @@ book report # On development branch only. This should be removed for point releases -Cargo.lock +# Cargo.lock *.log # Ignore DataStore, Database and Log files @@ -39,4 +39,4 @@ base_layer/wallet_ffi/build.config /base_layer/wallet_ffi/logs/ base_layer/wallet_ffi/.cargo/config -keys.json \ No newline at end of file +keys.json diff --git a/Cargo.toml b/Cargo.toml index f070abe0c2..ac268c2585 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -16,6 +16,7 @@ members = [ "infrastructure/shutdown", "infrastructure/storage", "infrastructure/test_utils", + # "applications/installer", "applications/tari_base_node", "applications/tari_console_wallet", "applications/test_faucet", diff --git a/applications/installer/Cargo.toml b/applications/installer/Cargo.toml new file mode 100644 index 0000000000..87b343848d --- /dev/null +++ b/applications/installer/Cargo.toml @@ -0,0 +1,7 @@ +[package] +name = "installer" +version = "0.1.0" +edition = "2018" + +[dependencies] +dirs = "3.0" diff --git a/applications/installer/src/config/base_node.rs b/applications/installer/src/config/base_node.rs new file mode 100644 index 0000000000..d3ab644bcc --- /dev/null +++ b/applications/installer/src/config/base_node.rs @@ -0,0 +1,45 @@ +// Copyright 2021. The Tari Project +// +// Redistribution and use in source and binary forms, with or without modification, are permitted provided that the +// following conditions are met: +// +// 1. Redistributions of source code must retain the above copyright notice, this list of conditions and the following +// disclaimer. +// +// 2. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the +// following disclaimer in the documentation and/or other materials provided with the distribution. +// +// 3. Neither the name of the copyright holder nor the names of its contributors may be used to endorse or promote +// products derived from this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, +// INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE +// DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR +// SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, +// WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE +// USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +use crate::config::common::{InstallLocation, SourceLocation}; + +pub struct BaseNodeOptions { + // Where do we get the base node code from? + source: SourceLocation, + // Where do the base node and related files live? + install_location: InstallLocation, + // Tor setup + tor_options: TorOptions, +} + +pub enum TorLocation { + // Use the globally instaled system version of tor + System, + // Run Tor from a docker image + Docker, + // Install a new version of Tor in the base node executable folder + Local, +} + +pub struct TorOptions { + location: TorLocation, +} diff --git a/applications/installer/src/config/combined.rs b/applications/installer/src/config/combined.rs new file mode 100644 index 0000000000..c0bfb17542 --- /dev/null +++ b/applications/installer/src/config/combined.rs @@ -0,0 +1,41 @@ +// Copyright 2021. The Tari Project +// +// Redistribution and use in source and binary forms, with or without modification, are permitted provided that the +// following conditions are met: +// +// 1. Redistributions of source code must retain the above copyright notice, this list of conditions and the following +// disclaimer. +// +// 2. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the +// following disclaimer in the documentation and/or other materials provided with the distribution. +// +// 3. Neither the name of the copyright holder nor the names of its contributors may be used to endorse or promote +// products derived from this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, +// INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE +// DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR +// SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, +// WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE +// USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +use crate::config::{ + common::{Network, TariConfig}, + BaseNodeOptions, + MiningOptions, + WalletOptions, +}; + +pub struct InstallerOptions { + // Selects the netowrk to run + network: Network, + // A way of getting at the tari global configuration files + tari_config: TariConfig, + // Installer options for a base node + base_node_options: Option, + // Installer options for the console wallet + wallet_options: Option, + // Installer options for mining + mining_options: Option, +} diff --git a/applications/installer/src/config/common.rs b/applications/installer/src/config/common.rs new file mode 100644 index 0000000000..8c26809355 --- /dev/null +++ b/applications/installer/src/config/common.rs @@ -0,0 +1,80 @@ +// Copyright 2021. The Tari Project +// +// Redistribution and use in source and binary forms, with or without modification, are permitted provided that the +// following conditions are met: +// +// 1. Redistributions of source code must retain the above copyright notice, this list of conditions and the following +// disclaimer. +// +// 2. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the +// following disclaimer in the documentation and/or other materials provided with the distribution. +// +// 3. Neither the name of the copyright holder nor the names of its contributors may be used to endorse or promote +// products derived from this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, +// INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE +// DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR +// SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, +// WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE +// USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +use std::path::PathBuf; + +#[cfg(target_os = "windows")] +const TARI_FOLDER: &str = "tari"; +#[cfg(any(target_os = "macos", target_os = "unix"))] +const TARI_FOLDER: &str = ".tari"; + +pub enum SourceLocation { + SourceCode(SourceCodeOptions), + Docker(DockerOptions), +} + +pub struct SourceCodeOptions {} + +pub struct DockerOptions {} + +pub struct InstallLocation { + config_folder: PathBuf, + executable_folder: PathBuf, + data_folder: PathBuf, +} + +impl Default for InstallLocation { + fn default() -> Self { + let mut home = dirs::home_dir().expect("No default home folder"); + let mut bin: PathBuf; + let data = dirs::data_dir().expect("No default data folder"); + #[cfg(target_os = "windows")] + { + home.push(TARI_FOLDER); + bin = PathBuf::from("C:\\Program Files"); + } + #[cfg(any(target_os = "macos", target_os = "unix"))] + { + bin = dirs::home_dir().expect("No default home folder"); + bin.push("bin"); + home.push(TARI_FOLDER); + } + + Self { + config_folder: home, + executable_folder: bin, + data_folder: data, + } + } +} + +pub enum TariConfig { + Default, + Supplied(PathBuf), + Inline(String), +} + +pub enum Network { + Stibbons, + Weatherwax, + Mainnet, +} diff --git a/applications/installer/src/config/mining.rs b/applications/installer/src/config/mining.rs new file mode 100644 index 0000000000..f344d57c5a --- /dev/null +++ b/applications/installer/src/config/mining.rs @@ -0,0 +1,49 @@ +// Copyright 2021. The Tari Project +// +// Redistribution and use in source and binary forms, with or without modification, are permitted provided that the +// following conditions are met: +// +// 1. Redistributions of source code must retain the above copyright notice, this list of conditions and the following +// disclaimer. +// +// 2. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the +// following disclaimer in the documentation and/or other materials provided with the distribution. +// +// 3. Neither the name of the copyright holder nor the names of its contributors may be used to endorse or promote +// products derived from this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, +// INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE +// DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR +// SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, +// WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE +// USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +use crate::config::{InstallLocation, SourceLocation}; + +pub enum PoolStrategy { + Solo, + Pool, +} + +pub enum Miners { + None, + Sha3Only(PoolStrategy), + MergeMineOnly(PoolStrategy), + Both { + sha3: PoolStrategy, + merge_mine: PoolStrategy, + }, +} + +pub struct MiningOptions { + source: SourceLocation, + install_location: InstallLocation, + miners: Miners, +} + +pub struct XmRigOptions { + source: SourceLocation, + install_location: InstallLocation, +} diff --git a/applications/installer/src/config/mod.rs b/applications/installer/src/config/mod.rs new file mode 100644 index 0000000000..284fb5100d --- /dev/null +++ b/applications/installer/src/config/mod.rs @@ -0,0 +1,33 @@ +// Copyright 2021. The Tari Project +// +// Redistribution and use in source and binary forms, with or without modification, are permitted provided that the +// following conditions are met: +// +// 1. Redistributions of source code must retain the above copyright notice, this list of conditions and the following +// disclaimer. +// +// 2. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the +// following disclaimer in the documentation and/or other materials provided with the distribution. +// +// 3. Neither the name of the copyright holder nor the names of its contributors may be used to endorse or promote +// products derived from this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, +// INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE +// DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR +// SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, +// WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE +// USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +mod base_node; +mod combined; +mod common; +mod mining; +mod wallet; + +pub use base_node::BaseNodeOptions; +pub use combined::InstallerOptions; +pub use common::{InstallLocation, SourceLocation}; +pub use mining::{Miners, MiningOptions}; +pub use wallet::WalletOptions; diff --git a/applications/installer/src/config/wallet.rs b/applications/installer/src/config/wallet.rs new file mode 100644 index 0000000000..9f2d6fe6fa --- /dev/null +++ b/applications/installer/src/config/wallet.rs @@ -0,0 +1,30 @@ +// Copyright 2021. The Tari Project +// +// Redistribution and use in source and binary forms, with or without modification, are permitted provided that the +// following conditions are met: +// +// 1. Redistributions of source code must retain the above copyright notice, this list of conditions and the following +// disclaimer. +// +// 2. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the +// following disclaimer in the documentation and/or other materials provided with the distribution. +// +// 3. Neither the name of the copyright holder nor the names of its contributors may be used to endorse or promote +// products derived from this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, +// INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE +// DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR +// SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, +// WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE +// USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +use crate::config::{InstallLocation, SourceLocation}; + +pub struct WalletOptions { + // Where to pull the wallet source or binary from + source: SourceLocation, + // Where the wallet and its data will live. SQLite installation will follow the settings chosen here. + install_location: InstallLocation, +} diff --git a/applications/installer/src/main.rs b/applications/installer/src/main.rs new file mode 100644 index 0000000000..e0265f2609 --- /dev/null +++ b/applications/installer/src/main.rs @@ -0,0 +1,3 @@ +mod config; + +fn main() {} diff --git a/applications/installer/src/utils/mod.rs b/applications/installer/src/utils/mod.rs new file mode 100644 index 0000000000..a1a28eef6f --- /dev/null +++ b/applications/installer/src/utils/mod.rs @@ -0,0 +1,23 @@ +// Copyright 2021. The Tari Project +// +// Redistribution and use in source and binary forms, with or without modification, are permitted provided that the +// following conditions are met: +// +// 1. Redistributions of source code must retain the above copyright notice, this list of conditions and the following +// disclaimer. +// +// 2. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the +// following disclaimer in the documentation and/or other materials provided with the distribution. +// +// 3. Neither the name of the copyright holder nor the names of its contributors may be used to endorse or promote +// products derived from this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, +// INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE +// DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR +// SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, +// WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE +// USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + + diff --git a/applications/tari_console_wallet/Cargo.toml b/applications/tari_console_wallet/Cargo.toml index 378a480d95..a45fdf58e2 100644 --- a/applications/tari_console_wallet/Cargo.toml +++ b/applications/tari_console_wallet/Cargo.toml @@ -44,7 +44,6 @@ tracing-subscriber = "0.2.20" opentelemetry = { version = "0.16", default-features = false, features = ["trace","rt-tokio"] } opentelemetry-jaeger = { version="0.15", features=["rt-tokio"]} - [dependencies.tari_core] path = "../../base_layer/core" version = "^0.9" diff --git a/buildtools/base_node.Dockerfile b/buildtools/docker/base_node.Dockerfile similarity index 100% rename from buildtools/base_node.Dockerfile rename to buildtools/docker/base_node.Dockerfile diff --git a/buildtools/docker_rig/README.md b/buildtools/docker_rig/README.md new file mode 100644 index 0000000000..1e38bb60ed --- /dev/null +++ b/buildtools/docker_rig/README.md @@ -0,0 +1,70 @@ +# The complete Docker guide to Tari + +## Quick Start + +Install docker + +Run the universal installer +Select 'docker' as the system layout +Configure the containers to run +Other config options incl tor password +"Go!" + +## Layout + + +-----------------------+ + | | ++---->| Console Wallet +------------------+ +| | | | +| +----------+------------+ | +| | | +| | gRPC | +| | | +| | | +| +----------v------------+ +------v-----+ +| | | Socks5 | | +| | Base Node +---------->| Tor |----> Network +| | | | | +| +----------^------------+ +------------+ +| | +| | +| | +| +----------+------------+ +| | | ++-----+ SHA3-Miner | +| | | +| +-----------------------+ +| +| +| +| +-----------------------+ +| | | ++-----+ XMRRig etc | + | | + +-----------------------+ + +#### Notes + +Building docker images: + +``` +cd buildtools/docker_rig +docker build -t quay.io/tarilabs/tor:latest -f base_node.Dockerfile . +docker build -t quay.io/tarilabs/tari_base_node:latest -f base_node.Dockerfile ../../ +``` + +Base node/Wallet config for using the Tor docker container: + +```toml +tcp_listener_address = "/ip4/0.0.0.0/tcp/18189" +transport = "tor" +tor_control_address = "/dns4/tor/tcp/9051" +tor_control_auth = "password=asdf" # replace with your configured password +tor_onion_port = 18141 +tor_forward_address = "/ip4/0.0.0.0/tcp/18189" +tor_socks_address_override="/dns4/tor/tcp/9050" +``` + +When attaching to a running container: + +To detach the tty without exiting the shell/program, use the escape sequence ^P^Q (Ctrl+P followed by Ctrl+Q). diff --git a/buildtools/docker_rig/base_node.Dockerfile b/buildtools/docker_rig/base_node.Dockerfile new file mode 100644 index 0000000000..f0962d0ae6 --- /dev/null +++ b/buildtools/docker_rig/base_node.Dockerfile @@ -0,0 +1,53 @@ +FROM quay.io/tarilabs/rust_tari-build-with-deps:nightly-2021-05-09 as builder + +WORKDIR /tari + +# Adding only necessary things up front and copying the entrypoint script last +# to take advantage of layer caching in docker +ADD Cargo.lock . +ADD Cargo.toml . +ADD applications applications +ADD base_layer base_layer +ADD common common +ADD comms comms +ADD infrastructure infrastructure +ADD meta meta +ADD rust-toolchain . + +# RUN rustup component add rustfmt --toolchain nightly-2020-08-13-x86_64-unknown-linux-gnu +#ARG TBN_ARCH=native +ARG TBN_ARCH=x86-64 +#ARG TBN_FEATURES=avx2 +ARG TBN_FEATURES=safe +ENV RUSTFLAGS="-C target_cpu=$TBN_ARCH" +ENV ROARING_ARCH=$TBN_ARCH + +RUN cargo build --bin tari_base_node --release --features $TBN_FEATURES --locked + +# Create a base minimal image for the executables +FROM quay.io/bitnami/minideb:buster as base +# Disable Prompt During Packages Installation +ARG DEBIAN_FRONTEND=noninteractive +RUN apt update && apt -y install \ + apt-transport-https \ + bash \ + ca-certificates \ + curl \ + gpg \ + iputils-ping \ + less \ + libreadline7 \ + libreadline-dev \ + libsqlite3-0 \ + openssl \ + telnet + +# Now create a new image with only the essentials and throw everything else away +FROM base +ENV APP_NAME=base_node APP_EXEC=tari_base_node + +COPY --from=builder /tari/target/release/$APP_EXEC /usr/bin/ +COPY buildtools/docker_rig/start_base_node.sh /usr/bin/start_tari_app.sh + +ENTRYPOINT [ "start_tari_app.sh", "-c", "/var/tari/config/config.toml", "-b", "/var/tari/base_node" ] +# CMD [ "--non-interactive-mode" ] diff --git a/buildtools/docker_rig/console_wallet.Dockerfile b/buildtools/docker_rig/console_wallet.Dockerfile new file mode 100644 index 0000000000..50f12eb2c4 --- /dev/null +++ b/buildtools/docker_rig/console_wallet.Dockerfile @@ -0,0 +1,53 @@ +FROM quay.io/tarilabs/rust_tari-build-with-deps:nightly-2021-05-09 as builder + +WORKDIR /tari + +# Adding only necessary things up front and copying the entrypoint script last +# to take advantage of layer caching in docker +ADD Cargo.lock . +ADD Cargo.toml . +ADD applications applications +ADD base_layer base_layer +ADD common common +ADD comms comms +ADD infrastructure infrastructure +ADD meta meta +ADD rust-toolchain . + +# RUN rustup component add rustfmt --toolchain nightly-2020-08-13-x86_64-unknown-linux-gnu +#ARG TBN_ARCH=native +ARG TBN_ARCH=x86-64 +#ARG TBN_FEATURES=avx2 +ARG TBN_FEATURES=safe +ENV RUSTFLAGS="-C target_cpu=$TBN_ARCH" +ENV ROARING_ARCH=$TBN_ARCH + +RUN cargo build --bin tari_console_wallet --release --features $TBN_FEATURES --locked + +# Create a base minimal image for the executables +FROM quay.io/bitnami/minideb:buster as base +# Disable Prompt During Packages Installation +ARG DEBIAN_FRONTEND=noninteractive +RUN apt update && apt -y install \ + apt-transport-https \ + bash \ + ca-certificates \ + curl \ + gpg \ + iputils-ping \ + less \ + libreadline7 \ + libreadline-dev \ + libsqlite3-0 \ + openssl \ + telnet + +# Now create a new image with only the essentials and throw everything else away +FROM base +ENV APP_NAME=wallet APP_EXEC=tari_console_wallet + +COPY --from=builder /tari/target/release/$APP_EXEC /usr/bin/ +COPY buildtools/docker_rig/start_wallet.sh /usr/bin/start_tari_app.sh + +ENTRYPOINT [ "start_tari_app.sh", "-c", "/var/tari/config/config.toml", "-b", "/var/tari/wallet" ] +# CMD [ "--non-interactive-mode" ] diff --git a/buildtools/docker_rig/docker-compose.yml b/buildtools/docker_rig/docker-compose.yml new file mode 100644 index 0000000000..ff149cce2c --- /dev/null +++ b/buildtools/docker_rig/docker-compose.yml @@ -0,0 +1,93 @@ +version: "3.9" +services: + tor: + image: quay.io/tarilabs/tor:latest + build: + context: . + dockerfile: tor.Dockerfile + ports: + - 9050:9050 + - 9051:9051 + wallet: + image: quay.io/tarilabs/tari_console_wallet:latest + build: + context: ./../.. + dockerfile: buildtools/docker_rig/console_wallet.Dockerfile + args: + ARG WALLET_ARCH: x86-64 + ports: + - 18188:18188 + environment: + TARI_LOG_CONFIGURATION: "/var/tari/config/log4rs.yml" + APP_NAME: wallet + APP_EXEC: tari_console_wallet + CREATE_CONFIG: 1 + CREATE_ID: 1 + WAIT_FOR_TOR: 60 + TARI_NETWORK: weatherwax + SHELL: "/bin/bash" + TERM: "linux" + PASSWORD: "asdf" + TARI_WALLET__WEATHERWAX__TOR_CONTROL_AUTH: "password=asdf" + TARI_WALLET__WEATHERWAX__TOR_CONTROL_ADDRESS: "/dns4/tor/tcp/9051" + TARI_WALLET__WEATHERWAX__TOR_SOCKS_ADDRESS_OVERRIDE: "/dns4/tor/tcp/9050" + TARI_WALLET__WEATHERWAX__TOR_FORWARD_ADDRESS: "/ip4/0.0.0.0/tcp/18188" + TARI_WALLET__WEATHERWAX__TCP_LISTENER_ADDRESS: "/ip4/0.0.0.0/tcp/18188" + command: [] + depends_on: + - tor + volumes: + - $HOME/.tari/config:/var/tari/config + - $HOME/.tari/wallet:/var/tari/wallet + - $HOME/.tari/wallet/log:/var/tari/log + stdin_open: true + tty: true + base_node: + image: quay.io/tarilabs/tari_base_node:latest + build: + context: ./../.. + dockerfile: buildtools/docker_rig/base_node.Dockerfile + args: + ARG WALLET_ARCH: x86-64 + environment: + TARI_LOG_CONFIGURATION: "/var/tari/config/log4rs.yml" + APP_NAME: base_node + APP_EXEC: tari_base_node + CREATE_CONFIG: 1 + CREATE_ID: 1 + WAIT_FOR_TOR: 60 + TARI_NETWORK: weatherwax + TARI_BASE_NODE__WEATHERWAX__TOR_CONTROL_AUTH: "password=asdf" + TARI_BASE_NODE__WEATHERWAX__TOR_CONTROL_ADDRESS: "/dns4/tor/tcp/9051" + TARI_BASE_NODE__WEATHERWAX__TOR_SOCKS_ADDRESS_OVERRIDE: "/dns4/tor/tcp/9050" + TARI_BASE_NODE__WEATHERWAX__TOR_FORWARD_ADDRESS: "/ip4/0.0.0.0/tcp/18189" + TARI_BASE_NODE__WEATHERWAX__TCP_LISTENER_ADDRESS: "/ip4/0.0.0.0/tcp/18189" + ports: + - 18189:18189 + command: [] + depends_on: + - tor + volumes: + - $HOME/.tari/config:/var/tari/config + - $HOME/.tari/base_node:/var/tari/base_node + - $HOME/.tari/base_node/log:/var/tari/log + stdin_open: true + tty: true +# xmrig: +# sha3-miner: +# pool-worker: +# pool-operator: + +#volumes: +# config: +# driver: local +# driver_opts: +# o: bind +# type: none +# device: $HOME/.tari/config +# data: +# driver: local +# driver_opts: +# o: bind +# type: none +# device: $HOME/.tari/data diff --git a/buildtools/docker_rig/start_base_node.sh b/buildtools/docker_rig/start_base_node.sh new file mode 100755 index 0000000000..6d6235bd97 --- /dev/null +++ b/buildtools/docker_rig/start_base_node.sh @@ -0,0 +1,56 @@ +#!/bin/bash +# +# Docker Start Script for Tari applications +# The docker compose environment should set the following envars +# - APP_NAME - the name of the app to run. This var is used to set the location of log files, and app-specific config +# - APP_EXEC - the name of the application executable. Just the name is enough, since the Dockerfile will put it in /usr/bin +# - CREATE_CONFIG - set to 1 if we should write a default config file if one is missing. +# - CREATE_ID - set to 1 if we should create an id file for this application if one is missing. It will be called +# {network}_{app_name}_id.json +# - WAIT_FOR_TOR - set to 1 to place a 30 second delay at the beginning of this script. +# - TARI_NETWORK - the Tari network to configure the docker rig for +# + +APP_NAME=${APP_NAME:-base_node} +APP_EXEC=${APP_EXEC:-tari_base_node} +CREATE_CONFIG=${CREATE_CONFIG:-0} +CREATE_ID=${CREATE_ID:-0} +WAIT_FOR_TOR=${WAIT_FOR_TOR:-0} +NETWORK=${TARI_NETWORK:-weatherwax} +TARI_BASE=/var/tari/$APP_NAME +CONFIG=/var/tari/config + +echo "Starting $APP_NAME with following docker environment:" +echo "executable: $APP_EXEC" +echo "network: $NETWORK" +echo "CREATE_CONFIG: $CREATE_CONFIG" +echo "CREATE_ID: $CREATE_ID" +echo "WAIT_FOR_TOR: $WAIT_FOR_TOR" +echo "base folder (in container): $TARI_BASE" +echo "config folder (in container): $CONFIG" + +if [[ $WAIT_FOR_TOR != 0 ]]; then + echo "Waiting $WAIT_FOR_TOR seconds for Tor to start up" + sleep "$WAIT_FOR_TOR" +fi + +cd "$TARI_BASE" || exit 1 + +ARGS=() +if [[ $CREATE_CONFIG == 1 && ! -f $CONFIG/config.toml ]]; then + echo "Creating config file." + ARGS+=("--init") +fi + +ID_FILENAME=${NETWORK}_${APP_NAME}_id.json +if [[ $CREATE_ID && ! -f $ID_FILENAME ]]; then + echo "Creating network identity file ($ID_FILENAME)." + ARGS+=("--create-id") +fi + +if [ -n "${ARGS[0]}" ]; then + echo "Initializing." + $APP_EXEC -b "$TARI_BASE" -c "$CONFIG/config.toml" "${ARGS[@]}" || exit 1 +fi + +$APP_EXEC "$@" diff --git a/buildtools/docker_rig/start_wallet.sh b/buildtools/docker_rig/start_wallet.sh new file mode 100755 index 0000000000..8cebe3949b --- /dev/null +++ b/buildtools/docker_rig/start_wallet.sh @@ -0,0 +1,46 @@ +#!/bin/bash +# +# Docker Start Script for Tari applications +# The docker compose environment should set the following envars +# - APP_NAME - the name of the app to run. This var is used to set the location of log files, and app-specific config +# - APP_EXEC - the name of the application executable. Just the name is enough, since the Dockerfile will put it in /usr/bin +# - CREATE_CONFIG - set to 1 if we should write a default config file if one is missing. +# - CREATE_ID - set to 1 if we should create an id file for this application if one is missing. It will be called +# {network}_{app_name}_id.json +# - WAIT_FOR_TOR - set to 1 to place a 30 second delay at the beginning of this script. +# - TARI_NETWORK - the Tari network to configure the docker rig for +# + +APP_NAME=${APP_NAME:-wallet} +APP_EXEC=${APP_EXEC:-tari_console_wallet} +CREATE_CONFIG=${CREATE_CONFIG:-0} +CREATE_ID=${CREATE_ID:-0} +WAIT_FOR_TOR=${WAIT_FOR_TOR:-0} +NETWORK=${TARI_NETWORK:-weatherwax} +TARI_BASE=/var/tari/$APP_NAME +CONFIG=/var/tari/config + +echo "Starting $APP_NAME with following docker environment:" +echo "executable: $APP_EXEC" +echo "network: $NETWORK" +echo "CREATE_CONFIG: $CREATE_CONFIG" +echo "CREATE_ID: $CREATE_ID" +echo "WAIT_FOR_TOR: $WAIT_FOR_TOR" +echo "base folder (in container): $TARI_BASE" +echo "config folder (in container): $CONFIG" +echo "wallet password: $PASSWORD" # delete this + +if [[ $WAIT_FOR_TOR != 0 ]]; then + echo "Waiting $WAIT_FOR_TOR seconds for Tor to start up" + sleep "$WAIT_FOR_TOR" +fi + +cd "$TARI_BASE" || exit 1 + +if [[ $CREATE_CONFIG == 1 && ! -f $CONFIG/config.toml ]]; then + $APP_EXEC --init --password "$PASSWORD" "$@" +else + $APP_EXEC --password "$PASSWORD" "$@" +fi + +# $APP_EXEC "$INIT" --password "$PASSWORD" "$@" diff --git a/buildtools/docker_rig/tor.Dockerfile b/buildtools/docker_rig/tor.Dockerfile new file mode 100644 index 0000000000..1034bc92be --- /dev/null +++ b/buildtools/docker_rig/tor.Dockerfile @@ -0,0 +1,15 @@ +FROM alpine:latest + +RUN apk update \ + && apk upgrade \ + && apk add tor \ + bash \ + && rm /var/cache/apk/* + +EXPOSE 9050 +EXPOSE 9051 + +ADD ./torrc /etc/tor/torrc + +USER tor +CMD /usr/bin/tor -f /etc/tor/torrc \ No newline at end of file diff --git a/buildtools/docker_rig/torrc b/buildtools/docker_rig/torrc new file mode 100644 index 0000000000..74392ecd7e --- /dev/null +++ b/buildtools/docker_rig/torrc @@ -0,0 +1,7 @@ +# Standard config for the tor client - /etc/tor/torrc +SocksPort 0.0.0.0:9050 +ControlPort 0.0.0.0:9051 +CookieAuthentication 0 +ClientOnly 1 +ClientUseIPv6 1 +HashedControlPassword 16:8318D1DA9334F90C603A7A7A7CD330E98B7A73AD516E810A48C6F50C6A diff --git a/integration_tests/helpers/ffi/walletFFI.js b/integration_tests/helpers/ffi/walletFFI.js new file mode 100644 index 0000000000..7816253500 --- /dev/null +++ b/integration_tests/helpers/ffi/walletFFI.js @@ -0,0 +1,2074 @@ +/** + * This library was AUTO-GENERATED. Do not modify manually! + */ + +const { expect } = require("chai"); +const ffi = require("ffi-napi"); +const ref = require("ref-napi"); +const dateFormat = require("dateformat"); +const { spawn } = require("child_process"); +const fs = require("fs"); + +class WalletFFI { + static byte_vector = ref.types.void; + static byte_vector_ptr = ref.refType(this.byte_vector); + static tari_comms_config = ref.types.void; + static tari_comms_config_ptr = ref.refType(this.tari_comms_config); + static tari_private_key = ref.types.void; + static tari_private_key_ptr = ref.refType(this.tari_private_key); + static tari_wallet = ref.types.void; + static tari_wallet_ptr = ref.refType(this.tari_wallet); + static tari_public_key = ref.types.void; + static tari_public_key_ptr = ref.refType(this.tari_public_key); + static tari_contacts = ref.types.void; + static tari_contacts_ptr = ref.refType(this.tari_contacts); + static tari_contact = ref.types.void; + static tari_contact_ptr = ref.refType(this.tari_contact); + static tari_completed_transactions = ref.types.void; + static tari_completed_transactions_ptr = ref.refType( + this.tari_completed_transactions + ); + static tari_completed_transaction = ref.types.void; + static tari_completed_transaction_ptr = ref.refType( + this.tari_completed_transaction + ); + static tari_pending_outbound_transactions = ref.types.void; + static tari_pending_outbound_transactions_ptr = ref.refType( + this.tari_pending_outbound_transactions + ); + static tari_pending_outbound_transaction = ref.types.void; + static tari_pending_outbound_transaction_ptr = ref.refType( + this.tari_pending_outbound_transaction + ); + static tari_pending_inbound_transactions = ref.types.void; + static tari_pending_inbound_transactions_ptr = ref.refType( + this.tari_pending_inbound_transactions + ); + static tari_pending_inbound_transaction = ref.types.void; + static tari_pending_inbound_transaction_ptr = ref.refType( + this.tari_pending_inbound_transaction + ); + static tari_transport_type = ref.types.void; + static tari_transport_type_ptr = ref.refType(this.tari_transport_type); + static tari_seed_words = ref.types.void; + static tari_seed_words_ptr = ref.refType(this.tari_seed_words); + static emoji_set = ref.types.void; + static emoji_set_ptr = ref.refType(this.emoji_set); + static tari_excess = ref.types.void; + static tari_excess_ptr = ref.refType(this.tari_excess); + static tari_excess_public_nonce = ref.types.void; + static tari_excess_public_nonce_ptr = ref.refType( + this.tari_excess_public_nonce + ); + static tari_excess_signature = ref.types.void; + static tari_excess_signature_ptr = ref.refType(this.tari_excess_signature); + + static #fn; + static error = ref.alloc(ref.types.int); + static recovery_in_progress = ref.alloc(ref.types.bool); + static NULL = ref.NULL; + static #loaded = false; + static #ps = null; + + static checkAsyncRes(resolve, reject, error_name) { + return (err, res) => { + if (err) reject(err); + expect(this.error.deref()).to.equal(0, `Error in ${error_name}`); + resolve(res); + }; + } + + static compile() { + return new Promise((resolve, _reject) => { + const cmd = "cargo"; + const args = [ + "build", + "--release", + "--package", + "tari_wallet_ffi", + "-Z", + "unstable-options", + "--out-dir", + process.cwd() + "/temp/out", + ]; + const baseDir = `./temp/base_nodes/${dateFormat( + new Date(), + "yyyymmddHHMM" + )}/WalletFFI-compile`; + if (!fs.existsSync(baseDir)) { + fs.mkdirSync(baseDir, { recursive: true }); + fs.mkdirSync(baseDir + "/log", { recursive: true }); + } + const ps = spawn(cmd, args, { + cwd: baseDir, + env: { ...process.env }, + }); + ps.on("close", (_code) => { + resolve(ps); + }); + ps.stderr.on("data", (data) => { + console.log("stderr : ", data.toString()); + }); + ps.on("error", (error) => { + console.log("error : ", error.toString()); + }); + expect(ps.error).to.be.an("undefined"); + this.#ps = ps; + }); + } + + static async Init() { + if (this.#loaded) { + return; + } + + this.#loaded = true; + await this.compile(); + const outputProcess = `${process.cwd()}/temp/out/${ + process.platform === "win32" ? "" : "lib" + }tari_wallet_ffi`; + + // Init callbacks + + this.createCallbackReceivedTransaction = (callback) => + ffi.Callback( + "void", + [this.tari_pending_inbound_transaction_ptr], + callback + ); + this.createCallbackReceivedTransactionReply = (callback) => + ffi.Callback("void", [this.tari_completed_transaction_ptr], callback); + this.createCallbackReceivedFinalizedTransaction = (callback) => + ffi.Callback("void", [this.tari_completed_transaction_ptr], callback); + this.createCallbackTransactionBroadcast = (callback) => + ffi.Callback("void", [this.tari_completed_transaction_ptr], callback); + this.createCallbackTransactionMined = (callback) => + ffi.Callback("void", [this.tari_completed_transaction_ptr], callback); + this.createCallbackTransactionMinedUnconfirmed = (callback) => + ffi.Callback( + "void", + [this.tari_completed_transaction_ptr, "uint64"], + callback + ); + this.createCallbackDirectSendResult = (callback) => + ffi.Callback("void", ["uint64", "bool"], callback); + this.createCallbackStoreAndForwardSendResult = (callback) => + ffi.Callback("void", ["uint64", "bool"], callback); + this.createCallbackTransactionCancellation = (callback) => + ffi.Callback("void", [this.tari_completed_transaction_ptr], callback); + this.createCallbackUtxoValidationComplete = (callback) => + ffi.Callback("void", ["uint64", "uchar"], callback); + this.createCallbackStxoValidationComplete = (callback) => + ffi.Callback("void", ["uint64", "uchar"], callback); + this.createCallbackInvalidTxoValidationComplete = (callback) => + ffi.Callback("void", ["uint64", "uchar"], callback); + this.createCallbackTransactionValidationComplete = (callback) => + ffi.Callback("void", ["uint64", "uchar"], callback); + this.createCallbackSafMessageReceived = (callback) => + ffi.Callback("void", [], callback); + this.createRecoveryProgressCallback = (callback) => + ffi.Callback("void", ["uchar", "uint64", "uint64"], callback); + // Load the library + this.#fn = ffi.Library(outputProcess, { + transport_memory_create: [this.tari_transport_type_ptr, []], + transport_tcp_create: [this.tari_transport_type_ptr, ["string", "int*"]], + transport_tor_create: [ + this.tari_transport_type_ptr, + ["string", this.byte_vector_ptr, "ushort", "string", "string", "int*"], + ], + transport_memory_get_address: [ + "char*", + [this.tari_transport_type_ptr, "int*"], + ], + transport_type_destroy: ["void", [this.tari_transport_type_ptr]], + string_destroy: ["void", ["string"]], + byte_vector_create: [this.byte_vector_ptr, ["uchar*", "uint", "int*"]], + byte_vector_get_at: ["uchar", [this.byte_vector_ptr, "uint", "int*"]], + byte_vector_get_length: ["uint", [this.byte_vector_ptr, "int*"]], + byte_vector_destroy: ["void", [this.byte_vector_ptr]], + public_key_create: [ + this.tari_public_key_ptr, + [this.byte_vector_ptr, "int*"], + ], + public_key_get_bytes: [ + this.byte_vector_ptr, + [this.tari_public_key_ptr, "int*"], + ], + public_key_from_private_key: [ + this.tari_public_key_ptr, + [this.tari_private_key_ptr, "int*"], + ], + public_key_from_hex: [this.tari_public_key_ptr, ["string", "int*"]], + public_key_destroy: ["void", [this.tari_public_key_ptr]], + public_key_to_emoji_id: ["char*", [this.tari_public_key_ptr, "int*"]], + emoji_id_to_public_key: [this.tari_public_key_ptr, ["string", "int*"]], + private_key_create: [ + this.tari_private_key_ptr, + [this.byte_vector_ptr, "int*"], + ], + private_key_generate: [this.tari_private_key_ptr, []], + private_key_get_bytes: [ + this.byte_vector_ptr, + [this.tari_private_key_ptr, "int*"], + ], + private_key_from_hex: [this.tari_private_key_ptr, ["string", "int*"]], + private_key_destroy: ["void", [this.tari_private_key_ptr]], + seed_words_create: [this.tari_seed_words_ptr, []], + seed_words_get_length: ["uint", [this.tari_seed_words_ptr, "int*"]], + seed_words_get_at: ["char*", [this.tari_seed_words_ptr, "uint", "int*"]], + seed_words_push_word: [ + "uchar", + [this.tari_seed_words_ptr, "string", "int*"], + ], + seed_words_destroy: ["void", [this.tari_seed_words_ptr]], + contact_create: [ + this.tari_contact_ptr, + ["string", this.tari_public_key_ptr, "int*"], + ], + contact_get_alias: ["char*", [this.tari_contact_ptr, "int*"]], + contact_get_public_key: [ + this.tari_public_key_ptr, + [this.tari_contact_ptr, "int*"], + ], + contact_destroy: ["void", [this.tari_contact_ptr]], + contacts_get_length: ["uint", [this.tari_contacts_ptr, "int*"]], + contacts_get_at: [ + this.tari_contact_ptr, + [this.tari_contacts_ptr, "uint", "int*"], + ], + contacts_destroy: ["void", [this.tari_contacts_ptr]], + completed_transaction_get_destination_public_key: [ + this.tari_public_key_ptr, + [this.tari_completed_transaction_ptr, "int*"], + ], + completed_transaction_get_source_public_key: [ + this.tari_public_key_ptr, + [this.tari_completed_transaction_ptr, "int*"], + ], + completed_transaction_get_amount: [ + "uint64", + [this.tari_completed_transaction_ptr, "int*"], + ], + completed_transaction_get_fee: [ + "uint64", + [this.tari_completed_transaction_ptr, "int*"], + ], + completed_transaction_get_message: [ + "char*", + [this.tari_completed_transaction_ptr, "int*"], + ], + completed_transaction_get_status: [ + "int", + [this.tari_completed_transaction_ptr, "int*"], + ], + completed_transaction_get_transaction_id: [ + "uint64", + [this.tari_completed_transaction_ptr, "int*"], + ], + completed_transaction_get_timestamp: [ + "uint64", + [this.tari_completed_transaction_ptr, "int*"], + ], + completed_transaction_is_valid: [ + "bool", + [this.tari_completed_transaction_ptr, "int*"], + ], + completed_transaction_is_outbound: [ + "bool", + [this.tari_completed_transaction_ptr, "int*"], + ], + completed_transaction_get_confirmations: [ + "uint64", + [this.tari_completed_transaction_ptr, "int*"], + ], + completed_transaction_destroy: [ + "void", + [this.tari_completed_transaction_ptr], + ], + completed_transaction_get_excess: [ + this.tari_excess_ptr, + [this.tari_completed_transaction_ptr, "int*"], + ], + completed_transaction_get_public_nonce: [ + this.tari_excess_public_nonce_ptr, + [this.tari_completed_transaction_ptr, "int*"], + ], + completed_transaction_get_signature: [ + this.tari_excess_signature_ptr, + [this.tari_completed_transaction_ptr, "int*"], + ], + excess_destroy: ["void", [this.tari_excess_ptr]], + nonce_destroy: ["void", [this.tari_excess_public_nonce_ptr]], + signature_destroy: ["void", [this.tari_excess_signature_ptr]], + completed_transactions_get_length: [ + "uint", + [this.tari_completed_transactions_ptr, "int*"], + ], + completed_transactions_get_at: [ + this.tari_completed_transaction_ptr, + [this.tari_completed_transactions_ptr, "uint", "int*"], + ], + completed_transactions_destroy: [ + "void", + [this.tari_completed_transactions_ptr], + ], + pending_outbound_transaction_get_transaction_id: [ + "uint64", + [this.tari_pending_outbound_transaction_ptr, "int*"], + ], + pending_outbound_transaction_get_destination_public_key: [ + this.tari_public_key_ptr, + [this.tari_pending_outbound_transaction_ptr, "int*"], + ], + pending_outbound_transaction_get_amount: [ + "uint64", + [this.tari_pending_outbound_transaction_ptr, "int*"], + ], + pending_outbound_transaction_get_fee: [ + "uint64", + [this.tari_pending_outbound_transaction_ptr, "int*"], + ], + pending_outbound_transaction_get_message: [ + "char*", + [this.tari_pending_outbound_transaction_ptr, "int*"], + ], + pending_outbound_transaction_get_timestamp: [ + "uint64", + [this.tari_pending_outbound_transaction_ptr, "int*"], + ], + pending_outbound_transaction_get_status: [ + "int", + [this.tari_pending_outbound_transaction_ptr, "int*"], + ], + pending_outbound_transaction_destroy: [ + "void", + [this.tari_pending_outbound_transaction_ptr], + ], + pending_outbound_transactions_get_length: [ + "uint", + [this.tari_pending_outbound_transactions_ptr, "int*"], + ], + pending_outbound_transactions_get_at: [ + this.tari_pending_outbound_transaction_ptr, + [this.tari_pending_outbound_transactions_ptr, "uint", "int*"], + ], + pending_outbound_transactions_destroy: [ + "void", + [this.tari_pending_outbound_transactions_ptr], + ], + pending_inbound_transaction_get_transaction_id: [ + "uint64", + [this.tari_pending_inbound_transaction_ptr, "int*"], + ], + pending_inbound_transaction_get_source_public_key: [ + this.tari_public_key_ptr, + [this.tari_pending_inbound_transaction_ptr, "int*"], + ], + pending_inbound_transaction_get_message: [ + "char*", + [this.tari_pending_inbound_transaction_ptr, "int*"], + ], + pending_inbound_transaction_get_amount: [ + "uint64", + [this.tari_pending_inbound_transaction_ptr, "int*"], + ], + pending_inbound_transaction_get_timestamp: [ + "uint64", + [this.tari_pending_inbound_transaction_ptr, "int*"], + ], + pending_inbound_transaction_get_status: [ + "int", + [this.tari_pending_inbound_transaction_ptr, "int*"], + ], + pending_inbound_transaction_destroy: [ + "void", + [this.tari_pending_inbound_transaction_ptr], + ], + pending_inbound_transactions_get_length: [ + "uint", + [this.tari_pending_inbound_transactions_ptr, "int*"], + ], + pending_inbound_transactions_get_at: [ + this.tari_pending_inbound_transaction_ptr, + [this.tari_pending_inbound_transactions_ptr, "uint", "int*"], + ], + pending_inbound_transactions_destroy: [ + "void", + [this.tari_pending_inbound_transactions_ptr], + ], + comms_config_create: [ + this.tari_comms_config_ptr, + [ + "string", + this.tari_transport_type_ptr, + "string", + "string", + "uint64", + "uint64", + "string", + "int*", + ], + ], + comms_config_destroy: ["void", [this.tari_comms_config_ptr]], + wallet_create: [ + this.tari_wallet_ptr, + [ + this.tari_comms_config_ptr, + "string", + "uint", + "uint", + "string", + this.tari_seed_words_ptr, + "pointer", + "pointer", + "pointer", + "pointer", + "pointer", + "pointer", + "pointer", + "pointer", + "pointer", + "pointer", + "pointer", + "pointer", + "pointer", + "pointer", + "bool*", + "int*", + ], + ], + wallet_sign_message: ["char*", [this.tari_wallet_ptr, "string", "int*"]], + wallet_verify_message_signature: [ + "bool", + [ + this.tari_wallet_ptr, + this.tari_public_key_ptr, + "string", + "string", + "int*", + ], + ], + wallet_add_base_node_peer: [ + "bool", + [this.tari_wallet_ptr, this.tari_public_key_ptr, "string", "int*"], + ], + wallet_upsert_contact: [ + "bool", + [this.tari_wallet_ptr, this.tari_contact_ptr, "int*"], + ], + wallet_remove_contact: [ + "bool", + [this.tari_wallet_ptr, this.tari_contact_ptr, "int*"], + ], + wallet_get_available_balance: ["uint64", [this.tari_wallet_ptr, "int*"]], + wallet_get_pending_incoming_balance: [ + "uint64", + [this.tari_wallet_ptr, "int*"], + ], + wallet_get_pending_outgoing_balance: [ + "uint64", + [this.tari_wallet_ptr, "int*"], + ], + wallet_get_fee_estimate: [ + "uint64", + [this.tari_wallet_ptr, "uint64", "uint64", "uint64", "uint64", "int*"], + ], + wallet_get_num_confirmations_required: [ + "uint64", + [this.tari_wallet_ptr, "int*"], + ], + wallet_set_num_confirmations_required: [ + "void", + [this.tari_wallet_ptr, "uint64", "int*"], + ], + wallet_send_transaction: [ + "uint64", + [ + this.tari_wallet_ptr, + this.tari_public_key_ptr, + "uint64", + "uint64", + "string", + "int*", + ], + ], + wallet_get_contacts: [ + this.tari_contacts_ptr, + [this.tari_wallet_ptr, "int*"], + ], + wallet_get_completed_transactions: [ + this.tari_completed_transactions_ptr, + [this.tari_wallet_ptr, "int*"], + ], + wallet_get_pending_outbound_transactions: [ + this.tari_pending_outbound_transactions_ptr, + [this.tari_wallet_ptr, "int*"], + ], + wallet_get_public_key: [ + this.tari_public_key_ptr, + [this.tari_wallet_ptr, "int*"], + ], + wallet_get_pending_inbound_transactions: [ + this.tari_pending_inbound_transactions_ptr, + [this.tari_wallet_ptr, "int*"], + ], + wallet_get_cancelled_transactions: [ + this.tari_completed_transactions_ptr, + [this.tari_wallet_ptr, "int*"], + ], + wallet_get_completed_transaction_by_id: [ + this.tari_completed_transaction_ptr, + [this.tari_wallet_ptr, "uint64", "int*"], + ], + wallet_get_pending_outbound_transaction_by_id: [ + this.tari_pending_outbound_transaction_ptr, + [this.tari_wallet_ptr, "uint64", "int*"], + ], + wallet_get_pending_inbound_transaction_by_id: [ + this.tari_pending_inbound_transaction_ptr, + [this.tari_wallet_ptr, "uint64", "int*"], + ], + wallet_get_cancelled_transaction_by_id: [ + this.tari_completed_transaction_ptr, + [this.tari_wallet_ptr, "uint64", "int*"], + ], + wallet_import_utxo: [ + "uint64", + [ + this.tari_wallet_ptr, + "uint64", + this.tari_private_key_ptr, + this.tari_public_key_ptr, + "string", + "int*", + ], + ], + wallet_start_utxo_validation: ["uint64", [this.tari_wallet_ptr, "int*"]], + wallet_start_stxo_validation: ["uint64", [this.tari_wallet_ptr, "int*"]], + wallet_start_invalid_txo_validation: [ + "uint64", + [this.tari_wallet_ptr, "int*"], + ], + wallet_start_transaction_validation: [ + "uint64", + [this.tari_wallet_ptr, "int*"], + ], + wallet_restart_transaction_broadcast: [ + "bool", + [this.tari_wallet_ptr, "int*"], + ], + wallet_set_low_power_mode: ["void", [this.tari_wallet_ptr, "int*"]], + wallet_set_normal_power_mode: ["void", [this.tari_wallet_ptr, "int*"]], + wallet_cancel_pending_transaction: [ + "bool", + [this.tari_wallet_ptr, "uint64", "int*"], + ], + wallet_coin_split: [ + "uint64", + [ + this.tari_wallet_ptr, + "uint64", + "uint64", + "uint64", + "string", + "uint64", + "int*", + ], + ], + wallet_get_seed_words: [ + this.tari_seed_words_ptr, + [this.tari_wallet_ptr, "int*"], + ], + wallet_apply_encryption: [ + "void", + [this.tari_wallet_ptr, "string", "int*"], + ], + wallet_remove_encryption: ["void", [this.tari_wallet_ptr, "int*"]], + wallet_set_key_value: [ + "bool", + [this.tari_wallet_ptr, "string", "string", "int*"], + ], + wallet_get_value: ["char*", [this.tari_wallet_ptr, "string", "int*"]], + wallet_clear_value: ["bool", [this.tari_wallet_ptr, "string", "int*"]], + wallet_is_recovery_in_progress: ["bool", [this.tari_wallet_ptr, "int*"]], + wallet_start_recovery: [ + "bool", + [this.tari_wallet_ptr, this.tari_public_key_ptr, "pointer", "int*"], + ], + wallet_destroy: ["void", [this.tari_wallet_ptr]], + file_partial_backup: ["void", ["string", "string", "int*"]], + log_debug_message: ["void", ["string"]], + get_emoji_set: [this.emoji_set_ptr, []], + emoji_set_destroy: ["void", [this.emoji_set_ptr]], + emoji_set_get_at: [ + this.byte_vector_ptr, + [this.emoji_set_ptr, "uint", "int*"], + ], + emoji_set_get_length: ["uint", [this.emoji_set_ptr, "int*"]], + }); + } + + static transportMemoryCreate() { + return new Promise((resolve, reject) => + this.#fn.transport_memory_create.async( + this.checkAsyncRes(resolve, reject, "transportMemoryCreate") + ) + ); + } + + static transportTcpCreate(listener_address) { + return new Promise((resolve, reject) => + this.#fn.transport_tcp_create.async( + listener_address, + this.error, + this.checkAsyncRes(resolve, reject, "transportTcpCreate") + ) + ); + } + + static transportTorCreate( + control_server_address, + tor_cookie, + tor_port, + socks_username, + socks_password + ) { + return new Promise((resolve, reject) => + this.#fn.transport_tor_create.async( + control_server_address, + tor_cookie, + tor_port, + socks_username, + socks_password, + this.error, + this.checkAsyncRes(resolve, reject, "transportTorCreate") + ) + ); + } + + static transportMemoryGetAddress(transport) { + return new Promise((resolve, reject) => + this.#fn.transport_memory_get_address.async( + transport, + this.error, + this.checkAsyncRes(resolve, reject, "transportMemoryGetAddress") + ) + ); + } + + static transportTypeDestroy(transport) { + return new Promise((resolve, reject) => + this.#fn.transport_type_destroy.async( + transport, + this.checkAsyncRes(resolve, reject, "transportTypeDestroy") + ) + ); + } + + static stringDestroy(s) { + return new Promise((resolve, reject) => + this.#fn.string_destroy.async( + s, + this.checkAsyncRes(resolve, reject, "stringDestroy") + ) + ); + } + + static byteVectorCreate(byte_array, element_count) { + return new Promise((resolve, reject) => + this.#fn.byte_vector_create.async( + byte_array, + element_count, + this.error, + this.checkAsyncRes(resolve, reject, "byteVectorCreate") + ) + ); + } + + static byteVectorGetAt(ptr, i) { + return new Promise((resolve, reject) => + this.#fn.byte_vector_get_at.async( + ptr, + i, + this.error, + this.checkAsyncRes(resolve, reject, "byteVectorGetAt") + ) + ); + } + + static byteVectorGetLength(vec) { + return new Promise((resolve, reject) => + this.#fn.byte_vector_get_length.async( + vec, + this.error, + this.checkAsyncRes(resolve, reject, "byteVectorGetLength") + ) + ); + } + + static byteVectorDestroy(bytes) { + return new Promise((resolve, reject) => + this.#fn.byte_vector_destroy.async( + bytes, + this.checkAsyncRes(resolve, reject, "byteVectorDestroy") + ) + ); + } + + static publicKeyCreate(bytes) { + return new Promise((resolve, reject) => + this.#fn.public_key_create.async( + bytes, + this.error, + this.checkAsyncRes(resolve, reject, "publicKeyCreate") + ) + ); + } + + static publicKeyGetBytes(public_key) { + return new Promise((resolve, reject) => + this.#fn.public_key_get_bytes.async( + public_key, + this.error, + this.checkAsyncRes(resolve, reject, "publicKeyGetBytes") + ) + ); + } + + static publicKeyFromPrivateKey(secret_key) { + return new Promise((resolve, reject) => + this.#fn.public_key_from_private_key.async( + secret_key, + this.error, + this.checkAsyncRes(resolve, reject, "publicKeyFromPrivateKey") + ) + ); + } + + static publicKeyFromHex(hex) { + return new Promise((resolve, reject) => + this.#fn.public_key_from_hex.async( + hex, + this.error, + this.checkAsyncRes(resolve, reject, "publicKeyFromHex") + ) + ); + } + + static publicKeyDestroy(pk) { + return new Promise((resolve, reject) => + this.#fn.public_key_destroy.async( + pk, + this.checkAsyncRes(resolve, reject, "publicKeyDestroy") + ) + ); + } + + static publicKeyToEmojiId(pk) { + return new Promise((resolve, reject) => + this.#fn.public_key_to_emoji_id.async( + pk, + this.error, + this.checkAsyncRes(resolve, reject, "publicKeyToEmojiId") + ) + ); + } + + static emojiIdToPublicKey(emoji) { + return new Promise((resolve, reject) => + this.#fn.emoji_id_to_public_key.async( + emoji, + this.error, + this.checkAsyncRes(resolve, reject, "emojiIdToPublicKey") + ) + ); + } + + static privateKeyCreate(bytes) { + return new Promise((resolve, reject) => + this.#fn.private_key_create.async( + bytes, + this.error, + this.checkAsyncRes(resolve, reject, "privateKeyCreate") + ) + ); + } + + static privateKeyGenerate() { + return new Promise((resolve, reject) => + this.#fn.private_key_generate.async( + this.checkAsyncRes(resolve, reject, "privateKeyGenerate") + ) + ); + } + + static privateKeyGetBytes(private_key) { + return new Promise((resolve, reject) => + this.#fn.private_key_get_bytes.async( + private_key, + this.error, + this.checkAsyncRes(resolve, reject, "privateKeyGetBytes") + ) + ); + } + + static privateKeyFromHex(hex) { + return new Promise((resolve, reject) => + this.#fn.private_key_from_hex.async( + hex, + this.error, + this.checkAsyncRes(resolve, reject, "privateKeyFromHex") + ) + ); + } + + static privateKeyDestroy(pk) { + return new Promise((resolve, reject) => + this.#fn.private_key_destroy.async( + pk, + this.checkAsyncRes(resolve, reject, "privateKeyDestroy") + ) + ); + } + + static seedWordsCreate() { + return new Promise((resolve, reject) => + this.#fn.seed_words_create.async( + this.checkAsyncRes(resolve, reject, "seedWordsCreate") + ) + ); + } + + static seedWordsGetLength(seed_words) { + return new Promise((resolve, reject) => + this.#fn.seed_words_get_length.async( + seed_words, + this.error, + this.checkAsyncRes(resolve, reject, "seedWordsGetLength") + ) + ); + } + + static seedWordsGetAt(seed_words, position) { + return new Promise((resolve, reject) => + this.#fn.seed_words_get_at.async( + seed_words, + position, + this.error, + this.checkAsyncRes(resolve, reject, "seedWordsGetAt") + ) + ); + } + + static seedWordsPushWord(seed_words, word) { + return new Promise((resolve, reject) => + this.#fn.seed_words_push_word.async( + seed_words, + word, + this.error, + this.checkAsyncRes(resolve, reject, "seedWordsPushWord") + ) + ); + } + + static seedWordsDestroy(seed_words) { + return new Promise((resolve, reject) => + this.#fn.seed_words_destroy.async( + seed_words, + this.checkAsyncRes(resolve, reject, "seedWordsDestroy") + ) + ); + } + + static contactCreate(alias, public_key) { + return new Promise((resolve, reject) => + this.#fn.contact_create.async( + alias, + public_key, + this.error, + this.checkAsyncRes(resolve, reject, "contactCreate") + ) + ); + } + + static contactGetAlias(contact) { + return new Promise((resolve, reject) => + this.#fn.contact_get_alias.async( + contact, + this.error, + this.checkAsyncRes(resolve, reject, "contactGetAlias") + ) + ); + } + + static contactGetPublicKey(contact) { + return new Promise((resolve, reject) => + this.#fn.contact_get_public_key.async( + contact, + this.error, + this.checkAsyncRes(resolve, reject, "contactGetPublicKey") + ) + ); + } + + static contactDestroy(contact) { + return new Promise((resolve, reject) => + this.#fn.contact_destroy.async( + contact, + this.checkAsyncRes(resolve, reject, "contactDestroy") + ) + ); + } + + static contactsGetLength(contacts) { + return new Promise((resolve, reject) => + this.#fn.contacts_get_length.async( + contacts, + this.error, + this.checkAsyncRes(resolve, reject, "contactsGetLength") + ) + ); + } + + static contactsGetAt(contacts, position) { + return new Promise((resolve, reject) => + this.#fn.contacts_get_at.async( + contacts, + position, + this.error, + this.checkAsyncRes(resolve, reject, "contactsGetAt") + ) + ); + } + + static contactsDestroy(contacts) { + return new Promise((resolve, reject) => + this.#fn.contacts_destroy.async( + contacts, + this.checkAsyncRes(resolve, reject, "contactsDestroy") + ) + ); + } + + static completedTransactionGetDestinationPublicKey(transaction) { + return new Promise((resolve, reject) => + this.#fn.completed_transaction_get_destination_public_key.async( + transaction, + this.error, + this.checkAsyncRes( + resolve, + reject, + "completedTransactionGetDestinationPublicKey" + ) + ) + ); + } + + static completedTransactionGetSourcePublicKey(transaction) { + return new Promise((resolve, reject) => + this.#fn.completed_transaction_get_source_public_key.async( + transaction, + this.error, + this.checkAsyncRes( + resolve, + reject, + "completedTransactionGetSourcePublicKey" + ) + ) + ); + } + + static completedTransactionGetAmount(transaction) { + return new Promise((resolve, reject) => + this.#fn.completed_transaction_get_amount.async( + transaction, + this.error, + this.checkAsyncRes(resolve, reject, "completedTransactionGetAmount") + ) + ); + } + + static completedTransactionGetFee(transaction) { + return new Promise((resolve, reject) => + this.#fn.completed_transaction_get_fee.async( + transaction, + this.error, + this.checkAsyncRes(resolve, reject, "completedTransactionGetFee") + ) + ); + } + + static completedTransactionGetMessage(transaction) { + return new Promise((resolve, reject) => + this.#fn.completed_transaction_get_message.async( + transaction, + this.error, + this.checkAsyncRes(resolve, reject, "completedTransactionGetMessage") + ) + ); + } + + static completedTransactionGetStatus(transaction) { + return new Promise((resolve, reject) => + this.#fn.completed_transaction_get_status.async( + transaction, + this.error, + this.checkAsyncRes(resolve, reject, "completedTransactionGetStatus") + ) + ); + } + + static completedTransactionGetTransactionId(transaction) { + return new Promise((resolve, reject) => + this.#fn.completed_transaction_get_transaction_id.async( + transaction, + this.error, + this.checkAsyncRes( + resolve, + reject, + "completedTransactionGetTransactionId" + ) + ) + ); + } + + static completedTransactionGetTimestamp(transaction) { + return new Promise((resolve, reject) => + this.#fn.completed_transaction_get_timestamp.async( + transaction, + this.error, + this.checkAsyncRes(resolve, reject, "completedTransactionGetTimestamp") + ) + ); + } + + static completedTransactionIsValid(tx) { + return new Promise((resolve, reject) => + this.#fn.completed_transaction_is_valid.async( + tx, + this.error, + this.checkAsyncRes(resolve, reject, "completedTransactionIsValid") + ) + ); + } + + static completedTransactionIsOutbound(tx) { + return new Promise((resolve, reject) => + this.#fn.completed_transaction_is_outbound.async( + tx, + this.error, + this.checkAsyncRes(resolve, reject, "completedTransactionIsOutbound") + ) + ); + } + + static completedTransactionGetConfirmations(transaction) { + return new Promise((resolve, reject) => + this.#fn.completed_transaction_get_confirmations.async( + transaction, + this.error, + this.checkAsyncRes( + resolve, + reject, + "completedTransactionGetConfirmations" + ) + ) + ); + } + + static completedTransactionDestroy(transaction) { + return new Promise((resolve, reject) => + this.#fn.completed_transaction_destroy.async( + transaction, + this.checkAsyncRes(resolve, reject, "completedTransactionDestroy") + ) + ); + } + + static completedTransactionGetExcess(transaction) { + return new Promise((resolve, reject) => + this.#fn.completed_transaction_get_excess.async( + transaction, + this.error, + this.checkAsyncRes(resolve, reject, "completedTransactionGetExcess") + ) + ); + } + + static completedTransactionGetPublicNonce(transaction) { + return new Promise((resolve, reject) => + this.#fn.completed_transaction_get_public_nonce.async( + transaction, + this.error, + this.checkAsyncRes( + resolve, + reject, + "completedTransactionGetPublicNonce" + ) + ) + ); + } + + static completedTransactionGetSignature(transaction) { + return new Promise((resolve, reject) => + this.#fn.completed_transaction_get_signature.async( + transaction, + this.error, + this.checkAsyncRes(resolve, reject, "completedTransactionGetSignature") + ) + ); + } + + static excessDestroy(excess) { + return new Promise((resolve, reject) => + this.#fn.excess_destroy.async( + excess, + this.checkAsyncRes(resolve, reject, "excessDestroy") + ) + ); + } + + static nonceDestroy(nonce) { + return new Promise((resolve, reject) => + this.#fn.nonce_destroy.async( + nonce, + this.checkAsyncRes(resolve, reject, "nonceDestroy") + ) + ); + } + + static signatureDestroy(signature) { + return new Promise((resolve, reject) => + this.#fn.signature_destroy.async( + signature, + this.checkAsyncRes(resolve, reject, "signatureDestroy") + ) + ); + } + + static completedTransactionsGetLength(transactions) { + return new Promise((resolve, reject) => + this.#fn.completed_transactions_get_length.async( + transactions, + this.error, + this.checkAsyncRes(resolve, reject, "completedTransactionsGetLength") + ) + ); + } + + static completedTransactionsGetAt(transactions, position) { + return new Promise((resolve, reject) => + this.#fn.completed_transactions_get_at.async( + transactions, + position, + this.error, + this.checkAsyncRes(resolve, reject, "completedTransactionsGetAt") + ) + ); + } + + static completedTransactionsDestroy(transactions) { + return new Promise((resolve, reject) => + this.#fn.completed_transactions_destroy.async( + transactions, + this.checkAsyncRes(resolve, reject, "completedTransactionsDestroy") + ) + ); + } + + static pendingOutboundTransactionGetTransactionId(transaction) { + return new Promise((resolve, reject) => + this.#fn.pending_outbound_transaction_get_transaction_id.async( + transaction, + this.error, + this.checkAsyncRes( + resolve, + reject, + "pendingOutboundTransactionGetTransactionId" + ) + ) + ); + } + + static pendingOutboundTransactionGetDestinationPublicKey(transaction) { + return new Promise((resolve, reject) => + this.#fn.pending_outbound_transaction_get_destination_public_key.async( + transaction, + this.error, + this.checkAsyncRes( + resolve, + reject, + "pendingOutboundTransactionGetDestinationPublicKey" + ) + ) + ); + } + + static pendingOutboundTransactionGetAmount(transaction) { + return new Promise((resolve, reject) => + this.#fn.pending_outbound_transaction_get_amount.async( + transaction, + this.error, + this.checkAsyncRes( + resolve, + reject, + "pendingOutboundTransactionGetAmount" + ) + ) + ); + } + + static pendingOutboundTransactionGetFee(transaction) { + return new Promise((resolve, reject) => + this.#fn.pending_outbound_transaction_get_fee.async( + transaction, + this.error, + this.checkAsyncRes(resolve, reject, "pendingOutboundTransactionGetFee") + ) + ); + } + + static pendingOutboundTransactionGetMessage(transaction) { + return new Promise((resolve, reject) => + this.#fn.pending_outbound_transaction_get_message.async( + transaction, + this.error, + this.checkAsyncRes( + resolve, + reject, + "pendingOutboundTransactionGetMessage" + ) + ) + ); + } + + static pendingOutboundTransactionGetTimestamp(transaction) { + return new Promise((resolve, reject) => + this.#fn.pending_outbound_transaction_get_timestamp.async( + transaction, + this.error, + this.checkAsyncRes( + resolve, + reject, + "pendingOutboundTransactionGetTimestamp" + ) + ) + ); + } + + static pendingOutboundTransactionGetStatus(transaction) { + return new Promise((resolve, reject) => + this.#fn.pending_outbound_transaction_get_status.async( + transaction, + this.error, + this.checkAsyncRes( + resolve, + reject, + "pendingOutboundTransactionGetStatus" + ) + ) + ); + } + + static pendingOutboundTransactionDestroy(transaction) { + return new Promise((resolve, reject) => + this.#fn.pending_outbound_transaction_destroy.async( + transaction, + this.checkAsyncRes(resolve, reject, "pendingOutboundTransactionDestroy") + ) + ); + } + + static pendingOutboundTransactionsGetLength(transactions) { + return new Promise((resolve, reject) => + this.#fn.pending_outbound_transactions_get_length.async( + transactions, + this.error, + this.checkAsyncRes( + resolve, + reject, + "pendingOutboundTransactionsGetLength" + ) + ) + ); + } + + static pendingOutboundTransactionsGetAt(transactions, position) { + return new Promise((resolve, reject) => + this.#fn.pending_outbound_transactions_get_at.async( + transactions, + position, + this.error, + this.checkAsyncRes(resolve, reject, "pendingOutboundTransactionsGetAt") + ) + ); + } + + static pendingOutboundTransactionsDestroy(transactions) { + return new Promise((resolve, reject) => + this.#fn.pending_outbound_transactions_destroy.async( + transactions, + this.checkAsyncRes( + resolve, + reject, + "pendingOutboundTransactionsDestroy" + ) + ) + ); + } + + static pendingInboundTransactionGetTransactionId(transaction) { + return new Promise((resolve, reject) => + this.#fn.pending_inbound_transaction_get_transaction_id.async( + transaction, + this.error, + this.checkAsyncRes( + resolve, + reject, + "pendingInboundTransactionGetTransactionId" + ) + ) + ); + } + + static pendingInboundTransactionGetSourcePublicKey(transaction) { + return new Promise((resolve, reject) => + this.#fn.pending_inbound_transaction_get_source_public_key.async( + transaction, + this.error, + this.checkAsyncRes( + resolve, + reject, + "pendingInboundTransactionGetSourcePublicKey" + ) + ) + ); + } + + static pendingInboundTransactionGetMessage(transaction) { + return new Promise((resolve, reject) => + this.#fn.pending_inbound_transaction_get_message.async( + transaction, + this.error, + this.checkAsyncRes( + resolve, + reject, + "pendingInboundTransactionGetMessage" + ) + ) + ); + } + + static pendingInboundTransactionGetAmount(transaction) { + return new Promise((resolve, reject) => + this.#fn.pending_inbound_transaction_get_amount.async( + transaction, + this.error, + this.checkAsyncRes( + resolve, + reject, + "pendingInboundTransactionGetAmount" + ) + ) + ); + } + + static pendingInboundTransactionGetTimestamp(transaction) { + return new Promise((resolve, reject) => + this.#fn.pending_inbound_transaction_get_timestamp.async( + transaction, + this.error, + this.checkAsyncRes( + resolve, + reject, + "pendingInboundTransactionGetTimestamp" + ) + ) + ); + } + + static pendingInboundTransactionGetStatus(transaction) { + return new Promise((resolve, reject) => + this.#fn.pending_inbound_transaction_get_status.async( + transaction, + this.error, + this.checkAsyncRes( + resolve, + reject, + "pendingInboundTransactionGetStatus" + ) + ) + ); + } + + static pendingInboundTransactionDestroy(transaction) { + return new Promise((resolve, reject) => + this.#fn.pending_inbound_transaction_destroy.async( + transaction, + this.checkAsyncRes(resolve, reject, "pendingInboundTransactionDestroy") + ) + ); + } + + static pendingInboundTransactionsGetLength(transactions) { + return new Promise((resolve, reject) => + this.#fn.pending_inbound_transactions_get_length.async( + transactions, + this.error, + this.checkAsyncRes( + resolve, + reject, + "pendingInboundTransactionsGetLength" + ) + ) + ); + } + + static pendingInboundTransactionsGetAt(transactions, position) { + return new Promise((resolve, reject) => + this.#fn.pending_inbound_transactions_get_at.async( + transactions, + position, + this.error, + this.checkAsyncRes(resolve, reject, "pendingInboundTransactionsGetAt") + ) + ); + } + + static pendingInboundTransactionsDestroy(transactions) { + return new Promise((resolve, reject) => + this.#fn.pending_inbound_transactions_destroy.async( + transactions, + this.checkAsyncRes(resolve, reject, "pendingInboundTransactionsDestroy") + ) + ); + } + + static commsConfigCreate( + public_address, + transport, + database_name, + datastore_path, + discovery_timeout_in_secs, + saf_message_duration_in_secs, + network + ) { + return new Promise((resolve, reject) => + this.#fn.comms_config_create.async( + public_address, + transport, + database_name, + datastore_path, + discovery_timeout_in_secs, + saf_message_duration_in_secs, + network, + this.error, + this.checkAsyncRes(resolve, reject, "commsConfigCreate") + ) + ); + } + + static commsConfigDestroy(wc) { + return new Promise((resolve, reject) => + this.#fn.comms_config_destroy.async( + wc, + this.checkAsyncRes(resolve, reject, "commsConfigDestroy") + ) + ); + } + + static walletCreate( + config, + log_path, + num_rolling_log_files, + size_per_log_file_bytes, + passphrase, + seed_words, + callback_received_transaction, + callback_received_transaction_reply, + callback_received_finalized_transaction, + callback_transaction_broadcast, + callback_transaction_mined, + callback_transaction_mined_unconfirmed, + callback_direct_send_result, + callback_store_and_forward_send_result, + callback_transaction_cancellation, + callback_utxo_validation_complete, + callback_stxo_validation_complete, + callback_invalid_txo_validation_complete, + callback_transaction_validation_complete, + callback_saf_message_received + ) { + return new Promise((resolve, reject) => + this.#fn.wallet_create.async( + config, + log_path, + num_rolling_log_files, + size_per_log_file_bytes, + passphrase, + seed_words, + callback_received_transaction, + callback_received_transaction_reply, + callback_received_finalized_transaction, + callback_transaction_broadcast, + callback_transaction_mined, + callback_transaction_mined_unconfirmed, + callback_direct_send_result, + callback_store_and_forward_send_result, + callback_transaction_cancellation, + callback_utxo_validation_complete, + callback_stxo_validation_complete, + callback_invalid_txo_validation_complete, + callback_transaction_validation_complete, + callback_saf_message_received, + this.recovery_in_progress, + this.error, + this.checkAsyncRes(resolve, reject, "walletCreate") + ) + ); + } + + static walletSignMessage(wallet, msg) { + return new Promise((resolve, reject) => + this.#fn.wallet_sign_message.async( + wallet, + msg, + this.error, + this.checkAsyncRes(resolve, reject, "walletSignMessage") + ) + ); + } + + static walletVerifyMessageSignature(wallet, public_key, hex_sig_nonce, msg) { + return new Promise((resolve, reject) => + this.#fn.wallet_verify_message_signature.async( + wallet, + public_key, + hex_sig_nonce, + msg, + this.error, + this.checkAsyncRes(resolve, reject, "walletVerifyMessageSignature") + ) + ); + } + + static walletAddBaseNodePeer(wallet, public_key, address) { + return new Promise((resolve, reject) => + this.#fn.wallet_add_base_node_peer.async( + wallet, + public_key, + address, + this.error, + this.checkAsyncRes(resolve, reject, "walletAddBaseNodePeer") + ) + ); + } + + static walletUpsertContact(wallet, contact) { + return new Promise((resolve, reject) => + this.#fn.wallet_upsert_contact.async( + wallet, + contact, + this.error, + this.checkAsyncRes(resolve, reject, "walletUpsertContact") + ) + ); + } + + static walletRemoveContact(wallet, contact) { + return new Promise((resolve, reject) => + this.#fn.wallet_remove_contact.async( + wallet, + contact, + this.error, + this.checkAsyncRes(resolve, reject, "walletRemoveContact") + ) + ); + } + + static walletGetAvailableBalance(wallet) { + return new Promise((resolve, reject) => + this.#fn.wallet_get_available_balance.async( + wallet, + this.error, + this.checkAsyncRes(resolve, reject, "walletGetAvailableBalance") + ) + ); + } + + static walletGetPendingIncomingBalance(wallet) { + return new Promise((resolve, reject) => + this.#fn.wallet_get_pending_incoming_balance.async( + wallet, + this.error, + this.checkAsyncRes(resolve, reject, "walletGetPendingIncomingBalance") + ) + ); + } + + static walletGetPendingOutgoingBalance(wallet) { + return new Promise((resolve, reject) => + this.#fn.wallet_get_pending_outgoing_balance.async( + wallet, + this.error, + this.checkAsyncRes(resolve, reject, "walletGetPendingOutgoingBalance") + ) + ); + } + + static walletGetFeeEstimate( + wallet, + amount, + fee_per_gram, + num_kernels, + num_outputs + ) { + return new Promise((resolve, reject) => + this.#fn.wallet_get_fee_estimate.async( + wallet, + amount, + fee_per_gram, + num_kernels, + num_outputs, + this.error, + this.checkAsyncRes(resolve, reject, "walletGetFeeEstimate") + ) + ); + } + + static walletGetNumConfirmationsRequired(wallet) { + return new Promise((resolve, reject) => + this.#fn.wallet_get_num_confirmations_required.async( + wallet, + this.error, + this.checkAsyncRes(resolve, reject, "walletGetNumConfirmationsRequired") + ) + ); + } + + static walletSetNumConfirmationsRequired(wallet, num) { + return new Promise((resolve, reject) => + this.#fn.wallet_set_num_confirmations_required.async( + wallet, + num, + this.error, + this.checkAsyncRes(resolve, reject, "walletSetNumConfirmationsRequired") + ) + ); + } + + static walletSendTransaction( + wallet, + destination, + amount, + fee_per_gram, + message + ) { + return new Promise((resolve, reject) => + this.#fn.wallet_send_transaction.async( + wallet, + destination, + amount, + fee_per_gram, + message, + this.error, + this.checkAsyncRes(resolve, reject, "walletSendTransaction") + ) + ); + } + + static walletGetContacts(wallet) { + return new Promise((resolve, reject) => + this.#fn.wallet_get_contacts.async( + wallet, + this.error, + this.checkAsyncRes(resolve, reject, "walletGetContacts") + ) + ); + } + + static walletGetCompletedTransactions(wallet) { + return new Promise((resolve, reject) => + this.#fn.wallet_get_completed_transactions.async( + wallet, + this.error, + this.checkAsyncRes(resolve, reject, "walletGetCompletedTransactions") + ) + ); + } + + static walletGetPendingOutboundTransactions(wallet) { + return new Promise((resolve, reject) => + this.#fn.wallet_get_pending_outbound_transactions.async( + wallet, + this.error, + this.checkAsyncRes( + resolve, + reject, + "walletGetPendingOutboundTransactions" + ) + ) + ); + } + + static walletGetPublicKey(wallet) { + return new Promise((resolve, reject) => + this.#fn.wallet_get_public_key.async( + wallet, + this.error, + this.checkAsyncRes(resolve, reject, "walletGetPublicKey") + ) + ); + } + + static walletGetPendingInboundTransactions(wallet) { + return new Promise((resolve, reject) => + this.#fn.wallet_get_pending_inbound_transactions.async( + wallet, + this.error, + this.checkAsyncRes( + resolve, + reject, + "walletGetPendingInboundTransactions" + ) + ) + ); + } + + static walletGetCancelledTransactions(wallet) { + return new Promise((resolve, reject) => + this.#fn.wallet_get_cancelled_transactions.async( + wallet, + this.error, + this.checkAsyncRes(resolve, reject, "walletGetCancelledTransactions") + ) + ); + } + + static walletGetCompletedTransactionById(wallet, transaction_id) { + return new Promise((resolve, reject) => + this.#fn.wallet_get_completed_transaction_by_id.async( + wallet, + transaction_id, + this.error, + this.checkAsyncRes(resolve, reject, "walletGetCompletedTransactionById") + ) + ); + } + + static walletGetPendingOutboundTransactionById(wallet, transaction_id) { + return new Promise((resolve, reject) => + this.#fn.wallet_get_pending_outbound_transaction_by_id.async( + wallet, + transaction_id, + this.error, + this.checkAsyncRes( + resolve, + reject, + "walletGetPendingOutboundTransactionById" + ) + ) + ); + } + + static walletGetPendingInboundTransactionById(wallet, transaction_id) { + return new Promise((resolve, reject) => + this.#fn.wallet_get_pending_inbound_transaction_by_id.async( + wallet, + transaction_id, + this.error, + this.checkAsyncRes( + resolve, + reject, + "walletGetPendingInboundTransactionById" + ) + ) + ); + } + + static walletGetCancelledTransactionById(wallet, transaction_id) { + return new Promise((resolve, reject) => + this.#fn.wallet_get_cancelled_transaction_by_id.async( + wallet, + transaction_id, + this.error, + this.checkAsyncRes(resolve, reject, "walletGetCancelledTransactionById") + ) + ); + } + + static walletImportUtxo( + wallet, + amount, + spending_key, + source_public_key, + message + ) { + return new Promise((resolve, reject) => + this.#fn.wallet_import_utxo.async( + wallet, + amount, + spending_key, + source_public_key, + message, + this.error, + this.checkAsyncRes(resolve, reject, "walletImportUtxo") + ) + ); + } + + static walletStartUtxoValidation(wallet) { + return new Promise((resolve, reject) => + this.#fn.wallet_start_utxo_validation.async( + wallet, + this.error, + this.checkAsyncRes(resolve, reject, "walletStartUtxoValidation") + ) + ); + } + + static walletStartStxoValidation(wallet) { + return new Promise((resolve, reject) => + this.#fn.wallet_start_stxo_validation.async( + wallet, + this.error, + this.checkAsyncRes(resolve, reject, "walletStartStxoValidation") + ) + ); + } + + static walletStartInvalidTxoValidation(wallet) { + return new Promise((resolve, reject) => + this.#fn.wallet_start_invalid_txo_validation.async( + wallet, + this.error, + this.checkAsyncRes(resolve, reject, "walletStartInvalidTxoValidation") + ) + ); + } + + static walletStartTransactionValidation(wallet) { + return new Promise((resolve, reject) => + this.#fn.wallet_start_transaction_validation.async( + wallet, + this.error, + this.checkAsyncRes(resolve, reject, "walletStartTransactionValidation") + ) + ); + } + + static walletRestartTransactionBroadcast(wallet) { + return new Promise((resolve, reject) => + this.#fn.wallet_restart_transaction_broadcast.async( + wallet, + this.error, + this.checkAsyncRes(resolve, reject, "walletRestartTransactionBroadcast") + ) + ); + } + + static walletSetLowPowerMode(wallet) { + return new Promise((resolve, reject) => + this.#fn.wallet_set_low_power_mode.async( + wallet, + this.error, + this.checkAsyncRes(resolve, reject, "walletSetLowPowerMode") + ) + ); + } + + static walletSetNormalPowerMode(wallet) { + return new Promise((resolve, reject) => + this.#fn.wallet_set_normal_power_mode.async( + wallet, + this.error, + this.checkAsyncRes(resolve, reject, "walletSetNormalPowerMode") + ) + ); + } + + static walletCancelPendingTransaction(wallet, transaction_id) { + return new Promise((resolve, reject) => + this.#fn.wallet_cancel_pending_transaction.async( + wallet, + transaction_id, + this.error, + this.checkAsyncRes(resolve, reject, "walletCancelPendingTransaction") + ) + ); + } + + static walletCoinSplit(wallet, amount, count, fee, msg, lock_height) { + return new Promise((resolve, reject) => + this.#fn.wallet_coin_split.async( + wallet, + amount, + count, + fee, + msg, + lock_height, + this.error, + this.checkAsyncRes(resolve, reject, "walletCoinSplit") + ) + ); + } + + static walletGetSeedWords(wallet) { + return new Promise((resolve, reject) => + this.#fn.wallet_get_seed_words.async( + wallet, + this.error, + this.checkAsyncRes(resolve, reject, "walletGetSeedWords") + ) + ); + } + + static walletApplyEncryption(wallet, passphrase) { + return new Promise((resolve, reject) => + this.#fn.wallet_apply_encryption.async( + wallet, + passphrase, + this.error, + this.checkAsyncRes(resolve, reject, "walletApplyEncryption") + ) + ); + } + + static walletRemoveEncryption(wallet) { + return new Promise((resolve, reject) => + this.#fn.wallet_remove_encryption.async( + wallet, + this.error, + this.checkAsyncRes(resolve, reject, "walletRemoveEncryption") + ) + ); + } + + static walletSetKeyValue(wallet, key, value) { + return new Promise((resolve, reject) => + this.#fn.wallet_set_key_value.async( + wallet, + key, + value, + this.error, + this.checkAsyncRes(resolve, reject, "walletSetKeyValue") + ) + ); + } + + static walletGetValue(wallet, key) { + return new Promise((resolve, reject) => + this.#fn.wallet_get_value.async( + wallet, + key, + this.error, + this.checkAsyncRes(resolve, reject, "walletGetValue") + ) + ); + } + + static walletClearValue(wallet, key) { + return new Promise((resolve, reject) => + this.#fn.wallet_clear_value.async( + wallet, + key, + this.error, + this.checkAsyncRes(resolve, reject, "walletClearValue") + ) + ); + } + + static walletIsRecoveryInProgress(wallet) { + return new Promise((resolve, reject) => + this.#fn.wallet_is_recovery_in_progress.async( + wallet, + this.error, + this.checkAsyncRes(resolve, reject, "walletIsRecoveryInProgress") + ) + ); + } + + static walletStartRecovery( + wallet, + base_node_public_key, + recovery_progress_callback + ) { + return new Promise((resolve, reject) => + this.#fn.wallet_start_recovery.async( + wallet, + base_node_public_key, + recovery_progress_callback, + this.error, + this.checkAsyncRes(resolve, reject, "walletStartRecovery") + ) + ); + } + + static walletDestroy(wallet) { + return new Promise((resolve, reject) => + this.#fn.wallet_destroy.async( + wallet, + this.checkAsyncRes(resolve, reject, "walletDestroy") + ) + ); + } + + static filePartialBackup(original_file_path, backup_file_path) { + return new Promise((resolve, reject) => + this.#fn.file_partial_backup.async( + original_file_path, + backup_file_path, + this.error, + this.checkAsyncRes(resolve, reject, "filePartialBackup") + ) + ); + } + + static logDebugMessage(msg) { + return new Promise((resolve, reject) => + this.#fn.log_debug_message.async( + msg, + this.checkAsyncRes(resolve, reject, "logDebugMessage") + ) + ); + } + + static getEmojiSet() { + return new Promise((resolve, reject) => + this.#fn.get_emoji_set.async( + this.checkAsyncRes(resolve, reject, "getEmojiSet") + ) + ); + } + + static emojiSetDestroy(emoji_set) { + return new Promise((resolve, reject) => + this.#fn.emoji_set_destroy.async( + emoji_set, + this.checkAsyncRes(resolve, reject, "emojiSetDestroy") + ) + ); + } + + static emojiSetGetAt(emoji_set, position) { + return new Promise((resolve, reject) => + this.#fn.emoji_set_get_at.async( + emoji_set, + position, + this.error, + this.checkAsyncRes(resolve, reject, "emojiSetGetAt") + ) + ); + } + + static emojiSetGetLength(emoji_set) { + return new Promise((resolve, reject) => + this.#fn.emoji_set_get_length.async( + emoji_set, + this.error, + this.checkAsyncRes(resolve, reject, "emojiSetGetLength") + ) + ); + } +} +module.exports = WalletFFI;