Skip to content

Commit

Permalink
feat: implement native iota sdk
Browse files Browse the repository at this point in the history
  • Loading branch information
lmoe committed Sep 14, 2023
1 parent 3febeac commit 13ede60
Show file tree
Hide file tree
Showing 14 changed files with 932 additions and 0 deletions.
93 changes: 93 additions & 0 deletions .github/workflows/bindings-native-publish.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,93 @@
name: Native prebuilt publish

on: workflow_dispatch

env:
CARGO_INCREMENTAL: 0

jobs:
native-binding-prebuilt:
runs-on: ${{ matrix.os }}
strategy:
fail-fast: false
matrix:
os: [ubuntu-20.04, macos-13, windows-2022]

steps:
- uses: actions/checkout@v3

- name: Select Xcode
uses: maxim-lobanov/setup-xcode@v1
if: matrix.os == 'macos-13'
with:
xcode-version: '14.3'

- name: Install Rust toolchain
uses: actions-rs/toolchain@v1
with:
toolchain: stable
override: true

- name: Install LLVM and Clang (Windows) # required for bindgen to work, see https://github.com/rust-lang/rust-bindgen/issues/1797
uses: KyleMayes/install-llvm-action@32c4866ebb71e0949e8833eb49beeebed48532bd
if: matrix.os == 'windows-2022'
with:
version: "11.0"
directory: ${{ runner.temp }}/llvm

- name: Set LIBCLANG_PATH (Windows)
run: echo "LIBCLANG_PATH=$((gcm clang).source -replace "clang.exe")" >> $env:GITHUB_ENV
if: matrix.os == 'windows-2022'

- name: Set deployment target (macOS)
run: echo "MACOSX_DEPLOYMENT_TARGET=10.13" >> $GITHUB_ENV
if: matrix.os == 'macos-13'

- name: Get current date
run: echo "CURRENT_DATE=$(date +'%Y-%m-%d')" >> $GITHUB_ENV
if: matrix.os == 'macos-13' || ${{ startsWith(matrix.os, 'ubuntu') }}

- name: Get current date
if: matrix.os == 'windows-2022'
run: echo "CURRENT_DATE=$(Get-Date -Format "yyyy-MM-dd")" | Out-File -FilePath $env:GITHUB_ENV -Encoding utf8 -Append

- name: Install required packages (Ubuntu)
if: ${{ startsWith(matrix.os, 'ubuntu') }}
run: |
sudo apt-get update
sudo apt-get install libudev-dev libusb-1.0-0-dev
- name: Cache cargo registry
uses: actions/cache@v3
with:
path: ~/.cargo/registry
# Add date to the cache to keep it up to date
key: ${{ matrix.os }}-stable-cargo-registry-${{ hashFiles('**/Cargo.lock') }}-${{ env.CURRENT_DATE }}
# Restore from outdated cache for speed
restore-keys: |
${{ matrix.os }}-stable-cargo-registry-${{ hashFiles('**/Cargo.lock') }}
${{ matrix.os }}-stable-cargo-registry-
- name: Cache cargo index
uses: actions/cache@v3
with:
path: ~/.cargo/git
# Add date to the cache to keep it up to date
key: ${{ matrix.os }}-stable-cargo-index-${{ hashFiles('**/Cargo.lock') }}-${{ env.CURRENT_DATE }}
# Restore from outdated cache for speed
restore-keys: |
${{ matrix.os }}-stable-cargo-index-${{ hashFiles('**/Cargo.lock') }}
${{ matrix.os }}-stable-cargo-index-
# This step is required to support macOS 10.13
- name: Patch librocksdb-sys (macOS)
if: ${{ startsWith(matrix.os, 'macos') }}
run: |
cargo install cargo-patch
cp ${{ github.workspace }}/.patches/rocksdb_faligned_allocation.patch .
git apply --ignore-space-change --ignore-whitespace ${{ github.workspace }}/.patches/macos_cargo_toml.patch
cat Cargo.toml
cargo patch
- name: Cargo build
run: cargo build --release
working-directory: bindings/native
13 changes: 13 additions & 0 deletions Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

1 change: 1 addition & 0 deletions Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@
resolver = "2"
members = [
"bindings/core",
"bindings/native",
"bindings/nodejs",
"bindings/nodejs-old",
"bindings/python",
Expand Down
2 changes: 2 additions & 0 deletions bindings/native/.cargo/config.toml
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
[target.x86_64-pc-windows-msvc]
rustflags = ["-C", "target-feature=+crt-static"]
32 changes: 32 additions & 0 deletions bindings/native/Cargo.toml
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
[package]
name = "iota-sdk-native"
version = "0.1.0"
authors = [ "IOTA Stiftung" ]
edition = "2021"
description = "Native wrapper for the IOTA SDK library"
documentation = "https://wiki.iota.org/iota-sdk/welcome"
homepage = "https://www.iota.org/"
repository = "https://github.com/iotaledger/iota-sdk"
license = "Apache-2.0"
keywords = [ "iota", "client", "wallet", "transaction", "native" ]
categories = [ "cryptography::cryptocurrencies" ]
publish = false

[lib]
name = "iota_sdk_native"
crate-type = [ "cdylib" ]
doc = false

[features]
default = ["std"]
std = ["zeroize/std"]

[dependencies]
iota-sdk-bindings-core = { path = "../core", default-features = false, features = [ "events", "rocksdb", "ledger_nano", "storage", "stronghold" ] }

futures = { version = "0.3.28", default-features = false }
once_cell = { version = "1.17.2", default-features = false }
serde_json = { version = "1.0.96", default-features = false }
tokio = { version = "1.28.2", default-features = false }
log = { version = "0.4.14" }
zeroize = { version = "1.6.0", default-features = false }
46 changes: 46 additions & 0 deletions bindings/native/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,46 @@
# IOTA SDK Native

This binding wraps the IOTA SDK into a native, shared library.

It can be referenced by other languages such as Go, C/C++ or C#.

It exports the following functions:

```
init_logger
binding_get_last_error
call_client_method
call_secret_manager_method
call_utils_method
call_wallet_method
create_client
create_secret_manager
create_wallet
listen_wallet
destroy_client
destroy_secret_manager
destroy_string
destroy_wallet
get_client_from_wallet
get_secret_manager_from_wallet
```

Generated C/C++ headers can be found under `bindings/native/headers`.

Headers can be regenerated by running `bindings/native/bindgen.sh`. This requires [cbindgen](https://github.com/mozilla/cbindgen/).

An example implementation in Go can be found [here](https://github.com/iotaledger/wasp-wallet-sdk/blob/main/wrapper.go).

# Usage

All strings need to be null terminated.

All strings coming from the library need to be free'd by calling `destroy_string` after receiving and copying them.

Any function that either returns a `NULL` pointer or `false` might have catched an error.

This error can be obtained via `get_last_error`.
5 changes: 5 additions & 0 deletions bindings/native/bindgen.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
#!/usr/bin/env bash
set -euo pipefail

cbindgen --crate iota-sdk-native --output headers/iota_sdk.h --lang c
cbindgen --crate iota-sdk-native --output headers/iota_sdk.hpp --lang c++
42 changes: 42 additions & 0 deletions bindings/native/headers/iota_sdk.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
#include <stdarg.h>
#include <stdbool.h>
#include <stdint.h>
#include <stdlib.h>

typedef struct Client Client;

typedef struct SecretManager SecretManager;

typedef struct Wallet Wallet;

bool destroy_string(char *ptr);

bool init_logger(const char *config_ptr);

const char *call_utils_method(const char *config_ptr);

const struct Client *create_client(const char *options_ptr);

bool destroy_client(struct Client *client_ptr);

const char *call_client_method(struct Client *client_ptr, char *method_ptr);

const char *binding_get_last_error(void);

const struct SecretManager *create_secret_manager(const char *options_ptr);

bool destroy_secret_manager(struct SecretManager *secret_manager_ptr);

const char *call_secret_manager_method(struct SecretManager *secret_manager, const char *method);

bool destroy_wallet(struct Wallet *wallet_ptr);

const struct Wallet *create_wallet(const char *options_ptr);

const char *call_wallet_method(struct Wallet *wallet_ptr, const char *method_ptr);

bool listen_wallet(struct Wallet *wallet_ptr, const char *events, void (*handler)(const char*));

const struct Client *get_client_from_wallet(struct Wallet *wallet_ptr);

const struct SecretManager *get_secret_manager_from_wallet(struct Wallet *wallet_ptr);
47 changes: 47 additions & 0 deletions bindings/native/headers/iota_sdk.hpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,47 @@
#include <cstdarg>
#include <cstdint>
#include <cstdlib>
#include <ostream>
#include <new>

struct Client;

struct SecretManager;

struct Wallet;

extern "C" {

bool destroy_string(char *ptr);

bool init_logger(const char *config_ptr);

const char *call_utils_method(const char *config_ptr);

const Client *create_client(const char *options_ptr);

bool destroy_client(Client *client_ptr);

const char *call_client_method(Client *client_ptr, char *method_ptr);

const char *binding_get_last_error();

const SecretManager *create_secret_manager(const char *options_ptr);

bool destroy_secret_manager(SecretManager *secret_manager_ptr);

const char *call_secret_manager_method(SecretManager *secret_manager, const char *method);

bool destroy_wallet(Wallet *wallet_ptr);

const Wallet *create_wallet(const char *options_ptr);

const char *call_wallet_method(Wallet *wallet_ptr, const char *method_ptr);

bool listen_wallet(Wallet *wallet_ptr, const char *events, void (*handler)(const char*));

const Client *get_client_from_wallet(Wallet *wallet_ptr);

const SecretManager *get_secret_manager_from_wallet(Wallet *wallet_ptr);

} // extern "C"
Loading

0 comments on commit 13ede60

Please sign in to comment.