diff --git a/.github/workflows/ci.yaml b/.github/workflows/ci.yaml
new file mode 100644
index 00000000..f386da5c
--- /dev/null
+++ b/.github/workflows/ci.yaml
@@ -0,0 +1,62 @@
+name: ci
+
+on:
+ pull_request:
+ branches:
+ - main
+ push:
+ branches:
+ - main
+
+jobs:
+ build:
+ runs-on: ubuntu-latest
+ steps:
+ -
+ name: Checkout
+ uses: actions/checkout@v4
+ -
+ name: Login to Docker Hub
+ uses: docker/login-action@v3
+ with:
+ username: commerceblockx
+ password: ${{ secrets.DOCKER_HUB_PASSWORD }}
+ -
+ name: Set up Docker Buildx
+ uses: docker/setup-buildx-action@v3
+ -
+ name: Get last commit hash
+ id: get_commit_hash
+ run: echo "COMMIT_HASH=$(git rev-parse --short HEAD)" >> $GITHUB_ENV
+ -
+ name: Build and push for mercury-server
+ uses: docker/build-push-action@v5
+ with:
+ context: .
+ file: ./server/Dockerfile
+ push: true
+ tags: commerceblockx/mercury-server:${{ env.COMMIT_HASH }}
+ -
+ name: Build and push for token-server
+ uses: docker/build-push-action@v5
+ with:
+ context: .
+ file: ./token-server/Dockerfile
+ push: true
+ tags: commerceblockx/token-server:${{ env.COMMIT_HASH }}
+ -
+ name: Build and push for mercury-explorer
+ uses: docker/build-push-action@v5
+ with:
+ context: .
+ file: ./explorer/Dockerfile
+ push: true
+ tags: commerceblockx/mercury-explorer:${{ env.COMMIT_HASH }}
+ -
+ name: Build and push for keylist-cronjob
+ uses: docker/build-push-action@v5
+ with:
+ context: .
+ file: ./keylistCron/Dockerfile
+ push: true
+ tags: commerceblockx/keylist-cronjob:${{ env.COMMIT_HASH }}
diff --git a/.github/workflows/tests.yml b/.github/workflows/tests.yml
new file mode 100644
index 00000000..bc05bc7c
--- /dev/null
+++ b/.github/workflows/tests.yml
@@ -0,0 +1,112 @@
+name: Integration Tests
+
+on:
+ push:
+ branches:
+ - dev
+ pull_request:
+ branches:
+ - dev
+
+jobs:
+ test:
+ runs-on: ubuntu-latest
+
+ services:
+ docker:
+ image: docker:19.03.12
+ options: --privileged
+ ports:
+ - 5432:5432
+ - 18443:18443
+ - 50002:50002
+ - 50001:50001
+ - 8000:8000
+ - 18080:18080
+ volumes:
+ - /var/run/docker.sock:/var/run/docker.sock
+
+ steps:
+ - name: Checkout code
+ uses: actions/checkout@v2
+
+ - name: Set up Docker Compose
+ run: |
+ docker-compose -f docker-compose-test.yml up --build -d
+ - name: Wait for services to be ready
+ run: |
+ sleep 80 # Adjust time as necessary for services to initialize
+ - name: Verify Bitcoin daemon Service with Curl
+ run: |
+ container_id=$(docker ps -qf "name=mercurylayer_bitcoind_1")
+ echo "Container ID: $container_id"
+ docker logs $container_id
+ wallet_name="new_wallet"
+ docker exec $container_id bitcoin-cli -regtest -rpcuser=user -rpcpassword=pass createwallet $wallet_name
+ address=$(docker exec $container_id bitcoin-cli -regtest -rpcuser=user -rpcpassword=pass getnewaddress $wallet_name)
+ echo "New Wallet Address: $address"
+ docker exec $container_id bitcoin-cli -regtest -rpcuser=user -rpcpassword=pass generatetoaddress 101 "$address"
+ docker exec $container_id bitcoin-cli -regtest -rpcuser=user -rpcpassword=pass sendtoaddress bcrt1pcngfxjdkf4r2h26k52dh5nunxg8m68uf4lkfhmfjvjj6agfkm5jqmftw4e 0.0001
+ - name: Verify ElectrumX Service with Curl
+ run: |
+ container_id=$(docker ps -qf "name=mercurylayer_electrs_1")
+ echo "Container ID: $container_id"
+ docker logs $container_id
+ - name: Verify Enclave Service with Curl
+ run: |
+ container_id=$(docker ps -qf "name=mercurylayer_enclave-sgx_1")
+ echo "Container ID: $container_id"
+ docker logs $container_id
+ - name: Verify Mercury Service with Curl
+ run: |
+ container_id=$(docker ps -qf "name=mercurylayer_mercury_1")
+ echo "Container ID: $container_id"
+ docker logs $container_id
+ docker exec $container_id \
+ curl http://0.0.0.0:8000/info/config
+ - name: Get Public Key
+ run: |
+ docker exec $(docker ps -qf "name=enclave") \
+ curl -X POST http://0.0.0.0:18080/get_public_key \
+ -H "Content-Type: application/json" \
+ -d '{"statechain_id":"550e8400e29b41d4a716446655440000"}'
+ docker logs $(docker ps -qf "name=enclave")
+ - name: Check connectivity between containers
+ run: |
+ # Get container IDs
+ enclave_container=$(docker ps -qf "name=mercurylayer_enclave-sgx_1")
+ mercury_container=$(docker ps -qf "name=mercurylayer_mercury_1")
+
+ # Check if mercurylayer_mercury_1 can reach mercurylayer_enclave-sgx_1
+ docker exec $mercury_container curl -v http://mercurylayer_enclave-sgx_1:18080/get_public_key \
+ -H "Content-Type: application/json" \
+ -d '{"statechain_id":"550e8400e29b41d4a716446655440000"}'
+
+ # Alternatively, using IP address if service name resolution fails
+ enclave_ip=$(docker inspect -f '{{range .NetworkSettings.Networks}}{{.IPAddress}}{{end}}' $enclave_container)
+ docker exec $mercury_container curl -v http://$enclave_ip:18080/get_public_key \
+ -H "Content-Type: application/json" \
+ -d '{"statechain_id":"550e8400e29b41d4a716446655440000"}'
+
+ docker inspect mercurylayer_mercury_1
+ - name: Set up Node.js
+ uses: actions/setup-node@v2
+ with:
+ node-version: '20.12.2'
+
+ - name: Install Node.js dependencies for client
+ run: |
+ cd clients/apps/nodejs
+ npm install
+ - name: Install Node.js dependencies for lib
+ run: |
+ cd clients/libs/nodejs
+ npm install
+ - name: Run Client-Side Tests
+ run: |
+ cd clients/apps/nodejs
+ node test_basic_workflow2.js
+ node test_atomic_swap.js
+ - name: Tear Down
+ run: |
+ docker-compose -f docker-compose-test.yml down
diff --git a/.gitignore b/.gitignore
new file mode 100644
index 00000000..54e5a418
--- /dev/null
+++ b/.gitignore
@@ -0,0 +1,4 @@
+/target
+.vscode
+/server/.env
+/token-server/.env
diff --git a/Cargo.lock b/Cargo.lock
new file mode 100644
index 00000000..a339f0cd
--- /dev/null
+++ b/Cargo.lock
@@ -0,0 +1,4056 @@
+# This file is automatically @generated by Cargo.
+# It is not intended for manual editing.
+version = 3
+
+[[package]]
+name = "addr2line"
+version = "0.21.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "8a30b2e23b9e17a9f90641c7ab1549cd9b44f296d3ccbf309d2863cfe398a0cb"
+dependencies = [
+ "gimli",
+]
+
+[[package]]
+name = "adler"
+version = "1.0.2"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "f26201604c87b1e01bd3d98f8d5d9a8fcbb815e8cedb41ffccbeb4bf593a35fe"
+
+[[package]]
+name = "aead"
+version = "0.5.2"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "d122413f284cf2d62fb1b7db97e02edb8cda96d769b16e443a4f6195e35662b0"
+dependencies = [
+ "crypto-common",
+ "generic-array",
+]
+
+[[package]]
+name = "aes"
+version = "0.8.3"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "ac1f845298e95f983ff1944b728ae08b8cebab80d684f0a832ed0fc74dfa27e2"
+dependencies = [
+ "cfg-if",
+ "cipher",
+ "cpufeatures",
+]
+
+[[package]]
+name = "aes-gcm"
+version = "0.10.3"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "831010a0f742e1209b3bcea8fab6a8e149051ba6099432c8cb2cc117dec3ead1"
+dependencies = [
+ "aead",
+ "aes",
+ "cipher",
+ "ctr",
+ "ghash",
+ "subtle",
+]
+
+[[package]]
+name = "ahash"
+version = "0.7.6"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "fcb51a0695d8f838b1ee009b3fbf66bda078cd64590202a864a8f3e8c4315c47"
+dependencies = [
+ "getrandom",
+ "once_cell",
+ "version_check",
+]
+
+[[package]]
+name = "ahash"
+version = "0.8.3"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "2c99f64d1e06488f620f932677e24bc6e2897582980441ae90a671415bd7ec2f"
+dependencies = [
+ "cfg-if",
+ "getrandom",
+ "once_cell",
+ "version_check",
+]
+
+[[package]]
+name = "aho-corasick"
+version = "1.1.2"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "b2969dcb958b36655471fc61f7e416fa76033bdd4bfed0678d8fee1e2d07a1f0"
+dependencies = [
+ "memchr",
+]
+
+[[package]]
+name = "allocator-api2"
+version = "0.2.16"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "0942ffc6dcaadf03badf6e6a2d0228460359d5e34b57ccdc720b7382dfbd5ec5"
+
+[[package]]
+name = "android-tzdata"
+version = "0.1.1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "e999941b234f3131b00bc13c22d06e8c5ff726d1b6318ac7eb276997bbb4fef0"
+
+[[package]]
+name = "android_system_properties"
+version = "0.1.5"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "819e7219dbd41043ac279b19830f2efc897156490d7fd6ea916720117ee66311"
+dependencies = [
+ "libc",
+]
+
+[[package]]
+name = "anstream"
+version = "0.6.4"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "2ab91ebe16eb252986481c5b62f6098f3b698a45e34b5b98200cf20dd2484a44"
+dependencies = [
+ "anstyle",
+ "anstyle-parse",
+ "anstyle-query",
+ "anstyle-wincon",
+ "colorchoice",
+ "utf8parse",
+]
+
+[[package]]
+name = "anstyle"
+version = "1.0.4"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "7079075b41f533b8c61d2a4d073c4676e1f8b249ff94a393b0595db304e0dd87"
+
+[[package]]
+name = "anstyle-parse"
+version = "0.2.2"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "317b9a89c1868f5ea6ff1d9539a69f45dffc21ce321ac1fd1160dfa48c8e2140"
+dependencies = [
+ "utf8parse",
+]
+
+[[package]]
+name = "anstyle-query"
+version = "1.0.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "5ca11d4be1bab0c8bc8734a9aa7bf4ee8316d462a08c6ac5052f888fef5b494b"
+dependencies = [
+ "windows-sys",
+]
+
+[[package]]
+name = "anstyle-wincon"
+version = "3.0.1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "f0699d10d2f4d628a98ee7b57b289abbc98ff3bad977cb3152709d4bf2330628"
+dependencies = [
+ "anstyle",
+ "windows-sys",
+]
+
+[[package]]
+name = "anyhow"
+version = "1.0.75"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "a4668cab20f66d8d020e1fbc0ebe47217433c1b6c8f2040faf858554e394ace6"
+
+[[package]]
+name = "arrayref"
+version = "0.3.7"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "6b4930d2cb77ce62f89ee5d5289b4ac049559b1c45539271f5ed4fdc7db34545"
+
+[[package]]
+name = "askama"
+version = "0.12.1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "b79091df18a97caea757e28cd2d5fda49c6cd4bd01ddffd7ff01ace0c0ad2c28"
+dependencies = [
+ "askama_derive",
+ "askama_escape",
+]
+
+[[package]]
+name = "askama_derive"
+version = "0.12.5"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "19fe8d6cb13c4714962c072ea496f3392015f0989b1a2847bb4b2d9effd71d83"
+dependencies = [
+ "askama_parser",
+ "basic-toml",
+ "mime",
+ "mime_guess",
+ "proc-macro2",
+ "quote",
+ "serde",
+ "syn 2.0.60",
+]
+
+[[package]]
+name = "askama_escape"
+version = "0.10.3"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "619743e34b5ba4e9703bba34deac3427c72507c7159f5fd030aea8cac0cfe341"
+
+[[package]]
+name = "askama_parser"
+version = "0.2.1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "acb1161c6b64d1c3d83108213c2a2533a342ac225aabd0bda218278c2ddb00c0"
+dependencies = [
+ "nom",
+]
+
+[[package]]
+name = "async-stream"
+version = "0.3.5"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "cd56dd203fef61ac097dd65721a419ddccb106b2d2b70ba60a6b529f03961a51"
+dependencies = [
+ "async-stream-impl",
+ "futures-core",
+ "pin-project-lite",
+]
+
+[[package]]
+name = "async-stream-impl"
+version = "0.3.5"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "16e62a023e7c117e27523144c5d2459f4397fcc3cab0085af8e2224f643a0193"
+dependencies = [
+ "proc-macro2",
+ "quote",
+ "syn 2.0.60",
+]
+
+[[package]]
+name = "async-trait"
+version = "0.1.74"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "a66537f1bb974b254c98ed142ff995236e81b9d0fe4db0575f46612cb15eb0f9"
+dependencies = [
+ "proc-macro2",
+ "quote",
+ "syn 2.0.60",
+]
+
+[[package]]
+name = "atoi"
+version = "2.0.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "f28d99ec8bfea296261ca1af174f24225171fea9664ba9003cbebee704810528"
+dependencies = [
+ "num-traits",
+]
+
+[[package]]
+name = "atomic"
+version = "0.5.3"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "c59bdb34bc650a32731b31bd8f0829cc15d24a708ee31559e0bb34f2bc320cba"
+
+[[package]]
+name = "atomic"
+version = "0.6.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "8d818003e740b63afc82337e3160717f4f63078720a810b7b903e70a5d1d2994"
+dependencies = [
+ "bytemuck",
+]
+
+[[package]]
+name = "autocfg"
+version = "1.1.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "d468802bab17cbc0cc575e9b053f41e72aa36bfa6b7f55e3529ffa43161b97fa"
+
+[[package]]
+name = "backtrace"
+version = "0.3.69"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "2089b7e3f35b9dd2d0ed921ead4f6d318c27680d4a5bd167b3ee120edb105837"
+dependencies = [
+ "addr2line",
+ "cc",
+ "cfg-if",
+ "libc",
+ "miniz_oxide",
+ "object",
+ "rustc-demangle",
+]
+
+[[package]]
+name = "base64"
+version = "0.13.1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "9e1b586273c5702936fe7b7d6896644d8be71e6314cfe09d3167c95f712589e8"
+
+[[package]]
+name = "base64"
+version = "0.21.4"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "9ba43ea6f343b788c8764558649e08df62f86c6ef251fdaeb1ffd010a9ae50a2"
+
+[[package]]
+name = "base64ct"
+version = "1.6.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "8c3c1a368f70d6cf7302d78f8f7093da241fb8e8807c05cc9e51a125895a6d5b"
+
+[[package]]
+name = "basic-toml"
+version = "0.1.9"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "823388e228f614e9558c6804262db37960ec8821856535f5c3f59913140558f8"
+dependencies = [
+ "serde",
+]
+
+[[package]]
+name = "bech32"
+version = "0.9.1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "d86b93f97252c47b41663388e6d155714a9d0c398b99f1005cbc5f978b29f445"
+
+[[package]]
+name = "binascii"
+version = "0.1.4"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "383d29d513d8764dcdc42ea295d979eb99c3c9f00607b3692cf68a431f7dca72"
+
+[[package]]
+name = "bincode"
+version = "1.3.3"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "b1f45e9417d87227c7a56d22e471c6206462cba514c7590c09aff4cf6d1ddcad"
+dependencies = [
+ "serde",
+]
+
+[[package]]
+name = "bip39"
+version = "1.2.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "29b9e657de8ff1c3488a4ab77cb51d604eab53415ce34f0bc800f2eac9b13c28"
+dependencies = [
+ "bitcoin_hashes 0.11.0",
+ "rand_core 0.4.2",
+ "serde",
+ "unicode-normalization",
+]
+
+[[package]]
+name = "bitcoin"
+version = "0.30.1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "4e99ff7289b20a7385f66a0feda78af2fc119d28fb56aea8886a9cd0a4abdd75"
+dependencies = [
+ "base64 0.13.1",
+ "bech32",
+ "bitcoin-private",
+ "bitcoin_hashes 0.12.0",
+ "bitcoinconsensus",
+ "hex_lit",
+ "secp256k1",
+ "serde",
+]
+
+[[package]]
+name = "bitcoin-private"
+version = "0.1.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "73290177011694f38ec25e165d0387ab7ea749a4b81cd4c80dae5988229f7a57"
+
+[[package]]
+name = "bitcoin_hashes"
+version = "0.11.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "90064b8dee6815a6470d60bad07bbbaee885c0e12d04177138fa3291a01b7bc4"
+
+[[package]]
+name = "bitcoin_hashes"
+version = "0.12.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "5d7066118b13d4b20b23645932dfb3a81ce7e29f95726c2036fa33cd7b092501"
+dependencies = [
+ "bitcoin-private",
+ "serde",
+]
+
+[[package]]
+name = "bitcoinconsensus"
+version = "0.20.2-0.5.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "54505558b77e0aa21b2491a7b39cbae9db22ac8b1bc543ef4600edb762306f9c"
+dependencies = [
+ "cc",
+ "libc",
+]
+
+[[package]]
+name = "bitflags"
+version = "1.3.2"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "bef38d45163c2f1dde094a7dfd33ccf595c92905c8f8f4fdc18d06fb1037718a"
+
+[[package]]
+name = "bitflags"
+version = "2.4.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "b4682ae6287fcf752ecaabbfcc7b6f9b72aa33933dc23a554d853aea8eea8635"
+dependencies = [
+ "serde",
+]
+
+[[package]]
+name = "block-buffer"
+version = "0.10.4"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "3078c7629b62d3f0439517fa394996acacc5cbc91c5a20d8c658e77abd503a71"
+dependencies = [
+ "generic-array",
+]
+
+[[package]]
+name = "bumpalo"
+version = "3.14.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "7f30e7476521f6f8af1a1c4c0b8cc94f0bee37d91763d0ca2665f299b6cd8aec"
+
+[[package]]
+name = "bytemuck"
+version = "1.14.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "374d28ec25809ee0e23827c2ab573d729e293f281dfe393500e7ad618baa61c6"
+
+[[package]]
+name = "byteorder"
+version = "1.5.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "1fd0f2584146f6f2ef48085050886acf353beff7305ebd1ae69500e27c67f64b"
+
+[[package]]
+name = "bytes"
+version = "1.5.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "a2bd12c1caf447e69cd4528f47f94d203fd2582878ecb9e9465484c4148a8223"
+
+[[package]]
+name = "camino"
+version = "1.1.6"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "c59e92b5a388f549b863a7bea62612c09f24c8393560709a54558a9abdfb3b9c"
+dependencies = [
+ "serde",
+]
+
+[[package]]
+name = "cargo-platform"
+version = "0.1.8"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "24b1f0365a6c6bb4020cd05806fd0d33c44d38046b8bd7f0e40814b9763cabfc"
+dependencies = [
+ "serde",
+]
+
+[[package]]
+name = "cargo_metadata"
+version = "0.15.4"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "eee4243f1f26fc7a42710e7439c149e2b10b05472f88090acce52632f231a73a"
+dependencies = [
+ "camino",
+ "cargo-platform",
+ "semver",
+ "serde",
+ "serde_json",
+ "thiserror",
+]
+
+[[package]]
+name = "cc"
+version = "1.0.83"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "f1174fb0b6ec23863f8b971027804a42614e347eafb0a95bf0b12cdae21fc4d0"
+dependencies = [
+ "libc",
+]
+
+[[package]]
+name = "cfg-if"
+version = "1.0.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "baf1de4339761588bc0619e3cbc0120ee582ebb74b53b4efbf79117bd2da40fd"
+
+[[package]]
+name = "chrono"
+version = "0.4.31"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "7f2c685bad3eb3d45a01354cedb7d5faa66194d1d58ba6e267a8de788f79db38"
+dependencies = [
+ "android-tzdata",
+ "iana-time-zone",
+ "js-sys",
+ "num-traits",
+ "wasm-bindgen",
+ "windows-targets",
+]
+
+[[package]]
+name = "cipher"
+version = "0.4.4"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "773f3b9af64447d2ce9850330c473515014aa235e6a783b02db81ff39e4a3dad"
+dependencies = [
+ "crypto-common",
+ "inout",
+]
+
+[[package]]
+name = "clap"
+version = "4.4.6"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "d04704f56c2cde07f43e8e2c154b43f216dc5c92fc98ada720177362f953b956"
+dependencies = [
+ "clap_builder",
+ "clap_derive",
+]
+
+[[package]]
+name = "clap_builder"
+version = "4.4.6"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "0e231faeaca65ebd1ea3c737966bf858971cd38c3849107aa3ea7de90a804e45"
+dependencies = [
+ "anstream",
+ "anstyle",
+ "clap_lex",
+ "strsim",
+]
+
+[[package]]
+name = "clap_derive"
+version = "4.4.2"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "0862016ff20d69b84ef8247369fabf5c008a7417002411897d40ee1f4532b873"
+dependencies = [
+ "heck",
+ "proc-macro2",
+ "quote",
+ "syn 2.0.60",
+]
+
+[[package]]
+name = "clap_lex"
+version = "0.5.1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "cd7cc57abe963c6d3b9d8be5b06ba7c8957a930305ca90304f24ef040aa6f961"
+
+[[package]]
+name = "client-rust"
+version = "0.1.0"
+dependencies = [
+ "anyhow",
+ "bech32",
+ "bip39",
+ "bitcoin",
+ "chrono",
+ "clap",
+ "config",
+ "electrum-client",
+ "hex",
+ "mercuryrustlib",
+ "rand",
+ "reqwest",
+ "schemars",
+ "secp256k1-zkp",
+ "serde",
+ "serde_json",
+ "sqlx",
+ "tokio",
+ "uuid 1.4.1",
+]
+
+[[package]]
+name = "colorchoice"
+version = "1.0.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "acbf1af155f9b9ef647e42cdc158db4b64a1b61f743629225fde6f3e0be2a7c7"
+
+[[package]]
+name = "config"
+version = "0.13.3"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "d379af7f68bfc21714c6c7dea883544201741d2ce8274bb12fa54f89507f52a7"
+dependencies = [
+ "async-trait",
+ "json5",
+ "lazy_static",
+ "nom",
+ "pathdiff",
+ "ron",
+ "rust-ini",
+ "serde",
+ "serde_json",
+ "toml 0.5.11",
+ "yaml-rust",
+]
+
+[[package]]
+name = "console_error_panic_hook"
+version = "0.1.7"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "a06aeb73f470f66dcdbf7223caeebb85984942f22f1adb2a088cf9668146bbbc"
+dependencies = [
+ "cfg-if",
+ "wasm-bindgen",
+]
+
+[[package]]
+name = "const-oid"
+version = "0.9.5"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "28c122c3980598d243d63d9a704629a2d748d101f278052ff068be5a4423ab6f"
+
+[[package]]
+name = "cookie"
+version = "0.18.1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "4ddef33a339a91ea89fb53151bd0a4689cfce27055c291dfa69945475d22c747"
+dependencies = [
+ "percent-encoding",
+ "time",
+ "version_check",
+]
+
+[[package]]
+name = "core-foundation"
+version = "0.9.3"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "194a7a9e6de53fa55116934067c844d9d749312f75c6f6d0980e8c252f8c2146"
+dependencies = [
+ "core-foundation-sys",
+ "libc",
+]
+
+[[package]]
+name = "core-foundation-sys"
+version = "0.8.4"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "e496a50fda8aacccc86d7529e2c1e0892dbd0f898a6b5645b5561b89c3210efa"
+
+[[package]]
+name = "cpufeatures"
+version = "0.2.9"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "a17b76ff3a4162b0b27f354a0c87015ddad39d35f9c0c36607a3bdd175dde1f1"
+dependencies = [
+ "libc",
+]
+
+[[package]]
+name = "crc"
+version = "3.0.1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "86ec7a15cbe22e59248fc7eadb1907dab5ba09372595da4d73dd805ed4417dfe"
+dependencies = [
+ "crc-catalog",
+]
+
+[[package]]
+name = "crc-catalog"
+version = "2.2.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "9cace84e55f07e7301bae1c519df89cdad8cc3cd868413d3fdbdeca9ff3db484"
+
+[[package]]
+name = "critical-section"
+version = "1.1.2"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "7059fff8937831a9ae6f0fe4d658ffabf58f2ca96aa9dec1c889f936f705f216"
+
+[[package]]
+name = "crossbeam-queue"
+version = "0.3.8"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "d1cfb3ea8a53f37c40dea2c7bedcbd88bdfae54f5e2175d6ecaff1c988353add"
+dependencies = [
+ "cfg-if",
+ "crossbeam-utils",
+]
+
+[[package]]
+name = "crossbeam-utils"
+version = "0.8.16"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "5a22b2d63d4d1dc0b7f1b6b2747dd0088008a9be28b6ddf0b1e7d335e3037294"
+dependencies = [
+ "cfg-if",
+]
+
+[[package]]
+name = "crunchy"
+version = "0.2.2"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "7a81dae078cea95a014a339291cec439d2f232ebe854a9d672b796c6afafa9b7"
+
+[[package]]
+name = "crypto-common"
+version = "0.1.6"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "1bfb12502f3fc46cca1bb51ac28df9d618d813cdc3d2f25b9fe775a34af26bb3"
+dependencies = [
+ "generic-array",
+ "typenum",
+]
+
+[[package]]
+name = "ctr"
+version = "0.9.2"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "0369ee1ad671834580515889b80f2ea915f23b8be8d0daa4bbaf2ac5c7590835"
+dependencies = [
+ "cipher",
+]
+
+[[package]]
+name = "der"
+version = "0.7.8"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "fffa369a668c8af7dbf8b5e56c9f744fbd399949ed171606040001947de40b1c"
+dependencies = [
+ "const-oid",
+ "pem-rfc7468",
+ "zeroize",
+]
+
+[[package]]
+name = "deranged"
+version = "0.3.8"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "f2696e8a945f658fd14dc3b87242e6b80cd0f36ff04ea560fa39082368847946"
+
+[[package]]
+name = "devise"
+version = "0.4.1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "d6eacefd3f541c66fc61433d65e54e0e46e0a029a819a7dbbc7a7b489e8a85f8"
+dependencies = [
+ "devise_codegen",
+ "devise_core",
+]
+
+[[package]]
+name = "devise_codegen"
+version = "0.4.1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "9c8cf4b8dd484ede80fd5c547592c46c3745a617c8af278e2b72bea86b2dfed6"
+dependencies = [
+ "devise_core",
+ "quote",
+]
+
+[[package]]
+name = "devise_core"
+version = "0.4.1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "35b50dba0afdca80b187392b24f2499a88c336d5a8493e4b4ccfb608708be56a"
+dependencies = [
+ "bitflags 2.4.0",
+ "proc-macro2",
+ "proc-macro2-diagnostics",
+ "quote",
+ "syn 2.0.60",
+]
+
+[[package]]
+name = "digest"
+version = "0.9.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "d3dd60d1080a57a05ab032377049e0591415d2b31afd7028356dbf3cc6dcb066"
+dependencies = [
+ "generic-array",
+]
+
+[[package]]
+name = "digest"
+version = "0.10.7"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "9ed9a281f7bc9b7576e61468ba615a66a5c8cfdff42420a70aa82701a3b1e292"
+dependencies = [
+ "block-buffer",
+ "const-oid",
+ "crypto-common",
+ "subtle",
+]
+
+[[package]]
+name = "dlv-list"
+version = "0.3.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "0688c2a7f92e427f44895cd63841bff7b29f8d7a1648b9e7e07a4a365b2e1257"
+
+[[package]]
+name = "dotenvy"
+version = "0.15.7"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "1aaf95b3e5c8f23aa320147307562d361db0ae0d51242340f558153b4eb2439b"
+
+[[package]]
+name = "dyn-clone"
+version = "1.0.14"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "23d2f3407d9a573d666de4b5bdf10569d73ca9478087346697dcbae6244bfbcd"
+
+[[package]]
+name = "ecies"
+version = "0.2.7"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "e0206e602d2645ec8b24ed8307fadbc6c3110e2b11ab2f806fc02fee49327079"
+dependencies = [
+ "aes-gcm",
+ "getrandom",
+ "hkdf",
+ "libsecp256k1",
+ "once_cell",
+ "parking_lot",
+ "rand_core 0.6.4",
+ "sha2",
+ "typenum",
+ "wasm-bindgen",
+]
+
+[[package]]
+name = "either"
+version = "1.9.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "a26ae43d7bcc3b814de94796a5e736d4029efb0ee900c12e2d54c993ad1a1e07"
+dependencies = [
+ "serde",
+]
+
+[[package]]
+name = "electrum-client"
+version = "0.18.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "6bc133f1c8d829d254f013f946653cbeb2b08674b960146361d1e9b67733ad19"
+dependencies = [
+ "bitcoin",
+ "bitcoin-private",
+ "byteorder",
+ "libc",
+ "log",
+ "rustls",
+ "serde",
+ "serde_json",
+ "webpki",
+ "webpki-roots 0.22.6",
+ "winapi",
+]
+
+[[package]]
+name = "encoding_rs"
+version = "0.8.33"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "7268b386296a025e474d5140678f75d6de9493ae55a5d709eeb9dd08149945e1"
+dependencies = [
+ "cfg-if",
+]
+
+[[package]]
+name = "equivalent"
+version = "1.0.1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "5443807d6dff69373d433ab9ef5378ad8df50ca6298caf15de6e52e24aaf54d5"
+
+[[package]]
+name = "errno"
+version = "0.3.5"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "ac3e13f66a2f95e32a39eaa81f6b95d42878ca0e1db0c7543723dfe12557e860"
+dependencies = [
+ "libc",
+ "windows-sys",
+]
+
+[[package]]
+name = "etcetera"
+version = "0.8.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "136d1b5283a1ab77bd9257427ffd09d8667ced0570b6f938942bc7568ed5b943"
+dependencies = [
+ "cfg-if",
+ "home",
+ "windows-sys",
+]
+
+[[package]]
+name = "event-listener"
+version = "2.5.3"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "0206175f82b8d6bf6652ff7d71a1e27fd2e4efde587fd368662814d6ec1d9ce0"
+
+[[package]]
+name = "fastrand"
+version = "2.0.1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "25cbce373ec4653f1a01a31e8a5e5ec0c622dc27ff9c4e6606eefef5cbbed4a5"
+
+[[package]]
+name = "figment"
+version = "0.10.11"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "a014ac935975a70ad13a3bff2463b1c1b083b35ae4cb6309cfc59476aa7a181f"
+dependencies = [
+ "atomic 0.6.0",
+ "pear",
+ "serde",
+ "toml 0.8.2",
+ "uncased",
+ "version_check",
+]
+
+[[package]]
+name = "finl_unicode"
+version = "1.2.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "8fcfdc7a0362c9f4444381a9e697c79d435fe65b52a37466fc2c1184cee9edc6"
+
+[[package]]
+name = "flume"
+version = "0.11.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "55ac459de2512911e4b674ce33cf20befaba382d05b62b008afc1c8b57cbf181"
+dependencies = [
+ "futures-core",
+ "futures-sink",
+ "spin 0.9.8",
+]
+
+[[package]]
+name = "fnv"
+version = "1.0.7"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "3f9eec918d3f24069decb9af1554cad7c880e2da24a9afd88aca000531ab82c1"
+
+[[package]]
+name = "foreign-types"
+version = "0.3.2"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "f6f339eb8adc052cd2ca78910fda869aefa38d22d5cb648e6485e4d3fc06f3b1"
+dependencies = [
+ "foreign-types-shared",
+]
+
+[[package]]
+name = "foreign-types-shared"
+version = "0.1.1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "00b0228411908ca8685dba7fc2cdd70ec9990a6e753e89b6ac91a84c40fbaf4b"
+
+[[package]]
+name = "form_urlencoded"
+version = "1.2.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "a62bc1cf6f830c2ec14a513a9fb124d0a213a629668a4186f329db21fe045652"
+dependencies = [
+ "percent-encoding",
+]
+
+[[package]]
+name = "fs-err"
+version = "2.11.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "88a41f105fe1d5b6b34b2055e3dc59bb79b46b48b2040b9e6c7b4b5de097aa41"
+dependencies = [
+ "autocfg",
+]
+
+[[package]]
+name = "futures"
+version = "0.3.28"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "23342abe12aba583913b2e62f22225ff9c950774065e4bfb61a19cd9770fec40"
+dependencies = [
+ "futures-channel",
+ "futures-core",
+ "futures-io",
+ "futures-sink",
+ "futures-task",
+ "futures-util",
+]
+
+[[package]]
+name = "futures-channel"
+version = "0.3.28"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "955518d47e09b25bbebc7a18df10b81f0c766eaf4c4f1cccef2fca5f2a4fb5f2"
+dependencies = [
+ "futures-core",
+ "futures-sink",
+]
+
+[[package]]
+name = "futures-core"
+version = "0.3.28"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "4bca583b7e26f571124fe5b7561d49cb2868d79116cfa0eefce955557c6fee8c"
+
+[[package]]
+name = "futures-executor"
+version = "0.3.28"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "ccecee823288125bd88b4d7f565c9e58e41858e47ab72e8ea2d64e93624386e0"
+dependencies = [
+ "futures-core",
+ "futures-task",
+ "futures-util",
+]
+
+[[package]]
+name = "futures-intrusive"
+version = "0.5.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "1d930c203dd0b6ff06e0201a4a2fe9149b43c684fd4420555b26d21b1a02956f"
+dependencies = [
+ "futures-core",
+ "lock_api",
+ "parking_lot",
+]
+
+[[package]]
+name = "futures-io"
+version = "0.3.28"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "4fff74096e71ed47f8e023204cfd0aa1289cd54ae5430a9523be060cdb849964"
+
+[[package]]
+name = "futures-sink"
+version = "0.3.28"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "f43be4fe21a13b9781a69afa4985b0f6ee0e1afab2c6f454a8cf30e2b2237b6e"
+
+[[package]]
+name = "futures-task"
+version = "0.3.28"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "76d3d132be6c0e6aa1534069c705a74a5997a356c0dc2f86a47765e5617c5b65"
+
+[[package]]
+name = "futures-util"
+version = "0.3.28"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "26b01e40b772d54cf6c6d721c1d1abd0647a0106a12ecaa1c186273392a69533"
+dependencies = [
+ "futures-channel",
+ "futures-core",
+ "futures-io",
+ "futures-sink",
+ "futures-task",
+ "memchr",
+ "pin-project-lite",
+ "pin-utils",
+ "slab",
+]
+
+[[package]]
+name = "generator"
+version = "0.7.5"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "5cc16584ff22b460a382b7feec54b23d2908d858152e5739a120b949293bd74e"
+dependencies = [
+ "cc",
+ "libc",
+ "log",
+ "rustversion",
+ "windows",
+]
+
+[[package]]
+name = "generic-array"
+version = "0.14.7"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "85649ca51fd72272d7821adaf274ad91c288277713d9c18820d8499a7ff69e9a"
+dependencies = [
+ "typenum",
+ "version_check",
+]
+
+[[package]]
+name = "getrandom"
+version = "0.2.14"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "94b22e06ecb0110981051723910cbf0b5f5e09a2062dd7663334ee79a9d1286c"
+dependencies = [
+ "cfg-if",
+ "js-sys",
+ "libc",
+ "wasi",
+ "wasm-bindgen",
+]
+
+[[package]]
+name = "ghash"
+version = "0.5.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "d930750de5717d2dd0b8c0d42c076c0e884c81a73e6cab859bbd2339c71e3e40"
+dependencies = [
+ "opaque-debug",
+ "polyval",
+]
+
+[[package]]
+name = "gimli"
+version = "0.28.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "6fb8d784f27acf97159b40fc4db5ecd8aa23b9ad5ef69cdd136d3bc80665f0c0"
+
+[[package]]
+name = "glob"
+version = "0.3.1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "d2fabcfbdc87f4758337ca535fb41a6d701b65693ce38287d856d1674551ec9b"
+
+[[package]]
+name = "goblin"
+version = "0.8.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "bb07a4ffed2093b118a525b1d8f5204ae274faed5604537caf7135d0f18d9887"
+dependencies = [
+ "log",
+ "plain",
+ "scroll",
+]
+
+[[package]]
+name = "h2"
+version = "0.3.21"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "91fc23aa11be92976ef4729127f1a74adf36d8436f7816b185d18df956790833"
+dependencies = [
+ "bytes",
+ "fnv",
+ "futures-core",
+ "futures-sink",
+ "futures-util",
+ "http",
+ "indexmap 1.9.3",
+ "slab",
+ "tokio",
+ "tokio-util",
+ "tracing",
+]
+
+[[package]]
+name = "hashbrown"
+version = "0.12.3"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "8a9ee70c43aaf417c914396645a0fa852624801b24ebb7ae78fe8272889ac888"
+dependencies = [
+ "ahash 0.7.6",
+]
+
+[[package]]
+name = "hashbrown"
+version = "0.14.1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "7dfda62a12f55daeae5015f81b0baea145391cb4520f86c248fc615d72640d12"
+dependencies = [
+ "ahash 0.8.3",
+ "allocator-api2",
+]
+
+[[package]]
+name = "hashlink"
+version = "0.8.4"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "e8094feaf31ff591f651a2664fb9cfd92bba7a60ce3197265e9482ebe753c8f7"
+dependencies = [
+ "hashbrown 0.14.1",
+]
+
+[[package]]
+name = "heck"
+version = "0.4.1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "95505c38b4572b2d910cecb0281560f54b440a19336cbbcb27bf6ce6adc6f5a8"
+dependencies = [
+ "unicode-segmentation",
+]
+
+[[package]]
+name = "hermit-abi"
+version = "0.3.3"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "d77f7ec81a6d05a3abb01ab6eb7590f6083d08449fe5a1c8b1e620283546ccb7"
+
+[[package]]
+name = "hex"
+version = "0.4.3"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "7f24254aa9a54b5c858eaee2f5bccdb46aaf0e486a595ed5fd8f86ba55232a70"
+
+[[package]]
+name = "hex_lit"
+version = "0.1.1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "3011d1213f159867b13cfd6ac92d2cd5f1345762c63be3554e84092d85a50bbd"
+
+[[package]]
+name = "hkdf"
+version = "0.12.4"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "7b5f8eb2ad728638ea2c7d47a21db23b7b58a72ed6a38256b8a1849f15fbbdf7"
+dependencies = [
+ "hmac",
+]
+
+[[package]]
+name = "hmac"
+version = "0.12.1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "6c49c37c09c17a53d937dfbb742eb3a961d65a994e6bcdcf37e7399d0cc8ab5e"
+dependencies = [
+ "digest 0.10.7",
+]
+
+[[package]]
+name = "home"
+version = "0.5.5"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "5444c27eef6923071f7ebcc33e3444508466a76f7a2b93da00ed6e19f30c1ddb"
+dependencies = [
+ "windows-sys",
+]
+
+[[package]]
+name = "http"
+version = "0.2.9"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "bd6effc99afb63425aff9b05836f029929e345a6148a14b7ecd5ab67af944482"
+dependencies = [
+ "bytes",
+ "fnv",
+ "itoa",
+]
+
+[[package]]
+name = "http-body"
+version = "0.4.5"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "d5f38f16d184e36f2408a55281cd658ecbd3ca05cce6d6510a176eca393e26d1"
+dependencies = [
+ "bytes",
+ "http",
+ "pin-project-lite",
+]
+
+[[package]]
+name = "httparse"
+version = "1.8.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "d897f394bad6a705d5f4104762e116a75639e470d80901eed05a860a95cb1904"
+
+[[package]]
+name = "httpdate"
+version = "1.0.3"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "df3b46402a9d5adb4c86a0cf463f42e19994e3ee891101b1841f30a545cb49a9"
+
+[[package]]
+name = "hyper"
+version = "0.14.27"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "ffb1cfd654a8219eaef89881fdb3bb3b1cdc5fa75ded05d6933b2b382e395468"
+dependencies = [
+ "bytes",
+ "futures-channel",
+ "futures-core",
+ "futures-util",
+ "h2",
+ "http",
+ "http-body",
+ "httparse",
+ "httpdate",
+ "itoa",
+ "pin-project-lite",
+ "socket2 0.4.9",
+ "tokio",
+ "tower-service",
+ "tracing",
+ "want",
+]
+
+[[package]]
+name = "hyper-tls"
+version = "0.5.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "d6183ddfa99b85da61a140bea0efc93fdf56ceaa041b37d553518030827f9905"
+dependencies = [
+ "bytes",
+ "hyper",
+ "native-tls",
+ "tokio",
+ "tokio-native-tls",
+]
+
+[[package]]
+name = "iana-time-zone"
+version = "0.1.58"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "8326b86b6cff230b97d0d312a6c40a60726df3332e721f72a1b035f451663b20"
+dependencies = [
+ "android_system_properties",
+ "core-foundation-sys",
+ "iana-time-zone-haiku",
+ "js-sys",
+ "wasm-bindgen",
+ "windows-core",
+]
+
+[[package]]
+name = "iana-time-zone-haiku"
+version = "0.1.2"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "f31827a206f56af32e590ba56d5d2d085f558508192593743f16b2306495269f"
+dependencies = [
+ "cc",
+]
+
+[[package]]
+name = "idna"
+version = "0.2.1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "de910d521f7cc3135c4de8db1cb910e0b5ed1dc6f57c381cd07e8e661ce10094"
+dependencies = [
+ "matches",
+ "unicode-bidi",
+ "unicode-normalization",
+]
+
+[[package]]
+name = "indexmap"
+version = "1.9.3"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "bd070e393353796e801d209ad339e89596eb4c8d430d18ede6a1cced8fafbd99"
+dependencies = [
+ "autocfg",
+ "hashbrown 0.12.3",
+]
+
+[[package]]
+name = "indexmap"
+version = "2.0.2"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "8adf3ddd720272c6ea8bf59463c04e0f93d0bbf7c5439b691bca2987e0270897"
+dependencies = [
+ "equivalent",
+ "hashbrown 0.14.1",
+ "serde",
+]
+
+[[package]]
+name = "inlinable_string"
+version = "0.1.15"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "c8fae54786f62fb2918dcfae3d568594e50eb9b5c25bf04371af6fe7516452fb"
+
+[[package]]
+name = "inout"
+version = "0.1.3"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "a0c10553d664a4d0bcff9f4215d0aac67a639cc68ef660840afe309b807bc9f5"
+dependencies = [
+ "generic-array",
+]
+
+[[package]]
+name = "ipnet"
+version = "2.8.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "28b29a3cd74f0f4598934efe3aeba42bae0eb4680554128851ebbecb02af14e6"
+
+[[package]]
+name = "is-terminal"
+version = "0.4.9"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "cb0889898416213fab133e1d33a0e5858a48177452750691bde3666d0fdbaf8b"
+dependencies = [
+ "hermit-abi",
+ "rustix",
+ "windows-sys",
+]
+
+[[package]]
+name = "itertools"
+version = "0.11.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "b1c173a5686ce8bfa551b3563d0c2170bf24ca44da99c7ca4bfdab5418c3fe57"
+dependencies = [
+ "either",
+]
+
+[[package]]
+name = "itoa"
+version = "1.0.9"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "af150ab688ff2122fcef229be89cb50dd66af9e01a4ff320cc137eecc9bacc38"
+
+[[package]]
+name = "js-sys"
+version = "0.3.64"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "c5f195fe497f702db0f318b07fdd68edb16955aed830df8363d837542f8f935a"
+dependencies = [
+ "wasm-bindgen",
+]
+
+[[package]]
+name = "json5"
+version = "0.4.1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "96b0db21af676c1ce64250b5f40f3ce2cf27e4e47cb91ed91eb6fe9350b430c1"
+dependencies = [
+ "pest",
+ "pest_derive",
+ "serde",
+]
+
+[[package]]
+name = "lazy_static"
+version = "1.4.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "e2abad23fbc42b3700f2f279844dc832adb2b2eb069b2df918f455c4e18cc646"
+dependencies = [
+ "spin 0.5.2",
+]
+
+[[package]]
+name = "libc"
+version = "0.2.149"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "a08173bc88b7955d1b3145aa561539096c421ac8debde8cbc3612ec635fee29b"
+
+[[package]]
+name = "libm"
+version = "0.2.8"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "4ec2a862134d2a7d32d7983ddcdd1c4923530833c9f2ea1a44fc5fa473989058"
+
+[[package]]
+name = "libsecp256k1"
+version = "0.7.1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "95b09eff1b35ed3b33b877ced3a691fc7a481919c7e29c53c906226fcf55e2a1"
+dependencies = [
+ "arrayref",
+ "base64 0.13.1",
+ "digest 0.9.0",
+ "libsecp256k1-core",
+ "libsecp256k1-gen-ecmult",
+ "libsecp256k1-gen-genmult",
+ "rand",
+ "serde",
+]
+
+[[package]]
+name = "libsecp256k1-core"
+version = "0.3.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "5be9b9bb642d8522a44d533eab56c16c738301965504753b03ad1de3425d5451"
+dependencies = [
+ "crunchy",
+ "digest 0.9.0",
+ "subtle",
+]
+
+[[package]]
+name = "libsecp256k1-gen-ecmult"
+version = "0.3.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "3038c808c55c87e8a172643a7d87187fc6c4174468159cb3090659d55bcb4809"
+dependencies = [
+ "libsecp256k1-core",
+]
+
+[[package]]
+name = "libsecp256k1-gen-genmult"
+version = "0.3.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "3db8d6ba2cec9eacc40e6e8ccc98931840301f1006e95647ceb2dd5c3aa06f7c"
+dependencies = [
+ "libsecp256k1-core",
+]
+
+[[package]]
+name = "libsqlite3-sys"
+version = "0.26.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "afc22eff61b133b115c6e8c74e818c628d6d5e7a502afea6f64dee076dd94326"
+dependencies = [
+ "cc",
+ "pkg-config",
+ "vcpkg",
+]
+
+[[package]]
+name = "linked-hash-map"
+version = "0.5.6"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "0717cef1bc8b636c6e1c1bbdefc09e6322da8a9321966e8928ef80d20f7f770f"
+
+[[package]]
+name = "linux-raw-sys"
+version = "0.4.10"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "da2479e8c062e40bf0066ffa0bc823de0a9368974af99c9f6df941d2c231e03f"
+
+[[package]]
+name = "lock_api"
+version = "0.4.10"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "c1cc9717a20b1bb222f333e6a92fd32f7d8a18ddc5a3191a11af45dcbf4dcd16"
+dependencies = [
+ "autocfg",
+ "scopeguard",
+]
+
+[[package]]
+name = "log"
+version = "0.4.20"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "b5e6163cb8c49088c2c36f57875e58ccd8c87c7427f7fbd50ea6710b2f3f2e8f"
+
+[[package]]
+name = "loom"
+version = "0.5.6"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "ff50ecb28bb86013e935fb6683ab1f6d3a20016f123c76fd4c27470076ac30f5"
+dependencies = [
+ "cfg-if",
+ "generator",
+ "scoped-tls",
+ "serde",
+ "serde_json",
+ "tracing",
+ "tracing-subscriber",
+]
+
+[[package]]
+name = "matchers"
+version = "0.1.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "8263075bb86c5a1b1427b5ae862e8889656f126e9f77c484496e8b47cf5c5558"
+dependencies = [
+ "regex-automata 0.1.10",
+]
+
+[[package]]
+name = "matches"
+version = "0.1.10"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "2532096657941c2fea9c289d370a250971c689d4f143798ff67113ec042024a5"
+
+[[package]]
+name = "maybe-uninit"
+version = "2.0.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "60302e4db3a61da70c0cb7991976248362f30319e88850c487b9b95bbf059e00"
+
+[[package]]
+name = "md-5"
+version = "0.10.6"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "d89e7ee0cfbedfc4da3340218492196241d89eefb6dab27de5df917a6d2e78cf"
+dependencies = [
+ "cfg-if",
+ "digest 0.10.7",
+]
+
+[[package]]
+name = "memchr"
+version = "2.6.4"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "f665ee40bc4a3c5590afb1e9677db74a508659dfd71e126420da8274909a0167"
+
+[[package]]
+name = "mercury-server"
+version = "0.1.0"
+dependencies = [
+ "bitcoin",
+ "chrono",
+ "config",
+ "hex",
+ "mercurylib",
+ "rand",
+ "reqwest",
+ "rocket",
+ "schemars",
+ "secp256k1-zkp",
+ "serde",
+ "serde_json",
+ "sha2",
+ "sqlx",
+ "uuid 1.4.1",
+]
+
+[[package]]
+name = "mercury-wasm"
+version = "0.1.0"
+dependencies = [
+ "bip39",
+ "console_error_panic_hook",
+ "getrandom",
+ "js-sys",
+ "mercurylib",
+ "rand",
+ "serde",
+ "serde-wasm-bindgen",
+ "wasm-bindgen",
+ "wasm-bindgen-futures",
+ "wasm-bindgen-test",
+ "web-sys",
+]
+
+[[package]]
+name = "mercurylib"
+version = "0.1.0"
+dependencies = [
+ "bech32",
+ "bip39",
+ "bitcoin",
+ "ecies",
+ "hex",
+ "secp256k1-zkp",
+ "serde",
+ "serde_json",
+ "thiserror",
+ "uniffi",
+]
+
+[[package]]
+name = "mercuryrustlib"
+version = "0.1.0"
+dependencies = [
+ "anyhow",
+ "bech32",
+ "bip39",
+ "bitcoin",
+ "chrono",
+ "clap",
+ "config",
+ "electrum-client",
+ "hex",
+ "mercurylib",
+ "rand",
+ "reqwest",
+ "schemars",
+ "secp256k1-zkp",
+ "serde",
+ "serde_json",
+ "sqlx",
+ "tokio",
+ "uuid 1.4.1",
+]
+
+[[package]]
+name = "mime"
+version = "0.3.17"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "6877bb514081ee2a7ff5ef9de3281f14a4dd4bceac4c09388074a6b5df8a139a"
+
+[[package]]
+name = "mime_guess"
+version = "2.0.4"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "4192263c238a5f0d0c6bfd21f336a313a4ce1c450542449ca191bb657b4642ef"
+dependencies = [
+ "mime",
+ "unicase",
+]
+
+[[package]]
+name = "minimal-lexical"
+version = "0.2.1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "68354c5c6bd36d73ff3feceb05efa59b6acb7626617f4962be322a825e61f79a"
+
+[[package]]
+name = "miniz_oxide"
+version = "0.7.1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "e7810e0be55b428ada41041c41f32c9f1a42817901b4ccf45fa3d4b6561e74c7"
+dependencies = [
+ "adler",
+]
+
+[[package]]
+name = "mio"
+version = "0.8.8"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "927a765cd3fc26206e66b296465fa9d3e5ab003e651c1b3c060e7956d96b19d2"
+dependencies = [
+ "libc",
+ "wasi",
+ "windows-sys",
+]
+
+[[package]]
+name = "multer"
+version = "2.1.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "01acbdc23469fd8fe07ab135923371d5f5a422fbf9c522158677c8eb15bc51c2"
+dependencies = [
+ "bytes",
+ "encoding_rs",
+ "futures-util",
+ "http",
+ "httparse",
+ "log",
+ "memchr",
+ "mime",
+ "spin 0.9.8",
+ "tokio",
+ "tokio-util",
+ "version_check",
+]
+
+[[package]]
+name = "native-tls"
+version = "0.2.11"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "07226173c32f2926027b63cce4bcd8076c3552846cbe7925f3aaffeac0a3b92e"
+dependencies = [
+ "lazy_static",
+ "libc",
+ "log",
+ "openssl",
+ "openssl-probe",
+ "openssl-sys",
+ "schannel",
+ "security-framework",
+ "security-framework-sys",
+ "tempfile",
+]
+
+[[package]]
+name = "nom"
+version = "7.1.3"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "d273983c5a657a70a3e8f2a01329822f3b8c8172b73826411a55751e404a0a4a"
+dependencies = [
+ "memchr",
+ "minimal-lexical",
+]
+
+[[package]]
+name = "nu-ansi-term"
+version = "0.46.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "77a8165726e8236064dbb45459242600304b42a5ea24ee2948e18e023bf7ba84"
+dependencies = [
+ "overload",
+ "winapi",
+]
+
+[[package]]
+name = "num-bigint-dig"
+version = "0.8.4"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "dc84195820f291c7697304f3cbdadd1cb7199c0efc917ff5eafd71225c136151"
+dependencies = [
+ "byteorder",
+ "lazy_static",
+ "libm",
+ "num-integer",
+ "num-iter",
+ "num-traits",
+ "rand",
+ "smallvec 1.11.1",
+ "zeroize",
+]
+
+[[package]]
+name = "num-integer"
+version = "0.1.45"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "225d3389fb3509a24c93f5c29eb6bde2586b98d9f016636dff58d7c6f7569cd9"
+dependencies = [
+ "autocfg",
+ "num-traits",
+]
+
+[[package]]
+name = "num-iter"
+version = "0.1.43"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "7d03e6c028c5dc5cac6e2dec0efda81fc887605bb3d884578bb6d6bf7514e252"
+dependencies = [
+ "autocfg",
+ "num-integer",
+ "num-traits",
+]
+
+[[package]]
+name = "num-traits"
+version = "0.2.17"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "39e3200413f237f41ab11ad6d161bc7239c84dcb631773ccd7de3dfe4b5c267c"
+dependencies = [
+ "autocfg",
+ "libm",
+]
+
+[[package]]
+name = "num_cpus"
+version = "1.16.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "4161fcb6d602d4d2081af7c3a45852d875a03dd337a6bfdd6e06407b61342a43"
+dependencies = [
+ "hermit-abi",
+ "libc",
+]
+
+[[package]]
+name = "object"
+version = "0.32.1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "9cf5f9dd3933bd50a9e1f149ec995f39ae2c496d31fd772c1fd45ebc27e902b0"
+dependencies = [
+ "memchr",
+]
+
+[[package]]
+name = "once_cell"
+version = "1.19.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "3fdb12b2476b595f9358c5161aa467c2438859caa136dec86c26fdd2efe17b92"
+dependencies = [
+ "critical-section",
+ "portable-atomic",
+]
+
+[[package]]
+name = "oneshot-uniffi"
+version = "0.1.6"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "6c548d5c78976f6955d72d0ced18c48ca07030f7a1d4024529fedd7c1c01b29c"
+
+[[package]]
+name = "opaque-debug"
+version = "0.3.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "624a8340c38c1b80fd549087862da4ba43e08858af025b236e509b6649fc13d5"
+
+[[package]]
+name = "openssl"
+version = "0.10.57"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "bac25ee399abb46215765b1cb35bc0212377e58a061560d8b29b024fd0430e7c"
+dependencies = [
+ "bitflags 2.4.0",
+ "cfg-if",
+ "foreign-types",
+ "libc",
+ "once_cell",
+ "openssl-macros",
+ "openssl-sys",
+]
+
+[[package]]
+name = "openssl-macros"
+version = "0.1.1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "a948666b637a0f465e8564c73e89d4dde00d72d4d473cc972f390fc3dcee7d9c"
+dependencies = [
+ "proc-macro2",
+ "quote",
+ "syn 2.0.60",
+]
+
+[[package]]
+name = "openssl-probe"
+version = "0.1.5"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "ff011a302c396a5197692431fc1948019154afc178baf7d8e37367442a4601cf"
+
+[[package]]
+name = "openssl-sys"
+version = "0.9.93"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "db4d56a4c0478783083cfafcc42493dd4a981d41669da64b4572a2a089b51b1d"
+dependencies = [
+ "cc",
+ "libc",
+ "pkg-config",
+ "vcpkg",
+]
+
+[[package]]
+name = "ordered-multimap"
+version = "0.4.3"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "ccd746e37177e1711c20dd619a1620f34f5c8b569c53590a72dedd5344d8924a"
+dependencies = [
+ "dlv-list",
+ "hashbrown 0.12.3",
+]
+
+[[package]]
+name = "overload"
+version = "0.1.1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "b15813163c1d831bf4a13c3610c05c0d03b39feb07f7e09fa234dac9b15aaf39"
+
+[[package]]
+name = "parking_lot"
+version = "0.12.3"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "f1bf18183cf54e8d6059647fc3063646a1801cf30896933ec2311622cc4b9a27"
+dependencies = [
+ "lock_api",
+ "parking_lot_core",
+]
+
+[[package]]
+name = "parking_lot_core"
+version = "0.9.8"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "93f00c865fe7cabf650081affecd3871070f26767e7b2070a3ffae14c654b447"
+dependencies = [
+ "cfg-if",
+ "libc",
+ "redox_syscall",
+ "smallvec 1.11.1",
+ "windows-targets",
+]
+
+[[package]]
+name = "paste"
+version = "1.0.14"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "de3145af08024dea9fa9914f381a17b8fc6034dfb00f3a84013f7ff43f29ed4c"
+
+[[package]]
+name = "pathdiff"
+version = "0.2.1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "8835116a5c179084a830efb3adc117ab007512b535bc1a21c991d3b32a6b44dd"
+
+[[package]]
+name = "pear"
+version = "0.2.7"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "61a386cd715229d399604b50d1361683fe687066f42d56f54be995bc6868f71c"
+dependencies = [
+ "inlinable_string",
+ "pear_codegen",
+ "yansi",
+]
+
+[[package]]
+name = "pear_codegen"
+version = "0.2.7"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "da9f0f13dac8069c139e8300a6510e3f4143ecf5259c60b116a9b271b4ca0d54"
+dependencies = [
+ "proc-macro2",
+ "proc-macro2-diagnostics",
+ "quote",
+ "syn 2.0.60",
+]
+
+[[package]]
+name = "pem-rfc7468"
+version = "0.7.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "88b39c9bfcfc231068454382784bb460aae594343fb030d46e9f50a645418412"
+dependencies = [
+ "base64ct",
+]
+
+[[package]]
+name = "percent-encoding"
+version = "2.3.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "9b2a4787296e9989611394c33f193f676704af1686e70b8f8033ab5ba9a35a94"
+
+[[package]]
+name = "pest"
+version = "2.7.4"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "c022f1e7b65d6a24c0dbbd5fb344c66881bc01f3e5ae74a1c8100f2f985d98a4"
+dependencies = [
+ "memchr",
+ "thiserror",
+ "ucd-trie",
+]
+
+[[package]]
+name = "pest_derive"
+version = "2.7.4"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "35513f630d46400a977c4cb58f78e1bfbe01434316e60c37d27b9ad6139c66d8"
+dependencies = [
+ "pest",
+ "pest_generator",
+]
+
+[[package]]
+name = "pest_generator"
+version = "2.7.4"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "bc9fc1b9e7057baba189b5c626e2d6f40681ae5b6eb064dc7c7834101ec8123a"
+dependencies = [
+ "pest",
+ "pest_meta",
+ "proc-macro2",
+ "quote",
+ "syn 2.0.60",
+]
+
+[[package]]
+name = "pest_meta"
+version = "2.7.4"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "1df74e9e7ec4053ceb980e7c0c8bd3594e977fde1af91daba9c928e8e8c6708d"
+dependencies = [
+ "once_cell",
+ "pest",
+ "sha2",
+]
+
+[[package]]
+name = "pin-project-lite"
+version = "0.2.13"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "8afb450f006bf6385ca15ef45d71d2288452bc3683ce2e2cacc0d18e4be60b58"
+
+[[package]]
+name = "pin-utils"
+version = "0.1.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "8b870d8c151b6f2fb93e84a13146138f05d02ed11c7e7c54f8826aaaf7c9f184"
+
+[[package]]
+name = "pkcs1"
+version = "0.7.5"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "c8ffb9f10fa047879315e6625af03c164b16962a5368d724ed16323b68ace47f"
+dependencies = [
+ "der",
+ "pkcs8",
+ "spki",
+]
+
+[[package]]
+name = "pkcs8"
+version = "0.10.2"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "f950b2377845cebe5cf8b5165cb3cc1a5e0fa5cfa3e1f7f55707d8fd82e0a7b7"
+dependencies = [
+ "der",
+ "spki",
+]
+
+[[package]]
+name = "pkg-config"
+version = "0.3.27"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "26072860ba924cbfa98ea39c8c19b4dd6a4a25423dbdf219c1eca91aa0cf6964"
+
+[[package]]
+name = "plain"
+version = "0.2.3"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "b4596b6d070b27117e987119b4dac604f3c58cfb0b191112e24771b2faeac1a6"
+
+[[package]]
+name = "polyval"
+version = "0.6.1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "d52cff9d1d4dee5fe6d03729099f4a310a41179e0a10dbf542039873f2e826fb"
+dependencies = [
+ "cfg-if",
+ "cpufeatures",
+ "opaque-debug",
+ "universal-hash",
+]
+
+[[package]]
+name = "portable-atomic"
+version = "1.6.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "7170ef9988bc169ba16dd36a7fa041e5c4cbeb6a35b76d4c03daded371eae7c0"
+
+[[package]]
+name = "ppv-lite86"
+version = "0.2.17"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "5b40af805b3121feab8a3c29f04d8ad262fa8e0561883e7653e024ae4479e6de"
+
+[[package]]
+name = "proc-macro2"
+version = "1.0.81"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "3d1597b0c024618f09a9c3b8655b7e430397a36d23fdafec26d6965e9eec3eba"
+dependencies = [
+ "unicode-ident",
+]
+
+[[package]]
+name = "proc-macro2-diagnostics"
+version = "0.10.1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "af066a9c399a26e020ada66a034357a868728e72cd426f3adcd35f80d88d88c8"
+dependencies = [
+ "proc-macro2",
+ "quote",
+ "syn 2.0.60",
+ "version_check",
+ "yansi",
+]
+
+[[package]]
+name = "quote"
+version = "1.0.36"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "0fa76aaf39101c457836aec0ce2316dbdc3ab723cdda1c6bd4e6ad4208acaca7"
+dependencies = [
+ "proc-macro2",
+]
+
+[[package]]
+name = "rand"
+version = "0.8.5"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "34af8d1a0e25924bc5b7c43c079c942339d8f0a8b57c39049bef581b46327404"
+dependencies = [
+ "libc",
+ "rand_chacha",
+ "rand_core 0.6.4",
+]
+
+[[package]]
+name = "rand_chacha"
+version = "0.3.1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "e6c10a63a0fa32252be49d21e7709d4d4baf8d231c2dbce1eaa8141b9b127d88"
+dependencies = [
+ "ppv-lite86",
+ "rand_core 0.6.4",
+]
+
+[[package]]
+name = "rand_core"
+version = "0.4.2"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "9c33a3c44ca05fa6f1807d8e6743f3824e8509beca625669633be0acbdf509dc"
+
+[[package]]
+name = "rand_core"
+version = "0.6.4"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "ec0be4795e2f6a28069bec0b5ff3e2ac9bafc99e6a9a7dc3547996c5c816922c"
+dependencies = [
+ "getrandom",
+]
+
+[[package]]
+name = "redox_syscall"
+version = "0.3.5"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "567664f262709473930a4bf9e51bf2ebf3348f2e748ccc50dea20646858f8f29"
+dependencies = [
+ "bitflags 1.3.2",
+]
+
+[[package]]
+name = "ref-cast"
+version = "1.0.20"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "acde58d073e9c79da00f2b5b84eed919c8326832648a5b109b3fce1bb1175280"
+dependencies = [
+ "ref-cast-impl",
+]
+
+[[package]]
+name = "ref-cast-impl"
+version = "1.0.20"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "7f7473c2cfcf90008193dd0e3e16599455cb601a9fce322b5bb55de799664925"
+dependencies = [
+ "proc-macro2",
+ "quote",
+ "syn 2.0.60",
+]
+
+[[package]]
+name = "regex"
+version = "1.10.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "d119d7c7ca818f8a53c300863d4f87566aac09943aef5b355bb83969dae75d87"
+dependencies = [
+ "aho-corasick",
+ "memchr",
+ "regex-automata 0.4.1",
+ "regex-syntax 0.8.0",
+]
+
+[[package]]
+name = "regex-automata"
+version = "0.1.10"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "6c230d73fb8d8c1b9c0b3135c5142a8acee3a0558fb8db5cf1cb65f8d7862132"
+dependencies = [
+ "regex-syntax 0.6.29",
+]
+
+[[package]]
+name = "regex-automata"
+version = "0.4.1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "465c6fc0621e4abc4187a2bda0937bfd4f722c2730b29562e19689ea796c9a4b"
+dependencies = [
+ "aho-corasick",
+ "memchr",
+ "regex-syntax 0.8.0",
+]
+
+[[package]]
+name = "regex-syntax"
+version = "0.6.29"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "f162c6dd7b008981e4d40210aca20b4bd0f9b60ca9271061b07f78537722f2e1"
+
+[[package]]
+name = "regex-syntax"
+version = "0.8.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "c3cbb081b9784b07cceb8824c8583f86db4814d172ab043f3c23f7dc600bf83d"
+
+[[package]]
+name = "reqwest"
+version = "0.11.22"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "046cd98826c46c2ac8ddecae268eb5c2e58628688a5fc7a2643704a73faba95b"
+dependencies = [
+ "base64 0.21.4",
+ "bytes",
+ "encoding_rs",
+ "futures-core",
+ "futures-util",
+ "h2",
+ "http",
+ "http-body",
+ "hyper",
+ "hyper-tls",
+ "ipnet",
+ "js-sys",
+ "log",
+ "mime",
+ "native-tls",
+ "once_cell",
+ "percent-encoding",
+ "pin-project-lite",
+ "serde",
+ "serde_json",
+ "serde_urlencoded",
+ "system-configuration",
+ "tokio",
+ "tokio-native-tls",
+ "tokio-socks",
+ "tower-service",
+ "url",
+ "wasm-bindgen",
+ "wasm-bindgen-futures",
+ "web-sys",
+ "winreg",
+]
+
+[[package]]
+name = "ring"
+version = "0.16.20"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "3053cf52e236a3ed746dfc745aa9cacf1b791d846bdaf412f60a8d7d6e17c8fc"
+dependencies = [
+ "cc",
+ "libc",
+ "once_cell",
+ "spin 0.5.2",
+ "untrusted 0.7.1",
+ "web-sys",
+ "winapi",
+]
+
+[[package]]
+name = "ring"
+version = "0.17.3"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "9babe80d5c16becf6594aa32ad2be8fe08498e7ae60b77de8df700e67f191d7e"
+dependencies = [
+ "cc",
+ "getrandom",
+ "libc",
+ "spin 0.9.8",
+ "untrusted 0.9.0",
+ "windows-sys",
+]
+
+[[package]]
+name = "rocket"
+version = "0.5.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "9e7bb57ccb26670d73b6a47396c83139447b9e7878cab627fdfe9ea8da489150"
+dependencies = [
+ "async-stream",
+ "async-trait",
+ "atomic 0.5.3",
+ "binascii",
+ "bytes",
+ "either",
+ "figment",
+ "futures",
+ "indexmap 2.0.2",
+ "log",
+ "memchr",
+ "multer",
+ "num_cpus",
+ "parking_lot",
+ "pin-project-lite",
+ "rand",
+ "ref-cast",
+ "rocket_codegen",
+ "rocket_http",
+ "serde",
+ "serde_json",
+ "state",
+ "tempfile",
+ "time",
+ "tokio",
+ "tokio-stream",
+ "tokio-util",
+ "ubyte",
+ "version_check",
+ "yansi",
+]
+
+[[package]]
+name = "rocket_codegen"
+version = "0.5.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "a2238066abf75f21be6cd7dc1a09d5414a671f4246e384e49fe3f8a4936bd04c"
+dependencies = [
+ "devise",
+ "glob",
+ "indexmap 2.0.2",
+ "proc-macro2",
+ "quote",
+ "rocket_http",
+ "syn 2.0.60",
+ "unicode-xid",
+ "version_check",
+]
+
+[[package]]
+name = "rocket_http"
+version = "0.5.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "37a1663694d059fe5f943ea5481363e48050acedd241d46deb2e27f71110389e"
+dependencies = [
+ "cookie",
+ "either",
+ "futures",
+ "http",
+ "hyper",
+ "indexmap 2.0.2",
+ "log",
+ "memchr",
+ "pear",
+ "percent-encoding",
+ "pin-project-lite",
+ "ref-cast",
+ "serde",
+ "smallvec 1.11.1",
+ "stable-pattern",
+ "state",
+ "time",
+ "tokio",
+ "uncased",
+]
+
+[[package]]
+name = "ron"
+version = "0.7.1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "88073939a61e5b7680558e6be56b419e208420c2adb92be54921fa6b72283f1a"
+dependencies = [
+ "base64 0.13.1",
+ "bitflags 1.3.2",
+ "serde",
+]
+
+[[package]]
+name = "rsa"
+version = "0.9.2"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "6ab43bb47d23c1a631b4b680199a45255dce26fa9ab2fa902581f624ff13e6a8"
+dependencies = [
+ "byteorder",
+ "const-oid",
+ "digest 0.10.7",
+ "num-bigint-dig",
+ "num-integer",
+ "num-iter",
+ "num-traits",
+ "pkcs1",
+ "pkcs8",
+ "rand_core 0.6.4",
+ "signature",
+ "spki",
+ "subtle",
+ "zeroize",
+]
+
+[[package]]
+name = "rust"
+version = "0.1.0"
+dependencies = [
+ "anyhow",
+ "electrum-client",
+ "hex",
+ "mercuryrustlib",
+ "serde",
+ "serde_json",
+ "sha2",
+ "tokio",
+ "uuid 1.4.1",
+]
+
+[[package]]
+name = "rust-ini"
+version = "0.18.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "f6d5f2436026b4f6e79dc829837d467cc7e9a55ee40e750d716713540715a2df"
+dependencies = [
+ "cfg-if",
+ "ordered-multimap",
+]
+
+[[package]]
+name = "rustc-demangle"
+version = "0.1.23"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "d626bb9dae77e28219937af045c257c28bfd3f69333c512553507f5f9798cb76"
+
+[[package]]
+name = "rustix"
+version = "0.38.18"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "5a74ee2d7c2581cd139b42447d7d9389b889bdaad3a73f1ebb16f2a3237bb19c"
+dependencies = [
+ "bitflags 2.4.0",
+ "errno",
+ "libc",
+ "linux-raw-sys",
+ "windows-sys",
+]
+
+[[package]]
+name = "rustls"
+version = "0.21.7"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "cd8d6c9f025a446bc4d18ad9632e69aec8f287aa84499ee335599fabd20c3fd8"
+dependencies = [
+ "log",
+ "ring 0.16.20",
+ "rustls-webpki",
+ "sct",
+]
+
+[[package]]
+name = "rustls-pemfile"
+version = "1.0.4"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "1c74cae0a4cf6ccbbf5f359f08efdf8ee7e1dc532573bf0db71968cb56b1448c"
+dependencies = [
+ "base64 0.21.4",
+]
+
+[[package]]
+name = "rustls-webpki"
+version = "0.101.6"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "3c7d5dece342910d9ba34d259310cae3e0154b873b35408b787b59bce53d34fe"
+dependencies = [
+ "ring 0.16.20",
+ "untrusted 0.7.1",
+]
+
+[[package]]
+name = "rustversion"
+version = "1.0.14"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "7ffc183a10b4478d04cbbbfc96d0873219d962dd5accaff2ffbd4ceb7df837f4"
+
+[[package]]
+name = "ryu"
+version = "1.0.15"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "1ad4cc8da4ef723ed60bced201181d83791ad433213d8c24efffda1eec85d741"
+
+[[package]]
+name = "schannel"
+version = "0.1.22"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "0c3733bf4cf7ea0880754e19cb5a462007c4a8c1914bff372ccc95b464f1df88"
+dependencies = [
+ "windows-sys",
+]
+
+[[package]]
+name = "schemars"
+version = "0.8.15"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "1f7b0ce13155372a76ee2e1c5ffba1fe61ede73fbea5630d61eee6fac4929c0c"
+dependencies = [
+ "chrono",
+ "dyn-clone",
+ "schemars_derive",
+ "serde",
+ "serde_json",
+ "uuid 0.8.2",
+]
+
+[[package]]
+name = "schemars_derive"
+version = "0.8.15"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "e85e2a16b12bdb763244c69ab79363d71db2b4b918a2def53f80b02e0574b13c"
+dependencies = [
+ "proc-macro2",
+ "quote",
+ "serde_derive_internals",
+ "syn 1.0.109",
+]
+
+[[package]]
+name = "scoped-tls"
+version = "1.0.1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "e1cf6437eb19a8f4a6cc0f7dca544973b0b78843adbfeb3683d1a94a0024a294"
+
+[[package]]
+name = "scopeguard"
+version = "1.2.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "94143f37725109f92c262ed2cf5e59bce7498c01bcc1502d7b9afe439a4e9f49"
+
+[[package]]
+name = "scroll"
+version = "0.12.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "6ab8598aa408498679922eff7fa985c25d58a90771bd6be794434c5277eab1a6"
+dependencies = [
+ "scroll_derive",
+]
+
+[[package]]
+name = "scroll_derive"
+version = "0.12.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "7f81c2fde025af7e69b1d1420531c8a8811ca898919db177141a85313b1cb932"
+dependencies = [
+ "proc-macro2",
+ "quote",
+ "syn 2.0.60",
+]
+
+[[package]]
+name = "sct"
+version = "0.7.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "d53dcdb7c9f8158937a7981b48accfd39a43af418591a5d008c7b22b5e1b7ca4"
+dependencies = [
+ "ring 0.16.20",
+ "untrusted 0.7.1",
+]
+
+[[package]]
+name = "secp256k1"
+version = "0.27.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "25996b82292a7a57ed3508f052cfff8640d38d32018784acd714758b43da9c8f"
+dependencies = [
+ "bitcoin_hashes 0.12.0",
+ "rand",
+ "secp256k1-sys",
+ "serde",
+]
+
+[[package]]
+name = "secp256k1-sys"
+version = "0.8.1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "70a129b9e9efbfb223753b9163c4ab3b13cff7fd9c7f010fbac25ab4099fa07e"
+dependencies = [
+ "cc",
+]
+
+[[package]]
+name = "secp256k1-zkp"
+version = "0.9.2"
+source = "git+https://github.com/ssantos21/rust-secp256k1-zkp.git?branch=blinded-musig-scheme#e03de85e3c74e58249bb3bb43e8642e5e744cfa0"
+dependencies = [
+ "bitcoin-private",
+ "rand",
+ "secp256k1",
+ "secp256k1-zkp-sys",
+]
+
+[[package]]
+name = "secp256k1-zkp-sys"
+version = "0.8.1"
+source = "git+https://github.com/ssantos21/rust-secp256k1-zkp.git?branch=blinded-musig-scheme#e03de85e3c74e58249bb3bb43e8642e5e744cfa0"
+dependencies = [
+ "cc",
+ "secp256k1-sys",
+]
+
+[[package]]
+name = "security-framework"
+version = "2.9.2"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "05b64fb303737d99b81884b2c63433e9ae28abebe5eb5045dcdd175dc2ecf4de"
+dependencies = [
+ "bitflags 1.3.2",
+ "core-foundation",
+ "core-foundation-sys",
+ "libc",
+ "security-framework-sys",
+]
+
+[[package]]
+name = "security-framework-sys"
+version = "2.9.1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "e932934257d3b408ed8f30db49d85ea163bfe74961f017f405b025af298f0c7a"
+dependencies = [
+ "core-foundation-sys",
+ "libc",
+]
+
+[[package]]
+name = "semver"
+version = "1.0.22"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "92d43fe69e652f3df9bdc2b85b2854a0825b86e4fb76bc44d945137d053639ca"
+dependencies = [
+ "serde",
+]
+
+[[package]]
+name = "serde"
+version = "1.0.199"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "0c9f6e76df036c77cd94996771fb40db98187f096dd0b9af39c6c6e452ba966a"
+dependencies = [
+ "serde_derive",
+]
+
+[[package]]
+name = "serde-wasm-bindgen"
+version = "0.4.5"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "e3b4c031cd0d9014307d82b8abf653c0290fbdaeb4c02d00c63cf52f728628bf"
+dependencies = [
+ "js-sys",
+ "serde",
+ "wasm-bindgen",
+]
+
+[[package]]
+name = "serde_derive"
+version = "1.0.199"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "11bd257a6541e141e42ca6d24ae26f7714887b47e89aa739099104c7e4d3b7fc"
+dependencies = [
+ "proc-macro2",
+ "quote",
+ "syn 2.0.60",
+]
+
+[[package]]
+name = "serde_derive_internals"
+version = "0.26.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "85bf8229e7920a9f636479437026331ce11aa132b4dde37d121944a44d6e5f3c"
+dependencies = [
+ "proc-macro2",
+ "quote",
+ "syn 1.0.109",
+]
+
+[[package]]
+name = "serde_json"
+version = "1.0.107"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "6b420ce6e3d8bd882e9b243c6eed35dbc9a6110c9769e74b584e0d68d1f20c65"
+dependencies = [
+ "itoa",
+ "ryu",
+ "serde",
+]
+
+[[package]]
+name = "serde_spanned"
+version = "0.6.3"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "96426c9936fd7a0124915f9185ea1d20aa9445cc9821142f0a73bc9207a2e186"
+dependencies = [
+ "serde",
+]
+
+[[package]]
+name = "serde_urlencoded"
+version = "0.7.1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "d3491c14715ca2294c4d6a88f15e84739788c1d030eed8c110436aafdaa2f3fd"
+dependencies = [
+ "form_urlencoded",
+ "itoa",
+ "ryu",
+ "serde",
+]
+
+[[package]]
+name = "sha1"
+version = "0.10.6"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "e3bf829a2d51ab4a5ddf1352d8470c140cadc8301b2ae1789db023f01cedd6ba"
+dependencies = [
+ "cfg-if",
+ "cpufeatures",
+ "digest 0.10.7",
+]
+
+[[package]]
+name = "sha2"
+version = "0.10.8"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "793db75ad2bcafc3ffa7c68b215fee268f537982cd901d132f89c6343f3a3dc8"
+dependencies = [
+ "cfg-if",
+ "cpufeatures",
+ "digest 0.10.7",
+]
+
+[[package]]
+name = "sharded-slab"
+version = "0.1.7"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "f40ca3c46823713e0d4209592e8d6e826aa57e928f09752619fc696c499637f6"
+dependencies = [
+ "lazy_static",
+]
+
+[[package]]
+name = "signal-hook-registry"
+version = "1.4.1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "d8229b473baa5980ac72ef434c4415e70c4b5e71b423043adb4ba059f89c99a1"
+dependencies = [
+ "libc",
+]
+
+[[package]]
+name = "signature"
+version = "2.1.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "5e1788eed21689f9cf370582dfc467ef36ed9c707f073528ddafa8d83e3b8500"
+dependencies = [
+ "digest 0.10.7",
+ "rand_core 0.6.4",
+]
+
+[[package]]
+name = "siphasher"
+version = "0.3.11"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "38b58827f4464d87d377d175e90bf58eb00fd8716ff0a62f80356b5e61555d0d"
+
+[[package]]
+name = "slab"
+version = "0.4.9"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "8f92a496fb766b417c996b9c5e57daf2f7ad3b0bebe1ccfca4856390e3d3bb67"
+dependencies = [
+ "autocfg",
+]
+
+[[package]]
+name = "smallvec"
+version = "0.6.14"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "b97fcaeba89edba30f044a10c6a3cc39df9c3f17d7cd829dd1446cab35f890e0"
+dependencies = [
+ "maybe-uninit",
+]
+
+[[package]]
+name = "smallvec"
+version = "1.11.1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "942b4a808e05215192e39f4ab80813e599068285906cc91aa64f923db842bd5a"
+
+[[package]]
+name = "smawk"
+version = "0.3.2"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "b7c388c1b5e93756d0c740965c41e8822f866621d41acbdf6336a6a168f8840c"
+
+[[package]]
+name = "socket2"
+version = "0.4.9"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "64a4a911eed85daf18834cfaa86a79b7d266ff93ff5ba14005426219480ed662"
+dependencies = [
+ "libc",
+ "winapi",
+]
+
+[[package]]
+name = "socket2"
+version = "0.5.4"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "4031e820eb552adee9295814c0ced9e5cf38ddf1e8b7d566d6de8e2538ea989e"
+dependencies = [
+ "libc",
+ "windows-sys",
+]
+
+[[package]]
+name = "spin"
+version = "0.5.2"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "6e63cff320ae2c57904679ba7cb63280a3dc4613885beafb148ee7bf9aa9042d"
+
+[[package]]
+name = "spin"
+version = "0.9.8"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "6980e8d7511241f8acf4aebddbb1ff938df5eebe98691418c4468d0b72a96a67"
+dependencies = [
+ "lock_api",
+]
+
+[[package]]
+name = "spki"
+version = "0.7.2"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "9d1e996ef02c474957d681f1b05213dfb0abab947b446a62d37770b23500184a"
+dependencies = [
+ "base64ct",
+ "der",
+]
+
+[[package]]
+name = "sqlformat"
+version = "0.2.2"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "6b7b278788e7be4d0d29c0f39497a0eef3fba6bbc8e70d8bf7fde46edeaa9e85"
+dependencies = [
+ "itertools",
+ "nom",
+ "unicode_categories",
+]
+
+[[package]]
+name = "sqlx"
+version = "0.7.2"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "0e50c216e3624ec8e7ecd14c6a6a6370aad6ee5d8cfc3ab30b5162eeeef2ed33"
+dependencies = [
+ "sqlx-core",
+ "sqlx-macros",
+ "sqlx-mysql",
+ "sqlx-postgres",
+ "sqlx-sqlite",
+]
+
+[[package]]
+name = "sqlx-core"
+version = "0.7.2"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "8d6753e460c998bbd4cd8c6f0ed9a64346fcca0723d6e75e52fdc351c5d2169d"
+dependencies = [
+ "ahash 0.8.3",
+ "atoi",
+ "byteorder",
+ "bytes",
+ "chrono",
+ "crc",
+ "crossbeam-queue",
+ "dotenvy",
+ "either",
+ "event-listener",
+ "futures-channel",
+ "futures-core",
+ "futures-intrusive",
+ "futures-io",
+ "futures-util",
+ "hashlink",
+ "hex",
+ "indexmap 2.0.2",
+ "log",
+ "memchr",
+ "once_cell",
+ "paste",
+ "percent-encoding",
+ "rustls",
+ "rustls-pemfile",
+ "serde",
+ "serde_json",
+ "sha2",
+ "smallvec 1.11.1",
+ "sqlformat",
+ "thiserror",
+ "time",
+ "tokio",
+ "tokio-stream",
+ "tracing",
+ "url",
+ "uuid 1.4.1",
+ "webpki-roots 0.24.0",
+]
+
+[[package]]
+name = "sqlx-macros"
+version = "0.7.2"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "9a793bb3ba331ec8359c1853bd39eed32cdd7baaf22c35ccf5c92a7e8d1189ec"
+dependencies = [
+ "proc-macro2",
+ "quote",
+ "sqlx-core",
+ "sqlx-macros-core",
+ "syn 1.0.109",
+]
+
+[[package]]
+name = "sqlx-macros-core"
+version = "0.7.2"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "0a4ee1e104e00dedb6aa5ffdd1343107b0a4702e862a84320ee7cc74782d96fc"
+dependencies = [
+ "dotenvy",
+ "either",
+ "heck",
+ "hex",
+ "once_cell",
+ "proc-macro2",
+ "quote",
+ "serde",
+ "serde_json",
+ "sha2",
+ "sqlx-core",
+ "sqlx-mysql",
+ "sqlx-postgres",
+ "sqlx-sqlite",
+ "syn 1.0.109",
+ "tempfile",
+ "tokio",
+ "url",
+]
+
+[[package]]
+name = "sqlx-mysql"
+version = "0.7.2"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "864b869fdf56263f4c95c45483191ea0af340f9f3e3e7b4d57a61c7c87a970db"
+dependencies = [
+ "atoi",
+ "base64 0.21.4",
+ "bitflags 2.4.0",
+ "byteorder",
+ "bytes",
+ "chrono",
+ "crc",
+ "digest 0.10.7",
+ "dotenvy",
+ "either",
+ "futures-channel",
+ "futures-core",
+ "futures-io",
+ "futures-util",
+ "generic-array",
+ "hex",
+ "hkdf",
+ "hmac",
+ "itoa",
+ "log",
+ "md-5",
+ "memchr",
+ "once_cell",
+ "percent-encoding",
+ "rand",
+ "rsa",
+ "serde",
+ "sha1",
+ "sha2",
+ "smallvec 1.11.1",
+ "sqlx-core",
+ "stringprep",
+ "thiserror",
+ "time",
+ "tracing",
+ "uuid 1.4.1",
+ "whoami",
+]
+
+[[package]]
+name = "sqlx-postgres"
+version = "0.7.2"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "eb7ae0e6a97fb3ba33b23ac2671a5ce6e3cabe003f451abd5a56e7951d975624"
+dependencies = [
+ "atoi",
+ "base64 0.21.4",
+ "bitflags 2.4.0",
+ "byteorder",
+ "chrono",
+ "crc",
+ "dotenvy",
+ "etcetera",
+ "futures-channel",
+ "futures-core",
+ "futures-io",
+ "futures-util",
+ "hex",
+ "hkdf",
+ "hmac",
+ "home",
+ "itoa",
+ "log",
+ "md-5",
+ "memchr",
+ "once_cell",
+ "rand",
+ "serde",
+ "serde_json",
+ "sha1",
+ "sha2",
+ "smallvec 1.11.1",
+ "sqlx-core",
+ "stringprep",
+ "thiserror",
+ "time",
+ "tracing",
+ "uuid 1.4.1",
+ "whoami",
+]
+
+[[package]]
+name = "sqlx-sqlite"
+version = "0.7.2"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "d59dc83cf45d89c555a577694534fcd1b55c545a816c816ce51f20bbe56a4f3f"
+dependencies = [
+ "atoi",
+ "chrono",
+ "flume",
+ "futures-channel",
+ "futures-core",
+ "futures-executor",
+ "futures-intrusive",
+ "futures-util",
+ "libsqlite3-sys",
+ "log",
+ "percent-encoding",
+ "serde",
+ "sqlx-core",
+ "time",
+ "tracing",
+ "url",
+ "uuid 1.4.1",
+]
+
+[[package]]
+name = "stable-pattern"
+version = "0.1.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "4564168c00635f88eaed410d5efa8131afa8d8699a612c80c455a0ba05c21045"
+dependencies = [
+ "memchr",
+]
+
+[[package]]
+name = "state"
+version = "0.6.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "2b8c4a4445d81357df8b1a650d0d0d6fbbbfe99d064aa5e02f3e4022061476d8"
+dependencies = [
+ "loom",
+]
+
+[[package]]
+name = "static_assertions"
+version = "1.1.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "a2eb9349b6444b326872e140eb1cf5e7c522154d69e7a0ffb0fb81c06b37543f"
+
+[[package]]
+name = "stringprep"
+version = "0.1.4"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "bb41d74e231a107a1b4ee36bd1214b11285b77768d2e3824aedafa988fd36ee6"
+dependencies = [
+ "finl_unicode",
+ "unicode-bidi",
+ "unicode-normalization",
+]
+
+[[package]]
+name = "strsim"
+version = "0.10.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "73473c0e59e6d5812c5dfe2a064a6444949f089e20eec9a2e5506596494e4623"
+
+[[package]]
+name = "subtle"
+version = "2.5.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "81cdd64d312baedb58e21336b31bc043b77e01cc99033ce76ef539f78e965ebc"
+
+[[package]]
+name = "syn"
+version = "1.0.109"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "72b64191b275b66ffe2469e8af2c1cfe3bafa67b529ead792a6d0160888b4237"
+dependencies = [
+ "proc-macro2",
+ "quote",
+ "unicode-ident",
+]
+
+[[package]]
+name = "syn"
+version = "2.0.60"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "909518bc7b1c9b779f1bbf07f2929d35af9f0f37e47c6e9ef7f9dddc1e1821f3"
+dependencies = [
+ "proc-macro2",
+ "quote",
+ "unicode-ident",
+]
+
+[[package]]
+name = "system-configuration"
+version = "0.5.1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "ba3a3adc5c275d719af8cb4272ea1c4a6d668a777f37e115f6d11ddbc1c8e0e7"
+dependencies = [
+ "bitflags 1.3.2",
+ "core-foundation",
+ "system-configuration-sys",
+]
+
+[[package]]
+name = "system-configuration-sys"
+version = "0.5.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "a75fb188eb626b924683e3b95e3a48e63551fcfb51949de2f06a9d91dbee93c9"
+dependencies = [
+ "core-foundation-sys",
+ "libc",
+]
+
+[[package]]
+name = "tempfile"
+version = "3.8.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "cb94d2f3cc536af71caac6b6fcebf65860b347e7ce0cc9ebe8f70d3e521054ef"
+dependencies = [
+ "cfg-if",
+ "fastrand",
+ "redox_syscall",
+ "rustix",
+ "windows-sys",
+]
+
+[[package]]
+name = "textwrap"
+version = "0.16.1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "23d434d3f8967a09480fb04132ebe0a3e088c173e6d0ee7897abbdf4eab0f8b9"
+dependencies = [
+ "smawk",
+ "unicode-linebreak",
+ "unicode-width",
+]
+
+[[package]]
+name = "thiserror"
+version = "1.0.59"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "f0126ad08bff79f29fc3ae6a55cc72352056dfff61e3ff8bb7129476d44b23aa"
+dependencies = [
+ "thiserror-impl",
+]
+
+[[package]]
+name = "thiserror-impl"
+version = "1.0.59"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "d1cd413b5d558b4c5bf3680e324a6fa5014e7b7c067a51e69dbdf47eb7148b66"
+dependencies = [
+ "proc-macro2",
+ "quote",
+ "syn 2.0.60",
+]
+
+[[package]]
+name = "thread_local"
+version = "1.1.7"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "3fdd6f064ccff2d6567adcb3873ca630700f00b5ad3f060c25b5dcfd9a4ce152"
+dependencies = [
+ "cfg-if",
+ "once_cell",
+]
+
+[[package]]
+name = "time"
+version = "0.3.29"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "426f806f4089c493dcac0d24c29c01e2c38baf8e30f1b716ee37e83d200b18fe"
+dependencies = [
+ "deranged",
+ "itoa",
+ "serde",
+ "time-core",
+ "time-macros",
+]
+
+[[package]]
+name = "time-core"
+version = "0.1.2"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "ef927ca75afb808a4d64dd374f00a2adf8d0fcff8e7b184af886c3c87ec4a3f3"
+
+[[package]]
+name = "time-macros"
+version = "0.2.15"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "4ad70d68dba9e1f8aceda7aa6711965dfec1cac869f311a51bd08b3a2ccbce20"
+dependencies = [
+ "time-core",
+]
+
+[[package]]
+name = "token-server"
+version = "0.1.0"
+dependencies = [
+ "config",
+ "hex",
+ "rand",
+ "reqwest",
+ "rocket",
+ "schemars",
+ "serde",
+ "serde_json",
+ "sqlx",
+ "uuid 1.4.1",
+]
+
+[[package]]
+name = "tokio"
+version = "1.33.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "4f38200e3ef7995e5ef13baec2f432a6da0aa9ac495b2c0e8f3b7eec2c92d653"
+dependencies = [
+ "backtrace",
+ "bytes",
+ "libc",
+ "mio",
+ "num_cpus",
+ "parking_lot",
+ "pin-project-lite",
+ "signal-hook-registry",
+ "socket2 0.5.4",
+ "tokio-macros",
+ "windows-sys",
+]
+
+[[package]]
+name = "tokio-macros"
+version = "2.1.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "630bdcf245f78637c13ec01ffae6187cca34625e8c63150d424b59e55af2675e"
+dependencies = [
+ "proc-macro2",
+ "quote",
+ "syn 2.0.60",
+]
+
+[[package]]
+name = "tokio-native-tls"
+version = "0.3.1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "bbae76ab933c85776efabc971569dd6119c580d8f5d448769dec1764bf796ef2"
+dependencies = [
+ "native-tls",
+ "tokio",
+]
+
+[[package]]
+name = "tokio-socks"
+version = "0.5.1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "51165dfa029d2a65969413a6cc96f354b86b464498702f174a4efa13608fd8c0"
+dependencies = [
+ "either",
+ "futures-util",
+ "thiserror",
+ "tokio",
+]
+
+[[package]]
+name = "tokio-stream"
+version = "0.1.14"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "397c988d37662c7dda6d2208364a706264bf3d6138b11d436cbac0ad38832842"
+dependencies = [
+ "futures-core",
+ "pin-project-lite",
+ "tokio",
+]
+
+[[package]]
+name = "tokio-util"
+version = "0.7.9"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "1d68074620f57a0b21594d9735eb2e98ab38b17f80d3fcb189fca266771ca60d"
+dependencies = [
+ "bytes",
+ "futures-core",
+ "futures-sink",
+ "pin-project-lite",
+ "tokio",
+ "tracing",
+]
+
+[[package]]
+name = "toml"
+version = "0.5.11"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "f4f7f0dd8d50a853a531c426359045b1998f04219d88799810762cd4ad314234"
+dependencies = [
+ "serde",
+]
+
+[[package]]
+name = "toml"
+version = "0.8.2"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "185d8ab0dfbb35cf1399a6344d8484209c088f75f8f68230da55d48d95d43e3d"
+dependencies = [
+ "serde",
+ "serde_spanned",
+ "toml_datetime",
+ "toml_edit",
+]
+
+[[package]]
+name = "toml_datetime"
+version = "0.6.3"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "7cda73e2f1397b1262d6dfdcef8aafae14d1de7748d66822d3bfeeb6d03e5e4b"
+dependencies = [
+ "serde",
+]
+
+[[package]]
+name = "toml_edit"
+version = "0.20.2"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "396e4d48bbb2b7554c944bde63101b5ae446cff6ec4a24227428f15eb72ef338"
+dependencies = [
+ "indexmap 2.0.2",
+ "serde",
+ "serde_spanned",
+ "toml_datetime",
+ "winnow",
+]
+
+[[package]]
+name = "tower-service"
+version = "0.3.2"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "b6bc1c9ce2b5135ac7f93c72918fc37feb872bdc6a5533a8b85eb4b86bfdae52"
+
+[[package]]
+name = "tracing"
+version = "0.1.37"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "8ce8c33a8d48bd45d624a6e523445fd21ec13d3653cd51f681abf67418f54eb8"
+dependencies = [
+ "cfg-if",
+ "log",
+ "pin-project-lite",
+ "tracing-attributes",
+ "tracing-core",
+]
+
+[[package]]
+name = "tracing-attributes"
+version = "0.1.26"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "5f4f31f56159e98206da9efd823404b79b6ef3143b4a7ab76e67b1751b25a4ab"
+dependencies = [
+ "proc-macro2",
+ "quote",
+ "syn 2.0.60",
+]
+
+[[package]]
+name = "tracing-core"
+version = "0.1.31"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "0955b8137a1df6f1a2e9a37d8a6656291ff0297c1a97c24e0d8425fe2312f79a"
+dependencies = [
+ "once_cell",
+ "valuable",
+]
+
+[[package]]
+name = "tracing-log"
+version = "0.1.3"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "78ddad33d2d10b1ed7eb9d1f518a5674713876e97e5bb9b7345a7984fbb4f922"
+dependencies = [
+ "lazy_static",
+ "log",
+ "tracing-core",
+]
+
+[[package]]
+name = "tracing-subscriber"
+version = "0.3.17"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "30a651bc37f915e81f087d86e62a18eec5f79550c7faff886f7090b4ea757c77"
+dependencies = [
+ "matchers",
+ "nu-ansi-term",
+ "once_cell",
+ "regex",
+ "sharded-slab",
+ "smallvec 1.11.1",
+ "thread_local",
+ "tracing",
+ "tracing-core",
+ "tracing-log",
+]
+
+[[package]]
+name = "try-lock"
+version = "0.2.4"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "3528ecfd12c466c6f163363caf2d02a71161dd5e1cc6ae7b34207ea2d42d81ed"
+
+[[package]]
+name = "typenum"
+version = "1.17.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "42ff0bf0c66b8238c6f3b578df37d0b7848e55df8577b3f74f92a69acceeb825"
+
+[[package]]
+name = "ubyte"
+version = "0.10.4"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "f720def6ce1ee2fc44d40ac9ed6d3a59c361c80a75a7aa8e75bb9baed31cf2ea"
+dependencies = [
+ "serde",
+]
+
+[[package]]
+name = "ucd-trie"
+version = "0.1.6"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "ed646292ffc8188ef8ea4d1e0e0150fb15a5c2e12ad9b8fc191ae7a8a7f3c4b9"
+
+[[package]]
+name = "uncased"
+version = "0.9.9"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "9b9bc53168a4be7402ab86c3aad243a84dd7381d09be0eddc81280c1da95ca68"
+dependencies = [
+ "serde",
+ "version_check",
+]
+
+[[package]]
+name = "unicase"
+version = "2.7.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "f7d2d4dafb69621809a81864c9c1b864479e1235c0dd4e199924b9742439ed89"
+dependencies = [
+ "version_check",
+]
+
+[[package]]
+name = "unicode-bidi"
+version = "0.3.13"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "92888ba5573ff080736b3648696b70cafad7d250551175acbaa4e0385b3e1460"
+
+[[package]]
+name = "unicode-ident"
+version = "1.0.12"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "3354b9ac3fae1ff6755cb6db53683adb661634f67557942dea4facebec0fee4b"
+
+[[package]]
+name = "unicode-linebreak"
+version = "0.1.5"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "3b09c83c3c29d37506a3e260c08c03743a6bb66a9cd432c6934ab501a190571f"
+
+[[package]]
+name = "unicode-normalization"
+version = "0.1.9"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "09c8070a9942f5e7cfccd93f490fdebd230ee3c3c9f107cb25bad5351ef671cf"
+dependencies = [
+ "smallvec 0.6.14",
+]
+
+[[package]]
+name = "unicode-segmentation"
+version = "1.10.1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "1dd624098567895118886609431a7c3b8f516e41d30e0643f03d94592a147e36"
+
+[[package]]
+name = "unicode-width"
+version = "0.1.12"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "68f5e5f3158ecfd4b8ff6fe086db7c8467a2dfdac97fe420f2b7c4aa97af66d6"
+
+[[package]]
+name = "unicode-xid"
+version = "0.2.4"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "f962df74c8c05a667b5ee8bcf162993134c104e96440b663c8daa176dc772d8c"
+
+[[package]]
+name = "unicode_categories"
+version = "0.1.1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "39ec24b3121d976906ece63c9daad25b85969647682eee313cb5779fdd69e14e"
+
+[[package]]
+name = "uniffi"
+version = "0.27.1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "a5566fae48a5cb017005bf9cd622af5236b2a203a13fb548afde3506d3c68277"
+dependencies = [
+ "anyhow",
+ "camino",
+ "clap",
+ "uniffi_bindgen",
+ "uniffi_core",
+ "uniffi_macros",
+]
+
+[[package]]
+name = "uniffi_bindgen"
+version = "0.27.1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "4a77bb514bcd4bf27c9bd404d7c3f2a6a8131b957eba9c22cfeb7751c4278e09"
+dependencies = [
+ "anyhow",
+ "askama",
+ "camino",
+ "cargo_metadata",
+ "clap",
+ "fs-err",
+ "glob",
+ "goblin",
+ "heck",
+ "once_cell",
+ "paste",
+ "serde",
+ "textwrap",
+ "toml 0.5.11",
+ "uniffi_meta",
+ "uniffi_testing",
+ "uniffi_udl",
+]
+
+[[package]]
+name = "uniffi_checksum_derive"
+version = "0.27.1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "ae7e5a6c33b1dec3f255f57ec0b6af0f0b2bb3021868be1d5eec7a38e2905ebc"
+dependencies = [
+ "quote",
+ "syn 2.0.60",
+]
+
+[[package]]
+name = "uniffi_core"
+version = "0.27.1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "0ea3eb5474d50fc149b7e4d86b9c5bd4a61dcc167f0683902bf18ae7bbb3deef"
+dependencies = [
+ "anyhow",
+ "bytes",
+ "camino",
+ "log",
+ "once_cell",
+ "oneshot-uniffi",
+ "paste",
+ "static_assertions",
+]
+
+[[package]]
+name = "uniffi_macros"
+version = "0.27.1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "18331d35003f46f0d04047fbe4227291815b83a937a8c32bc057f990962182c4"
+dependencies = [
+ "bincode",
+ "camino",
+ "fs-err",
+ "once_cell",
+ "proc-macro2",
+ "quote",
+ "serde",
+ "syn 2.0.60",
+ "toml 0.5.11",
+ "uniffi_meta",
+]
+
+[[package]]
+name = "uniffi_meta"
+version = "0.27.1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "f7224422c4cfd181c7ca9fca2154abca4d21db962f926f270f996edd38b0c4b8"
+dependencies = [
+ "anyhow",
+ "bytes",
+ "siphasher",
+ "uniffi_checksum_derive",
+]
+
+[[package]]
+name = "uniffi_testing"
+version = "0.27.1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "f8ce878d0bdfc288b58797044eaaedf748526c56eef3575380bb4d4b19d69eee"
+dependencies = [
+ "anyhow",
+ "camino",
+ "cargo_metadata",
+ "fs-err",
+ "once_cell",
+]
+
+[[package]]
+name = "uniffi_udl"
+version = "0.27.1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "8c43c9ed40a8d20a5c3eae2d23031092db6b96dc8e571beb449ba9757484cea0"
+dependencies = [
+ "anyhow",
+ "textwrap",
+ "uniffi_meta",
+ "uniffi_testing",
+ "weedle2",
+]
+
+[[package]]
+name = "universal-hash"
+version = "0.5.1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "fc1de2c688dc15305988b563c3854064043356019f97a4b46276fe734c4f07ea"
+dependencies = [
+ "crypto-common",
+ "subtle",
+]
+
+[[package]]
+name = "untrusted"
+version = "0.7.1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "a156c684c91ea7d62626509bce3cb4e1d9ed5c4d978f7b4352658f96a4c26b4a"
+
+[[package]]
+name = "untrusted"
+version = "0.9.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "8ecb6da28b8a351d773b68d5825ac39017e680750f980f3a1a85cd8dd28a47c1"
+
+[[package]]
+name = "url"
+version = "2.3.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "22fe195a4f217c25b25cb5058ced57059824a678474874038dc88d211bf508d3"
+dependencies = [
+ "form_urlencoded",
+ "idna",
+ "percent-encoding",
+]
+
+[[package]]
+name = "utf8parse"
+version = "0.2.1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "711b9620af191e0cdc7468a8d14e709c3dcdb115b36f838e601583af800a370a"
+
+[[package]]
+name = "uuid"
+version = "0.8.2"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "bc5cf98d8186244414c848017f0e2676b3fcb46807f6668a97dfe67359a3c4b7"
+
+[[package]]
+name = "uuid"
+version = "1.4.1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "79daa5ed5740825c40b389c5e50312b9c86df53fccd33f281df655642b43869d"
+dependencies = [
+ "getrandom",
+ "serde",
+]
+
+[[package]]
+name = "valuable"
+version = "0.1.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "830b7e5d4d90034032940e4ace0d9a9a057e7a45cd94e6c007832e39edb82f6d"
+
+[[package]]
+name = "vcpkg"
+version = "0.2.15"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "accd4ea62f7bb7a82fe23066fb0957d48ef677f6eeb8215f372f52e48bb32426"
+
+[[package]]
+name = "version_check"
+version = "0.9.4"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "49874b5167b65d7193b8aba1567f5c7d93d001cafc34600cee003eda787e483f"
+
+[[package]]
+name = "want"
+version = "0.3.1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "bfa7760aed19e106de2c7c0b581b509f2f25d3dacaf737cb82ac61bc6d760b0e"
+dependencies = [
+ "try-lock",
+]
+
+[[package]]
+name = "wasi"
+version = "0.11.0+wasi-snapshot-preview1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "9c8d87e72b64a3b4db28d11ce29237c246188f4f51057d65a7eab63b7987e423"
+
+[[package]]
+name = "wasm-bindgen"
+version = "0.2.92"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "4be2531df63900aeb2bca0daaaddec08491ee64ceecbee5076636a3b026795a8"
+dependencies = [
+ "cfg-if",
+ "wasm-bindgen-macro",
+]
+
+[[package]]
+name = "wasm-bindgen-backend"
+version = "0.2.92"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "614d787b966d3989fa7bb98a654e369c762374fd3213d212cfc0251257e747da"
+dependencies = [
+ "bumpalo",
+ "log",
+ "once_cell",
+ "proc-macro2",
+ "quote",
+ "syn 2.0.60",
+ "wasm-bindgen-shared",
+]
+
+[[package]]
+name = "wasm-bindgen-futures"
+version = "0.4.37"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "c02dbc21516f9f1f04f187958890d7e6026df8d16540b7ad9492bc34a67cea03"
+dependencies = [
+ "cfg-if",
+ "js-sys",
+ "wasm-bindgen",
+ "web-sys",
+]
+
+[[package]]
+name = "wasm-bindgen-macro"
+version = "0.2.92"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "a1f8823de937b71b9460c0c34e25f3da88250760bec0ebac694b49997550d726"
+dependencies = [
+ "quote",
+ "wasm-bindgen-macro-support",
+]
+
+[[package]]
+name = "wasm-bindgen-macro-support"
+version = "0.2.92"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "e94f17b526d0a461a191c78ea52bbce64071ed5c04c9ffe424dcb38f74171bb7"
+dependencies = [
+ "proc-macro2",
+ "quote",
+ "syn 2.0.60",
+ "wasm-bindgen-backend",
+ "wasm-bindgen-shared",
+]
+
+[[package]]
+name = "wasm-bindgen-shared"
+version = "0.2.92"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "af190c94f2773fdb3729c55b007a722abb5384da03bc0986df4c289bf5567e96"
+
+[[package]]
+name = "wasm-bindgen-test"
+version = "0.3.37"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "6e6e302a7ea94f83a6d09e78e7dc7d9ca7b186bc2829c24a22d0753efd680671"
+dependencies = [
+ "console_error_panic_hook",
+ "js-sys",
+ "scoped-tls",
+ "wasm-bindgen",
+ "wasm-bindgen-futures",
+ "wasm-bindgen-test-macro",
+]
+
+[[package]]
+name = "wasm-bindgen-test-macro"
+version = "0.3.37"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "ecb993dd8c836930ed130e020e77d9b2e65dd0fbab1b67c790b0f5d80b11a575"
+dependencies = [
+ "proc-macro2",
+ "quote",
+]
+
+[[package]]
+name = "web-sys"
+version = "0.3.64"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "9b85cbef8c220a6abc02aefd892dfc0fc23afb1c6a426316ec33253a3877249b"
+dependencies = [
+ "js-sys",
+ "wasm-bindgen",
+]
+
+[[package]]
+name = "webpki"
+version = "0.22.4"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "ed63aea5ce73d0ff405984102c42de94fc55a6b75765d621c65262469b3c9b53"
+dependencies = [
+ "ring 0.17.3",
+ "untrusted 0.9.0",
+]
+
+[[package]]
+name = "webpki-roots"
+version = "0.22.6"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "b6c71e40d7d2c34a5106301fb632274ca37242cd0c9d3e64dbece371a40a2d87"
+dependencies = [
+ "webpki",
+]
+
+[[package]]
+name = "webpki-roots"
+version = "0.24.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "b291546d5d9d1eab74f069c77749f2cb8504a12caa20f0f2de93ddbf6f411888"
+dependencies = [
+ "rustls-webpki",
+]
+
+[[package]]
+name = "weedle2"
+version = "5.0.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "998d2c24ec099a87daf9467808859f9d82b61f1d9c9701251aea037f514eae0e"
+dependencies = [
+ "nom",
+]
+
+[[package]]
+name = "whoami"
+version = "1.4.1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "22fc3756b8a9133049b26c7f61ab35416c130e8c09b660f5b3958b446f52cc50"
+
+[[package]]
+name = "winapi"
+version = "0.3.9"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "5c839a674fcd7a98952e593242ea400abe93992746761e38641405d28b00f419"
+dependencies = [
+ "winapi-i686-pc-windows-gnu",
+ "winapi-x86_64-pc-windows-gnu",
+]
+
+[[package]]
+name = "winapi-i686-pc-windows-gnu"
+version = "0.4.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "ac3b87c63620426dd9b991e5ce0329eff545bccbbb34f3be09ff6fb6ab51b7b6"
+
+[[package]]
+name = "winapi-x86_64-pc-windows-gnu"
+version = "0.4.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "712e227841d057c1ee1cd2fb22fa7e5a5461ae8e48fa2ca79ec42cfc1931183f"
+
+[[package]]
+name = "windows"
+version = "0.48.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "e686886bc078bc1b0b600cac0147aadb815089b6e4da64016cbd754b6342700f"
+dependencies = [
+ "windows-targets",
+]
+
+[[package]]
+name = "windows-core"
+version = "0.51.1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "f1f8cf84f35d2db49a46868f947758c7a1138116f7fac3bc844f43ade1292e64"
+dependencies = [
+ "windows-targets",
+]
+
+[[package]]
+name = "windows-sys"
+version = "0.48.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "677d2418bec65e3338edb076e806bc1ec15693c5d0104683f2efe857f61056a9"
+dependencies = [
+ "windows-targets",
+]
+
+[[package]]
+name = "windows-targets"
+version = "0.48.5"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "9a2fa6e2155d7247be68c096456083145c183cbbbc2764150dda45a87197940c"
+dependencies = [
+ "windows_aarch64_gnullvm",
+ "windows_aarch64_msvc",
+ "windows_i686_gnu",
+ "windows_i686_msvc",
+ "windows_x86_64_gnu",
+ "windows_x86_64_gnullvm",
+ "windows_x86_64_msvc",
+]
+
+[[package]]
+name = "windows_aarch64_gnullvm"
+version = "0.48.5"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "2b38e32f0abccf9987a4e3079dfb67dcd799fb61361e53e2882c3cbaf0d905d8"
+
+[[package]]
+name = "windows_aarch64_msvc"
+version = "0.48.5"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "dc35310971f3b2dbbf3f0690a219f40e2d9afcf64f9ab7cc1be722937c26b4bc"
+
+[[package]]
+name = "windows_i686_gnu"
+version = "0.48.5"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "a75915e7def60c94dcef72200b9a8e58e5091744960da64ec734a6c6e9b3743e"
+
+[[package]]
+name = "windows_i686_msvc"
+version = "0.48.5"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "8f55c233f70c4b27f66c523580f78f1004e8b5a8b659e05a4eb49d4166cca406"
+
+[[package]]
+name = "windows_x86_64_gnu"
+version = "0.48.5"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "53d40abd2583d23e4718fddf1ebec84dbff8381c07cae67ff7768bbf19c6718e"
+
+[[package]]
+name = "windows_x86_64_gnullvm"
+version = "0.48.5"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "0b7b52767868a23d5bab768e390dc5f5c55825b6d30b86c844ff2dc7414044cc"
+
+[[package]]
+name = "windows_x86_64_msvc"
+version = "0.48.5"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "ed94fce61571a4006852b7389a063ab983c02eb1bb37b47f8272ce92d06d9538"
+
+[[package]]
+name = "winnow"
+version = "0.5.16"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "037711d82167854aff2018dfd193aa0fef5370f456732f0d5a0c59b0f1b4b907"
+dependencies = [
+ "memchr",
+]
+
+[[package]]
+name = "winreg"
+version = "0.50.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "524e57b2c537c0f9b1e69f1965311ec12182b4122e45035b1508cd24d2adadb1"
+dependencies = [
+ "cfg-if",
+ "windows-sys",
+]
+
+[[package]]
+name = "yaml-rust"
+version = "0.4.5"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "56c1936c4cc7a1c9ab21a1ebb602eb942ba868cbd44a99cb7cdc5892335e1c85"
+dependencies = [
+ "linked-hash-map",
+]
+
+[[package]]
+name = "yansi"
+version = "1.0.0-rc.1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "1367295b8f788d371ce2dbc842c7b709c73ee1364d30351dd300ec2203b12377"
+dependencies = [
+ "is-terminal",
+]
+
+[[package]]
+name = "zeroize"
+version = "1.6.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "2a0956f1ba7c7909bfb66c2e9e4124ab6f6482560f6628b5aaeba39207c9aad9"
diff --git a/Cargo.toml b/Cargo.toml
new file mode 100644
index 00000000..5f7d46e9
--- /dev/null
+++ b/Cargo.toml
@@ -0,0 +1,4 @@
+[workspace]
+members = ["clients/apps/rust", "clients/libs/rust", "server", "wasm", "lib", "token-server", "clients/tests/rust"]
+exclude = ["clients/apps/kotlin", "clients/apps/nodejs", "clients/apps/react-app", "clients/libs/nodejs", "docs", "enclave", "explorer", "keylistCron"]
+resolver = "2"
diff --git a/Rocket.toml b/Rocket.toml
new file mode 100644
index 00000000..dea7ede3
--- /dev/null
+++ b/Rocket.toml
@@ -0,0 +1,3 @@
+[global]
+address = "0.0.0.0"
+port = 8000
\ No newline at end of file
diff --git a/Usage.md b/Usage.md
new file mode 100644
index 00000000..bd8762fc
--- /dev/null
+++ b/Usage.md
@@ -0,0 +1,38 @@
+# Usage
+
+## Simulation mode
+
+### Bulid and run docker containers
+
+```bash
+$ cd mercurylayer
+$ docker compose -f docker-compose-sim.yml up --build
+```
+### Add mmnemonics
+
+```bash
+$ docker exec -it mercurylayer-enclave-sgx-1 bash
+$ curl -X POST http://0.0.0.0:18080/add_mnemonic \
+-H "Content-Type: application/json" \
+-d '{
+ "mnemonic": "achieve merry hidden lyrics element brand student armed dismiss vague fury avocado grief crazy garlic gallery blur spider bag bless motor crawl surround copper",
+ "password": "b1gHKyfXTzs6",
+ "index": 0,
+ "threshold": 2
+}'
+```
+
+## Hardware Mode
+
+```bash
+$ cd mercurylayer
+$ ./build_compose_hw_run.sh
+```
+
+Add mnemonics in the same way as above.
+
+## Compose down
+
+`docker compose -f docker-compose-sim.yml down -v` in simulation mode
+
+`docker compose -f docker-compose-hw.yml down -v` in hardware mode
diff --git a/build_compose_hw_run.sh b/build_compose_hw_run.sh
new file mode 100755
index 00000000..ad45db12
--- /dev/null
+++ b/build_compose_hw_run.sh
@@ -0,0 +1,5 @@
+set -e
+
+docker volume create --driver local --opt type=tmpfs --opt device=tmpfs --opt o=rw aesmd-socket
+
+docker compose -f docker-compose-hw.yml up --build
diff --git a/client/README.md b/client/README.md
deleted file mode 100644
index bca84705..00000000
--- a/client/README.md
+++ /dev/null
@@ -1,3 +0,0 @@
-# Mercury Layer Client
-
-Mercury layer client provides a user interface to the Mercury Layer protocol, via the Mercury Layer server.
diff --git a/clients/apps/kotlin/.gitignore b/clients/apps/kotlin/.gitignore
new file mode 100644
index 00000000..d02394dd
--- /dev/null
+++ b/clients/apps/kotlin/.gitignore
@@ -0,0 +1,44 @@
+.gradle
+build/
+!gradle/wrapper/gradle-wrapper.jar
+!**/src/main/**/build/
+!**/src/test/**/build/
+
+### IntelliJ IDEA ###
+.idea/modules.xml
+.idea/jarRepositories.xml
+.idea/compiler.xml
+.idea/libraries/
+*.iws
+*.iml
+*.ipr
+out/
+!**/src/main/**/out/
+!**/src/test/**/out/
+
+### Eclipse ###
+.apt_generated
+.classpath
+.factorypath
+.project
+.settings
+.springBeans
+.sts4-cache
+bin/
+!**/src/main/**/bin/
+!**/src/test/**/bin/
+
+### NetBeans ###
+/nbproject/private/
+/nbbuild/
+/dist/
+/nbdist/
+/.nb-gradle/
+
+### VS Code ###
+.vscode/
+
+### Mac OS ###
+.DS_Store
+
+wallet.db
\ No newline at end of file
diff --git a/clients/apps/kotlin/.idea/.gitignore b/clients/apps/kotlin/.idea/.gitignore
new file mode 100644
index 00000000..26d33521
--- /dev/null
+++ b/clients/apps/kotlin/.idea/.gitignore
@@ -0,0 +1,3 @@
+# Default ignored files
+/shelf/
+/workspace.xml
diff --git a/clients/apps/kotlin/.idea/.name b/clients/apps/kotlin/.idea/.name
new file mode 100644
index 00000000..d606037c
--- /dev/null
+++ b/clients/apps/kotlin/.idea/.name
@@ -0,0 +1 @@
+test2
\ No newline at end of file
diff --git a/clients/apps/kotlin/.idea/gradle.xml b/clients/apps/kotlin/.idea/gradle.xml
new file mode 100644
index 00000000..2a65317e
--- /dev/null
+++ b/clients/apps/kotlin/.idea/gradle.xml
@@ -0,0 +1,17 @@
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/clients/apps/kotlin/.idea/kotlinc.xml b/clients/apps/kotlin/.idea/kotlinc.xml
new file mode 100644
index 00000000..fe63bb67
--- /dev/null
+++ b/clients/apps/kotlin/.idea/kotlinc.xml
@@ -0,0 +1,6 @@
+
+
+
+
+
+
\ No newline at end of file
diff --git a/clients/apps/kotlin/.idea/misc.xml b/clients/apps/kotlin/.idea/misc.xml
new file mode 100644
index 00000000..85d2fc04
--- /dev/null
+++ b/clients/apps/kotlin/.idea/misc.xml
@@ -0,0 +1,7 @@
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/clients/apps/kotlin/.idea/vcs.xml b/clients/apps/kotlin/.idea/vcs.xml
new file mode 100644
index 00000000..def3818f
--- /dev/null
+++ b/clients/apps/kotlin/.idea/vcs.xml
@@ -0,0 +1,7 @@
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/clients/apps/kotlin/README.md b/clients/apps/kotlin/README.md
new file mode 100644
index 00000000..500ddfae
--- /dev/null
+++ b/clients/apps/kotlin/README.md
@@ -0,0 +1,49 @@
+# Mercury Layer CL Kotlin client
+
+## Command-line arguments:
+
+### Create Wallet
+`create-wallet `
+
+Example: `create-wallet w1`
+
+### New Deposit Address
+`new-deposit-address `
+
+Example: `new-deposit-address w1 1000`
+
+### List Statecoins
+
+`list-statecoins `
+
+Example: `list-statecoins w1`
+
+### New Statechain Adress
+
+`new-transfer-address `
+
+Example: `new-transfer-address w2`
+
+### Send a Statecoin
+
+`new-transfer-address `
+
+Example: `transfer-send w1 2dd78ce438a1450083996fa7f37a02d0 tml1qqp3sp8pu0v38d9krdekckuy4qnueqtnlq8radjwf5rvvgkdnm4y03szgljuxjweppkyymh44wr034avmut5w83xcaey83pp7nqqxqcnyldsa3jpyr`
+
+### Receive a Statecoin
+
+`transfer-receive `
+
+Example: `transfer-receive w2`
+
+### Withdraw a Statecoin to a Bitcoin Address
+
+`withdraw `
+
+Example: `withdraw w1 453351464f6a4b0ab8401826576c69be tb1qw2hfzv5qzxtmzatjxn5600k9yqnhhddeu6npu5`
+
+### Broadcast Basckup Transaction to a Bitcoin Address
+
+`broadcast-backup-transaction `
+
+Example: `broadcast-backup-transaction w1 e82e423298ca4c7bb7e37771b4dc3e8a tb1qw2hfzv5qzxtmzatjxn5600k9yqnhhddeu6npu5`
\ No newline at end of file
diff --git a/clients/apps/kotlin/Settings.toml b/clients/apps/kotlin/Settings.toml
new file mode 100644
index 00000000..ae064d0d
--- /dev/null
+++ b/clients/apps/kotlin/Settings.toml
@@ -0,0 +1,11 @@
+statechain_entity = "http://127.0.0.1:8000"
+#statechain_entity = "http://j23wevaeducxuy3zahd6bpn4x76cymwz2j3bdixv7ow4awjrg5p6jaid.onion"
+#electrum_server = "tcp://127.0.0.1:50001"
+electrum_server = "tcp://signet-electrumx.wakiyamap.dev:50001"
+electrum_type = "electrs"
+network = "signet"
+fee_rate_tolerance = 5
+database_file="wallet.db"
+confirmation_target = 2
+#tor_proxy = "socks5h://localhost:9050"
+max_fee_rate = 1
\ No newline at end of file
diff --git a/clients/apps/kotlin/build.gradle.kts b/clients/apps/kotlin/build.gradle.kts
new file mode 100644
index 00000000..9db9b58a
--- /dev/null
+++ b/clients/apps/kotlin/build.gradle.kts
@@ -0,0 +1,43 @@
+plugins {
+ kotlin("jvm") version "1.9.23"
+ kotlin("plugin.serialization") version "1.9.23"
+}
+
+group = "org.example"
+version = "1.0-SNAPSHOT"
+
+repositories {
+ google()
+ mavenCentral()
+ maven { url = uri("https://jitpack.io") }
+}
+
+val ktor_version: String by project
+
+dependencies {
+ testImplementation(kotlin("test"))
+ implementation("net.java.dev.jna:jna:5.14.0")
+ implementation("org.jetbrains.kotlinx:kotlinx-serialization-json:1.6.0")
+ implementation("org.jetbrains.kotlinx:kotlinx-coroutines-core:1.6.4")
+ implementation("com.github.ajalt.clikt:clikt:4.4.0")
+ implementation("com.squareup.okio:okio:3.9.0")
+ implementation("com.akuleshov7:ktoml-core:0.5.1")
+ implementation("com.akuleshov7:ktoml-file:0.5.1")
+ implementation("io.ktor:ktor-client-core:$ktor_version")
+ implementation("io.ktor:ktor-client-cio:$ktor_version")
+ implementation("io.ktor:ktor-client-content-negotiation:$ktor_version")
+ implementation("io.ktor:ktor-serialization-kotlinx-json:$ktor_version")
+ implementation("org.slf4j:slf4j-nop:2.1.0-alpha1")
+ implementation("org.slf4j:slf4j-api:2.1.0-alpha1")
+ // implementation("org.bitcoindevkit:bdk-jvm:1.0.0-alpha.9")
+ implementation("com.github.bitcoinj:bitcoinj:release-0.16-SNAPSHOT")
+ implementation("com.github.spindj:electrumj:11eb7ceef7")
+ implementation("org.xerial:sqlite-jdbc:3.45.3.0")
+}
+
+tasks.test {
+ useJUnitPlatform()
+}
+kotlin {
+ jvmToolchain(21)
+}
\ No newline at end of file
diff --git a/clients/apps/kotlin/gradle.properties b/clients/apps/kotlin/gradle.properties
new file mode 100644
index 00000000..8d251a6e
--- /dev/null
+++ b/clients/apps/kotlin/gradle.properties
@@ -0,0 +1,2 @@
+kotlin.code.style=official
+ktor_version=2.3.10
\ No newline at end of file
diff --git a/clients/apps/kotlin/gradle/wrapper/gradle-wrapper.jar b/clients/apps/kotlin/gradle/wrapper/gradle-wrapper.jar
new file mode 100644
index 00000000..249e5832
Binary files /dev/null and b/clients/apps/kotlin/gradle/wrapper/gradle-wrapper.jar differ
diff --git a/clients/apps/kotlin/gradle/wrapper/gradle-wrapper.properties b/clients/apps/kotlin/gradle/wrapper/gradle-wrapper.properties
new file mode 100644
index 00000000..1b17dfed
--- /dev/null
+++ b/clients/apps/kotlin/gradle/wrapper/gradle-wrapper.properties
@@ -0,0 +1,6 @@
+#Sat Apr 27 06:09:37 BRT 2024
+distributionBase=GRADLE_USER_HOME
+distributionPath=wrapper/dists
+distributionUrl=https\://services.gradle.org/distributions/gradle-8.5-bin.zip
+zipStoreBase=GRADLE_USER_HOME
+zipStorePath=wrapper/dists
diff --git a/clients/apps/kotlin/gradlew b/clients/apps/kotlin/gradlew
new file mode 100755
index 00000000..1b6c7873
--- /dev/null
+++ b/clients/apps/kotlin/gradlew
@@ -0,0 +1,234 @@
+#!/bin/sh
+
+#
+# Copyright © 2015-2021 the original authors.
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+# https://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+#
+
+##############################################################################
+#
+# Gradle start up script for POSIX generated by Gradle.
+#
+# Important for running:
+#
+# (1) You need a POSIX-compliant shell to run this script. If your /bin/sh is
+# noncompliant, but you have some other compliant shell such as ksh or
+# bash, then to run this script, type that shell name before the whole
+# command line, like:
+#
+# ksh Gradle
+#
+# Busybox and similar reduced shells will NOT work, because this script
+# requires all of these POSIX shell features:
+# * functions;
+# * expansions «$var», «${var}», «${var:-default}», «${var+SET}»,
+# «${var#prefix}», «${var%suffix}», and «$( cmd )»;
+# * compound commands having a testable exit status, especially «case»;
+# * various built-in commands including «command», «set», and «ulimit».
+#
+# Important for patching:
+#
+# (2) This script targets any POSIX shell, so it avoids extensions provided
+# by Bash, Ksh, etc; in particular arrays are avoided.
+#
+# The "traditional" practice of packing multiple parameters into a
+# space-separated string is a well documented source of bugs and security
+# problems, so this is (mostly) avoided, by progressively accumulating
+# options in "$@", and eventually passing that to Java.
+#
+# Where the inherited environment variables (DEFAULT_JVM_OPTS, JAVA_OPTS,
+# and GRADLE_OPTS) rely on word-splitting, this is performed explicitly;
+# see the in-line comments for details.
+#
+# There are tweaks for specific operating systems such as AIX, CygWin,
+# Darwin, MinGW, and NonStop.
+#
+# (3) This script is generated from the Groovy template
+# https://github.com/gradle/gradle/blob/master/subprojects/plugins/src/main/resources/org/gradle/api/internal/plugins/unixStartScript.txt
+# within the Gradle project.
+#
+# You can find Gradle at https://github.com/gradle/gradle/.
+#
+##############################################################################
+
+# Attempt to set APP_HOME
+
+# Resolve links: $0 may be a link
+app_path=$0
+
+# Need this for daisy-chained symlinks.
+while
+ APP_HOME=${app_path%"${app_path##*/}"} # leaves a trailing /; empty if no leading path
+ [ -h "$app_path" ]
+do
+ ls=$( ls -ld "$app_path" )
+ link=${ls#*' -> '}
+ case $link in #(
+ /*) app_path=$link ;; #(
+ *) app_path=$APP_HOME$link ;;
+ esac
+done
+
+APP_HOME=$( cd "${APP_HOME:-./}" && pwd -P ) || exit
+
+APP_NAME="Gradle"
+APP_BASE_NAME=${0##*/}
+
+# Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.
+DEFAULT_JVM_OPTS='"-Xmx64m" "-Xms64m"'
+
+# Use the maximum available, or set MAX_FD != -1 to use that value.
+MAX_FD=maximum
+
+warn () {
+ echo "$*"
+} >&2
+
+die () {
+ echo
+ echo "$*"
+ echo
+ exit 1
+} >&2
+
+# OS specific support (must be 'true' or 'false').
+cygwin=false
+msys=false
+darwin=false
+nonstop=false
+case "$( uname )" in #(
+ CYGWIN* ) cygwin=true ;; #(
+ Darwin* ) darwin=true ;; #(
+ MSYS* | MINGW* ) msys=true ;; #(
+ NONSTOP* ) nonstop=true ;;
+esac
+
+CLASSPATH=$APP_HOME/gradle/wrapper/gradle-wrapper.jar
+
+
+# Determine the Java command to use to start the JVM.
+if [ -n "$JAVA_HOME" ] ; then
+ if [ -x "$JAVA_HOME/jre/sh/java" ] ; then
+ # IBM's JDK on AIX uses strange locations for the executables
+ JAVACMD=$JAVA_HOME/jre/sh/java
+ else
+ JAVACMD=$JAVA_HOME/bin/java
+ fi
+ if [ ! -x "$JAVACMD" ] ; then
+ die "ERROR: JAVA_HOME is set to an invalid directory: $JAVA_HOME
+
+Please set the JAVA_HOME variable in your environment to match the
+location of your Java installation."
+ fi
+else
+ JAVACMD=java
+ which java >/dev/null 2>&1 || die "ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH.
+
+Please set the JAVA_HOME variable in your environment to match the
+location of your Java installation."
+fi
+
+# Increase the maximum file descriptors if we can.
+if ! "$cygwin" && ! "$darwin" && ! "$nonstop" ; then
+ case $MAX_FD in #(
+ max*)
+ MAX_FD=$( ulimit -H -n ) ||
+ warn "Could not query maximum file descriptor limit"
+ esac
+ case $MAX_FD in #(
+ '' | soft) :;; #(
+ *)
+ ulimit -n "$MAX_FD" ||
+ warn "Could not set maximum file descriptor limit to $MAX_FD"
+ esac
+fi
+
+# Collect all arguments for the java command, stacking in reverse order:
+# * args from the command line
+# * the main class name
+# * -classpath
+# * -D...appname settings
+# * --module-path (only if needed)
+# * DEFAULT_JVM_OPTS, JAVA_OPTS, and GRADLE_OPTS environment variables.
+
+# For Cygwin or MSYS, switch paths to Windows format before running java
+if "$cygwin" || "$msys" ; then
+ APP_HOME=$( cygpath --path --mixed "$APP_HOME" )
+ CLASSPATH=$( cygpath --path --mixed "$CLASSPATH" )
+
+ JAVACMD=$( cygpath --unix "$JAVACMD" )
+
+ # Now convert the arguments - kludge to limit ourselves to /bin/sh
+ for arg do
+ if
+ case $arg in #(
+ -*) false ;; # don't mess with options #(
+ /?*) t=${arg#/} t=/${t%%/*} # looks like a POSIX filepath
+ [ -e "$t" ] ;; #(
+ *) false ;;
+ esac
+ then
+ arg=$( cygpath --path --ignore --mixed "$arg" )
+ fi
+ # Roll the args list around exactly as many times as the number of
+ # args, so each arg winds up back in the position where it started, but
+ # possibly modified.
+ #
+ # NB: a `for` loop captures its iteration list before it begins, so
+ # changing the positional parameters here affects neither the number of
+ # iterations, nor the values presented in `arg`.
+ shift # remove old arg
+ set -- "$@" "$arg" # push replacement arg
+ done
+fi
+
+# Collect all arguments for the java command;
+# * $DEFAULT_JVM_OPTS, $JAVA_OPTS, and $GRADLE_OPTS can contain fragments of
+# shell script including quotes and variable substitutions, so put them in
+# double quotes to make sure that they get re-expanded; and
+# * put everything else in single quotes, so that it's not re-expanded.
+
+set -- \
+ "-Dorg.gradle.appname=$APP_BASE_NAME" \
+ -classpath "$CLASSPATH" \
+ org.gradle.wrapper.GradleWrapperMain \
+ "$@"
+
+# Use "xargs" to parse quoted args.
+#
+# With -n1 it outputs one arg per line, with the quotes and backslashes removed.
+#
+# In Bash we could simply go:
+#
+# readarray ARGS < <( xargs -n1 <<<"$var" ) &&
+# set -- "${ARGS[@]}" "$@"
+#
+# but POSIX shell has neither arrays nor command substitution, so instead we
+# post-process each arg (as a line of input to sed) to backslash-escape any
+# character that might be a shell metacharacter, then use eval to reverse
+# that process (while maintaining the separation between arguments), and wrap
+# the whole thing up as a single "set" statement.
+#
+# This will of course break if any of these variables contains a newline or
+# an unmatched quote.
+#
+
+eval "set -- $(
+ printf '%s\n' "$DEFAULT_JVM_OPTS $JAVA_OPTS $GRADLE_OPTS" |
+ xargs -n1 |
+ sed ' s~[^-[:alnum:]+,./:=@_]~\\&~g; ' |
+ tr '\n' ' '
+ )" '"$@"'
+
+exec "$JAVACMD" "$@"
diff --git a/clients/apps/kotlin/gradlew.bat b/clients/apps/kotlin/gradlew.bat
new file mode 100644
index 00000000..ac1b06f9
--- /dev/null
+++ b/clients/apps/kotlin/gradlew.bat
@@ -0,0 +1,89 @@
+@rem
+@rem Copyright 2015 the original author or authors.
+@rem
+@rem Licensed under the Apache License, Version 2.0 (the "License");
+@rem you may not use this file except in compliance with the License.
+@rem You may obtain a copy of the License at
+@rem
+@rem https://www.apache.org/licenses/LICENSE-2.0
+@rem
+@rem Unless required by applicable law or agreed to in writing, software
+@rem distributed under the License is distributed on an "AS IS" BASIS,
+@rem WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+@rem See the License for the specific language governing permissions and
+@rem limitations under the License.
+@rem
+
+@if "%DEBUG%" == "" @echo off
+@rem ##########################################################################
+@rem
+@rem Gradle startup script for Windows
+@rem
+@rem ##########################################################################
+
+@rem Set local scope for the variables with windows NT shell
+if "%OS%"=="Windows_NT" setlocal
+
+set DIRNAME=%~dp0
+if "%DIRNAME%" == "" set DIRNAME=.
+set APP_BASE_NAME=%~n0
+set APP_HOME=%DIRNAME%
+
+@rem Resolve any "." and ".." in APP_HOME to make it shorter.
+for %%i in ("%APP_HOME%") do set APP_HOME=%%~fi
+
+@rem Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.
+set DEFAULT_JVM_OPTS="-Xmx64m" "-Xms64m"
+
+@rem Find java.exe
+if defined JAVA_HOME goto findJavaFromJavaHome
+
+set JAVA_EXE=java.exe
+%JAVA_EXE% -version >NUL 2>&1
+if "%ERRORLEVEL%" == "0" goto execute
+
+echo.
+echo ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH.
+echo.
+echo Please set the JAVA_HOME variable in your environment to match the
+echo location of your Java installation.
+
+goto fail
+
+:findJavaFromJavaHome
+set JAVA_HOME=%JAVA_HOME:"=%
+set JAVA_EXE=%JAVA_HOME%/bin/java.exe
+
+if exist "%JAVA_EXE%" goto execute
+
+echo.
+echo ERROR: JAVA_HOME is set to an invalid directory: %JAVA_HOME%
+echo.
+echo Please set the JAVA_HOME variable in your environment to match the
+echo location of your Java installation.
+
+goto fail
+
+:execute
+@rem Setup the command line
+
+set CLASSPATH=%APP_HOME%\gradle\wrapper\gradle-wrapper.jar
+
+
+@rem Execute Gradle
+"%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -classpath "%CLASSPATH%" org.gradle.wrapper.GradleWrapperMain %*
+
+:end
+@rem End local scope for the variables with windows NT shell
+if "%ERRORLEVEL%"=="0" goto mainEnd
+
+:fail
+rem Set variable GRADLE_EXIT_CONSOLE if you need the _script_ return code instead of
+rem the _cmd.exe /c_ return code!
+if not "" == "%GRADLE_EXIT_CONSOLE%" exit 1
+exit /b 1
+
+:mainEnd
+if "%OS%"=="Windows_NT" endlocal
+
+:omega
diff --git a/clients/apps/kotlin/settings.gradle.kts b/clients/apps/kotlin/settings.gradle.kts
new file mode 100644
index 00000000..4e93638f
--- /dev/null
+++ b/clients/apps/kotlin/settings.gradle.kts
@@ -0,0 +1,5 @@
+plugins {
+ id("org.gradle.toolchains.foojay-resolver-convention") version "0.5.0"
+}
+rootProject.name = "test2"
+
diff --git a/clients/apps/kotlin/src/main/kotlin/BroadcastBackupTransaction.kt b/clients/apps/kotlin/src/main/kotlin/BroadcastBackupTransaction.kt
new file mode 100644
index 00000000..c06731a8
--- /dev/null
+++ b/clients/apps/kotlin/src/main/kotlin/BroadcastBackupTransaction.kt
@@ -0,0 +1,104 @@
+import com.github.ajalt.clikt.core.CliktCommand
+import com.github.ajalt.clikt.parameters.arguments.argument
+import com.github.ajalt.clikt.parameters.arguments.convert
+import com.github.ajalt.clikt.parameters.arguments.optional
+import kotlinx.coroutines.runBlocking
+import kotlinx.serialization.encodeToString
+import kotlinx.serialization.json.Json
+import kotlinx.serialization.json.buildJsonObject
+import kotlinx.serialization.json.put
+
+class BroadcastBackupTransaction: CliktCommand(help = "Broadcast a backup transaction via CPFP") {
+
+ private val walletName: String by argument(help = "Name of the wallet")
+
+ private val statechainId: String by argument(help = "Statechain id")
+
+ private val toAddress: String by argument(help = "Address to send the funds")
+
+ private val feeRate: UInt? by argument(help = "Fee Rate").convert { it.toUInt() }.optional()
+
+ private val appContext: AppContext by lazy {
+ requireNotNull(currentContext.findObject() as? AppContext) {
+ "ClientConfig not found in context"
+ }
+ }
+
+ private suspend fun execute() {
+ val wallet = appContext.sqliteManager.loadWallet(walletName)
+
+ CoinUpdate.execute(wallet, appContext)
+
+ if (!validateAddress(toAddress, wallet.network)) {
+ throw Exception("Invalid address")
+ }
+
+ val backupTxs = appContext.sqliteManager.getBackupTxs(statechainId)
+
+ // val backupTx = if (backupTxs.isEmpty()) null else backupTxs.maxByOrNull { it.txN }
+
+ val coinsWithStatechainId = wallet.coins.filter { it.statechainId == statechainId }
+
+ if (coinsWithStatechainId.isEmpty()) {
+ throw Exception("There is no coin for the statechain id $statechainId")
+ }
+
+ val coin = coinsWithStatechainId.sortedBy { it.locktime }.first()
+
+ if (coin.status != CoinStatus.CONFIRMED && coin.status != CoinStatus.IN_TRANSFER) {
+ throw Exception("Coin status must be CONFIRMED or IN_TRANSFER to transfer it. The current status is ${coin.status}");
+ }
+
+ var backupTx: BackupTx? = null
+
+ try {
+ backupTx = latestBackupTxPaysToUserPubkey(backupTxs, coin, wallet.network)
+ } catch (e: Exception) {
+ println("Error: ${e.message}")
+ return
+ }
+
+ var feeRateSatsPerByte: UInt = 0u
+
+ if (feeRate == null) {
+ val electrumFeeRate = getFeeRateSatsPerByte(appContext.clientConfig)
+ feeRateSatsPerByte = if (electrumFeeRate > appContext.clientConfig.maxFeeRate.toUInt()) {
+ appContext.clientConfig.maxFeeRate.toUInt()
+ } else {
+ electrumFeeRate.toUInt()
+ }
+ } else {
+ feeRateSatsPerByte = feeRate as UInt
+ }
+
+
+ val cpfpTx = createCpfpTx(backupTx, coin, toAddress, feeRateSatsPerByte.toULong(), wallet.network);
+
+ val electrumClient = getElectrumClient(appContext.clientConfig)
+
+ val backupTxTxid = electrumClient.blockchainTransactionBroadcast(backupTx.tx)
+
+ val cpfpTxTxid = electrumClient.blockchainTransactionBroadcast(cpfpTx)
+
+ electrumClient.closeConnection()
+
+ coin.txCpfp = cpfpTxTxid
+ coin.withdrawalAddress = toAddress
+ coin.status = CoinStatus.WITHDRAWING
+
+ appContext.sqliteManager.updateWallet(wallet)
+
+ completeWithdraw(appContext.clientConfig, coin.statechainId!!, coin.signedStatechainId!!)
+
+ val json = buildJsonObject {
+ put("backupTx", backupTxTxid)
+ put("cpfpTx", cpfpTxTxid)
+ }
+
+ println(Json.encodeToString(json))
+ }
+
+ override fun run() {
+ runBlocking { execute() }
+ }
+}
\ No newline at end of file
diff --git a/clients/apps/kotlin/src/main/kotlin/ClientConfig.kt b/clients/apps/kotlin/src/main/kotlin/ClientConfig.kt
new file mode 100644
index 00000000..2a27f55f
--- /dev/null
+++ b/clients/apps/kotlin/src/main/kotlin/ClientConfig.kt
@@ -0,0 +1,58 @@
+import com.akuleshov7.ktoml.Toml
+import com.akuleshov7.ktoml.TomlInputConfig
+import com.akuleshov7.ktoml.parsers.TomlParser
+import com.akuleshov7.ktoml.source.decodeFromStream
+import kotlinx.serialization.SerialName
+import kotlinx.serialization.Serializable
+import java.io.File
+import java.io.InputStream
+
+@Serializable
+data class ConfigData(
+ @SerialName("statechain_entity")
+ val statechainEntity: String,
+ @SerialName("electrum_server")
+ val electrumServer: String,
+ @SerialName("electrum_type")
+ val electrumType: String,
+ @SerialName("network")
+ val network: String,
+ @SerialName("fee_rate_tolerance")
+ val feeRateTolerance: Short,
+ @SerialName("database_file")
+ val databaseFile: String,
+ @SerialName("confirmation_target")
+ val confirmationTarget: Short,
+ @SerialName("max_fee_rate")
+ val maxFeeRate: Short,
+)
+
+class ClientConfig {
+
+ val statechainEntity: String
+ val electrumServer: String
+ val electrumType: String
+ val network: String
+ val feeRateTolerance: Int
+ val databaseFile: String
+ val confirmationTarget: Int
+ val maxFeeRate: Int
+
+ init {
+ val file = File("Settings.toml")
+ if (!file.exists()) {
+ throw Exception("The file 'Settings.toml' does not exist.")
+ }
+
+ val configData = Toml.decodeFromStream(file.inputStream())
+
+ statechainEntity = configData.statechainEntity
+ electrumServer = configData.electrumServer
+ electrumType = configData.electrumType
+ network = configData.network
+ feeRateTolerance = configData.feeRateTolerance.toInt()
+ databaseFile = configData.databaseFile
+ confirmationTarget = configData.confirmationTarget.toInt()
+ maxFeeRate = configData.maxFeeRate.toInt()
+ }
+}
\ No newline at end of file
diff --git a/clients/apps/kotlin/src/main/kotlin/CoinUpdate.kt b/clients/apps/kotlin/src/main/kotlin/CoinUpdate.kt
new file mode 100644
index 00000000..25a7ab9a
--- /dev/null
+++ b/clients/apps/kotlin/src/main/kotlin/CoinUpdate.kt
@@ -0,0 +1,291 @@
+import io.ktor.client.*
+import io.ktor.client.call.*
+import io.ktor.client.engine.cio.*
+import io.ktor.client.plugins.contentnegotiation.*
+import io.ktor.client.request.*
+import io.ktor.serialization.kotlinx.json.*
+import org.bitcoinj.core.NetworkParameters
+import org.electrumj.Util
+import org.electrumj.dto.BlockchainScripthashListUnspentResponseEntry
+
+data class DepositResult(
+ val activity: Activity,
+ val backupTx: BackupTx
+)
+
+class CoinUpdate() {
+
+ companion object {
+
+ private suspend fun createTx1(
+ coin: Coin,
+ clientConfig: ClientConfig,
+ walletNetwork: String,
+ tx0Hash: String,
+ tx0Vout: UInt
+ ): BackupTx {
+
+ if (coin.status != CoinStatus.INITIALISED) {
+ throw IllegalStateException("The coin with the public key ${coin.userPubkey} is not in the INITIALISED state");
+ }
+
+ if (coin.utxoTxid != null && coin.utxoVout != null) {
+ throw Exception("The coin with the public key ${coin.userPubkey} has already been deposited")
+ }
+ coin.utxoTxid = tx0Hash
+ coin.utxoVout = tx0Vout
+
+ coin.status = CoinStatus.IN_MEMPOOL
+
+ val toAddress = getUserBackupAddress(coin, walletNetwork)
+
+ val infoConfig = getInfoConfig(clientConfig)
+
+ val initlock = infoConfig.initlock;
+ val interval = infoConfig.interval;
+
+ val feeRateSatsPerByte: UInt = if (infoConfig.feeRateSatsPerByte > clientConfig.maxFeeRate.toUInt()) {
+ clientConfig.maxFeeRate.toUInt()
+ } else {
+ infoConfig.feeRateSatsPerByte.toUInt()
+ }
+
+ val signedTx = Transaction.create(
+ coin,
+ clientConfig,
+ null,
+ 0u,
+ toAddress,
+ walletNetwork,
+ false,
+ feeRateSatsPerByte,
+ initlock,
+ interval
+ )
+
+ if (coin.publicNonce == null) {
+ throw Exception("coin.publicNonce is None")
+ }
+
+ if (coin.blindingFactor == null) {
+ throw Exception("coin.blindingFactor is None")
+ }
+
+ if (coin.statechainId == null) {
+ throw Exception("coin.statechainId is None")
+ }
+
+ val backupTx = BackupTx(
+ txN = 1u,
+ tx = signedTx,
+ clientPublicNonce = coin.publicNonce ?: throw Exception("publicNonce is null"),
+ serverPublicNonce = coin.serverPublicNonce ?: throw Exception("serverPublicNonce is null"),
+ clientPublicKey = coin.userPubkey,
+ serverPublicKey = coin.serverPubkey ?: throw Exception("serverPubkey is null"),
+ blindingFactor = coin.blindingFactor ?: throw Exception("blindingFactor is null")
+ )
+
+ val blockHeight = getBlockheight(backupTx)
+ coin.locktime = blockHeight
+
+ return backupTx
+ }
+
+ /*fun testElect(clientConfig: ClientConfig) {
+ val electrumClient = getElectrumClient(clientConfig)
+
+ val netParam = NetworkParameters.fromID(NetworkParameters.ID_TESTNET)
+ val scripthash: String = Util.scripthash(netParam,"tb1p8jgrjg4rt4rt9nydw0r2ql9yl77ns069a3czkz3ml7zyc2whfdks0td33p")
+
+ val responseEntries: List = electrumClient.blockchainScripthashListUnspent(scripthash)
+
+ electrumClient.closeConnection()
+
+ println("responseEntries.count: ${responseEntries.count()}")
+
+ responseEntries.forEach { entry ->
+
+ println("entry.height: ${entry.height}")
+ println("entry.txHash: ${entry.txHash}")
+ println("entry.txPos: ${entry.txPos}")
+ println("entry.value: ${entry.value}")
+
+ }
+ }*/
+
+ private suspend fun checkDeposit(coin: Coin, clientConfig: ClientConfig, walletNetwork: String): DepositResult? {
+
+ if (coin.statechainId == null && coin.utxoTxid == null && coin.utxoVout == null) {
+ if (coin.status != CoinStatus.INITIALISED) {
+ throw IllegalStateException("Coin does not have a statechain ID, a UTXO and the status is not INITIALISED")
+ } else {
+ return null
+ }
+ }
+
+ val electrumClient = getElectrumClient(clientConfig)
+
+ // TODO: check wallet network
+ val netParam = NetworkParameters.fromID(NetworkParameters.ID_TESTNET)
+ val scripthash: String = Util.scripthash(netParam, coin.aggregatedAddress)
+
+ val responseEntries: List =
+ electrumClient.blockchainScripthashListUnspent(scripthash)
+
+ var utxo: BlockchainScripthashListUnspentResponseEntry? = null;
+
+ responseEntries.forEach { entry ->
+ if (entry.value == coin.amount!!.toLong()) {
+ utxo = entry
+ }
+ }
+
+ if (utxo == null) {
+ return null
+ }
+
+ if (utxo!!.height == 0.toLong() && coin.status == CoinStatus.IN_MEMPOOL) {
+ return null
+ }
+
+ val blockHeader = electrumClient.blockchainHeadersSubscribe()
+ val blockheight = blockHeader.height.toUInt();
+
+ electrumClient.closeConnection()
+
+ var depositResult: DepositResult? = null
+
+ if (coin.status == CoinStatus.INITIALISED) {
+ val utxoTxid = utxo!!.txHash;
+ val utxoVout = utxo!!.txPos;
+
+ val backupTx = createTx1(coin, clientConfig, walletNetwork, utxoTxid, utxoVout.toUInt())
+
+ val activityUtxo = "${utxo!!.txHash}:${utxo!!.txPos}"
+
+ val activity = createActivity(activityUtxo, utxo!!.value.toUInt(), "deposit")
+
+ depositResult = DepositResult(activity, backupTx)
+ }
+
+ if (utxo!!.height > 0) {
+ val confirmations = blockheight - utxo!!.height.toUInt() + 1u
+
+ coin.status = CoinStatus.UNCONFIRMED
+
+ if (confirmations >= clientConfig.confirmationTarget.toUInt()) {
+ coin.status = CoinStatus.CONFIRMED
+ }
+ }
+
+ return depositResult
+ }
+
+ private suspend fun checkTransfer(coin: Coin, clientConfig: ClientConfig): Boolean {
+
+ if (coin.statechainId == null) {
+ throw Exception("The coin with the aggregated address ${coin.aggregatedAddress} does not have a statechain ID");
+ }
+
+ val statechainInfo = getStatechainInfo(clientConfig, coin.statechainId!!) ?: return true
+
+ val enclavePublicKey = statechainInfo.enclavePublicKey
+
+ val isTransferred = !isEnclavePubkeyPartOfCoin(coin, enclavePublicKey)
+
+ return isTransferred
+ }
+
+ private fun checkWithdrawal(coin: Coin, clientConfig: ClientConfig, walletNetwork: String): Boolean {
+
+ var txid: String? = null
+
+ if (coin.txWithdraw != null) {
+ txid = coin.txWithdraw
+ }
+
+ if (coin.txCpfp != null) {
+ if (txid != null) {
+ throw Exception("Coin ${coin.aggregatedAddress} has both txWithdraw and txCpfp")
+ }
+ txid = coin.txCpfp
+ }
+
+ if (txid == null) {
+ throw Exception("Coin ${coin.aggregatedAddress} has neither txWithdraw nor txCpfp")
+ }
+
+ if (coin.withdrawalAddress == null) {
+ throw Exception("Coin ${coin.aggregatedAddress} has no withdrawalAddress")
+ }
+
+ val electrumClient = getElectrumClient(clientConfig)
+
+ // TODO: check wallet network
+ val netParam = NetworkParameters.fromID(NetworkParameters.ID_TESTNET)
+ val scripthash: String = Util.scripthash(netParam, coin.withdrawalAddress!!)
+
+ val responseEntries: List =
+ electrumClient.blockchainScripthashListUnspent(scripthash)
+
+ var utxo: BlockchainScripthashListUnspentResponseEntry? = null;
+
+ responseEntries.forEach { entry ->
+ if (entry.txHash == txid) {
+ utxo = entry
+ }
+ }
+
+ if (utxo == null) {
+ return false
+ }
+
+ val blockHeader = electrumClient.blockchainHeadersSubscribe()
+ val blockheight = blockHeader.height.toUInt()
+
+ electrumClient.closeConnection()
+
+ if (utxo!!.height > 0) {
+ val confirmations = blockheight - utxo!!.height.toUInt() + 1u
+ return confirmations >= clientConfig.confirmationTarget.toUInt()
+ }
+
+ return false
+ }
+
+ suspend fun execute(wallet: Wallet, appContext: AppContext) {
+
+ val clientConfig = appContext.clientConfig
+ val sqliteManager = appContext.sqliteManager
+
+ // testElect(clientConfig)
+
+ wallet.coins.forEach { coin ->
+ if (coin.status == CoinStatus.INITIALISED || coin.status == CoinStatus.IN_MEMPOOL || coin.status == CoinStatus.UNCONFIRMED) {
+ val depositResult = checkDeposit(coin, clientConfig, wallet.network)
+
+ if (depositResult != null) {
+ wallet.activities = wallet.activities.plus(depositResult.activity)
+ sqliteManager.insertBackupTxs(coin.statechainId!!, listOf(depositResult.backupTx))
+ }
+ }
+ else if (coin.status == CoinStatus.IN_TRANSFER) {
+ val isTransferred = checkTransfer(coin, clientConfig)
+
+ if (isTransferred) {
+ coin.status = CoinStatus.TRANSFERRED;
+ }
+ }
+ else if (coin.status == CoinStatus.WITHDRAWING) {
+ val isWithdrawn = checkWithdrawal(coin, clientConfig, wallet.network)
+
+ if (isWithdrawn) {
+ coin.status = CoinStatus.WITHDRAWN;
+ }
+ }
+ }
+
+ sqliteManager.updateWallet(wallet)
+ }
+ }
+}
\ No newline at end of file
diff --git a/clients/apps/kotlin/src/main/kotlin/CreateWallet.kt b/clients/apps/kotlin/src/main/kotlin/CreateWallet.kt
new file mode 100644
index 00000000..d5aa85a1
--- /dev/null
+++ b/clients/apps/kotlin/src/main/kotlin/CreateWallet.kt
@@ -0,0 +1,100 @@
+import com.github.ajalt.clikt.core.CliktCommand
+import com.github.ajalt.clikt.parameters.arguments.argument
+import kotlinx.coroutines.runBlocking
+import kotlinx.serialization.encodeToString
+import kotlinx.serialization.json.Json
+import kotlinx.serialization.json.buildJsonObject
+import kotlinx.serialization.json.put
+
+class CreateWallet : CliktCommand(help = "Creates a new wallet") {
+ private val walletName: String by argument(help = "Name of the wallet to create")
+
+ private val appContext: AppContext by lazy {
+ requireNotNull(currentContext.findObject() as? AppContext) {
+ "ClientConfig not found in context"
+ }
+ }
+
+ override fun run() {
+
+ val clientConfig = appContext.clientConfig;
+ val sqliteManager = appContext.sqliteManager;
+
+ var mnemonic: String? = null
+
+ try {
+ mnemonic = generateMnemonic()
+ } catch (e: MercuryException) {
+ println("Failed to generate mnemonic: ${e.message}")
+ }
+
+ var infoConfig: InfoConfig? = null
+
+ // TODO: not recommend for production. Change to use CoroutineScope or another approach
+ runBlocking {
+ infoConfig = getInfoConfig(clientConfig)
+ }
+
+ if (infoConfig == null) {
+ println("ERROR: infoConfig is null.")
+ return
+ }
+
+ val electrumClient = getElectrumClient(clientConfig)
+
+ val blockHeader = electrumClient.blockchainHeadersSubscribe()
+ val blockheight = blockHeader.height.toUInt();
+
+ electrumClient.closeConnection()
+
+ val notifications = false;
+ val tutorials = false;
+
+ val (electrumProtocol, electrumHost, electrumPort) = splitUrl(clientConfig.electrumServer)
+
+ val settings = Settings(
+ clientConfig.network,
+ null,
+ null,
+ null,
+ null,
+ null,
+ clientConfig.statechainEntity,
+ null,
+ electrumProtocol,
+ electrumHost,
+ electrumPort.toString(),
+ clientConfig.electrumType,
+ notifications,
+ tutorials
+ )
+
+ val mutableTokenList: MutableList = mutableListOf()
+ val mutableActivityList: MutableList = mutableListOf()
+ val mutableCoinList: MutableList = mutableListOf()
+
+ val wallet = Wallet(
+ walletName,
+ mnemonic!!,
+ "0.0.1",
+ clientConfig.statechainEntity,
+ clientConfig.electrumServer,
+ clientConfig.network,
+ blockheight,
+ infoConfig!!.initlock,
+ infoConfig!!.interval,
+ mutableTokenList,
+ mutableActivityList,
+ mutableCoinList,
+ settings
+ )
+
+ sqliteManager.insertWallet(wallet);
+
+ val json = buildJsonObject {
+ put("result", "Wallet '$walletName' has been created successfully.")
+ }
+
+ println(Json.encodeToString(json))
+ }
+}
\ No newline at end of file
diff --git a/clients/apps/kotlin/src/main/kotlin/Deposit.kt b/clients/apps/kotlin/src/main/kotlin/Deposit.kt
new file mode 100644
index 00000000..9875f7a2
--- /dev/null
+++ b/clients/apps/kotlin/src/main/kotlin/Deposit.kt
@@ -0,0 +1,122 @@
+import com.github.ajalt.clikt.core.CliktCommand
+import com.github.ajalt.clikt.parameters.arguments.argument
+import com.github.ajalt.clikt.parameters.arguments.convert
+import io.ktor.client.*
+import io.ktor.client.call.*
+import io.ktor.client.engine.cio.*
+import io.ktor.client.plugins.contentnegotiation.*
+import io.ktor.client.request.*
+import io.ktor.client.statement.*
+import io.ktor.http.*
+import io.ktor.serialization.kotlinx.json.*
+import kotlinx.coroutines.runBlocking
+import kotlinx.serialization.encodeToString
+import kotlinx.serialization.json.Json
+import kotlinx.serialization.json.buildJsonObject
+import kotlinx.serialization.json.put
+import kotlinx.serialization.json.putJsonObject
+
+class Deposit: CliktCommand(help = "Generates a new deposit address", name = "new-deposit-address") {
+
+ private val walletName: String by argument(help = "Name of the wallet to create")
+
+ private val amount: UInt by argument(help = "Statecoin amount").convert { it.toUInt() }
+
+ private val appContext: AppContext by lazy {
+ requireNotNull(currentContext.findObject() as? AppContext) {
+ "ClientConfig not found in context"
+ }
+ }
+
+ private suspend fun getTokenFromServer() : Token {
+ val endpoint = "tokens/token_init"
+
+ val clientConfig = appContext.clientConfig;
+
+ val url = clientConfig.statechainEntity + "/" + endpoint;
+
+ val httpClient = HttpClient(CIO) {
+ install(ContentNegotiation) {
+ json()
+ }
+ }
+
+ val token: Token = httpClient.get(url).body()
+
+ httpClient.close()
+
+ return token
+ }
+
+ private suspend fun addTokenToWallet(wallet: Wallet) {
+ val token = getTokenFromServer()
+ token.confirmed = true
+ wallet.tokens = wallet.tokens.plus(token)
+
+ appContext.sqliteManager.updateWallet(wallet)
+ }
+
+ private suspend fun execute(wallet: Wallet, token: Token, amount: UInt) {
+
+ val coin = getNewCoin(wallet)
+ wallet.coins = wallet.coins.plus(coin)
+
+ appContext.sqliteManager.updateWallet(wallet)
+
+ val depositMsg1 = createDepositMsg1(coin, token.tokenId)
+
+ val httpClient = HttpClient(CIO) {
+ install(ContentNegotiation) {
+ json()
+ }
+ }
+
+ val url = appContext.clientConfig.statechainEntity + "/" + "deposit/init/pod"
+
+ val depositMsg1Response: DepositMsg1Response = httpClient.post(url) {
+ contentType(ContentType.Application.Json)
+ setBody(depositMsg1)
+ }.body()
+
+ httpClient.close()
+
+ val depositInitResult = handleDepositMsg1Response(coin, depositMsg1Response)
+
+ coin.statechainId = depositInitResult.statechainId;
+ coin.signedStatechainId = depositInitResult.signedStatechainId;
+ coin.serverPubkey = depositInitResult.serverPubkey;
+
+ val aggregatedPublicKey = createAggregatedAddress(coin, wallet.network);
+
+ coin.amount = amount
+ coin.aggregatedAddress = aggregatedPublicKey.aggregateAddress;
+ coin.aggregatedPubkey = aggregatedPublicKey.aggregatePubkey;
+
+ token.spent = true
+
+ appContext.sqliteManager.updateWallet(wallet)
+
+ val json = buildJsonObject {
+ put("deposit_address", coin.aggregatedAddress!!)
+ put("statechain_id", coin.statechainId!!)
+ }
+
+ println(Json.encodeToString(json))
+ }
+
+ override fun run() {
+ val wallet = appContext.sqliteManager.loadWallet(walletName)
+
+ runBlocking {
+ addTokenToWallet(wallet)
+
+ val foundToken = wallet.tokens.find { token -> token.confirmed && !token.spent }
+
+ if (foundToken == null) {
+ throw Exception("There is no token available")
+ }
+
+ execute(wallet, foundToken, amount)
+ }
+ }
+}
\ No newline at end of file
diff --git a/clients/apps/kotlin/src/main/kotlin/ListStatecoins.kt b/clients/apps/kotlin/src/main/kotlin/ListStatecoins.kt
new file mode 100644
index 00000000..45315d24
--- /dev/null
+++ b/clients/apps/kotlin/src/main/kotlin/ListStatecoins.kt
@@ -0,0 +1,43 @@
+import com.github.ajalt.clikt.core.CliktCommand
+import com.github.ajalt.clikt.parameters.arguments.argument
+import kotlinx.coroutines.runBlocking
+import kotlinx.serialization.json.*
+
+class ListStatecoins: CliktCommand(help = "List all wallet' statecoins") {
+
+ private val walletName: String by argument(help = "Name of the wallet to create")
+
+ private val appContext: AppContext by lazy {
+ requireNotNull(currentContext.findObject() as? AppContext) {
+ "ClientConfig not found in context"
+ }
+ }
+
+ override fun run() {
+
+ // TODO: not recommend for production. Change to use CoroutineScope or another approach
+ runBlocking {
+ val wallet = appContext.sqliteManager.loadWallet(walletName)
+
+ CoinUpdate.execute(wallet, appContext)
+
+ val resultJson = buildJsonObject {
+ putJsonArray("coins") {
+ wallet.coins.forEach { coin ->
+ add(buildJsonObject {
+ put("statechain_id", coin.statechainId ?: "Empty")
+ put("amount", coin.amount.toString())
+ put("status", coin.status.toString())
+ put("deposit_address", coin.aggregatedAddress ?: "Empty")
+ put("statechain_address", coin.address ?: "Empty")
+ put("locktime", coin.locktime.toString())
+ })
+ }
+ }
+ }
+
+ val prettyJsonString = Json { prettyPrint = true }.encodeToString(JsonObject.serializer(), resultJson)
+ println(prettyJsonString)
+ }
+ }
+}
\ No newline at end of file
diff --git a/clients/apps/kotlin/src/main/kotlin/Main.kt b/clients/apps/kotlin/src/main/kotlin/Main.kt
new file mode 100644
index 00000000..bb956be8
--- /dev/null
+++ b/clients/apps/kotlin/src/main/kotlin/Main.kt
@@ -0,0 +1,188 @@
+import com.github.ajalt.clikt.core.CliktCommand
+import com.github.ajalt.clikt.core.context
+import com.github.ajalt.clikt.core.subcommands
+
+import io.ktor.client.*
+import io.ktor.client.call.*
+import io.ktor.client.engine.cio.*
+import io.ktor.client.plugins.contentnegotiation.*
+import io.ktor.client.request.*
+import io.ktor.client.statement.*
+import io.ktor.http.*
+import io.ktor.serialization.kotlinx.json.*
+import org.electrumj.ElectrumClient
+import java.time.ZonedDateTime
+import java.time.format.DateTimeFormatter
+
+suspend fun getStatechainInfo(clientConfig: ClientConfig, statechainId: String): StatechainInfoResponsePayload? {
+ val url = "${clientConfig.statechainEntity}/info/statechain/${statechainId}"
+
+ val httpClient = HttpClient(CIO) {
+ install(ContentNegotiation) {
+ json()
+ }
+ }
+
+ val response = httpClient.get(url)
+
+ if (response.status == HttpStatusCode.NotFound) {
+ return null
+ }
+
+ val payload: StatechainInfoResponsePayload = response.body()
+
+ httpClient.close()
+
+ return payload
+}
+
+suspend fun completeWithdraw(clientConfig: ClientConfig, statechainId: String, signedStatechainId: String) {
+
+ val withdrawCompletePayload = WithdrawCompletePayload(
+ statechainId,
+ signedStatechainId
+ )
+
+ val url = "${clientConfig.statechainEntity}/withdraw/complete"
+
+ val httpClient = HttpClient(CIO) {
+ install(ContentNegotiation) {
+ json()
+ }
+ }
+
+ val response = httpClient.post(url) {
+ contentType(ContentType.Application.Json)
+ setBody(withdrawCompletePayload)
+ }
+
+ if (response.status != HttpStatusCode.OK) {
+ val errorBody: String = response.bodyAsText()
+ throw Exception("Failed to complete withdraw: HTTP ${response.status} - $errorBody")
+ }
+
+ httpClient.close()
+}
+
+fun createActivity(utxo: String, amount: UInt, action: String): Activity {
+ val date = ZonedDateTime.now() // This will get the current date and time in UTC
+ val isoString = date.format(DateTimeFormatter.ISO_ZONED_DATE_TIME) // Converts the date to an ISO 8601 string
+
+ return Activity(
+ utxo = utxo,
+ amount = amount,
+ action = action,
+ date = isoString
+ )
+}
+
+fun splitUrl(electrumServerUrl: String): Triple {
+ val protocolEndIndex = electrumServerUrl.indexOf("://")
+ if (protocolEndIndex == -1) throw IllegalArgumentException("Invalid URL: Protocol delimiter not found")
+
+ val protocol = electrumServerUrl.substring(0, protocolEndIndex)
+ val remainder = electrumServerUrl.substring(protocolEndIndex + 3)
+
+ val colonIndex = remainder.lastIndexOf(':')
+ if (colonIndex == -1) throw IllegalArgumentException("Invalid URL: Port delimiter not found")
+
+ val host = remainder.substring(0, colonIndex)
+ val port = remainder.substring(colonIndex + 1).toIntOrNull()
+ ?: throw IllegalArgumentException("Invalid URL: Port is not an integer")
+
+ return Triple(protocol, host, port)
+}
+
+fun getElectrumClient(clientConfig: ClientConfig): ElectrumClient{
+
+ val (protocol, host, port) = splitUrl(clientConfig.electrumServer)
+
+ val electrumClient = ElectrumClient(host, port)
+
+ var isSecure = false
+
+ if (protocol == "ssl") {
+ isSecure = true
+ }
+
+ electrumClient.openConnection(isSecure)
+
+ return electrumClient;
+}
+
+suspend fun getFeeRateSatsPerByte(clientConfig: ClientConfig): ULong {
+ val electrumClient = getElectrumClient(clientConfig)
+
+ var feeRateBtcPerKb = electrumClient.blockchainEstimatefee(3)
+
+ if (feeRateBtcPerKb <= 0.0) {
+ feeRateBtcPerKb = 0.00001
+ }
+
+ val feeRateSatsPerByte = (feeRateBtcPerKb * 100000.0).toULong()
+
+ electrumClient.closeConnection()
+
+ return feeRateSatsPerByte
+}
+
+suspend fun getInfoConfig(clientConfig: ClientConfig): InfoConfig {
+ val endpoint = "info/config"
+
+ // TODO: add support to Tor
+
+ val url = clientConfig.statechainEntity + "/" + endpoint;
+
+ // val client = HttpClient(CIO)
+ val httpClient = HttpClient(CIO) {
+ install(ContentNegotiation) {
+ json()
+ }
+ }
+
+ val serverConfig: ServerConfig = httpClient.get(url).body()
+
+ httpClient.close()
+
+ val feeRateSatsPerByte = getFeeRateSatsPerByte(clientConfig)
+
+ return InfoConfig(
+ serverConfig.initlock,
+ serverConfig.interval,
+ feeRateSatsPerByte
+ )
+}
+
+data class AppContext(
+ val clientConfig: ClientConfig,
+ val sqliteManager: SqliteManager
+)
+
+//TIP To Run code, press or
+// click the icon in the gutter.
+class MainCommand : CliktCommand() {
+ private val clientConfig = ClientConfig()
+ private val sqliteManager = SqliteManager(clientConfig)
+
+ init {
+
+ context {
+ obj = AppContext(clientConfig, sqliteManager)
+ }
+ }
+
+ override fun run() = Unit // Main command does nothing on its own
+}
+
+fun main(args: Array) = MainCommand()
+ .subcommands(
+ CreateWallet(),
+ Deposit(),
+ ListStatecoins(),
+ Withdraw(),
+ BroadcastBackupTransaction(),
+ NewTransferAddress(),
+ TransferSend(),
+ TransferReceive()
+ )
+ .main(args)
diff --git a/clients/apps/kotlin/src/main/kotlin/NewTransferAddress.kt b/clients/apps/kotlin/src/main/kotlin/NewTransferAddress.kt
new file mode 100644
index 00000000..30e1a08d
--- /dev/null
+++ b/clients/apps/kotlin/src/main/kotlin/NewTransferAddress.kt
@@ -0,0 +1,43 @@
+import com.github.ajalt.clikt.core.CliktCommand
+import com.github.ajalt.clikt.parameters.arguments.argument
+import com.github.ajalt.clikt.parameters.options.flag
+import com.github.ajalt.clikt.parameters.options.option
+import kotlinx.serialization.encodeToString
+import kotlinx.serialization.json.Json
+import kotlinx.serialization.json.JsonObject
+import kotlinx.serialization.json.buildJsonObject
+import kotlinx.serialization.json.put
+import java.util.UUID
+
+class NewTransferAddress: CliktCommand(help = "New transfer address for a statecoin") {
+
+ private val walletName: String by argument(help = "Name of the wallet to create")
+
+ private val generateBatchId: Boolean by option("-b", "--generate-batch-id",
+ help = "Generate a batch ID for the transfer").flag(default = false)
+
+ private val appContext: AppContext by lazy {
+ requireNotNull(currentContext.findObject() as? AppContext) {
+ "ClientConfig not found in context"
+ }
+ }
+
+ override fun run() {
+ val wallet = appContext.sqliteManager.loadWallet(walletName)
+
+ val coin = getNewCoin(wallet)
+ wallet.coins = wallet.coins.plus(coin)
+
+ appContext.sqliteManager.updateWallet(wallet)
+
+ val json = buildJsonObject {
+ put("transfer-address", coin.address)
+ if (generateBatchId) {
+ put("batch-id", UUID.randomUUID().toString())
+ }
+ }
+
+ val prettyJsonString = Json { prettyPrint = true }.encodeToString(JsonObject.serializer(), json)
+ println(prettyJsonString)
+ }
+}
\ No newline at end of file
diff --git a/clients/apps/kotlin/src/main/kotlin/SqliteManager.kt b/clients/apps/kotlin/src/main/kotlin/SqliteManager.kt
new file mode 100644
index 00000000..c233228e
--- /dev/null
+++ b/clients/apps/kotlin/src/main/kotlin/SqliteManager.kt
@@ -0,0 +1,124 @@
+import kotlinx.serialization.builtins.ListSerializer
+import kotlinx.serialization.json.Json
+import java.sql.DriverManager
+
+class SqliteManager(clientConfig: ClientConfig) {
+
+ private val databaseUrl = "jdbc:sqlite:" + clientConfig.databaseFile
+
+ init {
+ createDatabase()
+ }
+
+ private fun createDatabase() {
+ DriverManager.getConnection(databaseUrl).use { conn ->
+ conn.createStatement().use { statement ->
+ statement.execute("CREATE TABLE IF NOT EXISTS wallet (wallet_name TEXT NOT NULL UNIQUE, wallet_json TEXT NOT NULL)")
+ statement.execute("CREATE TABLE IF NOT EXISTS backup_txs (statechain_id TEXT NOT NULL, txs TEXT NOT NULL)")
+ }
+ }
+ }
+
+ fun insertWallet(wallet: Wallet) {
+
+ val walletJson = Json.encodeToString(Wallet.serializer(), wallet)
+
+ DriverManager.getConnection(databaseUrl).use { conn ->
+ conn.prepareStatement("INSERT INTO wallet (wallet_name, wallet_json) VALUES (?, ?)").use { statement ->
+ statement.setString(1, wallet.name)
+ statement.setString(2, walletJson)
+ statement.executeUpdate()
+ }
+ }
+ }
+
+ fun loadWallet(walletName: String) : Wallet {
+ DriverManager.getConnection(databaseUrl).use { conn ->
+ conn.prepareStatement("SELECT wallet_json FROM wallet WHERE wallet_name = ?").use { statement ->
+ statement.setString(1, walletName)
+ val rs = statement.executeQuery()
+ if (rs.next()) {
+ val walletJson = rs.getString("wallet_json");
+ val wallet = Json.decodeFromString(Wallet.serializer(), walletJson)
+ return wallet
+ } else {
+ throw InternalException("Wallet $walletName not found !")
+ }
+ }
+ }
+ }
+
+ fun updateWallet(wallet: Wallet) {
+
+ val walletJson = Json.encodeToString(Wallet.serializer(), wallet)
+
+ DriverManager.getConnection(databaseUrl).use { conn ->
+ conn.prepareStatement("UPDATE wallet SET wallet_json = ? WHERE wallet_name = ?").use { statement ->
+ statement.setString(1, walletJson)
+ statement.setString(2, wallet.name)
+ statement.executeUpdate()
+ }
+ }
+ }
+
+ fun insertBackupTxs(statechainId: String, listBackupTx: List) {
+
+ val listBackupTxJson = Json.encodeToString(ListSerializer(BackupTx.serializer()), listBackupTx)
+
+ DriverManager.getConnection(databaseUrl).use { conn ->
+ conn.prepareStatement("INSERT INTO backup_txs (statechain_id, txs) VALUES (?, ?)").use { statement ->
+ statement.setString(1, statechainId)
+ statement.setString(2, listBackupTxJson)
+ statement.executeUpdate()
+ }
+ }
+ }
+
+ fun getBackupTxs(statechainId: String): List {
+ DriverManager.getConnection(databaseUrl).use { conn ->
+ conn.prepareStatement("SELECT txs FROM backup_txs WHERE statechain_id = ?").use { statement ->
+ statement.setString(1, statechainId)
+ val rs = statement.executeQuery()
+ if (rs.next()) {
+ val txsJson = rs.getString("txs");
+ val backupTxs = Json.decodeFromString(ListSerializer(BackupTx.serializer()), txsJson)
+ return backupTxs
+ } else {
+ throw InternalException("StatechainId $statechainId not found !")
+ }
+ }
+ }
+ }
+
+ fun updateBackupTxs(statechainId: String, listBackupTx: List) {
+
+ val listBackupTxJson = Json.encodeToString(ListSerializer(BackupTx.serializer()), listBackupTx)
+
+ DriverManager.getConnection(databaseUrl).use { conn ->
+ conn.prepareStatement("UPDATE backup_txs SET txs = ? WHERE statechain_id = ?").use { statement ->
+ statement.setString(1, listBackupTxJson)
+ statement.setString(2, statechainId)
+ statement.executeUpdate()
+ }
+ }
+ }
+
+ fun insertOrUpdateBackupTxs(statechainId: String, listBackupTx: List) {
+
+ DriverManager.getConnection(databaseUrl).use { conn ->
+ conn.prepareStatement("DELETE FROM backup_txs WHERE statechain_id = ?").use { statement ->
+ statement.setString(1, statechainId)
+ statement.executeUpdate()
+ }
+
+ val listBackupTxJson = Json.encodeToString(ListSerializer(BackupTx.serializer()), listBackupTx)
+
+ conn.prepareStatement("INSERT INTO backup_txs (statechain_id, txs) VALUES (?, ?)").use { statement ->
+ statement.setString(1, statechainId)
+ statement.setString(2, listBackupTxJson)
+ statement.executeUpdate()
+ }
+ }
+
+ }
+}
\ No newline at end of file
diff --git a/clients/apps/kotlin/src/main/kotlin/Transaction.kt b/clients/apps/kotlin/src/main/kotlin/Transaction.kt
new file mode 100644
index 00000000..83324aa3
--- /dev/null
+++ b/clients/apps/kotlin/src/main/kotlin/Transaction.kt
@@ -0,0 +1,127 @@
+import io.ktor.client.*
+import io.ktor.client.call.*
+import io.ktor.client.engine.cio.*
+import io.ktor.client.plugins.contentnegotiation.*
+import io.ktor.client.request.*
+import io.ktor.http.*
+import io.ktor.serialization.kotlinx.json.*
+
+class Transaction() {
+
+ companion object {
+
+ private suspend fun signFirst(clientConfig: ClientConfig, signFirstRequestPayload: SignFirstRequestPayload): String {
+
+ val url = clientConfig.statechainEntity + "/" + "sign/first"
+
+ val httpClient = HttpClient(CIO) {
+ install(ContentNegotiation) {
+ json()
+ }
+ }
+
+ val signFirstResponsePayload: SignFirstResponsePayload = httpClient.post(url) {
+ contentType(ContentType.Application.Json)
+ setBody(signFirstRequestPayload)
+ }.body()
+
+ httpClient.close()
+
+ var serverPubNonceHex = signFirstResponsePayload.serverPubnonce
+
+ if (serverPubNonceHex.startsWith("0x")) {
+ serverPubNonceHex = serverPubNonceHex.substring(2)
+ }
+
+ return serverPubNonceHex
+ }
+
+ private suspend fun signSecond(clientConfig: ClientConfig, partialSigRequest: PartialSignatureRequestPayload) : String {
+
+ val url = clientConfig.statechainEntity + "/" + "sign/second"
+
+ val httpClient = HttpClient(CIO) {
+ install(ContentNegotiation) {
+ json()
+ }
+ }
+
+ val partialSignatureResponsePayload: PartialSignatureResponsePayload = httpClient.post(url) {
+ contentType(ContentType.Application.Json)
+ setBody(partialSigRequest)
+ }.body()
+
+ httpClient.close()
+
+ var partialSigHex = partialSignatureResponsePayload.partialSig
+
+ if (partialSigHex.startsWith("0x")) {
+ partialSigHex = partialSigHex.substring(2)
+ }
+
+ return partialSigHex
+ }
+
+ suspend fun create(
+ coin: Coin,
+ clientConfig: ClientConfig,
+ blockHeight: UInt?,
+ qtBackupTx: UInt,
+ toAddress: String,
+ network: String,
+ isWithdrawal: Boolean,
+ feeRateSatsPerByte: UInt,
+ initlock: UInt,
+ interval: UInt
+ ) : String {
+ val coinNonce = createAndCommitNonces(coin)
+ coin.secretNonce = coinNonce.secretNonce
+ coin.publicNonce = coinNonce.publicNonce
+ coin.blindingFactor = coinNonce.blindingFactor
+
+ coin.serverPublicNonce = signFirst(clientConfig, coinNonce.signFirstRequestPayload)
+
+ var newBlockHeight: UInt = 0u
+
+ if (blockHeight == null) {
+ val electrumClient = getElectrumClient(clientConfig)
+
+ val blockHeader = electrumClient.blockchainHeadersSubscribe()
+ newBlockHeight = blockHeader.height.toUInt();
+
+ electrumClient.closeConnection()
+ } else {
+ newBlockHeight = blockHeight
+ }
+
+ val partialSigRequest = getPartialSigRequest(
+ coin,
+ newBlockHeight,
+ initlock,
+ interval,
+ feeRateSatsPerByte,
+ qtBackupTx,
+ toAddress,
+ network,
+ isWithdrawal)
+
+ val serverPartialSigRequest = partialSigRequest.partialSignatureRequestPayload
+
+ val serverPartialSig = signSecond(clientConfig, serverPartialSigRequest)
+
+ val clientPartialSig = partialSigRequest.clientPartialSig
+ val msg = partialSigRequest.msg
+ val session = partialSigRequest.encodedSession
+ val outputPubkey = partialSigRequest.outputPubkey
+
+ val signature = createSignature(msg, clientPartialSig, serverPartialSig, session, outputPubkey)
+
+ val encodedUnsignedTx = partialSigRequest.encodedUnsignedTx
+
+ val signedTx = newBackupTransaction(encodedUnsignedTx, signature)
+
+ return signedTx
+ }
+ }
+
+}
\ No newline at end of file
diff --git a/clients/apps/kotlin/src/main/kotlin/TransferReceive.kt b/clients/apps/kotlin/src/main/kotlin/TransferReceive.kt
new file mode 100644
index 00000000..ecc41d0a
--- /dev/null
+++ b/clients/apps/kotlin/src/main/kotlin/TransferReceive.kt
@@ -0,0 +1,376 @@
+import com.github.ajalt.clikt.core.CliktCommand
+import com.github.ajalt.clikt.parameters.arguments.argument
+import io.ktor.client.*
+import io.ktor.client.call.*
+import io.ktor.client.engine.cio.*
+import io.ktor.client.plugins.contentnegotiation.*
+import io.ktor.client.request.*
+import io.ktor.client.statement.*
+import io.ktor.http.*
+import io.ktor.serialization.kotlinx.json.*
+import kotlinx.coroutines.delay
+import kotlinx.coroutines.runBlocking
+import kotlinx.serialization.encodeToString
+import kotlinx.serialization.json.*
+import org.bitcoinj.core.NetworkParameters
+import org.electrumj.Util
+import org.electrumj.dto.BlockchainScripthashListUnspentResponseEntry
+
+class TransferReceive: CliktCommand(help = "Retrieve coins from server") {
+
+ private val walletName: String by argument(help = "Name of the wallet")
+
+ private val appContext: AppContext by lazy {
+ requireNotNull(currentContext.findObject() as? AppContext) {
+ "ClientConfig not found in context"
+ }
+ }
+
+ private suspend fun sendTransferReceiverRequestPayload(
+ transferReceiverRequestPayload: TransferReceiverRequestPayload) : String
+ {
+ val httpClient = HttpClient(CIO) {
+ install(ContentNegotiation) {
+ json()
+ }
+ }
+
+ val url = "${appContext.clientConfig.statechainEntity}/transfer/receiver"
+
+ while (true) {
+ val response = httpClient.post(url) {
+ contentType(ContentType.Application.Json)
+ setBody(transferReceiverRequestPayload)
+ }
+
+ if (response.status == HttpStatusCode.BadRequest) {
+
+ val transferReceiverErrorResponsePayload : TransferReceiverErrorResponsePayload = response.body()
+
+ if (transferReceiverErrorResponsePayload.code == TransferReceiverError.EXPIRED_BATCH_TIME_ERROR) {
+ throw Exception(transferReceiverErrorResponsePayload.message)
+ } else if (transferReceiverErrorResponsePayload.code == TransferReceiverError.STATECOIN_BATCH_LOCKED_ERROR) {
+ println("Statecoin batch still locked. Waiting until expiration or unlock.")
+ delay(5000)
+ continue
+ }
+ }
+
+ if (response.status == HttpStatusCode.OK) {
+ val transferReceiverPostResponsePayload : TransferReceiverPostResponsePayload = response.body()
+ return transferReceiverPostResponsePayload.serverPubkey
+ } else {
+ throw Exception("Failed to update transfer message")
+ }
+ }
+ }
+
+ private fun verifyTx0OutputIsUnspentAndConfirmed(
+ coin: Coin, tx0Outpoint: TxOutpoint, tx0Hex: String, walletNetwork: String) : Pair
+ {
+ val tx0outputAddress = getOutputAddressFromTx0(tx0Outpoint, tx0Hex, walletNetwork)
+
+ val electrumClient = getElectrumClient(appContext.clientConfig)
+
+ // TODO: check wallet network
+ val netParam = NetworkParameters.fromID(NetworkParameters.ID_TESTNET)
+ val scripthash: String = Util.scripthash(netParam, tx0outputAddress)
+
+ val responseEntries: List =
+ electrumClient.blockchainScripthashListUnspent(scripthash)
+
+ var status = CoinStatus.UNCONFIRMED;
+
+ responseEntries.forEach { entry ->
+ if (entry.txHash == tx0Outpoint.txid && entry.txPos == tx0Outpoint.vout.toLong()) {
+ val blockHeader = electrumClient.blockchainHeadersSubscribe()
+ val blockheight = blockHeader.height
+
+ val confirmations = blockheight - entry.height + 1
+
+ if (confirmations >= appContext.clientConfig.confirmationTarget) {
+ status = CoinStatus.CONFIRMED;
+ }
+
+ return Pair(true, status)
+ }
+ }
+
+ return Pair(false, status)
+ }
+
+ private suspend fun unlockStatecoin(statechainId: String, signedStatechainId: String, authPubkey: String) {
+ val url = "${appContext.clientConfig.statechainEntity}/transfer/unlock"
+
+ val httpClient = HttpClient(CIO) {
+ install(ContentNegotiation) {
+ json()
+ }
+ }
+
+ val transferUnlockRequestPayload = TransferUnlockRequestPayload (
+ statechainId,
+ signedStatechainId,
+ authPubkey
+ )
+
+ val response = httpClient.post(url) {
+ contentType(ContentType.Application.Json)
+ setBody(transferUnlockRequestPayload)
+ }
+
+ if (response.status != HttpStatusCode.OK) {
+ throw Exception("Failed to unlock transfer message")
+ }
+
+ httpClient.close()
+ }
+
+ private fun getTx0(tx0Txid: String) : String {
+ val electrumClient = getElectrumClient(appContext.clientConfig)
+
+ var txHex = electrumClient.blockchainTransactionGetNoVerbose(tx0Txid);
+
+ electrumClient.closeConnection()
+
+ return txHex
+ }
+
+ private suspend fun processEncryptedMessage(
+ coin: Coin,
+ encMessage: String,
+ network: String,
+ serverInfo: InfoConfig,
+ activities: MutableList) : String
+ {
+
+ val clientAuthKey = coin.authPrivkey
+ val newUserPubkey = coin.userPubkey
+
+
+ val transferMsg = fiiDecryptTransferMsg(encMessage, clientAuthKey)
+ val tx0Outpoint = getTx0Outpoint(transferMsg.backupTransactions)
+ val tx0Hex = getTx0(tx0Outpoint.txid)
+
+ val isTransferSignatureValid = ffiVerifyTransferSignature(newUserPubkey, tx0Outpoint, transferMsg)
+
+ if (!isTransferSignatureValid) {
+ throw Exception("Invalid transfer signature")
+ }
+
+ val statechainInfo = getStatechainInfo(appContext.clientConfig, transferMsg.statechainId)
+
+ if (statechainInfo == null) {
+ throw Exception("Statechain info not found")
+ }
+
+ val isTx0OutputPubkeyValid = fiiValidateTx0OutputPubkey(statechainInfo.enclavePublicKey, transferMsg, tx0Outpoint, tx0Hex, network)
+
+ if (!isTx0OutputPubkeyValid) {
+ throw Exception("Invalid tx0 output pubkey")
+ }
+
+ val latestBackupTxPaysToUserPubkey = fiiVerifyLatestBackupTxPaysToUserPubkey(transferMsg, newUserPubkey, network)
+
+ if (!latestBackupTxPaysToUserPubkey) {
+ throw Exception("Latest Backup Tx does not pay to the expected public key")
+ }
+
+ if (statechainInfo.numSigs.toInt() != transferMsg.backupTransactions.size) {
+ throw Exception("num_sigs is not correct")
+ }
+
+ val isTx0OutputUnspent = verifyTx0OutputIsUnspentAndConfirmed(coin, tx0Outpoint, tx0Hex, network);
+ if (!isTx0OutputUnspent.first) {
+ throw Exception("tx0 output is spent or not confirmed")
+ }
+
+ val currentFeeRateSatsPerByte: UInt = if (serverInfo.feeRateSatsPerByte > appContext.clientConfig.maxFeeRate.toUInt()) {
+ appContext.clientConfig.maxFeeRate.toUInt()
+ } else {
+ serverInfo.feeRateSatsPerByte.toUInt()
+ }
+
+ val feeRateTolerance = appContext.clientConfig.feeRateTolerance.toUInt()
+
+ val previousLockTime: UInt = ffiValidateSignatureScheme(
+ transferMsg,
+ statechainInfo,
+ tx0Hex,
+ feeRateTolerance,
+ currentFeeRateSatsPerByte,
+ serverInfo.interval
+ )
+
+ val transferReceiverRequestPayload = fiiCreateTransferReceiverRequestPayload(statechainInfo, transferMsg, coin)
+
+ val signedStatechainIdForUnlock = signMessage(transferMsg.statechainId, coin)
+
+ unlockStatecoin(transferMsg.statechainId, signedStatechainIdForUnlock, coin.authPubkey)
+
+ var serverPublicKeyHex = ""
+
+ try {
+ serverPublicKeyHex = sendTransferReceiverRequestPayload(transferReceiverRequestPayload)
+ } catch (e: Exception) {
+ throw Exception("Error: ${e.message}")
+ }
+
+ val newKeyInfo = getNewKeyInfo(serverPublicKeyHex, coin, transferMsg.statechainId, tx0Outpoint, tx0Hex, network)
+
+ coin.serverPubkey = serverPublicKeyHex
+ coin.aggregatedPubkey = newKeyInfo.aggregatePubkey
+ coin.aggregatedAddress = newKeyInfo.aggregateAddress
+ coin.statechainId = transferMsg.statechainId
+ coin.signedStatechainId = newKeyInfo.signedStatechainId
+ coin.amount = newKeyInfo.amount
+ coin.utxoTxid = tx0Outpoint.txid
+ coin.utxoVout = tx0Outpoint.vout
+ coin.locktime = previousLockTime
+ coin.status = isTx0OutputUnspent.second
+
+ val utxo = "${tx0Outpoint.txid}:${tx0Outpoint.vout}"
+
+ val activity = createActivity(utxo, newKeyInfo.amount, "Receive")
+ activities.add(activity)
+
+ appContext.sqliteManager.insertOrUpdateBackupTxs(transferMsg.statechainId, transferMsg.backupTransactions)
+
+
+ return transferMsg.statechainId
+ }
+
+ private suspend fun getMsgAddr(authPubkey: String) : List {
+ val url = "${appContext.clientConfig.statechainEntity}/transfer/get_msg_addr/${authPubkey}"
+
+ val httpClient = HttpClient(CIO) {
+ install(ContentNegotiation) {
+ json()
+ }
+ }
+
+ val response: GetMsgAddrResponsePayload = httpClient.get(url).body();
+
+ httpClient.close()
+
+ return response.listEncTransferMsg
+ }
+
+ private suspend fun execute() {
+
+ val wallet = appContext.sqliteManager.loadWallet(walletName)
+
+ CoinUpdate.execute(wallet, appContext)
+
+
+
+ val infoConfig = getInfoConfig(appContext.clientConfig)
+
+ val uniqueAuthPubkeys = mutableSetOf()
+
+ wallet.coins.forEach { coin ->
+ uniqueAuthPubkeys.add(coin.authPubkey)
+ }
+
+ val encMsgsPerAuthPubkey = mutableMapOf>()
+
+ for (authPubkey in uniqueAuthPubkeys) {
+ try {
+ val encMessages = getMsgAddr(authPubkey)
+ if (encMessages.isEmpty()) {
+ println("No messages")
+ continue
+ }
+
+ encMsgsPerAuthPubkey[authPubkey] = encMessages
+ } catch (err: Exception) {
+ err.printStackTrace()
+ }
+ }
+
+ val receivedStatechainIds = mutableListOf()
+
+ val tempCoins = wallet.coins.toMutableList()
+ val tempActivities = wallet.activities.toMutableList()
+
+ for ((authPubkey, encMessages) in encMsgsPerAuthPubkey) {
+ for (encMessage in encMessages) {
+ val coin = tempCoins.find { it.authPubkey == authPubkey && it.status == CoinStatus.INITIALISED }
+
+ if (coin != null) {
+ try {
+ val statechainIdAdded = processEncryptedMessage(coin, encMessage, wallet.network, infoConfig, tempActivities)
+ if (statechainIdAdded != null) {
+ receivedStatechainIds.add(statechainIdAdded)
+ }
+ } catch (error: Exception) {
+ println("Error: ${error.message}")
+ continue
+ }
+ } else {
+ try {
+ val newCoin = duplicateCoinToInitializedState(wallet, authPubkey)
+ if (newCoin != null) {
+ val statechainIdAdded = processEncryptedMessage(newCoin, encMessage, wallet.network, infoConfig, tempActivities)
+ if (statechainIdAdded != null) {
+ tempCoins.add(newCoin)
+ receivedStatechainIds.add(statechainIdAdded)
+ }
+ }
+ } catch (error: Exception) {
+ println("Error: ${error.message}")
+ continue
+ }
+ }
+ }
+ }
+
+ wallet.coins = tempCoins
+ wallet.activities = tempActivities
+
+
+
+
+
+ /*
+
+ wallet.coins.forEach { coin ->
+ if (coin.status != CoinStatus.INITIALISED) {
+ return@forEach // Continue in Kotlin's forEach
+ }
+
+ // Log information - assuming use of a logging library or println for simplicity
+// println("----\nuser_pubkey: ${coin.userPubkey}")
+// println("auth_pubkey: ${coin.authPubkey}")
+// println("statechain_id: ${coin.statechainId}")
+// println("coin.amount: ${coin.amount}")
+// println("coin.status: ${coin.status}")
+
+ val encMessages = getMsgAddr(coin.authPubkey)
+
+ if (encMessages.isEmpty()) {
+ return@forEach // Continue in Kotlin's forEach
+ }
+
+ val statechainIdsAdded = processEncryptedMessage(coin, encMessages, infoConfig, wallet)
+ receivedStatechainIds.addAll(statechainIdsAdded)
+ }
+
+
+ */
+
+ appContext.sqliteManager.updateWallet(wallet)
+
+ val json = buildJsonObject {
+ putJsonArray("receivedStatechainIds") {
+ receivedStatechainIds.forEach{ id -> add(id) }
+ }
+ }
+
+ println(Json.encodeToString(json))
+
+ }
+ override fun run() {
+ runBlocking { execute() }
+ }
+}
\ No newline at end of file
diff --git a/clients/apps/kotlin/src/main/kotlin/TransferSend.kt b/clients/apps/kotlin/src/main/kotlin/TransferSend.kt
new file mode 100644
index 00000000..09abbe76
--- /dev/null
+++ b/clients/apps/kotlin/src/main/kotlin/TransferSend.kt
@@ -0,0 +1,211 @@
+import com.github.ajalt.clikt.core.CliktCommand
+import com.github.ajalt.clikt.parameters.arguments.argument
+import com.github.ajalt.clikt.parameters.options.option
+import io.ktor.client.*
+import io.ktor.client.call.*
+import io.ktor.client.engine.cio.*
+import io.ktor.client.plugins.contentnegotiation.*
+import io.ktor.client.request.*
+import io.ktor.http.*
+import io.ktor.serialization.kotlinx.json.*
+import kotlinx.coroutines.runBlocking
+import kotlinx.serialization.encodeToString
+import kotlinx.serialization.json.Json
+import kotlinx.serialization.json.buildJsonObject
+import kotlinx.serialization.json.put
+
+class TransferSend: CliktCommand(help = "Send the specified coin to an statechain address") {
+
+ private val walletName: String by argument(help = "Name of the wallet")
+
+ private val statechainId: String by argument(help = "Statechain id")
+
+ private val toAddress: String by argument(help = "Address to send the funds")
+
+ private val batchId: String? by option("-b", "--generate-batch-id", help = "Optional batch ID for the transaction")
+
+ private val appContext: AppContext by lazy {
+ requireNotNull(currentContext.findObject() as? AppContext) {
+ "ClientConfig not found in context"
+ }
+ }
+
+ private suspend fun getNewX1(statechainId: String, signedStatechainId: String, newAuthPubkey: String, batchId: String?): String {
+
+ val transferSenderRequestPayload = TransferSenderRequestPayload(
+ statechainId,
+ signedStatechainId,
+ newAuthPubkey,
+ batchId
+ )
+
+ val url = "${appContext.clientConfig.statechainEntity}/transfer/sender"
+
+ val httpClient = HttpClient(CIO) {
+ install(ContentNegotiation) {
+ json()
+ }
+ }
+
+ val transferSenderResponsePayload: TransferSenderResponsePayload = httpClient.post(url) {
+ contentType(ContentType.Application.Json)
+ setBody(transferSenderRequestPayload)
+ }.body()
+
+ httpClient.close()
+
+ return transferSenderResponsePayload.x1
+ }
+
+ private suspend fun execute() {
+ val wallet = appContext.sqliteManager.loadWallet(walletName)
+
+ CoinUpdate.execute(wallet, appContext)
+
+ if (!validateAddress(toAddress, wallet.network)) {
+ throw Exception("Invalid address")
+ }
+
+ var backupTxs = appContext.sqliteManager.getBackupTxs(statechainId)
+
+ if (backupTxs.isEmpty()) {
+ throw Exception("There is no backup transaction for the statechain id $statechainId")
+ }
+
+ val newTxN = backupTxs.count() + 1
+
+ val coinsWithStatechainId = wallet.coins.filter { c -> c.statechainId == statechainId }
+
+ if (coinsWithStatechainId.isEmpty()) {
+ throw Exception("There is no coin for the statechain id $statechainId")
+ }
+
+ // If the user sends to himself, he will have two coins with the same statechain_id
+ // In this case, we need to find the one with the lowest locktime
+ // Sort the coins by locktime in ascending order and pick the first one
+ val coin = coinsWithStatechainId.minByOrNull { it.locktime!! }
+ ?: throw Exception("No coins available after sorting by locktime")
+
+ if (coin.status != CoinStatus.CONFIRMED && coin.status != CoinStatus.IN_TRANSFER) {
+ throw Exception("Coin status must be CONFIRMED or IN_TRANSFER to transfer it. The current status is ${coin.status}")
+ }
+
+ if (coin.locktime == null) {
+ throw Exception("Coin.locktime is null");
+ }
+
+ val electrumClient = getElectrumClient(appContext.clientConfig)
+
+ val blockHeader = electrumClient.blockchainHeadersSubscribe()
+ val currentBlockheight = blockHeader.height.toUInt()
+
+ electrumClient.closeConnection()
+
+ if (currentBlockheight > coin.locktime!!) {
+ throw Exception("The coin is expired. Coin locktime is ${coin.locktime} and current blockheight is $currentBlockheight");
+ }
+
+ val statechainId = coin.statechainId
+ val signedStatechainId = coin.signedStatechainId
+
+ val isWithdrawal = false
+ val qtBackupTx = backupTxs.size
+
+ // Sorting backup transactions by tx_n in ascending order
+ backupTxs = backupTxs.sortedBy { it.txN }
+
+ val bkpTx1 = backupTxs.firstOrNull() ?: throw Exception("No backup transactions available")
+
+ val blockHeight = getBlockheight(bkpTx1)
+
+ val decodedTransferAddress = decodeStatechainAddress(toAddress)
+ val newAuthPubkey = decodedTransferAddress.authPubkey
+
+ val newX1 = getNewX1(statechainId!!, signedStatechainId!!, newAuthPubkey, batchId)
+
+ val infoConfig = getInfoConfig(appContext.clientConfig)
+
+ val initlock = infoConfig.initlock;
+ val interval = infoConfig.interval;
+
+ val feeRateSatsPerByte: UInt = if (infoConfig.feeRateSatsPerByte > appContext.clientConfig.maxFeeRate.toUInt()) {
+ appContext.clientConfig.maxFeeRate.toUInt()
+ } else {
+ infoConfig.feeRateSatsPerByte.toUInt()
+ }
+
+ val signedTx = Transaction.create(
+ coin,
+ appContext.clientConfig,
+ blockHeight,
+ qtBackupTx.toUInt(),
+ toAddress,
+ wallet.network,
+ false,
+ feeRateSatsPerByte,
+ initlock,
+ interval
+ )
+
+ val backupTx = BackupTx(
+ txN = newTxN.toUInt(),
+ tx = signedTx,
+ clientPublicNonce = coin.publicNonce ?: throw Exception("publicNonce is null"),
+ serverPublicNonce = coin.serverPublicNonce ?: throw Exception("serverPublicNonce is null"),
+ clientPublicKey = coin.userPubkey,
+ serverPublicKey = coin.serverPubkey ?: throw Exception("serverPubkey is null"),
+ blindingFactor = coin.blindingFactor ?: throw Exception("blindingFactor is null")
+ )
+
+ backupTxs = backupTxs.plus(backupTx)
+
+ val inputTxid = coin.utxoTxid!!
+ val inputVout = coin.utxoVout!!
+ val clientSeckey = coin.userPrivkey
+ val recipientAddress = toAddress
+
+ val transferSignature = createTransferSignature(recipientAddress, inputTxid, inputVout, clientSeckey);
+
+ val transferUpdateMsgRequestPayload = createTransferUpdateMsg(newX1, recipientAddress, coin, transferSignature, backupTxs)
+
+ val url = "${appContext.clientConfig.statechainEntity}/transfer/update_msg"
+
+ val httpClient = HttpClient(CIO) {
+ install(ContentNegotiation) {
+ json()
+ }
+ }
+
+ val response = httpClient.post(url) {
+ contentType(ContentType.Application.Json)
+ setBody(transferUpdateMsgRequestPayload)
+ }
+
+ if (response.status != HttpStatusCode.OK) {
+ throw Exception("Failed to update transfer message")
+ }
+
+ httpClient.close()
+
+ appContext.sqliteManager.updateBackupTxs(coin.statechainId!!, backupTxs)
+
+ val activityUtxo = "${inputTxid}:${inputVout}"
+
+ val activity = createActivity(activityUtxo, coin.amount!!, "Transfer")
+
+ wallet.activities = wallet.activities.plus(activity)
+ coin.status = CoinStatus.IN_TRANSFER
+
+ appContext.sqliteManager.updateWallet(wallet)
+
+ val json = buildJsonObject {
+ put("status", "Transfer sent")
+ }
+
+ println(Json.encodeToString(json))
+ }
+
+ override fun run() {
+ runBlocking { execute() }
+ }
+}
\ No newline at end of file
diff --git a/clients/apps/kotlin/src/main/kotlin/Withdraw.kt b/clients/apps/kotlin/src/main/kotlin/Withdraw.kt
new file mode 100644
index 00000000..cc7efad4
--- /dev/null
+++ b/clients/apps/kotlin/src/main/kotlin/Withdraw.kt
@@ -0,0 +1,143 @@
+import com.github.ajalt.clikt.core.CliktCommand
+import com.github.ajalt.clikt.parameters.arguments.argument
+import com.github.ajalt.clikt.parameters.arguments.convert
+import com.github.ajalt.clikt.parameters.arguments.optional
+import kotlinx.coroutines.runBlocking
+import kotlinx.serialization.encodeToString
+import kotlinx.serialization.json.Json
+import kotlinx.serialization.json.buildJsonObject
+import kotlinx.serialization.json.put
+
+class Withdraw: CliktCommand(help = "Withdraw funds from a statecoin to a BTC address") {
+
+ private val walletName: String by argument(help = "Name of the wallet")
+
+ private val statechainId: String by argument(help = "Statechain id")
+
+ private val toAddress: String by argument(help = "Address to send the funds")
+
+ private val feeRate: UInt? by argument(help = "Fee Rate").convert { it.toUInt() }.optional()
+
+ private val appContext: AppContext by lazy {
+ requireNotNull(currentContext.findObject() as? AppContext) {
+ "ClientConfig not found in context"
+ }
+ }
+
+ private suspend fun execute() {
+ val wallet = appContext.sqliteManager.loadWallet(walletName)
+
+ CoinUpdate.execute(wallet, appContext)
+
+ if (!validateAddress(toAddress, wallet.network)) {
+ throw Exception("Invalid address")
+ }
+
+ var backupTxs = appContext.sqliteManager.getBackupTxs(statechainId)
+
+ if (backupTxs.isEmpty()) {
+ throw Exception("No backup transaction associated with this statechain ID were found")
+ }
+
+ val qtBackupTx = backupTxs.count()
+
+ val newTxN = qtBackupTx + 1
+
+ val coin = wallet.coins
+ .filter { tx -> tx.statechainId == statechainId.toString() } // Filter coins with the specified statechainId
+ .minByOrNull { tx -> tx.locktime!! } // Find the one with the lowest locktime
+
+ if (coin == null) {
+ throw Exception("No coins associated with this statechain ID were found")
+ }
+
+ if (coin.amount == null) {
+ throw Exception("coin.amount is None")
+ }
+
+ if (coin.status != CoinStatus.CONFIRMED && coin.status != CoinStatus.IN_TRANSFER) {
+ throw Exception("Coin status must be CONFIRMED or IN_TRANSFER to transfer it. The current status is ${coin.status}");
+ }
+
+ val infoConfig = getInfoConfig(appContext.clientConfig)
+
+ var feeRateSatsPerByte: UInt = 0u
+
+ if (feeRate == null) {
+ feeRateSatsPerByte = if (infoConfig.feeRateSatsPerByte > appContext.clientConfig.maxFeeRate.toUInt()) {
+ appContext.clientConfig.maxFeeRate.toUInt()
+ } else {
+ infoConfig.feeRateSatsPerByte.toUInt()
+ }
+ } else {
+ feeRateSatsPerByte = feeRate as UInt
+ }
+
+ val signedTx = Transaction.create(
+ coin,
+ appContext.clientConfig,
+ null,
+ qtBackupTx.toUInt(),
+ toAddress,
+ wallet.network,
+ false,
+ feeRateSatsPerByte,
+ infoConfig.initlock,
+ infoConfig.interval
+ )
+
+ if (coin.publicNonce == null) {
+ throw Exception("coin.publicNonce is None")
+ }
+
+ if (coin.blindingFactor == null) {
+ throw Exception("coin.blindingFactor is None")
+ }
+
+ if (coin.statechainId == null) {
+ throw Exception("coin.statechainId is None")
+ }
+
+ val backupTx = BackupTx(
+ txN = newTxN.toUInt(),
+ tx = signedTx,
+ clientPublicNonce = coin.publicNonce ?: throw Exception("publicNonce is null"),
+ serverPublicNonce = coin.serverPublicNonce ?: throw Exception("serverPublicNonce is null"),
+ clientPublicKey = coin.userPubkey,
+ serverPublicKey = coin.serverPubkey ?: throw Exception("serverPubkey is null"),
+ blindingFactor = coin.blindingFactor ?: throw Exception("blindingFactor is null")
+ )
+
+ backupTxs = backupTxs.plus(backupTx)
+
+ appContext.sqliteManager.updateBackupTxs(coin.statechainId!!, backupTxs)
+
+ val electrumClient = getElectrumClient(appContext.clientConfig)
+
+ val txId = electrumClient.blockchainTransactionBroadcast(signedTx)
+
+ electrumClient.closeConnection()
+
+ coin.txWithdraw = txId
+ coin.withdrawalAddress = toAddress
+ coin.status = CoinStatus.WITHDRAWING
+
+ val activity = createActivity(txId, coin.amount!!, "Withdraw")
+
+ wallet.activities = wallet.activities.plus(activity)
+
+ appContext.sqliteManager.updateWallet(wallet)
+
+ completeWithdraw(appContext.clientConfig, coin.statechainId!!, coin.signedStatechainId!!)
+
+ val json = buildJsonObject {
+ put("txId", txId)
+ }
+
+ println(Json.encodeToString(json))
+ }
+
+ override fun run() {
+ runBlocking { execute() }
+ }
+}
\ No newline at end of file
diff --git a/clients/apps/kotlin/src/main/kotlin/mercurylib.kt b/clients/apps/kotlin/src/main/kotlin/mercurylib.kt
new file mode 100644
index 00000000..41e4238e
--- /dev/null
+++ b/clients/apps/kotlin/src/main/kotlin/mercurylib.kt
@@ -0,0 +1,4611 @@
+// This file was autogenerated by some hot garbage in the `uniffi` crate.
+// Trust me, you don't want to mess with it!
+
+@file:Suppress("NAME_SHADOWING")
+
+
+// Common helper code.
+//
+// Ideally this would live in a separate .kt file where it can be unittested etc
+// in isolation, and perhaps even published as a re-useable package.
+//
+// However, it's important that the details of how this helper code works (e.g. the
+// way that different builtin types are passed across the FFI) exactly match what's
+// expected by the Rust code on the other side of the interface. In practice right
+// now that means coming from the exact some version of `uniffi` that was used to
+// compile the Rust component. The easiest way to ensure this is to bundle the Kotlin
+// helpers directly inline like we're doing here.
+
+import com.sun.jna.Callback
+import com.sun.jna.Library
+import com.sun.jna.Native
+import com.sun.jna.Pointer
+import com.sun.jna.Structure
+import com.sun.jna.ptr.*
+import kotlinx.serialization.Serializable
+import kotlinx.serialization.SerialName
+import java.nio.ByteBuffer
+import java.nio.ByteOrder
+import java.nio.CharBuffer
+import java.nio.charset.CodingErrorAction
+import java.util.concurrent.ConcurrentHashMap
+import java.util.concurrent.atomic.AtomicLong
+
+// This is a helper for safely working with byte buffers returned from the Rust code.
+// A rust-owned buffer is represented by its capacity, its current length, and a
+// pointer to the underlying data.
+
+@Structure.FieldOrder("capacity", "len", "data")
+open class RustBuffer : Structure() {
+ // Note: `capacity` and `len` are actually `ULong` values, but JVM only supports signed values.
+ // When dealing with these fields, make sure to call `toULong()`.
+ @JvmField var capacity: Long = 0
+
+ @JvmField var len: Long = 0
+
+ @JvmField var data: Pointer? = null
+
+ class ByValue : RustBuffer(), Structure.ByValue
+
+ class ByReference : RustBuffer(), Structure.ByReference
+
+ internal fun setValue(other: RustBuffer) {
+ capacity = other.capacity
+ len = other.len
+ data = other.data
+ }
+
+ companion object {
+ internal fun alloc(size: ULong = 0UL) =
+ uniffiRustCall { status ->
+ // Note: need to convert the size to a `Long` value to make this work with JVM.
+ UniffiLib.INSTANCE.ffi_mercurylib_rustbuffer_alloc(size.toLong(), status)
+ }.also {
+ if (it.data == null) {
+ throw RuntimeException("RustBuffer.alloc() returned null data pointer (size=$size)")
+ }
+ }
+
+ internal fun create(
+ capacity: ULong,
+ len: ULong,
+ data: Pointer?,
+ ): RustBuffer.ByValue {
+ var buf = RustBuffer.ByValue()
+ buf.capacity = capacity.toLong()
+ buf.len = len.toLong()
+ buf.data = data
+ return buf
+ }
+
+ internal fun free(buf: RustBuffer.ByValue) =
+ uniffiRustCall { status ->
+ UniffiLib.INSTANCE.ffi_mercurylib_rustbuffer_free(buf, status)
+ }
+ }
+
+ @Suppress("TooGenericExceptionThrown")
+ fun asByteBuffer() =
+ this.data?.getByteBuffer(0, this.len.toLong())?.also {
+ it.order(ByteOrder.BIG_ENDIAN)
+ }
+}
+
+/**
+ * The equivalent of the `*mut RustBuffer` type.
+ * Required for callbacks taking in an out pointer.
+ *
+ * Size is the sum of all values in the struct.
+ */
+class RustBufferByReference : ByReference(16) {
+ /**
+ * Set the pointed-to `RustBuffer` to the given value.
+ */
+ fun setValue(value: RustBuffer.ByValue) {
+ // NOTE: The offsets are as they are in the C-like struct.
+ val pointer = getPointer()
+ pointer.setLong(0, value.capacity)
+ pointer.setLong(8, value.len)
+ pointer.setPointer(16, value.data)
+ }
+
+ /**
+ * Get a `RustBuffer.ByValue` from this reference.
+ */
+ fun getValue(): RustBuffer.ByValue {
+ val pointer = getPointer()
+ val value = RustBuffer.ByValue()
+ value.writeField("capacity", pointer.getLong(0))
+ value.writeField("len", pointer.getLong(8))
+ value.writeField("data", pointer.getLong(16))
+
+ return value
+ }
+}
+
+// This is a helper for safely passing byte references into the rust code.
+// It's not actually used at the moment, because there aren't many things that you
+// can take a direct pointer to in the JVM, and if we're going to copy something
+// then we might as well copy it into a `RustBuffer`. But it's here for API
+// completeness.
+
+@Structure.FieldOrder("len", "data")
+open class ForeignBytes : Structure() {
+ @JvmField var len: Int = 0
+
+ @JvmField var data: Pointer? = null
+
+ class ByValue : ForeignBytes(), Structure.ByValue
+}
+
+// The FfiConverter interface handles converter types to and from the FFI
+//
+// All implementing objects should be public to support external types. When a
+// type is external we need to import it's FfiConverter.
+public interface FfiConverter {
+ // Convert an FFI type to a Kotlin type
+ fun lift(value: FfiType): KotlinType
+
+ // Convert an Kotlin type to an FFI type
+ fun lower(value: KotlinType): FfiType
+
+ // Read a Kotlin type from a `ByteBuffer`
+ fun read(buf: ByteBuffer): KotlinType
+
+ // Calculate bytes to allocate when creating a `RustBuffer`
+ //
+ // This must return at least as many bytes as the write() function will
+ // write. It can return more bytes than needed, for example when writing
+ // Strings we can't know the exact bytes needed until we the UTF-8
+ // encoding, so we pessimistically allocate the largest size possible (3
+ // bytes per codepoint). Allocating extra bytes is not really a big deal
+ // because the `RustBuffer` is short-lived.
+ fun allocationSize(value: KotlinType): ULong
+
+ // Write a Kotlin type to a `ByteBuffer`
+ fun write(
+ value: KotlinType,
+ buf: ByteBuffer,
+ )
+
+ // Lower a value into a `RustBuffer`
+ //
+ // This method lowers a value into a `RustBuffer` rather than the normal
+ // FfiType. It's used by the callback interface code. Callback interface
+ // returns are always serialized into a `RustBuffer` regardless of their
+ // normal FFI type.
+ fun lowerIntoRustBuffer(value: KotlinType): RustBuffer.ByValue {
+ val rbuf = RustBuffer.alloc(allocationSize(value))
+ try {
+ val bbuf =
+ rbuf.data!!.getByteBuffer(0, rbuf.capacity).also {
+ it.order(ByteOrder.BIG_ENDIAN)
+ }
+ write(value, bbuf)
+ rbuf.writeField("len", bbuf.position().toLong())
+ return rbuf
+ } catch (e: Throwable) {
+ RustBuffer.free(rbuf)
+ throw e
+ }
+ }
+
+ // Lift a value from a `RustBuffer`.
+ //
+ // This here mostly because of the symmetry with `lowerIntoRustBuffer()`.
+ // It's currently only used by the `FfiConverterRustBuffer` class below.
+ fun liftFromRustBuffer(rbuf: RustBuffer.ByValue): KotlinType {
+ val byteBuf = rbuf.asByteBuffer()!!
+ try {
+ val item = read(byteBuf)
+ if (byteBuf.hasRemaining()) {
+ throw RuntimeException("junk remaining in buffer after lifting, something is very wrong!!")
+ }
+ return item
+ } finally {
+ RustBuffer.free(rbuf)
+ }
+ }
+}
+
+// FfiConverter that uses `RustBuffer` as the FfiType
+public interface FfiConverterRustBuffer : FfiConverter {
+ override fun lift(value: RustBuffer.ByValue) = liftFromRustBuffer(value)
+
+ override fun lower(value: KotlinType) = lowerIntoRustBuffer(value)
+}
+// A handful of classes and functions to support the generated data structures.
+// This would be a good candidate for isolating in its own ffi-support lib.
+
+internal const val UNIFFI_CALL_SUCCESS = 0.toByte()
+internal const val UNIFFI_CALL_ERROR = 1.toByte()
+internal const val UNIFFI_CALL_UNEXPECTED_ERROR = 2.toByte()
+
+@Structure.FieldOrder("code", "error_buf")
+internal open class UniffiRustCallStatus : Structure() {
+ @JvmField var code: Byte = 0
+
+ @JvmField var error_buf: RustBuffer.ByValue = RustBuffer.ByValue()
+
+ class ByValue : UniffiRustCallStatus(), Structure.ByValue
+
+ fun isSuccess(): Boolean {
+ return code == UNIFFI_CALL_SUCCESS
+ }
+
+ fun isError(): Boolean {
+ return code == UNIFFI_CALL_ERROR
+ }
+
+ fun isPanic(): Boolean {
+ return code == UNIFFI_CALL_UNEXPECTED_ERROR
+ }
+
+ companion object {
+ fun create(
+ code: Byte,
+ errorBuf: RustBuffer.ByValue,
+ ): UniffiRustCallStatus.ByValue {
+ val callStatus = UniffiRustCallStatus.ByValue()
+ callStatus.code = code
+ callStatus.error_buf = errorBuf
+ return callStatus
+ }
+ }
+}
+
+class InternalException(message: String) : Exception(message)
+
+// Each top-level error class has a companion object that can lift the error from the call status's rust buffer
+interface UniffiRustCallStatusErrorHandler {
+ fun lift(error_buf: RustBuffer.ByValue): E
+}
+
+// Helpers for calling Rust
+// In practice we usually need to be synchronized to call this safely, so it doesn't
+// synchronize itself
+
+// Call a rust function that returns a Result<>. Pass in the Error class companion that corresponds to the Err
+private inline fun uniffiRustCallWithError(
+ errorHandler: UniffiRustCallStatusErrorHandler,
+ callback: (UniffiRustCallStatus) -> U,
+): U {
+ var status = UniffiRustCallStatus()
+ val return_value = callback(status)
+ uniffiCheckCallStatus(errorHandler, status)
+ return return_value
+}
+
+// Check UniffiRustCallStatus and throw an error if the call wasn't successful
+private fun uniffiCheckCallStatus(
+ errorHandler: UniffiRustCallStatusErrorHandler,
+ status: UniffiRustCallStatus,
+) {
+ if (status.isSuccess()) {
+ return
+ } else if (status.isError()) {
+ throw errorHandler.lift(status.error_buf)
+ } else if (status.isPanic()) {
+ // when the rust code sees a panic, it tries to construct a rustbuffer
+ // with the message. but if that code panics, then it just sends back
+ // an empty buffer.
+ if (status.error_buf.len > 0) {
+ throw InternalException(FfiConverterString.lift(status.error_buf))
+ } else {
+ throw InternalException("Rust panic")
+ }
+ } else {
+ throw InternalException("Unknown rust call status: $status.code")
+ }
+}
+
+// UniffiRustCallStatusErrorHandler implementation for times when we don't expect a CALL_ERROR
+object UniffiNullRustCallStatusErrorHandler : UniffiRustCallStatusErrorHandler {
+ override fun lift(error_buf: RustBuffer.ByValue): InternalException {
+ RustBuffer.free(error_buf)
+ return InternalException("Unexpected CALL_ERROR")
+ }
+}
+
+// Call a rust function that returns a plain value
+private inline fun uniffiRustCall(callback: (UniffiRustCallStatus) -> U): U {
+ return uniffiRustCallWithError(UniffiNullRustCallStatusErrorHandler, callback)
+}
+
+internal inline fun uniffiTraitInterfaceCall(
+ callStatus: UniffiRustCallStatus,
+ makeCall: () -> T,
+ writeReturn: (T) -> Unit,
+) {
+ try {
+ writeReturn(makeCall())
+ } catch (e: Exception) {
+ callStatus.code = UNIFFI_CALL_UNEXPECTED_ERROR
+ callStatus.error_buf = FfiConverterString.lower(e.toString())
+ }
+}
+
+internal inline fun uniffiTraitInterfaceCallWithError(
+ callStatus: UniffiRustCallStatus,
+ makeCall: () -> T,
+ writeReturn: (T) -> Unit,
+ lowerError: (E) -> RustBuffer.ByValue,
+) {
+ try {
+ writeReturn(makeCall())
+ } catch (e: Exception) {
+ if (e is E) {
+ callStatus.code = UNIFFI_CALL_ERROR
+ callStatus.error_buf = lowerError(e)
+ } else {
+ callStatus.code = UNIFFI_CALL_UNEXPECTED_ERROR
+ callStatus.error_buf = FfiConverterString.lower(e.toString())
+ }
+ }
+}
+
+// Map handles to objects
+//
+// This is used pass an opaque 64-bit handle representing a foreign object to the Rust code.
+internal class UniffiHandleMap {
+ private val map = ConcurrentHashMap()
+ private val counter = java.util.concurrent.atomic.AtomicLong(0)
+
+ val size: Int
+ get() = map.size
+
+ // Insert a new object into the handle map and get a handle for it
+ fun insert(obj: T): Long {
+ val handle = counter.getAndAdd(1)
+ map.put(handle, obj)
+ return handle
+ }
+
+ // Get an object from the handle map
+ fun get(handle: Long): T {
+ return map.get(handle) ?: throw InternalException("UniffiHandleMap.get: Invalid handle")
+ }
+
+ // Remove an entry from the handlemap and get the Kotlin object back
+ fun remove(handle: Long): T {
+ return map.remove(handle) ?: throw InternalException("UniffiHandleMap: Invalid handle")
+ }
+}
+
+// Contains loading, initialization code,
+// and the FFI Function declarations in a com.sun.jna.Library.
+@Synchronized
+private fun findLibraryName(componentName: String): String {
+ val libOverride = System.getProperty("uniffi.component.$componentName.libraryOverride")
+ if (libOverride != null) {
+ return libOverride
+ }
+ return "mercurylib"
+}
+
+private inline fun loadIndirect(componentName: String): Lib {
+ return Native.load(findLibraryName(componentName), Lib::class.java)
+}
+
+// Define FFI callback types
+internal interface UniffiRustFutureContinuationCallback : com.sun.jna.Callback {
+ fun callback(
+ `data`: Long,
+ `pollResult`: Byte,
+ )
+}
+
+internal interface UniffiForeignFutureFree : com.sun.jna.Callback {
+ fun callback(`handle`: Long)
+}
+
+internal interface UniffiCallbackInterfaceFree : com.sun.jna.Callback {
+ fun callback(`handle`: Long)
+}
+
+@Structure.FieldOrder("handle", "free")
+internal open class UniffiForeignFuture(
+ @JvmField internal var `handle`: Long = 0.toLong(),
+ @JvmField internal var `free`: UniffiForeignFutureFree? = null,
+) : Structure() {
+ class UniffiByValue(
+ `handle`: Long = 0.toLong(),
+ `free`: UniffiForeignFutureFree? = null,
+ ) : UniffiForeignFuture(`handle`, `free`), Structure.ByValue
+
+ internal fun uniffiSetValue(other: UniffiForeignFuture) {
+ `handle` = other.`handle`
+ `free` = other.`free`
+ }
+}
+
+@Structure.FieldOrder("returnValue", "callStatus")
+internal open class UniffiForeignFutureStructU8(
+ @JvmField internal var `returnValue`: Byte = 0.toByte(),
+ @JvmField internal var `callStatus`: UniffiRustCallStatus.ByValue = UniffiRustCallStatus.ByValue(),
+) : Structure() {
+ class UniffiByValue(
+ `returnValue`: Byte = 0.toByte(),
+ `callStatus`: UniffiRustCallStatus.ByValue = UniffiRustCallStatus.ByValue(),
+ ) : UniffiForeignFutureStructU8(`returnValue`, `callStatus`), Structure.ByValue
+
+ internal fun uniffiSetValue(other: UniffiForeignFutureStructU8) {
+ `returnValue` = other.`returnValue`
+ `callStatus` = other.`callStatus`
+ }
+}
+
+internal interface UniffiForeignFutureCompleteU8 : com.sun.jna.Callback {
+ fun callback(
+ `callbackData`: Long,
+ `result`: UniffiForeignFutureStructU8.UniffiByValue,
+ )
+}
+
+@Structure.FieldOrder("returnValue", "callStatus")
+internal open class UniffiForeignFutureStructI8(
+ @JvmField internal var `returnValue`: Byte = 0.toByte(),
+ @JvmField internal var `callStatus`: UniffiRustCallStatus.ByValue = UniffiRustCallStatus.ByValue(),
+) : Structure() {
+ class UniffiByValue(
+ `returnValue`: Byte = 0.toByte(),
+ `callStatus`: UniffiRustCallStatus.ByValue = UniffiRustCallStatus.ByValue(),
+ ) : UniffiForeignFutureStructI8(`returnValue`, `callStatus`), Structure.ByValue
+
+ internal fun uniffiSetValue(other: UniffiForeignFutureStructI8) {
+ `returnValue` = other.`returnValue`
+ `callStatus` = other.`callStatus`
+ }
+}
+
+internal interface UniffiForeignFutureCompleteI8 : com.sun.jna.Callback {
+ fun callback(
+ `callbackData`: Long,
+ `result`: UniffiForeignFutureStructI8.UniffiByValue,
+ )
+}
+
+@Structure.FieldOrder("returnValue", "callStatus")
+internal open class UniffiForeignFutureStructU16(
+ @JvmField internal var `returnValue`: Short = 0.toShort(),
+ @JvmField internal var `callStatus`: UniffiRustCallStatus.ByValue = UniffiRustCallStatus.ByValue(),
+) : Structure() {
+ class UniffiByValue(
+ `returnValue`: Short = 0.toShort(),
+ `callStatus`: UniffiRustCallStatus.ByValue = UniffiRustCallStatus.ByValue(),
+ ) : UniffiForeignFutureStructU16(`returnValue`, `callStatus`), Structure.ByValue
+
+ internal fun uniffiSetValue(other: UniffiForeignFutureStructU16) {
+ `returnValue` = other.`returnValue`
+ `callStatus` = other.`callStatus`
+ }
+}
+
+internal interface UniffiForeignFutureCompleteU16 : com.sun.jna.Callback {
+ fun callback(
+ `callbackData`: Long,
+ `result`: UniffiForeignFutureStructU16.UniffiByValue,
+ )
+}
+
+@Structure.FieldOrder("returnValue", "callStatus")
+internal open class UniffiForeignFutureStructI16(
+ @JvmField internal var `returnValue`: Short = 0.toShort(),
+ @JvmField internal var `callStatus`: UniffiRustCallStatus.ByValue = UniffiRustCallStatus.ByValue(),
+) : Structure() {
+ class UniffiByValue(
+ `returnValue`: Short = 0.toShort(),
+ `callStatus`: UniffiRustCallStatus.ByValue = UniffiRustCallStatus.ByValue(),
+ ) : UniffiForeignFutureStructI16(`returnValue`, `callStatus`), Structure.ByValue
+
+ internal fun uniffiSetValue(other: UniffiForeignFutureStructI16) {
+ `returnValue` = other.`returnValue`
+ `callStatus` = other.`callStatus`
+ }
+}
+
+internal interface UniffiForeignFutureCompleteI16 : com.sun.jna.Callback {
+ fun callback(
+ `callbackData`: Long,
+ `result`: UniffiForeignFutureStructI16.UniffiByValue,
+ )
+}
+
+@Structure.FieldOrder("returnValue", "callStatus")
+internal open class UniffiForeignFutureStructU32(
+ @JvmField internal var `returnValue`: Int = 0,
+ @JvmField internal var `callStatus`: UniffiRustCallStatus.ByValue = UniffiRustCallStatus.ByValue(),
+) : Structure() {
+ class UniffiByValue(
+ `returnValue`: Int = 0,
+ `callStatus`: UniffiRustCallStatus.ByValue = UniffiRustCallStatus.ByValue(),
+ ) : UniffiForeignFutureStructU32(`returnValue`, `callStatus`), Structure.ByValue
+
+ internal fun uniffiSetValue(other: UniffiForeignFutureStructU32) {
+ `returnValue` = other.`returnValue`
+ `callStatus` = other.`callStatus`
+ }
+}
+
+internal interface UniffiForeignFutureCompleteU32 : com.sun.jna.Callback {
+ fun callback(
+ `callbackData`: Long,
+ `result`: UniffiForeignFutureStructU32.UniffiByValue,
+ )
+}
+
+@Structure.FieldOrder("returnValue", "callStatus")
+internal open class UniffiForeignFutureStructI32(
+ @JvmField internal var `returnValue`: Int = 0,
+ @JvmField internal var `callStatus`: UniffiRustCallStatus.ByValue = UniffiRustCallStatus.ByValue(),
+) : Structure() {
+ class UniffiByValue(
+ `returnValue`: Int = 0,
+ `callStatus`: UniffiRustCallStatus.ByValue = UniffiRustCallStatus.ByValue(),
+ ) : UniffiForeignFutureStructI32(`returnValue`, `callStatus`), Structure.ByValue
+
+ internal fun uniffiSetValue(other: UniffiForeignFutureStructI32) {
+ `returnValue` = other.`returnValue`
+ `callStatus` = other.`callStatus`
+ }
+}
+
+internal interface UniffiForeignFutureCompleteI32 : com.sun.jna.Callback {
+ fun callback(
+ `callbackData`: Long,
+ `result`: UniffiForeignFutureStructI32.UniffiByValue,
+ )
+}
+
+@Structure.FieldOrder("returnValue", "callStatus")
+internal open class UniffiForeignFutureStructU64(
+ @JvmField internal var `returnValue`: Long = 0.toLong(),
+ @JvmField internal var `callStatus`: UniffiRustCallStatus.ByValue = UniffiRustCallStatus.ByValue(),
+) : Structure() {
+ class UniffiByValue(
+ `returnValue`: Long = 0.toLong(),
+ `callStatus`: UniffiRustCallStatus.ByValue = UniffiRustCallStatus.ByValue(),
+ ) : UniffiForeignFutureStructU64(`returnValue`, `callStatus`), Structure.ByValue
+
+ internal fun uniffiSetValue(other: UniffiForeignFutureStructU64) {
+ `returnValue` = other.`returnValue`
+ `callStatus` = other.`callStatus`
+ }
+}
+
+internal interface UniffiForeignFutureCompleteU64 : com.sun.jna.Callback {
+ fun callback(
+ `callbackData`: Long,
+ `result`: UniffiForeignFutureStructU64.UniffiByValue,
+ )
+}
+
+@Structure.FieldOrder("returnValue", "callStatus")
+internal open class UniffiForeignFutureStructI64(
+ @JvmField internal var `returnValue`: Long = 0.toLong(),
+ @JvmField internal var `callStatus`: UniffiRustCallStatus.ByValue = UniffiRustCallStatus.ByValue(),
+) : Structure() {
+ class UniffiByValue(
+ `returnValue`: Long = 0.toLong(),
+ `callStatus`: UniffiRustCallStatus.ByValue = UniffiRustCallStatus.ByValue(),
+ ) : UniffiForeignFutureStructI64(`returnValue`, `callStatus`), Structure.ByValue
+
+ internal fun uniffiSetValue(other: UniffiForeignFutureStructI64) {
+ `returnValue` = other.`returnValue`
+ `callStatus` = other.`callStatus`
+ }
+}
+
+internal interface UniffiForeignFutureCompleteI64 : com.sun.jna.Callback {
+ fun callback(
+ `callbackData`: Long,
+ `result`: UniffiForeignFutureStructI64.UniffiByValue,
+ )
+}
+
+@Structure.FieldOrder("returnValue", "callStatus")
+internal open class UniffiForeignFutureStructF32(
+ @JvmField internal var `returnValue`: Float = 0.0f,
+ @JvmField internal var `callStatus`: UniffiRustCallStatus.ByValue = UniffiRustCallStatus.ByValue(),
+) : Structure() {
+ class UniffiByValue(
+ `returnValue`: Float = 0.0f,
+ `callStatus`: UniffiRustCallStatus.ByValue = UniffiRustCallStatus.ByValue(),
+ ) : UniffiForeignFutureStructF32(`returnValue`, `callStatus`), Structure.ByValue
+
+ internal fun uniffiSetValue(other: UniffiForeignFutureStructF32) {
+ `returnValue` = other.`returnValue`
+ `callStatus` = other.`callStatus`
+ }
+}
+
+internal interface UniffiForeignFutureCompleteF32 : com.sun.jna.Callback {
+ fun callback(
+ `callbackData`: Long,
+ `result`: UniffiForeignFutureStructF32.UniffiByValue,
+ )
+}
+
+@Structure.FieldOrder("returnValue", "callStatus")
+internal open class UniffiForeignFutureStructF64(
+ @JvmField internal var `returnValue`: Double = 0.0,
+ @JvmField internal var `callStatus`: UniffiRustCallStatus.ByValue = UniffiRustCallStatus.ByValue(),
+) : Structure() {
+ class UniffiByValue(
+ `returnValue`: Double = 0.0,
+ `callStatus`: UniffiRustCallStatus.ByValue = UniffiRustCallStatus.ByValue(),
+ ) : UniffiForeignFutureStructF64(`returnValue`, `callStatus`), Structure.ByValue
+
+ internal fun uniffiSetValue(other: UniffiForeignFutureStructF64) {
+ `returnValue` = other.`returnValue`
+ `callStatus` = other.`callStatus`
+ }
+}
+
+internal interface UniffiForeignFutureCompleteF64 : com.sun.jna.Callback {
+ fun callback(
+ `callbackData`: Long,
+ `result`: UniffiForeignFutureStructF64.UniffiByValue,
+ )
+}
+
+@Structure.FieldOrder("returnValue", "callStatus")
+internal open class UniffiForeignFutureStructPointer(
+ @JvmField internal var `returnValue`: Pointer = Pointer.NULL,
+ @JvmField internal var `callStatus`: UniffiRustCallStatus.ByValue = UniffiRustCallStatus.ByValue(),
+) : Structure() {
+ class UniffiByValue(
+ `returnValue`: Pointer = Pointer.NULL,
+ `callStatus`: UniffiRustCallStatus.ByValue = UniffiRustCallStatus.ByValue(),
+ ) : UniffiForeignFutureStructPointer(`returnValue`, `callStatus`), Structure.ByValue
+
+ internal fun uniffiSetValue(other: UniffiForeignFutureStructPointer) {
+ `returnValue` = other.`returnValue`
+ `callStatus` = other.`callStatus`
+ }
+}
+
+internal interface UniffiForeignFutureCompletePointer : com.sun.jna.Callback {
+ fun callback(
+ `callbackData`: Long,
+ `result`: UniffiForeignFutureStructPointer.UniffiByValue,
+ )
+}
+
+@Structure.FieldOrder("returnValue", "callStatus")
+internal open class UniffiForeignFutureStructRustBuffer(
+ @JvmField internal var `returnValue`: RustBuffer.ByValue = RustBuffer.ByValue(),
+ @JvmField internal var `callStatus`: UniffiRustCallStatus.ByValue = UniffiRustCallStatus.ByValue(),
+) : Structure() {
+ class UniffiByValue(
+ `returnValue`: RustBuffer.ByValue = RustBuffer.ByValue(),
+ `callStatus`: UniffiRustCallStatus.ByValue = UniffiRustCallStatus.ByValue(),
+ ) : UniffiForeignFutureStructRustBuffer(`returnValue`, `callStatus`), Structure.ByValue
+
+ internal fun uniffiSetValue(other: UniffiForeignFutureStructRustBuffer) {
+ `returnValue` = other.`returnValue`
+ `callStatus` = other.`callStatus`
+ }
+}
+
+internal interface UniffiForeignFutureCompleteRustBuffer : com.sun.jna.Callback {
+ fun callback(
+ `callbackData`: Long,
+ `result`: UniffiForeignFutureStructRustBuffer.UniffiByValue,
+ )
+}
+
+@Structure.FieldOrder("callStatus")
+internal open class UniffiForeignFutureStructVoid(
+ @JvmField internal var `callStatus`: UniffiRustCallStatus.ByValue = UniffiRustCallStatus.ByValue(),
+) : Structure() {
+ class UniffiByValue(
+ `callStatus`: UniffiRustCallStatus.ByValue = UniffiRustCallStatus.ByValue(),
+ ) : UniffiForeignFutureStructVoid(`callStatus`), Structure.ByValue
+
+ internal fun uniffiSetValue(other: UniffiForeignFutureStructVoid) {
+ `callStatus` = other.`callStatus`
+ }
+}
+
+internal interface UniffiForeignFutureCompleteVoid : com.sun.jna.Callback {
+ fun callback(
+ `callbackData`: Long,
+ `result`: UniffiForeignFutureStructVoid.UniffiByValue,
+ )
+}
+
+// A JNA Library to expose the extern-C FFI definitions.
+// This is an implementation detail which will be called internally by the public API.
+
+internal interface UniffiLib : Library {
+ companion object {
+ internal val INSTANCE: UniffiLib by lazy {
+ loadIndirect(componentName = "mercurylib")
+ .also { lib: UniffiLib ->
+ uniffiCheckContractApiVersion(lib)
+ uniffiCheckApiChecksums(lib)
+ }
+ }
+ }
+
+ fun uniffi_mercurylib_fn_func_create_aggregated_address(
+ `coin`: RustBuffer.ByValue,
+ `network`: RustBuffer.ByValue,
+ uniffi_out_err: UniffiRustCallStatus,
+ ): RustBuffer.ByValue
+
+ fun uniffi_mercurylib_fn_func_create_and_commit_nonces(
+ `coin`: RustBuffer.ByValue,
+ uniffi_out_err: UniffiRustCallStatus,
+ ): RustBuffer.ByValue
+
+ fun uniffi_mercurylib_fn_func_create_cpfp_tx(
+ `backupTx`: RustBuffer.ByValue,
+ `coin`: RustBuffer.ByValue,
+ `toAddress`: RustBuffer.ByValue,
+ `feeRateSatsPerByte`: Long,
+ `network`: RustBuffer.ByValue,
+ uniffi_out_err: UniffiRustCallStatus,
+ ): RustBuffer.ByValue
+
+ fun uniffi_mercurylib_fn_func_create_deposit_msg1(
+ `coin`: RustBuffer.ByValue,
+ `tokenId`: RustBuffer.ByValue,
+ uniffi_out_err: UniffiRustCallStatus,
+ ): RustBuffer.ByValue
+
+ fun uniffi_mercurylib_fn_func_create_signature(
+ `msg`: RustBuffer.ByValue,
+ `clientPartialSigHex`: RustBuffer.ByValue,
+ `serverPartialSigHex`: RustBuffer.ByValue,
+ `sessionHex`: RustBuffer.ByValue,
+ `outputPubkeyHex`: RustBuffer.ByValue,
+ uniffi_out_err: UniffiRustCallStatus,
+ ): RustBuffer.ByValue
+
+ fun uniffi_mercurylib_fn_func_create_transfer_signature(
+ `recipientAddress`: RustBuffer.ByValue,
+ `inputTxid`: RustBuffer.ByValue,
+ `inputVout`: Int,
+ `clientSeckey`: RustBuffer.ByValue,
+ uniffi_out_err: UniffiRustCallStatus,
+ ): RustBuffer.ByValue
+
+ fun uniffi_mercurylib_fn_func_create_transfer_update_msg(
+ `x1`: RustBuffer.ByValue,
+ `recipientAddress`: RustBuffer.ByValue,
+ `coin`: RustBuffer.ByValue,
+ `transferSignature`: RustBuffer.ByValue,
+ `backupTransactions`: RustBuffer.ByValue,
+ uniffi_out_err: UniffiRustCallStatus,
+ ): RustBuffer.ByValue
+
+ fun uniffi_mercurylib_fn_func_decode_statechain_address(
+ `scAddress`: RustBuffer.ByValue,
+ uniffi_out_err: UniffiRustCallStatus,
+ ): RustBuffer.ByValue
+
+ fun uniffi_mercurylib_fn_func_duplicate_coin_to_initialized_state(
+ `wallet`: RustBuffer.ByValue,
+ `authPubkey`: RustBuffer.ByValue,
+ uniffi_out_err: UniffiRustCallStatus,
+ ): RustBuffer.ByValue
+
+ fun uniffi_mercurylib_fn_func_ffi_validate_signature_scheme(
+ `ffiTransferMsg`: RustBuffer.ByValue,
+ `statechainInfo`: RustBuffer.ByValue,
+ `tx0Hex`: RustBuffer.ByValue,
+ `feeRateTolerance`: Int,
+ `currentFeeRateSatsPerByte`: Int,
+ `interval`: Int,
+ uniffi_out_err: UniffiRustCallStatus,
+ ): Int
+
+ fun uniffi_mercurylib_fn_func_ffi_verify_transfer_signature(
+ `newUserPubkey`: RustBuffer.ByValue,
+ `tx0Outpoint`: RustBuffer.ByValue,
+ `ffiTransferMsg`: RustBuffer.ByValue,
+ uniffi_out_err: UniffiRustCallStatus,
+ ): Byte
+
+ fun uniffi_mercurylib_fn_func_fii_create_transfer_receiver_request_payload(
+ `statechainInfo`: RustBuffer.ByValue,
+ `ffiTransferMsg`: RustBuffer.ByValue,
+ `coin`: RustBuffer.ByValue,
+ uniffi_out_err: UniffiRustCallStatus,
+ ): RustBuffer.ByValue
+
+ fun uniffi_mercurylib_fn_func_fii_decrypt_transfer_msg(
+ `encryptedMessage`: RustBuffer.ByValue,
+ `privateKeyWif`: RustBuffer.ByValue,
+ uniffi_out_err: UniffiRustCallStatus,
+ ): RustBuffer.ByValue
+
+ fun uniffi_mercurylib_fn_func_fii_validate_tx0_output_pubkey(
+ `enclavePublicKey`: RustBuffer.ByValue,
+ `ffiTransferMsg`: RustBuffer.ByValue,
+ `tx0Outpoint`: RustBuffer.ByValue,
+ `tx0Hex`: RustBuffer.ByValue,
+ `network`: RustBuffer.ByValue,
+ uniffi_out_err: UniffiRustCallStatus,
+ ): Byte
+
+ fun uniffi_mercurylib_fn_func_fii_verify_latest_backup_tx_pays_to_user_pubkey(
+ `ffiTransferMsg`: RustBuffer.ByValue,
+ `clientPubkeyShare`: RustBuffer.ByValue,
+ `network`: RustBuffer.ByValue,
+ uniffi_out_err: UniffiRustCallStatus,
+ ): Byte
+
+ fun uniffi_mercurylib_fn_func_generate_mnemonic(uniffi_out_err: UniffiRustCallStatus): RustBuffer.ByValue
+
+ fun uniffi_mercurylib_fn_func_get_blockheight(
+ `bkpTx`: RustBuffer.ByValue,
+ uniffi_out_err: UniffiRustCallStatus,
+ ): Int
+
+ fun uniffi_mercurylib_fn_func_get_new_coin(
+ `wallet`: RustBuffer.ByValue,
+ uniffi_out_err: UniffiRustCallStatus,
+ ): RustBuffer.ByValue
+
+ fun uniffi_mercurylib_fn_func_get_new_key_info(
+ `serverPublicKeyHex`: RustBuffer.ByValue,
+ `coin`: RustBuffer.ByValue,
+ `statechainId`: RustBuffer.ByValue,
+ `tx0Outpoint`: RustBuffer.ByValue,
+ `tx0Hex`: RustBuffer.ByValue,
+ `network`: RustBuffer.ByValue,
+ uniffi_out_err: UniffiRustCallStatus,
+ ): RustBuffer.ByValue
+
+ fun uniffi_mercurylib_fn_func_get_output_address_from_tx0(
+ `tx0Outpoint`: RustBuffer.ByValue,
+ `tx0Hex`: RustBuffer.ByValue,
+ `network`: RustBuffer.ByValue,
+ uniffi_out_err: UniffiRustCallStatus,
+ ): RustBuffer.ByValue
+
+ fun uniffi_mercurylib_fn_func_get_partial_sig_request(
+ `coin`: RustBuffer.ByValue,
+ `blockHeight`: Int,
+ `initlock`: Int,
+ `interval`: Int,
+ `feeRateSatsPerByte`: Int,
+ `qtBackupTx`: Int,
+ `toAddress`: RustBuffer.ByValue,
+ `network`: RustBuffer.ByValue,
+ `isWithdrawal`: Byte,
+ uniffi_out_err: UniffiRustCallStatus,
+ ): RustBuffer.ByValue
+
+ fun uniffi_mercurylib_fn_func_get_tx0_outpoint(
+ `backupTransactions`: RustBuffer.ByValue,
+ uniffi_out_err: UniffiRustCallStatus,
+ ): RustBuffer.ByValue
+
+ fun uniffi_mercurylib_fn_func_get_user_backup_address(
+ `coin`: RustBuffer.ByValue,
+ `network`: RustBuffer.ByValue,
+ uniffi_out_err: UniffiRustCallStatus,
+ ): RustBuffer.ByValue
+
+ fun uniffi_mercurylib_fn_func_handle_deposit_msg_1_response(
+ `coin`: RustBuffer.ByValue,
+ `depositMsg1Response`: RustBuffer.ByValue,
+ uniffi_out_err: UniffiRustCallStatus,
+ ): RustBuffer.ByValue
+
+ fun uniffi_mercurylib_fn_func_is_enclave_pubkey_part_of_coin(
+ `coin`: RustBuffer.ByValue,
+ `enclavePubkey`: RustBuffer.ByValue,
+ uniffi_out_err: UniffiRustCallStatus,
+ ): Byte
+
+ fun uniffi_mercurylib_fn_func_latest_backup_tx_pays_to_user_pubkey(
+ `backupTxs`: RustBuffer.ByValue,
+ `coin`: RustBuffer.ByValue,
+ `network`: RustBuffer.ByValue,
+ uniffi_out_err: UniffiRustCallStatus,
+ ): RustBuffer.ByValue
+
+ fun uniffi_mercurylib_fn_func_new_backup_transaction(
+ `encodedUnsignedTx`: RustBuffer.ByValue,
+ `signatureHex`: RustBuffer.ByValue,
+ uniffi_out_err: UniffiRustCallStatus,
+ ): RustBuffer.ByValue
+
+ fun uniffi_mercurylib_fn_func_sign_message(
+ `message`: RustBuffer.ByValue,
+ `coin`: RustBuffer.ByValue,
+ uniffi_out_err: UniffiRustCallStatus,
+ ): RustBuffer.ByValue
+
+ fun uniffi_mercurylib_fn_func_validate_address(
+ `address`: RustBuffer.ByValue,
+ `network`: RustBuffer.ByValue,
+ uniffi_out_err: UniffiRustCallStatus,
+ ): Byte
+
+ fun uniffi_mercurylib_fn_func_verify_blinded_musig_scheme(
+ `backupTx`: RustBuffer.ByValue,
+ `tx0Hex`: RustBuffer.ByValue,
+ `statechainInfo`: RustBuffer.ByValue,
+ uniffi_out_err: UniffiRustCallStatus,
+ ): Unit
+
+ fun uniffi_mercurylib_fn_func_verify_transaction_signature(
+ `txNHex`: RustBuffer.ByValue,
+ `tx0Hex`: RustBuffer.ByValue,
+ `feeRateTolerance`: Int,
+ `currentFeeRateSatsPerByte`: Int,
+ uniffi_out_err: UniffiRustCallStatus,
+ ): Unit
+
+ fun ffi_mercurylib_rustbuffer_alloc(
+ `size`: Long,
+ uniffi_out_err: UniffiRustCallStatus,
+ ): RustBuffer.ByValue
+
+ fun ffi_mercurylib_rustbuffer_from_bytes(
+ `bytes`: ForeignBytes.ByValue,
+ uniffi_out_err: UniffiRustCallStatus,
+ ): RustBuffer.ByValue
+
+ fun ffi_mercurylib_rustbuffer_free(
+ `buf`: RustBuffer.ByValue,
+ uniffi_out_err: UniffiRustCallStatus,
+ ): Unit
+
+ fun ffi_mercurylib_rustbuffer_reserve(
+ `buf`: RustBuffer.ByValue,
+ `additional`: Long,
+ uniffi_out_err: UniffiRustCallStatus,
+ ): RustBuffer.ByValue
+
+ fun ffi_mercurylib_rust_future_poll_u8(
+ `handle`: Long,
+ `callback`: UniffiRustFutureContinuationCallback,
+ `callbackData`: Long,
+ ): Unit
+
+ fun ffi_mercurylib_rust_future_cancel_u8(`handle`: Long): Unit
+
+ fun ffi_mercurylib_rust_future_free_u8(`handle`: Long): Unit
+
+ fun ffi_mercurylib_rust_future_complete_u8(
+ `handle`: Long,
+ uniffi_out_err: UniffiRustCallStatus,
+ ): Byte
+
+ fun ffi_mercurylib_rust_future_poll_i8(
+ `handle`: Long,
+ `callback`: UniffiRustFutureContinuationCallback,
+ `callbackData`: Long,
+ ): Unit
+
+ fun ffi_mercurylib_rust_future_cancel_i8(`handle`: Long): Unit
+
+ fun ffi_mercurylib_rust_future_free_i8(`handle`: Long): Unit
+
+ fun ffi_mercurylib_rust_future_complete_i8(
+ `handle`: Long,
+ uniffi_out_err: UniffiRustCallStatus,
+ ): Byte
+
+ fun ffi_mercurylib_rust_future_poll_u16(
+ `handle`: Long,
+ `callback`: UniffiRustFutureContinuationCallback,
+ `callbackData`: Long,
+ ): Unit
+
+ fun ffi_mercurylib_rust_future_cancel_u16(`handle`: Long): Unit
+
+ fun ffi_mercurylib_rust_future_free_u16(`handle`: Long): Unit
+
+ fun ffi_mercurylib_rust_future_complete_u16(
+ `handle`: Long,
+ uniffi_out_err: UniffiRustCallStatus,
+ ): Short
+
+ fun ffi_mercurylib_rust_future_poll_i16(
+ `handle`: Long,
+ `callback`: UniffiRustFutureContinuationCallback,
+ `callbackData`: Long,
+ ): Unit
+
+ fun ffi_mercurylib_rust_future_cancel_i16(`handle`: Long): Unit
+
+ fun ffi_mercurylib_rust_future_free_i16(`handle`: Long): Unit
+
+ fun ffi_mercurylib_rust_future_complete_i16(
+ `handle`: Long,
+ uniffi_out_err: UniffiRustCallStatus,
+ ): Short
+
+ fun ffi_mercurylib_rust_future_poll_u32(
+ `handle`: Long,
+ `callback`: UniffiRustFutureContinuationCallback,
+ `callbackData`: Long,
+ ): Unit
+
+ fun ffi_mercurylib_rust_future_cancel_u32(`handle`: Long): Unit
+
+ fun ffi_mercurylib_rust_future_free_u32(`handle`: Long): Unit
+
+ fun ffi_mercurylib_rust_future_complete_u32(
+ `handle`: Long,
+ uniffi_out_err: UniffiRustCallStatus,
+ ): Int
+
+ fun ffi_mercurylib_rust_future_poll_i32(
+ `handle`: Long,
+ `callback`: UniffiRustFutureContinuationCallback,
+ `callbackData`: Long,
+ ): Unit
+
+ fun ffi_mercurylib_rust_future_cancel_i32(`handle`: Long): Unit
+
+ fun ffi_mercurylib_rust_future_free_i32(`handle`: Long): Unit
+
+ fun ffi_mercurylib_rust_future_complete_i32(
+ `handle`: Long,
+ uniffi_out_err: UniffiRustCallStatus,
+ ): Int
+
+ fun ffi_mercurylib_rust_future_poll_u64(
+ `handle`: Long,
+ `callback`: UniffiRustFutureContinuationCallback,
+ `callbackData`: Long,
+ ): Unit
+
+ fun ffi_mercurylib_rust_future_cancel_u64(`handle`: Long): Unit
+
+ fun ffi_mercurylib_rust_future_free_u64(`handle`: Long): Unit
+
+ fun ffi_mercurylib_rust_future_complete_u64(
+ `handle`: Long,
+ uniffi_out_err: UniffiRustCallStatus,
+ ): Long
+
+ fun ffi_mercurylib_rust_future_poll_i64(
+ `handle`: Long,
+ `callback`: UniffiRustFutureContinuationCallback,
+ `callbackData`: Long,
+ ): Unit
+
+ fun ffi_mercurylib_rust_future_cancel_i64(`handle`: Long): Unit
+
+ fun ffi_mercurylib_rust_future_free_i64(`handle`: Long): Unit
+
+ fun ffi_mercurylib_rust_future_complete_i64(
+ `handle`: Long,
+ uniffi_out_err: UniffiRustCallStatus,
+ ): Long
+
+ fun ffi_mercurylib_rust_future_poll_f32(
+ `handle`: Long,
+ `callback`: UniffiRustFutureContinuationCallback,
+ `callbackData`: Long,
+ ): Unit
+
+ fun ffi_mercurylib_rust_future_cancel_f32(`handle`: Long): Unit
+
+ fun ffi_mercurylib_rust_future_free_f32(`handle`: Long): Unit
+
+ fun ffi_mercurylib_rust_future_complete_f32(
+ `handle`: Long,
+ uniffi_out_err: UniffiRustCallStatus,
+ ): Float
+
+ fun ffi_mercurylib_rust_future_poll_f64(
+ `handle`: Long,
+ `callback`: UniffiRustFutureContinuationCallback,
+ `callbackData`: Long,
+ ): Unit
+
+ fun ffi_mercurylib_rust_future_cancel_f64(`handle`: Long): Unit
+
+ fun ffi_mercurylib_rust_future_free_f64(`handle`: Long): Unit
+
+ fun ffi_mercurylib_rust_future_complete_f64(
+ `handle`: Long,
+ uniffi_out_err: UniffiRustCallStatus,
+ ): Double
+
+ fun ffi_mercurylib_rust_future_poll_pointer(
+ `handle`: Long,
+ `callback`: UniffiRustFutureContinuationCallback,
+ `callbackData`: Long,
+ ): Unit
+
+ fun ffi_mercurylib_rust_future_cancel_pointer(`handle`: Long): Unit
+
+ fun ffi_mercurylib_rust_future_free_pointer(`handle`: Long): Unit
+
+ fun ffi_mercurylib_rust_future_complete_pointer(
+ `handle`: Long,
+ uniffi_out_err: UniffiRustCallStatus,
+ ): Pointer
+
+ fun ffi_mercurylib_rust_future_poll_rust_buffer(
+ `handle`: Long,
+ `callback`: UniffiRustFutureContinuationCallback,
+ `callbackData`: Long,
+ ): Unit
+
+ fun ffi_mercurylib_rust_future_cancel_rust_buffer(`handle`: Long): Unit
+
+ fun ffi_mercurylib_rust_future_free_rust_buffer(`handle`: Long): Unit
+
+ fun ffi_mercurylib_rust_future_complete_rust_buffer(
+ `handle`: Long,
+ uniffi_out_err: UniffiRustCallStatus,
+ ): RustBuffer.ByValue
+
+ fun ffi_mercurylib_rust_future_poll_void(
+ `handle`: Long,
+ `callback`: UniffiRustFutureContinuationCallback,
+ `callbackData`: Long,
+ ): Unit
+
+ fun ffi_mercurylib_rust_future_cancel_void(`handle`: Long): Unit
+
+ fun ffi_mercurylib_rust_future_free_void(`handle`: Long): Unit
+
+ fun ffi_mercurylib_rust_future_complete_void(
+ `handle`: Long,
+ uniffi_out_err: UniffiRustCallStatus,
+ ): Unit
+
+ fun uniffi_mercurylib_checksum_func_create_aggregated_address(): Short
+
+ fun uniffi_mercurylib_checksum_func_create_and_commit_nonces(): Short
+
+ fun uniffi_mercurylib_checksum_func_create_cpfp_tx(): Short
+
+ fun uniffi_mercurylib_checksum_func_create_deposit_msg1(): Short
+
+ fun uniffi_mercurylib_checksum_func_create_signature(): Short
+
+ fun uniffi_mercurylib_checksum_func_create_transfer_signature(): Short
+
+ fun uniffi_mercurylib_checksum_func_create_transfer_update_msg(): Short
+
+ fun uniffi_mercurylib_checksum_func_decode_statechain_address(): Short
+
+ fun uniffi_mercurylib_checksum_func_duplicate_coin_to_initialized_state(): Short
+
+ fun uniffi_mercurylib_checksum_func_ffi_validate_signature_scheme(): Short
+
+ fun uniffi_mercurylib_checksum_func_ffi_verify_transfer_signature(): Short
+
+ fun uniffi_mercurylib_checksum_func_fii_create_transfer_receiver_request_payload(): Short
+
+ fun uniffi_mercurylib_checksum_func_fii_decrypt_transfer_msg(): Short
+
+ fun uniffi_mercurylib_checksum_func_fii_validate_tx0_output_pubkey(): Short
+
+ fun uniffi_mercurylib_checksum_func_fii_verify_latest_backup_tx_pays_to_user_pubkey(): Short
+
+ fun uniffi_mercurylib_checksum_func_generate_mnemonic(): Short
+
+ fun uniffi_mercurylib_checksum_func_get_blockheight(): Short
+
+ fun uniffi_mercurylib_checksum_func_get_new_coin(): Short
+
+ fun uniffi_mercurylib_checksum_func_get_new_key_info(): Short
+
+ fun uniffi_mercurylib_checksum_func_get_output_address_from_tx0(): Short
+
+ fun uniffi_mercurylib_checksum_func_get_partial_sig_request(): Short
+
+ fun uniffi_mercurylib_checksum_func_get_tx0_outpoint(): Short
+
+ fun uniffi_mercurylib_checksum_func_get_user_backup_address(): Short
+
+ fun uniffi_mercurylib_checksum_func_handle_deposit_msg_1_response(): Short
+
+ fun uniffi_mercurylib_checksum_func_is_enclave_pubkey_part_of_coin(): Short
+
+ fun uniffi_mercurylib_checksum_func_latest_backup_tx_pays_to_user_pubkey(): Short
+
+ fun uniffi_mercurylib_checksum_func_new_backup_transaction(): Short
+
+ fun uniffi_mercurylib_checksum_func_sign_message(): Short
+
+ fun uniffi_mercurylib_checksum_func_validate_address(): Short
+
+ fun uniffi_mercurylib_checksum_func_verify_blinded_musig_scheme(): Short
+
+ fun uniffi_mercurylib_checksum_func_verify_transaction_signature(): Short
+
+ fun ffi_mercurylib_uniffi_contract_version(): Int
+}
+
+private fun uniffiCheckContractApiVersion(lib: UniffiLib) {
+ // Get the bindings contract version from our ComponentInterface
+ val bindings_contract_version = 26
+ // Get the scaffolding contract version by calling the into the dylib
+ val scaffolding_contract_version = lib.ffi_mercurylib_uniffi_contract_version()
+ if (bindings_contract_version != scaffolding_contract_version) {
+ throw RuntimeException("UniFFI contract version mismatch: try cleaning and rebuilding your project")
+ }
+}
+
+@Suppress("UNUSED_PARAMETER")
+private fun uniffiCheckApiChecksums(lib: UniffiLib) {
+ if (lib.uniffi_mercurylib_checksum_func_create_aggregated_address() != 44269.toShort()) {
+ throw RuntimeException("UniFFI API checksum mismatch: try cleaning and rebuilding your project")
+ }
+ if (lib.uniffi_mercurylib_checksum_func_create_and_commit_nonces() != 16584.toShort()) {
+ throw RuntimeException("UniFFI API checksum mismatch: try cleaning and rebuilding your project")
+ }
+ if (lib.uniffi_mercurylib_checksum_func_create_cpfp_tx() != 63811.toShort()) {
+ throw RuntimeException("UniFFI API checksum mismatch: try cleaning and rebuilding your project")
+ }
+ if (lib.uniffi_mercurylib_checksum_func_create_deposit_msg1() != 9767.toShort()) {
+ throw RuntimeException("UniFFI API checksum mismatch: try cleaning and rebuilding your project")
+ }
+ if (lib.uniffi_mercurylib_checksum_func_create_signature() != 53021.toShort()) {
+ throw RuntimeException("UniFFI API checksum mismatch: try cleaning and rebuilding your project")
+ }
+ if (lib.uniffi_mercurylib_checksum_func_create_transfer_signature() != 61677.toShort()) {
+ throw RuntimeException("UniFFI API checksum mismatch: try cleaning and rebuilding your project")
+ }
+ if (lib.uniffi_mercurylib_checksum_func_create_transfer_update_msg() != 6918.toShort()) {
+ throw RuntimeException("UniFFI API checksum mismatch: try cleaning and rebuilding your project")
+ }
+ if (lib.uniffi_mercurylib_checksum_func_decode_statechain_address() != 7125.toShort()) {
+ throw RuntimeException("UniFFI API checksum mismatch: try cleaning and rebuilding your project")
+ }
+ if (lib.uniffi_mercurylib_checksum_func_duplicate_coin_to_initialized_state() != 30591.toShort()) {
+ throw RuntimeException("UniFFI API checksum mismatch: try cleaning and rebuilding your project")
+ }
+ if (lib.uniffi_mercurylib_checksum_func_ffi_validate_signature_scheme() != 26248.toShort()) {
+ throw RuntimeException("UniFFI API checksum mismatch: try cleaning and rebuilding your project")
+ }
+ if (lib.uniffi_mercurylib_checksum_func_ffi_verify_transfer_signature() != 18534.toShort()) {
+ throw RuntimeException("UniFFI API checksum mismatch: try cleaning and rebuilding your project")
+ }
+ if (lib.uniffi_mercurylib_checksum_func_fii_create_transfer_receiver_request_payload() != 58308.toShort()) {
+ throw RuntimeException("UniFFI API checksum mismatch: try cleaning and rebuilding your project")
+ }
+ if (lib.uniffi_mercurylib_checksum_func_fii_decrypt_transfer_msg() != 44515.toShort()) {
+ throw RuntimeException("UniFFI API checksum mismatch: try cleaning and rebuilding your project")
+ }
+ if (lib.uniffi_mercurylib_checksum_func_fii_validate_tx0_output_pubkey() != 51706.toShort()) {
+ throw RuntimeException("UniFFI API checksum mismatch: try cleaning and rebuilding your project")
+ }
+ if (lib.uniffi_mercurylib_checksum_func_fii_verify_latest_backup_tx_pays_to_user_pubkey() != 46083.toShort()) {
+ throw RuntimeException("UniFFI API checksum mismatch: try cleaning and rebuilding your project")
+ }
+ if (lib.uniffi_mercurylib_checksum_func_generate_mnemonic() != 62910.toShort()) {
+ throw RuntimeException("UniFFI API checksum mismatch: try cleaning and rebuilding your project")
+ }
+ if (lib.uniffi_mercurylib_checksum_func_get_blockheight() != 5222.toShort()) {
+ throw RuntimeException("UniFFI API checksum mismatch: try cleaning and rebuilding your project")
+ }
+ if (lib.uniffi_mercurylib_checksum_func_get_new_coin() != 45841.toShort()) {
+ throw RuntimeException("UniFFI API checksum mismatch: try cleaning and rebuilding your project")
+ }
+ if (lib.uniffi_mercurylib_checksum_func_get_new_key_info() != 64987.toShort()) {
+ throw RuntimeException("UniFFI API checksum mismatch: try cleaning and rebuilding your project")
+ }
+ if (lib.uniffi_mercurylib_checksum_func_get_output_address_from_tx0() != 62309.toShort()) {
+ throw RuntimeException("UniFFI API checksum mismatch: try cleaning and rebuilding your project")
+ }
+ if (lib.uniffi_mercurylib_checksum_func_get_partial_sig_request() != 13111.toShort()) {
+ throw RuntimeException("UniFFI API checksum mismatch: try cleaning and rebuilding your project")
+ }
+ if (lib.uniffi_mercurylib_checksum_func_get_tx0_outpoint() != 21467.toShort()) {
+ throw RuntimeException("UniFFI API checksum mismatch: try cleaning and rebuilding your project")
+ }
+ if (lib.uniffi_mercurylib_checksum_func_get_user_backup_address() != 29075.toShort()) {
+ throw RuntimeException("UniFFI API checksum mismatch: try cleaning and rebuilding your project")
+ }
+ if (lib.uniffi_mercurylib_checksum_func_handle_deposit_msg_1_response() != 64110.toShort()) {
+ throw RuntimeException("UniFFI API checksum mismatch: try cleaning and rebuilding your project")
+ }
+ if (lib.uniffi_mercurylib_checksum_func_is_enclave_pubkey_part_of_coin() != 37041.toShort()) {
+ throw RuntimeException("UniFFI API checksum mismatch: try cleaning and rebuilding your project")
+ }
+ if (lib.uniffi_mercurylib_checksum_func_latest_backup_tx_pays_to_user_pubkey() != 19689.toShort()) {
+ throw RuntimeException("UniFFI API checksum mismatch: try cleaning and rebuilding your project")
+ }
+ if (lib.uniffi_mercurylib_checksum_func_new_backup_transaction() != 56642.toShort()) {
+ throw RuntimeException("UniFFI API checksum mismatch: try cleaning and rebuilding your project")
+ }
+ if (lib.uniffi_mercurylib_checksum_func_sign_message() != 9994.toShort()) {
+ throw RuntimeException("UniFFI API checksum mismatch: try cleaning and rebuilding your project")
+ }
+ if (lib.uniffi_mercurylib_checksum_func_validate_address() != 16334.toShort()) {
+ throw RuntimeException("UniFFI API checksum mismatch: try cleaning and rebuilding your project")
+ }
+ if (lib.uniffi_mercurylib_checksum_func_verify_blinded_musig_scheme() != 42963.toShort()) {
+ throw RuntimeException("UniFFI API checksum mismatch: try cleaning and rebuilding your project")
+ }
+ if (lib.uniffi_mercurylib_checksum_func_verify_transaction_signature() != 32006.toShort()) {
+ throw RuntimeException("UniFFI API checksum mismatch: try cleaning and rebuilding your project")
+ }
+}
+
+// Async support
+
+// Public interface members begin here.
+
+// Interface implemented by anything that can contain an object reference.
+//
+// Such types expose a `destroy()` method that must be called to cleanly
+// dispose of the contained objects. Failure to call this method may result
+// in memory leaks.
+//
+// The easiest way to ensure this method is called is to use the `.use`
+// helper method to execute a block and destroy the object at the end.
+interface Disposable {
+ fun destroy()
+
+ companion object {
+ fun destroy(vararg args: Any?) {
+ args.filterIsInstance()
+ .forEach(Disposable::destroy)
+ }
+ }
+}
+
+inline fun T.use(block: (T) -> R) =
+ try {
+ block(this)
+ } finally {
+ try {
+ // N.B. our implementation is on the nullable type `Disposable?`.
+ this?.destroy()
+ } catch (e: Throwable) {
+ // swallow
+ }
+ }
+
+/** Used to instantiate an interface without an actual pointer, for fakes in tests, mostly. */
+object NoPointer
+
+public object FfiConverterUByte : FfiConverter {
+ override fun lift(value: Byte): UByte {
+ return value.toUByte()
+ }
+
+ override fun read(buf: ByteBuffer): UByte {
+ return lift(buf.get())
+ }
+
+ override fun lower(value: UByte): Byte {
+ return value.toByte()
+ }
+
+ override fun allocationSize(value: UByte) = 1UL
+
+ override fun write(
+ value: UByte,
+ buf: ByteBuffer,
+ ) {
+ buf.put(value.toByte())
+ }
+}
+
+public object FfiConverterUInt : FfiConverter {
+ override fun lift(value: Int): UInt {
+ return value.toUInt()
+ }
+
+ override fun read(buf: ByteBuffer): UInt {
+ return lift(buf.getInt())
+ }
+
+ override fun lower(value: UInt): Int {
+ return value.toInt()
+ }
+
+ override fun allocationSize(value: UInt) = 4UL
+
+ override fun write(
+ value: UInt,
+ buf: ByteBuffer,
+ ) {
+ buf.putInt(value.toInt())
+ }
+}
+
+public object FfiConverterULong : FfiConverter {
+ override fun lift(value: Long): ULong {
+ return value.toULong()
+ }
+
+ override fun read(buf: ByteBuffer): ULong {
+ return lift(buf.getLong())
+ }
+
+ override fun lower(value: ULong): Long {
+ return value.toLong()
+ }
+
+ override fun allocationSize(value: ULong) = 8UL
+
+ override fun write(
+ value: ULong,
+ buf: ByteBuffer,
+ ) {
+ buf.putLong(value.toLong())
+ }
+}
+
+public object FfiConverterBoolean : FfiConverter {
+ override fun lift(value: Byte): Boolean {
+ return value.toInt() != 0
+ }
+
+ override fun read(buf: ByteBuffer): Boolean {
+ return lift(buf.get())
+ }
+
+ override fun lower(value: Boolean): Byte {
+ return if (value) 1.toByte() else 0.toByte()
+ }
+
+ override fun allocationSize(value: Boolean) = 1UL
+
+ override fun write(
+ value: Boolean,
+ buf: ByteBuffer,
+ ) {
+ buf.put(lower(value))
+ }
+}
+
+public object FfiConverterString : FfiConverter {
+ // Note: we don't inherit from FfiConverterRustBuffer, because we use a
+ // special encoding when lowering/lifting. We can use `RustBuffer.len` to
+ // store our length and avoid writing it out to the buffer.
+ override fun lift(value: RustBuffer.ByValue): String {
+ try {
+ val byteArr = ByteArray(value.len.toInt())
+ value.asByteBuffer()!!.get(byteArr)
+ return byteArr.toString(Charsets.UTF_8)
+ } finally {
+ RustBuffer.free(value)
+ }
+ }
+
+ override fun read(buf: ByteBuffer): String {
+ val len = buf.getInt()
+ val byteArr = ByteArray(len)
+ buf.get(byteArr)
+ return byteArr.toString(Charsets.UTF_8)
+ }
+
+ fun toUtf8(value: String): ByteBuffer {
+ // Make sure we don't have invalid UTF-16, check for lone surrogates.
+ return Charsets.UTF_8.newEncoder().run {
+ onMalformedInput(CodingErrorAction.REPORT)
+ encode(CharBuffer.wrap(value))
+ }
+ }
+
+ override fun lower(value: String): RustBuffer.ByValue {
+ val byteBuf = toUtf8(value)
+ // Ideally we'd pass these bytes to `ffi_bytebuffer_from_bytes`, but doing so would require us
+ // to copy them into a JNA `Memory`. So we might as well directly copy them into a `RustBuffer`.
+ val rbuf = RustBuffer.alloc(byteBuf.limit().toULong())
+ rbuf.asByteBuffer()!!.put(byteBuf)
+ return rbuf
+ }
+
+ // We aren't sure exactly how many bytes our string will be once it's UTF-8
+ // encoded. Allocate 3 bytes per UTF-16 code unit which will always be
+ // enough.
+ override fun allocationSize(value: String): ULong {
+ val sizeForLength = 4UL
+ val sizeForString = value.length.toULong() * 3UL
+ return sizeForLength + sizeForString
+ }
+
+ override fun write(
+ value: String,
+ buf: ByteBuffer,
+ ) {
+ val byteBuf = toUtf8(value)
+ buf.putInt(byteBuf.limit())
+ buf.put(byteBuf)
+ }
+}
+
+public object FfiConverterByteArray : FfiConverterRustBuffer {
+ override fun read(buf: ByteBuffer): ByteArray {
+ val len = buf.getInt()
+ val byteArr = ByteArray(len)
+ buf.get(byteArr)
+ return byteArr
+ }
+
+ override fun allocationSize(value: ByteArray): ULong {
+ return 4UL + value.size.toULong()
+ }
+
+ override fun write(
+ value: ByteArray,
+ buf: ByteBuffer,
+ ) {
+ buf.putInt(value.size)
+ buf.put(value)
+ }
+}
+
+@Serializable
+data class Activity(
+ var `utxo`: kotlin.String,
+ var `amount`: kotlin.UInt,
+ var `action`: kotlin.String,
+ var `date`: kotlin.String,
+) {
+ companion object
+}
+
+public object FfiConverterTypeActivity : FfiConverterRustBuffer {
+ override fun read(buf: ByteBuffer): Activity {
+ return Activity(
+ FfiConverterString.read(buf),
+ FfiConverterUInt.read(buf),
+ FfiConverterString.read(buf),
+ FfiConverterString.read(buf),
+ )
+ }
+
+ override fun allocationSize(value: Activity) =
+ (
+ FfiConverterString.allocationSize(value.`utxo`) +
+ FfiConverterUInt.allocationSize(value.`amount`) +
+ FfiConverterString.allocationSize(value.`action`) +
+ FfiConverterString.allocationSize(value.`date`)
+ )
+
+ override fun write(
+ value: Activity,
+ buf: ByteBuffer,
+ ) {
+ FfiConverterString.write(value.`utxo`, buf)
+ FfiConverterUInt.write(value.`amount`, buf)
+ FfiConverterString.write(value.`action`, buf)
+ FfiConverterString.write(value.`date`, buf)
+ }
+}
+
+@Serializable
+data class AggregatedPublicKey(
+ var `aggregatePubkey`: kotlin.String,
+ var `aggregateAddress`: kotlin.String,
+) {
+ companion object
+}
+
+public object FfiConverterTypeAggregatedPublicKey : FfiConverterRustBuffer {
+ override fun read(buf: ByteBuffer): AggregatedPublicKey {
+ return AggregatedPublicKey(
+ FfiConverterString.read(buf),
+ FfiConverterString.read(buf),
+ )
+ }
+
+ override fun allocationSize(value: AggregatedPublicKey) =
+ (
+ FfiConverterString.allocationSize(value.`aggregatePubkey`) +
+ FfiConverterString.allocationSize(value.`aggregateAddress`)
+ )
+
+ override fun write(
+ value: AggregatedPublicKey,
+ buf: ByteBuffer,
+ ) {
+ FfiConverterString.write(value.`aggregatePubkey`, buf)
+ FfiConverterString.write(value.`aggregateAddress`, buf)
+ }
+}
+
+@Serializable
+data class BackupTx(
+ var `txN`: kotlin.UInt,
+ var `tx`: kotlin.String,
+ var `clientPublicNonce`: kotlin.String,
+ var `serverPublicNonce`: kotlin.String,
+ var `clientPublicKey`: kotlin.String,
+ var `serverPublicKey`: kotlin.String,
+ var `blindingFactor`: kotlin.String,
+) {
+ companion object
+}
+
+public object FfiConverterTypeBackupTx : FfiConverterRustBuffer {
+ override fun read(buf: ByteBuffer): BackupTx {
+ return BackupTx(
+ FfiConverterUInt.read(buf),
+ FfiConverterString.read(buf),
+ FfiConverterString.read(buf),
+ FfiConverterString.read(buf),
+ FfiConverterString.read(buf),
+ FfiConverterString.read(buf),
+ FfiConverterString.read(buf),
+ )
+ }
+
+ override fun allocationSize(value: BackupTx) =
+ (
+ FfiConverterUInt.allocationSize(value.`txN`) +
+ FfiConverterString.allocationSize(value.`tx`) +
+ FfiConverterString.allocationSize(value.`clientPublicNonce`) +
+ FfiConverterString.allocationSize(value.`serverPublicNonce`) +
+ FfiConverterString.allocationSize(value.`clientPublicKey`) +
+ FfiConverterString.allocationSize(value.`serverPublicKey`) +
+ FfiConverterString.allocationSize(value.`blindingFactor`)
+ )
+
+ override fun write(
+ value: BackupTx,
+ buf: ByteBuffer,
+ ) {
+ FfiConverterUInt.write(value.`txN`, buf)
+ FfiConverterString.write(value.`tx`, buf)
+ FfiConverterString.write(value.`clientPublicNonce`, buf)
+ FfiConverterString.write(value.`serverPublicNonce`, buf)
+ FfiConverterString.write(value.`clientPublicKey`, buf)
+ FfiConverterString.write(value.`serverPublicKey`, buf)
+ FfiConverterString.write(value.`blindingFactor`, buf)
+ }
+}
+
+@Serializable
+data class Coin(
+ var `index`: kotlin.UInt,
+ var `userPrivkey`: kotlin.String,
+ var `userPubkey`: kotlin.String,
+ var `authPrivkey`: kotlin.String,
+ var `authPubkey`: kotlin.String,
+ var `derivationPath`: kotlin.String,
+ var `fingerprint`: kotlin.String,
+ /**
+ * The coin address is the user_pubkey || auth_pubkey
+ * Used to transfer the coin to another wallet
+ */
+ var `address`: kotlin.String,
+ /**
+ * The backup address is the address used in backup transactions
+ * The backup address is the p2tr address of the user_pubkey
+ */
+ var `backupAddress`: kotlin.String,
+ var `serverPubkey`: kotlin.String?,
+ var `aggregatedPubkey`: kotlin.String?,
+ /**
+ * The aggregated address is the P2TR address from aggregated_pubkey
+ */
+ var `aggregatedAddress`: kotlin.String?,
+ var `utxoTxid`: kotlin.String?,
+ var `utxoVout`: kotlin.UInt?,
+ var `amount`: kotlin.UInt?,
+ var `statechainId`: kotlin.String?,
+ var `signedStatechainId`: kotlin.String?,
+ var `locktime`: kotlin.UInt?,
+ var `secretNonce`: kotlin.String?,
+ var `publicNonce`: kotlin.String?,
+ var `blindingFactor`: kotlin.String?,
+ var `serverPublicNonce`: kotlin.String?,
+ var `txCpfp`: kotlin.String?,
+ var `txWithdraw`: kotlin.String?,
+ var `withdrawalAddress`: kotlin.String?,
+ var `status`: CoinStatus,
+) {
+ companion object
+}
+
+public object FfiConverterTypeCoin : FfiConverterRustBuffer {
+ override fun read(buf: ByteBuffer): Coin {
+ return Coin(
+ FfiConverterUInt.read(buf),
+ FfiConverterString.read(buf),
+ FfiConverterString.read(buf),
+ FfiConverterString.read(buf),
+ FfiConverterString.read(buf),
+ FfiConverterString.read(buf),
+ FfiConverterString.read(buf),
+ FfiConverterString.read(buf),
+ FfiConverterString.read(buf),
+ FfiConverterOptionalString.read(buf),
+ FfiConverterOptionalString.read(buf),
+ FfiConverterOptionalString.read(buf),
+ FfiConverterOptionalString.read(buf),
+ FfiConverterOptionalUInt.read(buf),
+ FfiConverterOptionalUInt.read(buf),
+ FfiConverterOptionalString.read(buf),
+ FfiConverterOptionalString.read(buf),
+ FfiConverterOptionalUInt.read(buf),
+ FfiConverterOptionalString.read(buf),
+ FfiConverterOptionalString.read(buf),
+ FfiConverterOptionalString.read(buf),
+ FfiConverterOptionalString.read(buf),
+ FfiConverterOptionalString.read(buf),
+ FfiConverterOptionalString.read(buf),
+ FfiConverterOptionalString.read(buf),
+ FfiConverterTypeCoinStatus.read(buf),
+ )
+ }
+
+ override fun allocationSize(value: Coin) =
+ (
+ FfiConverterUInt.allocationSize(value.`index`) +
+ FfiConverterString.allocationSize(value.`userPrivkey`) +
+ FfiConverterString.allocationSize(value.`userPubkey`) +
+ FfiConverterString.allocationSize(value.`authPrivkey`) +
+ FfiConverterString.allocationSize(value.`authPubkey`) +
+ FfiConverterString.allocationSize(value.`derivationPath`) +
+ FfiConverterString.allocationSize(value.`fingerprint`) +
+ FfiConverterString.allocationSize(value.`address`) +
+ FfiConverterString.allocationSize(value.`backupAddress`) +
+ FfiConverterOptionalString.allocationSize(value.`serverPubkey`) +
+ FfiConverterOptionalString.allocationSize(value.`aggregatedPubkey`) +
+ FfiConverterOptionalString.allocationSize(value.`aggregatedAddress`) +
+ FfiConverterOptionalString.allocationSize(value.`utxoTxid`) +
+ FfiConverterOptionalUInt.allocationSize(value.`utxoVout`) +
+ FfiConverterOptionalUInt.allocationSize(value.`amount`) +
+ FfiConverterOptionalString.allocationSize(value.`statechainId`) +
+ FfiConverterOptionalString.allocationSize(value.`signedStatechainId`) +
+ FfiConverterOptionalUInt.allocationSize(value.`locktime`) +
+ FfiConverterOptionalString.allocationSize(value.`secretNonce`) +
+ FfiConverterOptionalString.allocationSize(value.`publicNonce`) +
+ FfiConverterOptionalString.allocationSize(value.`blindingFactor`) +
+ FfiConverterOptionalString.allocationSize(value.`serverPublicNonce`) +
+ FfiConverterOptionalString.allocationSize(value.`txCpfp`) +
+ FfiConverterOptionalString.allocationSize(value.`txWithdraw`) +
+ FfiConverterOptionalString.allocationSize(value.`withdrawalAddress`) +
+ FfiConverterTypeCoinStatus.allocationSize(value.`status`)
+ )
+
+ override fun write(
+ value: Coin,
+ buf: ByteBuffer,
+ ) {
+ FfiConverterUInt.write(value.`index`, buf)
+ FfiConverterString.write(value.`userPrivkey`, buf)
+ FfiConverterString.write(value.`userPubkey`, buf)
+ FfiConverterString.write(value.`authPrivkey`, buf)
+ FfiConverterString.write(value.`authPubkey`, buf)
+ FfiConverterString.write(value.`derivationPath`, buf)
+ FfiConverterString.write(value.`fingerprint`, buf)
+ FfiConverterString.write(value.`address`, buf)
+ FfiConverterString.write(value.`backupAddress`, buf)
+ FfiConverterOptionalString.write(value.`serverPubkey`, buf)
+ FfiConverterOptionalString.write(value.`aggregatedPubkey`, buf)
+ FfiConverterOptionalString.write(value.`aggregatedAddress`, buf)
+ FfiConverterOptionalString.write(value.`utxoTxid`, buf)
+ FfiConverterOptionalUInt.write(value.`utxoVout`, buf)
+ FfiConverterOptionalUInt.write(value.`amount`, buf)
+ FfiConverterOptionalString.write(value.`statechainId`, buf)
+ FfiConverterOptionalString.write(value.`signedStatechainId`, buf)
+ FfiConverterOptionalUInt.write(value.`locktime`, buf)
+ FfiConverterOptionalString.write(value.`secretNonce`, buf)
+ FfiConverterOptionalString.write(value.`publicNonce`, buf)
+ FfiConverterOptionalString.write(value.`blindingFactor`, buf)
+ FfiConverterOptionalString.write(value.`serverPublicNonce`, buf)
+ FfiConverterOptionalString.write(value.`txCpfp`, buf)
+ FfiConverterOptionalString.write(value.`txWithdraw`, buf)
+ FfiConverterOptionalString.write(value.`withdrawalAddress`, buf)
+ FfiConverterTypeCoinStatus.write(value.`status`, buf)
+ }
+}
+
+data class CoinNonce(
+ var `secretNonce`: kotlin.String,
+ var `publicNonce`: kotlin.String,
+ var `blindingFactor`: kotlin.String,
+ var `signFirstRequestPayload`: SignFirstRequestPayload,
+) {
+ companion object
+}
+
+public object FfiConverterTypeCoinNonce : FfiConverterRustBuffer {
+ override fun read(buf: ByteBuffer): CoinNonce {
+ return CoinNonce(
+ FfiConverterString.read(buf),
+ FfiConverterString.read(buf),
+ FfiConverterString.read(buf),
+ FfiConverterTypeSignFirstRequestPayload.read(buf),
+ )
+ }
+
+ override fun allocationSize(value: CoinNonce) =
+ (
+ FfiConverterString.allocationSize(value.`secretNonce`) +
+ FfiConverterString.allocationSize(value.`publicNonce`) +
+ FfiConverterString.allocationSize(value.`blindingFactor`) +
+ FfiConverterTypeSignFirstRequestPayload.allocationSize(value.`signFirstRequestPayload`)
+ )
+
+ override fun write(
+ value: CoinNonce,
+ buf: ByteBuffer,
+ ) {
+ FfiConverterString.write(value.`secretNonce`, buf)
+ FfiConverterString.write(value.`publicNonce`, buf)
+ FfiConverterString.write(value.`blindingFactor`, buf)
+ FfiConverterTypeSignFirstRequestPayload.write(value.`signFirstRequestPayload`, buf)
+ }
+}
+
+class CoinStatusParseError {
+ override fun equals(other: Any?): Boolean {
+ return other is CoinStatusParseError
+ }
+
+ override fun hashCode(): Int {
+ return javaClass.hashCode()
+ }
+
+ companion object
+}
+
+public object FfiConverterTypeCoinStatusParseError : FfiConverterRustBuffer {
+ override fun read(buf: ByteBuffer): CoinStatusParseError {
+ return CoinStatusParseError()
+ }
+
+ override fun allocationSize(value: CoinStatusParseError) = 0UL
+
+ override fun write(
+ value: CoinStatusParseError,
+ buf: ByteBuffer,
+ ) {
+ }
+}
+
+data class DecodedScAddress(
+ var `version`: kotlin.UByte,
+ var `userPubkey`: kotlin.String,
+ var `authPubkey`: kotlin.String,
+) {
+ companion object
+}
+
+public object FfiConverterTypeDecodedSCAddress : FfiConverterRustBuffer {
+ override fun read(buf: ByteBuffer): DecodedScAddress {
+ return DecodedScAddress(
+ FfiConverterUByte.read(buf),
+ FfiConverterString.read(buf),
+ FfiConverterString.read(buf),
+ )
+ }
+
+ override fun allocationSize(value: DecodedScAddress) =
+ (
+ FfiConverterUByte.allocationSize(value.`version`) +
+ FfiConverterString.allocationSize(value.`userPubkey`) +
+ FfiConverterString.allocationSize(value.`authPubkey`)
+ )
+
+ override fun write(
+ value: DecodedScAddress,
+ buf: ByteBuffer,
+ ) {
+ FfiConverterUByte.write(value.`version`, buf)
+ FfiConverterString.write(value.`userPubkey`, buf)
+ FfiConverterString.write(value.`authPubkey`, buf)
+ }
+}
+
+@Serializable
+data class DepositInitResult(
+ var `serverPubkey`: kotlin.String,
+ var `statechainId`: kotlin.String,
+ var `signedStatechainId`: kotlin.String,
+) {
+ companion object
+}
+
+public object FfiConverterTypeDepositInitResult : FfiConverterRustBuffer {
+ override fun read(buf: ByteBuffer): DepositInitResult {
+ return DepositInitResult(
+ FfiConverterString.read(buf),
+ FfiConverterString.read(buf),
+ FfiConverterString.read(buf),
+ )
+ }
+
+ override fun allocationSize(value: DepositInitResult) =
+ (
+ FfiConverterString.allocationSize(value.`serverPubkey`) +
+ FfiConverterString.allocationSize(value.`statechainId`) +
+ FfiConverterString.allocationSize(value.`signedStatechainId`)
+ )
+
+ override fun write(
+ value: DepositInitResult,
+ buf: ByteBuffer,
+ ) {
+ FfiConverterString.write(value.`serverPubkey`, buf)
+ FfiConverterString.write(value.`statechainId`, buf)
+ FfiConverterString.write(value.`signedStatechainId`, buf)
+ }
+}
+
+@Serializable
+data class DepositMsg1(
+ @SerialName("auth_key")
+ var `authKey`: kotlin.String,
+ @SerialName("token_id")
+ var `tokenId`: kotlin.String,
+ @SerialName("signed_token_id")
+ var `signedTokenId`: kotlin.String,
+) {
+ companion object
+}
+
+public object FfiConverterTypeDepositMsg1 : FfiConverterRustBuffer {
+ override fun read(buf: ByteBuffer): DepositMsg1 {
+ return DepositMsg1(
+ FfiConverterString.read(buf),
+ FfiConverterString.read(buf),
+ FfiConverterString.read(buf),
+ )
+ }
+
+ override fun allocationSize(value: DepositMsg1) =
+ (
+ FfiConverterString.allocationSize(value.`authKey`) +
+ FfiConverterString.allocationSize(value.`tokenId`) +
+ FfiConverterString.allocationSize(value.`signedTokenId`)
+ )
+
+ override fun write(
+ value: DepositMsg1,
+ buf: ByteBuffer,
+ ) {
+ FfiConverterString.write(value.`authKey`, buf)
+ FfiConverterString.write(value.`tokenId`, buf)
+ FfiConverterString.write(value.`signedTokenId`, buf)
+ }
+}
+
+@Serializable
+data class DepositMsg1Response(
+ @SerialName("server_pubkey")
+ var `serverPubkey`: kotlin.String,
+ @SerialName("statechain_id")
+ var `statechainId`: kotlin.String,
+) {
+ companion object
+}
+
+public object FfiConverterTypeDepositMsg1Response : FfiConverterRustBuffer {
+ override fun read(buf: ByteBuffer): DepositMsg1Response {
+ return DepositMsg1Response(
+ FfiConverterString.read(buf),
+ FfiConverterString.read(buf),
+ )
+ }
+
+ override fun allocationSize(value: DepositMsg1Response) =
+ (
+ FfiConverterString.allocationSize(value.`serverPubkey`) +
+ FfiConverterString.allocationSize(value.`statechainId`)
+ )
+
+ override fun write(
+ value: DepositMsg1Response,
+ buf: ByteBuffer,
+ ) {
+ FfiConverterString.write(value.`serverPubkey`, buf)
+ FfiConverterString.write(value.`statechainId`, buf)
+ }
+}
+
+data class FfiTransferMsg(
+ var `statechainId`: kotlin.String,
+ var `transferSignature`: kotlin.String,
+ var `backupTransactions`: List,
+ var `t1`: kotlin.ByteArray,
+ var `userPublicKey`: kotlin.String,
+) {
+ companion object
+}
+
+public object FfiConverterTypeFFITransferMsg : FfiConverterRustBuffer {
+ override fun read(buf: ByteBuffer): FfiTransferMsg {
+ return FfiTransferMsg(
+ FfiConverterString.read(buf),
+ FfiConverterString.read(buf),
+ FfiConverterSequenceTypeBackupTx.read(buf),
+ FfiConverterByteArray.read(buf),
+ FfiConverterString.read(buf),
+ )
+ }
+
+ override fun allocationSize(value: FfiTransferMsg) =
+ (
+ FfiConverterString.allocationSize(value.`statechainId`) +
+ FfiConverterString.allocationSize(value.`transferSignature`) +
+ FfiConverterSequenceTypeBackupTx.allocationSize(value.`backupTransactions`) +
+ FfiConverterByteArray.allocationSize(value.`t1`) +
+ FfiConverterString.allocationSize(value.`userPublicKey`)
+ )
+
+ override fun write(
+ value: FfiTransferMsg,
+ buf: ByteBuffer,
+ ) {
+ FfiConverterString.write(value.`statechainId`, buf)
+ FfiConverterString.write(value.`transferSignature`, buf)
+ FfiConverterSequenceTypeBackupTx.write(value.`backupTransactions`, buf)
+ FfiConverterByteArray.write(value.`t1`, buf)
+ FfiConverterString.write(value.`userPublicKey`, buf)
+ }
+}
+
+@Serializable
+data class GetMsgAddrResponsePayload(
+ @SerialName("list_enc_transfer_msg")
+ var `listEncTransferMsg`: List,
+) {
+ companion object
+}
+
+public object FfiConverterTypeGetMsgAddrResponsePayload : FfiConverterRustBuffer {
+ override fun read(buf: ByteBuffer): GetMsgAddrResponsePayload {
+ return GetMsgAddrResponsePayload(
+ FfiConverterSequenceString.read(buf),
+ )
+ }
+
+ override fun allocationSize(value: GetMsgAddrResponsePayload) =
+ (
+ FfiConverterSequenceString.allocationSize(value.`listEncTransferMsg`)
+ )
+
+ override fun write(
+ value: GetMsgAddrResponsePayload,
+ buf: ByteBuffer,
+ ) {
+ FfiConverterSequenceString.write(value.`listEncTransferMsg`, buf)
+ }
+}
+
+data class InfoConfig(
+ var `initlock`: kotlin.UInt,
+ var `interval`: kotlin.UInt,
+ var `feeRateSatsPerByte`: kotlin.ULong,
+) {
+ companion object
+}
+
+public object FfiConverterTypeInfoConfig : FfiConverterRustBuffer {
+ override fun read(buf: ByteBuffer): InfoConfig {
+ return InfoConfig(
+ FfiConverterUInt.read(buf),
+ FfiConverterUInt.read(buf),
+ FfiConverterULong.read(buf),
+ )
+ }
+
+ override fun allocationSize(value: InfoConfig) =
+ (
+ FfiConverterUInt.allocationSize(value.`initlock`) +
+ FfiConverterUInt.allocationSize(value.`interval`) +
+ FfiConverterULong.allocationSize(value.`feeRateSatsPerByte`)
+ )
+
+ override fun write(
+ value: InfoConfig,
+ buf: ByteBuffer,
+ ) {
+ FfiConverterUInt.write(value.`initlock`, buf)
+ FfiConverterUInt.write(value.`interval`, buf)
+ FfiConverterULong.write(value.`feeRateSatsPerByte`, buf)
+ }
+}
+
+data class KeyListResponsePayload(
+ var `listKeyinfo`: List,
+) {
+ companion object
+}
+
+public object FfiConverterTypeKeyListResponsePayload : FfiConverterRustBuffer {
+ override fun read(buf: ByteBuffer): KeyListResponsePayload {
+ return KeyListResponsePayload(
+ FfiConverterSequenceTypePubKeyInfo.read(buf),
+ )
+ }
+
+ override fun allocationSize(value: KeyListResponsePayload) =
+ (
+ FfiConverterSequenceTypePubKeyInfo.allocationSize(value.`listKeyinfo`)
+ )
+
+ override fun write(
+ value: KeyListResponsePayload,
+ buf: ByteBuffer,
+ ) {
+ FfiConverterSequenceTypePubKeyInfo.write(value.`listKeyinfo`, buf)
+ }
+}
+
+@Serializable
+data class KeyUpdateResponsePayload(
+ @SerialName("statechain_id")
+ var `statechainId`: kotlin.String,
+ var `t2`: kotlin.String,
+ var `x1`: kotlin.String,
+) {
+ companion object
+}
+
+public object FfiConverterTypeKeyUpdateResponsePayload : FfiConverterRustBuffer {
+ override fun read(buf: ByteBuffer): KeyUpdateResponsePayload {
+ return KeyUpdateResponsePayload(
+ FfiConverterString.read(buf),
+ FfiConverterString.read(buf),
+ FfiConverterString.read(buf),
+ )
+ }
+
+ override fun allocationSize(value: KeyUpdateResponsePayload) =
+ (
+ FfiConverterString.allocationSize(value.`statechainId`) +
+ FfiConverterString.allocationSize(value.`t2`) +
+ FfiConverterString.allocationSize(value.`x1`)
+ )
+
+ override fun write(
+ value: KeyUpdateResponsePayload,
+ buf: ByteBuffer,
+ ) {
+ FfiConverterString.write(value.`statechainId`, buf)
+ FfiConverterString.write(value.`t2`, buf)
+ FfiConverterString.write(value.`x1`, buf)
+ }
+}
+
+data class NewKeyInfo(
+ var `aggregatePubkey`: kotlin.String,
+ var `aggregateAddress`: kotlin.String,
+ var `signedStatechainId`: kotlin.String,
+ var `amount`: kotlin.UInt,
+) {
+ companion object
+}
+
+public object FfiConverterTypeNewKeyInfo : FfiConverterRustBuffer {
+ override fun read(buf: ByteBuffer): NewKeyInfo {
+ return NewKeyInfo(
+ FfiConverterString.read(buf),
+ FfiConverterString.read(buf),
+ FfiConverterString.read(buf),
+ FfiConverterUInt.read(buf),
+ )
+ }
+
+ override fun allocationSize(value: NewKeyInfo) =
+ (
+ FfiConverterString.allocationSize(value.`aggregatePubkey`) +
+ FfiConverterString.allocationSize(value.`aggregateAddress`) +
+ FfiConverterString.allocationSize(value.`signedStatechainId`) +
+ FfiConverterUInt.allocationSize(value.`amount`)
+ )
+
+ override fun write(
+ value: NewKeyInfo,
+ buf: ByteBuffer,
+ ) {
+ FfiConverterString.write(value.`aggregatePubkey`, buf)
+ FfiConverterString.write(value.`aggregateAddress`, buf)
+ FfiConverterString.write(value.`signedStatechainId`, buf)
+ FfiConverterUInt.write(value.`amount`, buf)
+ }
+}
+
+data class PartialSignatureMsg1(
+ var `msg`: kotlin.String,
+ var `outputPubkey`: kotlin.String,
+ var `clientPartialSig`: kotlin.String,
+ var `encodedSession`: kotlin.String,
+ var `encodedUnsignedTx`: kotlin.String,
+ var `partialSignatureRequestPayload`: PartialSignatureRequestPayload,
+) {
+ companion object
+}
+
+public object FfiConverterTypePartialSignatureMsg1 : FfiConverterRustBuffer {
+ override fun read(buf: ByteBuffer): PartialSignatureMsg1 {
+ return PartialSignatureMsg1(
+ FfiConverterString.read(buf),
+ FfiConverterString.read(buf),
+ FfiConverterString.read(buf),
+ FfiConverterString.read(buf),
+ FfiConverterString.read(buf),
+ FfiConverterTypePartialSignatureRequestPayload.read(buf),
+ )
+ }
+
+ override fun allocationSize(value: PartialSignatureMsg1) =
+ (
+ FfiConverterString.allocationSize(value.`msg`) +
+ FfiConverterString.allocationSize(value.`outputPubkey`) +
+ FfiConverterString.allocationSize(value.`clientPartialSig`) +
+ FfiConverterString.allocationSize(value.`encodedSession`) +
+ FfiConverterString.allocationSize(value.`encodedUnsignedTx`) +
+ FfiConverterTypePartialSignatureRequestPayload.allocationSize(value.`partialSignatureRequestPayload`)
+ )
+
+ override fun write(
+ value: PartialSignatureMsg1,
+ buf: ByteBuffer,
+ ) {
+ FfiConverterString.write(value.`msg`, buf)
+ FfiConverterString.write(value.`outputPubkey`, buf)
+ FfiConverterString.write(value.`clientPartialSig`, buf)
+ FfiConverterString.write(value.`encodedSession`, buf)
+ FfiConverterString.write(value.`encodedUnsignedTx`, buf)
+ FfiConverterTypePartialSignatureRequestPayload.write(value.`partialSignatureRequestPayload`, buf)
+ }
+}
+
+@Serializable
+data class PartialSignatureRequestPayload(
+ @SerialName("statechain_id")
+ var `statechainId`: kotlin.String,
+ @SerialName("negate_seckey")
+ var `negateSeckey`: kotlin.UByte,
+ var `session`: kotlin.String,
+ @SerialName("signed_statechain_id")
+ var `signedStatechainId`: kotlin.String,
+ @SerialName("server_pub_nonce")
+ var `serverPubNonce`: kotlin.String,
+) {
+ companion object
+}
+
+public object FfiConverterTypePartialSignatureRequestPayload : FfiConverterRustBuffer {
+ override fun read(buf: ByteBuffer): PartialSignatureRequestPayload {
+ return PartialSignatureRequestPayload(
+ FfiConverterString.read(buf),
+ FfiConverterUByte.read(buf),
+ FfiConverterString.read(buf),
+ FfiConverterString.read(buf),
+ FfiConverterString.read(buf),
+ )
+ }
+
+ override fun allocationSize(value: PartialSignatureRequestPayload) =
+ (
+ FfiConverterString.allocationSize(value.`statechainId`) +
+ FfiConverterUByte.allocationSize(value.`negateSeckey`) +
+ FfiConverterString.allocationSize(value.`session`) +
+ FfiConverterString.allocationSize(value.`signedStatechainId`) +
+ FfiConverterString.allocationSize(value.`serverPubNonce`)
+ )
+
+ override fun write(
+ value: PartialSignatureRequestPayload,
+ buf: ByteBuffer,
+ ) {
+ FfiConverterString.write(value.`statechainId`, buf)
+ FfiConverterUByte.write(value.`negateSeckey`, buf)
+ FfiConverterString.write(value.`session`, buf)
+ FfiConverterString.write(value.`signedStatechainId`, buf)
+ FfiConverterString.write(value.`serverPubNonce`, buf)
+ }
+}
+
+@Serializable
+data class PartialSignatureResponsePayload(
+ @SerialName("partial_sig")
+ var `partialSig`: kotlin.String,
+) {
+ companion object
+}
+
+public object FfiConverterTypePartialSignatureResponsePayload : FfiConverterRustBuffer {
+ override fun read(buf: ByteBuffer): PartialSignatureResponsePayload {
+ return PartialSignatureResponsePayload(
+ FfiConverterString.read(buf),
+ )
+ }
+
+ override fun allocationSize(value: PartialSignatureResponsePayload) =
+ (
+ FfiConverterString.allocationSize(value.`partialSig`)
+ )
+
+ override fun write(
+ value: PartialSignatureResponsePayload,
+ buf: ByteBuffer,
+ ) {
+ FfiConverterString.write(value.`partialSig`, buf)
+ }
+}
+
+data class PubKeyInfo(
+ var `serverPubkey`: kotlin.String,
+ var `txN`: kotlin.UInt,
+ var `updatedAt`: kotlin.String,
+) {
+ companion object
+}
+
+public object FfiConverterTypePubKeyInfo : FfiConverterRustBuffer {
+ override fun read(buf: ByteBuffer): PubKeyInfo {
+ return PubKeyInfo(
+ FfiConverterString.read(buf),
+ FfiConverterUInt.read(buf),
+ FfiConverterString.read(buf),
+ )
+ }
+
+ override fun allocationSize(value: PubKeyInfo) =
+ (
+ FfiConverterString.allocationSize(value.`serverPubkey`) +
+ FfiConverterUInt.allocationSize(value.`txN`) +
+ FfiConverterString.allocationSize(value.`updatedAt`)
+ )
+
+ override fun write(
+ value: PubKeyInfo,
+ buf: ByteBuffer,
+ ) {
+ FfiConverterString.write(value.`serverPubkey`, buf)
+ FfiConverterUInt.write(value.`txN`, buf)
+ FfiConverterString.write(value.`updatedAt`, buf)
+ }
+}
+
+@Serializable
+data class ServerConfig(
+ var `initlock`: kotlin.UInt,
+ var `interval`: kotlin.UInt,
+) {
+ companion object
+}
+
+public object FfiConverterTypeServerConfig : FfiConverterRustBuffer {
+ override fun read(buf: ByteBuffer): ServerConfig {
+ return ServerConfig(
+ FfiConverterUInt.read(buf),
+ FfiConverterUInt.read(buf),
+ )
+ }
+
+ override fun allocationSize(value: ServerConfig) =
+ (
+ FfiConverterUInt.allocationSize(value.`initlock`) +
+ FfiConverterUInt.allocationSize(value.`interval`)
+ )
+
+ override fun write(
+ value: ServerConfig,
+ buf: ByteBuffer,
+ ) {
+ FfiConverterUInt.write(value.`initlock`, buf)
+ FfiConverterUInt.write(value.`interval`, buf)
+ }
+}
+
+data class ServerPublicNonceResponsePayload(
+ var `serverPubnonce`: kotlin.String,
+) {
+ companion object
+}
+
+public object FfiConverterTypeServerPublicNonceResponsePayload : FfiConverterRustBuffer {
+ override fun read(buf: ByteBuffer): ServerPublicNonceResponsePayload {
+ return ServerPublicNonceResponsePayload(
+ FfiConverterString.read(buf),
+ )
+ }
+
+ override fun allocationSize(value: ServerPublicNonceResponsePayload) =
+ (
+ FfiConverterString.allocationSize(value.`serverPubnonce`)
+ )
+
+ override fun write(
+ value: ServerPublicNonceResponsePayload,
+ buf: ByteBuffer,
+ ) {
+ FfiConverterString.write(value.`serverPubnonce`, buf)
+ }
+}
+
+@Serializable
+data class Settings(
+ var `network`: kotlin.String,
+ var `blockExplorerUrl`: kotlin.String?,
+ var `torProxyHost`: kotlin.String?,
+ var `torProxyPort`: kotlin.String?,
+ var `torProxyControlPassword`: kotlin.String?,
+ var `torProxyControlPort`: kotlin.String?,
+ var `statechainEntityApi`: kotlin.String,
+ var `torStatechainEntityApi`: kotlin.String?,
+ var `electrumProtocol`: kotlin.String,
+ var `electrumHost`: kotlin.String,
+ var `electrumPort`: kotlin.String,
+ var `electrumType`: kotlin.String,
+ var `notifications`: kotlin.Boolean,
+ var `tutorials`: kotlin.Boolean,
+) {
+ companion object
+}
+
+public object FfiConverterTypeSettings : FfiConverterRustBuffer {
+ override fun read(buf: ByteBuffer): Settings {
+ return Settings(
+ FfiConverterString.read(buf),
+ FfiConverterOptionalString.read(buf),
+ FfiConverterOptionalString.read(buf),
+ FfiConverterOptionalString.read(buf),
+ FfiConverterOptionalString.read(buf),
+ FfiConverterOptionalString.read(buf),
+ FfiConverterString.read(buf),
+ FfiConverterOptionalString.read(buf),
+ FfiConverterString.read(buf),
+ FfiConverterString.read(buf),
+ FfiConverterString.read(buf),
+ FfiConverterString.read(buf),
+ FfiConverterBoolean.read(buf),
+ FfiConverterBoolean.read(buf),
+ )
+ }
+
+ override fun allocationSize(value: Settings) =
+ (
+ FfiConverterString.allocationSize(value.`network`) +
+ FfiConverterOptionalString.allocationSize(value.`blockExplorerUrl`) +
+ FfiConverterOptionalString.allocationSize(value.`torProxyHost`) +
+ FfiConverterOptionalString.allocationSize(value.`torProxyPort`) +
+ FfiConverterOptionalString.allocationSize(value.`torProxyControlPassword`) +
+ FfiConverterOptionalString.allocationSize(value.`torProxyControlPort`) +
+ FfiConverterString.allocationSize(value.`statechainEntityApi`) +
+ FfiConverterOptionalString.allocationSize(value.`torStatechainEntityApi`) +
+ FfiConverterString.allocationSize(value.`electrumProtocol`) +
+ FfiConverterString.allocationSize(value.`electrumHost`) +
+ FfiConverterString.allocationSize(value.`electrumPort`) +
+ FfiConverterString.allocationSize(value.`electrumType`) +
+ FfiConverterBoolean.allocationSize(value.`notifications`) +
+ FfiConverterBoolean.allocationSize(value.`tutorials`)
+ )
+
+ override fun write(
+ value: Settings,
+ buf: ByteBuffer,
+ ) {
+ FfiConverterString.write(value.`network`, buf)
+ FfiConverterOptionalString.write(value.`blockExplorerUrl`, buf)
+ FfiConverterOptionalString.write(value.`torProxyHost`, buf)
+ FfiConverterOptionalString.write(value.`torProxyPort`, buf)
+ FfiConverterOptionalString.write(value.`torProxyControlPassword`, buf)
+ FfiConverterOptionalString.write(value.`torProxyControlPort`, buf)
+ FfiConverterString.write(value.`statechainEntityApi`, buf)
+ FfiConverterOptionalString.write(value.`torStatechainEntityApi`, buf)
+ FfiConverterString.write(value.`electrumProtocol`, buf)
+ FfiConverterString.write(value.`electrumHost`, buf)
+ FfiConverterString.write(value.`electrumPort`, buf)
+ FfiConverterString.write(value.`electrumType`, buf)
+ FfiConverterBoolean.write(value.`notifications`, buf)
+ FfiConverterBoolean.write(value.`tutorials`, buf)
+ }
+}
+
+@Serializable
+data class SignFirstRequestPayload(
+ @SerialName("statechain_id")
+ var `statechainId`: kotlin.String,
+ @SerialName("signed_statechain_id")
+ var `signedStatechainId`: kotlin.String,
+) {
+ companion object
+}
+
+public object FfiConverterTypeSignFirstRequestPayload : FfiConverterRustBuffer {
+ override fun read(buf: ByteBuffer): SignFirstRequestPayload {
+ return SignFirstRequestPayload(
+ FfiConverterString.read(buf),
+ FfiConverterString.read(buf),
+ )
+ }
+
+ override fun allocationSize(value: SignFirstRequestPayload) =
+ (
+ FfiConverterString.allocationSize(value.`statechainId`) +
+ FfiConverterString.allocationSize(value.`signedStatechainId`)
+ )
+
+ override fun write(
+ value: SignFirstRequestPayload,
+ buf: ByteBuffer,
+ ) {
+ FfiConverterString.write(value.`statechainId`, buf)
+ FfiConverterString.write(value.`signedStatechainId`, buf)
+ }
+}
+
+@Serializable
+data class SignFirstResponsePayload(
+ @SerialName("server_pubnonce")
+ var `serverPubnonce`: kotlin.String,
+) {
+ companion object
+}
+
+public object FfiConverterTypeSignFirstResponsePayload : FfiConverterRustBuffer {
+ override fun read(buf: ByteBuffer): SignFirstResponsePayload {
+ return SignFirstResponsePayload(
+ FfiConverterString.read(buf),
+ )
+ }
+
+ override fun allocationSize(value: SignFirstResponsePayload) =
+ (
+ FfiConverterString.allocationSize(value.`serverPubnonce`)
+ )
+
+ override fun write(
+ value: SignFirstResponsePayload,
+ buf: ByteBuffer,
+ ) {
+ FfiConverterString.write(value.`serverPubnonce`, buf)
+ }
+}
+
+data class StatechainBackupTxs(
+ var `statechainId`: kotlin.String,
+ var `backupTxs`: List,
+) {
+ companion object
+}
+
+public object FfiConverterTypeStatechainBackupTxs : FfiConverterRustBuffer {
+ override fun read(buf: ByteBuffer): StatechainBackupTxs {
+ return StatechainBackupTxs(
+ FfiConverterString.read(buf),
+ FfiConverterSequenceTypeBackupTx.read(buf),
+ )
+ }
+
+ override fun allocationSize(value: StatechainBackupTxs) =
+ (
+ FfiConverterString.allocationSize(value.`statechainId`) +
+ FfiConverterSequenceTypeBackupTx.allocationSize(value.`backupTxs`)
+ )
+
+ override fun write(
+ value: StatechainBackupTxs,
+ buf: ByteBuffer,
+ ) {
+ FfiConverterString.write(value.`statechainId`, buf)
+ FfiConverterSequenceTypeBackupTx.write(value.`backupTxs`, buf)
+ }
+}
+
+@Serializable
+data class StatechainInfo(
+ @SerialName("statechain_id")
+ var `statechainId`: kotlin.String,
+ @SerialName("server_pubnonce")
+ var `serverPubnonce`: kotlin.String,
+ var `challenge`: kotlin.String,
+ @SerialName("tx_n")
+ var `txN`: kotlin.UInt,
+) {
+ companion object
+}
+
+public object FfiConverterTypeStatechainInfo : FfiConverterRustBuffer {
+ override fun read(buf: ByteBuffer): StatechainInfo {
+ return StatechainInfo(
+ FfiConverterString.read(buf),
+ FfiConverterString.read(buf),
+ FfiConverterString.read(buf),
+ FfiConverterUInt.read(buf),
+ )
+ }
+
+ override fun allocationSize(value: StatechainInfo) =
+ (
+ FfiConverterString.allocationSize(value.`statechainId`) +
+ FfiConverterString.allocationSize(value.`serverPubnonce`) +
+ FfiConverterString.allocationSize(value.`challenge`) +
+ FfiConverterUInt.allocationSize(value.`txN`)
+ )
+
+ override fun write(
+ value: StatechainInfo,
+ buf: ByteBuffer,
+ ) {
+ FfiConverterString.write(value.`statechainId`, buf)
+ FfiConverterString.write(value.`serverPubnonce`, buf)
+ FfiConverterString.write(value.`challenge`, buf)
+ FfiConverterUInt.write(value.`txN`, buf)
+ }
+}
+
+@Serializable
+data class StatechainInfoResponsePayload(
+ @SerialName("enclave_public_key")
+ var `enclavePublicKey`: kotlin.String,
+ @SerialName("num_sigs")
+ var `numSigs`: kotlin.UInt,
+ @SerialName("statechain_info")
+ var `statechainInfo`: List,
+ @SerialName("x1_pub")
+ var `x1Pub`: kotlin.String?,
+) {
+ companion object
+}
+
+public object FfiConverterTypeStatechainInfoResponsePayload : FfiConverterRustBuffer {
+ override fun read(buf: ByteBuffer): StatechainInfoResponsePayload {
+ return StatechainInfoResponsePayload(
+ FfiConverterString.read(buf),
+ FfiConverterUInt.read(buf),
+ FfiConverterSequenceTypeStatechainInfo.read(buf),
+ FfiConverterOptionalString.read(buf),
+ )
+ }
+
+ override fun allocationSize(value: StatechainInfoResponsePayload) =
+ (
+ FfiConverterString.allocationSize(value.`enclavePublicKey`) +
+ FfiConverterUInt.allocationSize(value.`numSigs`) +
+ FfiConverterSequenceTypeStatechainInfo.allocationSize(value.`statechainInfo`) +
+ FfiConverterOptionalString.allocationSize(value.`x1Pub`)
+ )
+
+ override fun write(
+ value: StatechainInfoResponsePayload,
+ buf: ByteBuffer,
+ ) {
+ FfiConverterString.write(value.`enclavePublicKey`, buf)
+ FfiConverterUInt.write(value.`numSigs`, buf)
+ FfiConverterSequenceTypeStatechainInfo.write(value.`statechainInfo`, buf)
+ FfiConverterOptionalString.write(value.`x1Pub`, buf)
+ }
+}
+
+@Serializable
+data class Token(
+ @SerialName("btc_payment_address")
+ var `btcPaymentAddress`: kotlin.String,
+ var `fee`: kotlin.String,
+ @SerialName("lightning_invoice")
+ var `lightningInvoice`: kotlin.String,
+ @SerialName("processor_id")
+ var `processorId`: kotlin.String,
+ @SerialName("token_id")
+ var `tokenId`: kotlin.String,
+ var `confirmed`: kotlin.Boolean,
+ var `spent`: kotlin.Boolean,
+ var `expiry`: kotlin.String,
+) {
+ companion object
+}
+
+public object FfiConverterTypeToken : FfiConverterRustBuffer {
+ override fun read(buf: ByteBuffer): Token {
+ return Token(
+ FfiConverterString.read(buf),
+ FfiConverterString.read(buf),
+ FfiConverterString.read(buf),
+ FfiConverterString.read(buf),
+ FfiConverterString.read(buf),
+ FfiConverterBoolean.read(buf),
+ FfiConverterBoolean.read(buf),
+ FfiConverterString.read(buf),
+ )
+ }
+
+ override fun allocationSize(value: Token) =
+ (
+ FfiConverterString.allocationSize(value.`btcPaymentAddress`) +
+ FfiConverterString.allocationSize(value.`fee`) +
+ FfiConverterString.allocationSize(value.`lightningInvoice`) +
+ FfiConverterString.allocationSize(value.`processorId`) +
+ FfiConverterString.allocationSize(value.`tokenId`) +
+ FfiConverterBoolean.allocationSize(value.`confirmed`) +
+ FfiConverterBoolean.allocationSize(value.`spent`) +
+ FfiConverterString.allocationSize(value.`expiry`)
+ )
+
+ override fun write(
+ value: Token,
+ buf: ByteBuffer,
+ ) {
+ FfiConverterString.write(value.`btcPaymentAddress`, buf)
+ FfiConverterString.write(value.`fee`, buf)
+ FfiConverterString.write(value.`lightningInvoice`, buf)
+ FfiConverterString.write(value.`processorId`, buf)
+ FfiConverterString.write(value.`tokenId`, buf)
+ FfiConverterBoolean.write(value.`confirmed`, buf)
+ FfiConverterBoolean.write(value.`spent`, buf)
+ FfiConverterString.write(value.`expiry`, buf)
+ }
+}
+
+@Serializable
+data class TransferReceiverErrorResponsePayload(
+ var `code`: TransferReceiverError,
+ var `message`: kotlin.String,
+) {
+ companion object
+}
+
+public object FfiConverterTypeTransferReceiverErrorResponsePayload : FfiConverterRustBuffer {
+ override fun read(buf: ByteBuffer): TransferReceiverErrorResponsePayload {
+ return TransferReceiverErrorResponsePayload(
+ FfiConverterTypeTransferReceiverError.read(buf),
+ FfiConverterString.read(buf),
+ )
+ }
+
+ override fun allocationSize(value: TransferReceiverErrorResponsePayload) =
+ (
+ FfiConverterTypeTransferReceiverError.allocationSize(value.`code`) +
+ FfiConverterString.allocationSize(value.`message`)
+ )
+
+ override fun write(
+ value: TransferReceiverErrorResponsePayload,
+ buf: ByteBuffer,
+ ) {
+ FfiConverterTypeTransferReceiverError.write(value.`code`, buf)
+ FfiConverterString.write(value.`message`, buf)
+ }
+}
+
+@Serializable
+data class TransferReceiverPostResponsePayload(
+ @SerialName("server_pubkey")
+ var `serverPubkey`: kotlin.String,
+) {
+ companion object
+}
+
+public object FfiConverterTypeTransferReceiverPostResponsePayload : FfiConverterRustBuffer {
+ override fun read(buf: ByteBuffer): TransferReceiverPostResponsePayload {
+ return TransferReceiverPostResponsePayload(
+ FfiConverterString.read(buf),
+ )
+ }
+
+ override fun allocationSize(value: TransferReceiverPostResponsePayload) =
+ (
+ FfiConverterString.allocationSize(value.`serverPubkey`)
+ )
+
+ override fun write(
+ value: TransferReceiverPostResponsePayload,
+ buf: ByteBuffer,
+ ) {
+ FfiConverterString.write(value.`serverPubkey`, buf)
+ }
+}
+
+@Serializable
+data class TransferReceiverRequestPayload(
+ @SerialName("statechain_id")
+ var `statechainId`: kotlin.String,
+ @SerialName("batch_data")
+ var `batchData`: kotlin.String?,
+ var `t2`: kotlin.String,
+ @SerialName("auth_sig")
+ var `authSig`: kotlin.String,
+) {
+ companion object
+}
+
+public object FfiConverterTypeTransferReceiverRequestPayload : FfiConverterRustBuffer {
+ override fun read(buf: ByteBuffer): TransferReceiverRequestPayload {
+ return TransferReceiverRequestPayload(
+ FfiConverterString.read(buf),
+ FfiConverterOptionalString.read(buf),
+ FfiConverterString.read(buf),
+ FfiConverterString.read(buf),
+ )
+ }
+
+ override fun allocationSize(value: TransferReceiverRequestPayload) =
+ (
+ FfiConverterString.allocationSize(value.`statechainId`) +
+ FfiConverterOptionalString.allocationSize(value.`batchData`) +
+ FfiConverterString.allocationSize(value.`t2`) +
+ FfiConverterString.allocationSize(value.`authSig`)
+ )
+
+ override fun write(
+ value: TransferReceiverRequestPayload,
+ buf: ByteBuffer,
+ ) {
+ FfiConverterString.write(value.`statechainId`, buf)
+ FfiConverterOptionalString.write(value.`batchData`, buf)
+ FfiConverterString.write(value.`t2`, buf)
+ FfiConverterString.write(value.`authSig`, buf)
+ }
+}
+
+@Serializable
+data class TransferSenderRequestPayload(
+ @SerialName("statechain_id")
+ var `statechainId`: kotlin.String,
+ @SerialName("auth_sig")
+ var `authSig`: kotlin.String,
+ @SerialName("new_user_auth_key")
+ var `newUserAuthKey`: kotlin.String,
+ @SerialName("batch_id")
+ var `batchId`: kotlin.String?,
+) {
+ companion object
+}
+
+public object FfiConverterTypeTransferSenderRequestPayload : FfiConverterRustBuffer {
+ override fun read(buf: ByteBuffer): TransferSenderRequestPayload {
+ return TransferSenderRequestPayload(
+ FfiConverterString.read(buf),
+ FfiConverterString.read(buf),
+ FfiConverterString.read(buf),
+ FfiConverterOptionalString.read(buf),
+ )
+ }
+
+ override fun allocationSize(value: TransferSenderRequestPayload) =
+ (
+ FfiConverterString.allocationSize(value.`statechainId`) +
+ FfiConverterString.allocationSize(value.`authSig`) +
+ FfiConverterString.allocationSize(value.`newUserAuthKey`) +
+ FfiConverterOptionalString.allocationSize(value.`batchId`)
+ )
+
+ override fun write(
+ value: TransferSenderRequestPayload,
+ buf: ByteBuffer,
+ ) {
+ FfiConverterString.write(value.`statechainId`, buf)
+ FfiConverterString.write(value.`authSig`, buf)
+ FfiConverterString.write(value.`newUserAuthKey`, buf)
+ FfiConverterOptionalString.write(value.`batchId`, buf)
+ }
+}
+
+@Serializable
+data class TransferSenderResponsePayload(
+ var `x1`: kotlin.String,
+) {
+ companion object
+}
+
+public object FfiConverterTypeTransferSenderResponsePayload : FfiConverterRustBuffer {
+ override fun read(buf: ByteBuffer): TransferSenderResponsePayload {
+ return TransferSenderResponsePayload(
+ FfiConverterString.read(buf),
+ )
+ }
+
+ override fun allocationSize(value: TransferSenderResponsePayload) =
+ (
+ FfiConverterString.allocationSize(value.`x1`)
+ )
+
+ override fun write(
+ value: TransferSenderResponsePayload,
+ buf: ByteBuffer,
+ ) {
+ FfiConverterString.write(value.`x1`, buf)
+ }
+}
+
+@Serializable
+data class TransferUnlockRequestPayload(
+ @SerialName("statechain_id")
+ var `statechainId`: kotlin.String,
+ @SerialName("auth_sig")
+ var `authSig`: kotlin.String,
+ @SerialName("auth_pub_key")
+ var `authPubKey`: kotlin.String,
+) {
+ companion object
+}
+
+public object FfiConverterTypeTransferUnlockRequestPayload : FfiConverterRustBuffer {
+ override fun read(buf: ByteBuffer): TransferUnlockRequestPayload {
+ return TransferUnlockRequestPayload(
+ FfiConverterString.read(buf),
+ FfiConverterString.read(buf),
+ FfiConverterString.read(buf),
+ )
+ }
+
+ override fun allocationSize(value: TransferUnlockRequestPayload) =
+ (
+ FfiConverterString.allocationSize(value.`statechainId`) +
+ FfiConverterString.allocationSize(value.`authSig`) +
+ FfiConverterString.allocationSize(value.`authPubKey`)
+ )
+
+ override fun write(
+ value: TransferUnlockRequestPayload,
+ buf: ByteBuffer,
+ ) {
+ FfiConverterString.write(value.`statechainId`, buf)
+ FfiConverterString.write(value.`authSig`, buf)
+ FfiConverterString.write(value.`authPubKey`, buf)
+ }
+}
+
+@Serializable
+data class TransferUpdateMsgRequestPayload(
+ @SerialName("statechain_id")
+ var `statechainId`: kotlin.String,
+ @SerialName("auth_sig")
+ var `authSig`: kotlin.String,
+ @SerialName("new_user_auth_key")
+ var `newUserAuthKey`: kotlin.String,
+ @SerialName("enc_transfer_msg")
+ var `encTransferMsg`: kotlin.String,
+) {
+ companion object
+}
+
+public object FfiConverterTypeTransferUpdateMsgRequestPayload : FfiConverterRustBuffer {
+ override fun read(buf: ByteBuffer): TransferUpdateMsgRequestPayload {
+ return TransferUpdateMsgRequestPayload(
+ FfiConverterString.read(buf),
+ FfiConverterString.read(buf),
+ FfiConverterString.read(buf),
+ FfiConverterString.read(buf),
+ )
+ }
+
+ override fun allocationSize(value: TransferUpdateMsgRequestPayload) =
+ (
+ FfiConverterString.allocationSize(value.`statechainId`) +
+ FfiConverterString.allocationSize(value.`authSig`) +
+ FfiConverterString.allocationSize(value.`newUserAuthKey`) +
+ FfiConverterString.allocationSize(value.`encTransferMsg`)
+ )
+
+ override fun write(
+ value: TransferUpdateMsgRequestPayload,
+ buf: ByteBuffer,
+ ) {
+ FfiConverterString.write(value.`statechainId`, buf)
+ FfiConverterString.write(value.`authSig`, buf)
+ FfiConverterString.write(value.`newUserAuthKey`, buf)
+ FfiConverterString.write(value.`encTransferMsg`, buf)
+ }
+}
+
+data class TxOutpoint(
+ var `txid`: kotlin.String,
+ var `vout`: kotlin.UInt,
+) {
+ companion object
+}
+
+public object FfiConverterTypeTxOutpoint : FfiConverterRustBuffer {
+ override fun read(buf: ByteBuffer): TxOutpoint {
+ return TxOutpoint(
+ FfiConverterString.read(buf),
+ FfiConverterUInt.read(buf),
+ )
+ }
+
+ override fun allocationSize(value: TxOutpoint) =
+ (
+ FfiConverterString.allocationSize(value.`txid`) +
+ FfiConverterUInt.allocationSize(value.`vout`)
+ )
+
+ override fun write(
+ value: TxOutpoint,
+ buf: ByteBuffer,
+ ) {
+ FfiConverterString.write(value.`txid`, buf)
+ FfiConverterUInt.write(value.`vout`, buf)
+ }
+}
+
+@Serializable
+data class Wallet(
+ var `name`: kotlin.String,
+ var `mnemonic`: kotlin.String,
+ var `version`: kotlin.String,
+ var `stateEntityEndpoint`: kotlin.String,
+ var `electrumEndpoint`: kotlin.String,
+ var `network`: kotlin.String,
+ var `blockheight`: kotlin.UInt,
+ var `initlock`: kotlin.UInt,
+ var `interval`: kotlin.UInt,
+ var `tokens`: List,
+ var `activities`: List,
+ var `coins`: List,
+ var `settings`: Settings,
+) {
+ companion object
+}
+
+public object FfiConverterTypeWallet : FfiConverterRustBuffer {
+ override fun read(buf: ByteBuffer): Wallet {
+ return Wallet(
+ FfiConverterString.read(buf),
+ FfiConverterString.read(buf),
+ FfiConverterString.read(buf),
+ FfiConverterString.read(buf),
+ FfiConverterString.read(buf),
+ FfiConverterString.read(buf),
+ FfiConverterUInt.read(buf),
+ FfiConverterUInt.read(buf),
+ FfiConverterUInt.read(buf),
+ FfiConverterSequenceTypeToken.read(buf),
+ FfiConverterSequenceTypeActivity.read(buf),
+ FfiConverterSequenceTypeCoin.read(buf),
+ FfiConverterTypeSettings.read(buf),
+ )
+ }
+
+ override fun allocationSize(value: Wallet) =
+ (
+ FfiConverterString.allocationSize(value.`name`) +
+ FfiConverterString.allocationSize(value.`mnemonic`) +
+ FfiConverterString.allocationSize(value.`version`) +
+ FfiConverterString.allocationSize(value.`stateEntityEndpoint`) +
+ FfiConverterString.allocationSize(value.`electrumEndpoint`) +
+ FfiConverterString.allocationSize(value.`network`) +
+ FfiConverterUInt.allocationSize(value.`blockheight`) +
+ FfiConverterUInt.allocationSize(value.`initlock`) +
+ FfiConverterUInt.allocationSize(value.`interval`) +
+ FfiConverterSequenceTypeToken.allocationSize(value.`tokens`) +
+ FfiConverterSequenceTypeActivity.allocationSize(value.`activities`) +
+ FfiConverterSequenceTypeCoin.allocationSize(value.`coins`) +
+ FfiConverterTypeSettings.allocationSize(value.`settings`)
+ )
+
+ override fun write(
+ value: Wallet,
+ buf: ByteBuffer,
+ ) {
+ FfiConverterString.write(value.`name`, buf)
+ FfiConverterString.write(value.`mnemonic`, buf)
+ FfiConverterString.write(value.`version`, buf)
+ FfiConverterString.write(value.`stateEntityEndpoint`, buf)
+ FfiConverterString.write(value.`electrumEndpoint`, buf)
+ FfiConverterString.write(value.`network`, buf)
+ FfiConverterUInt.write(value.`blockheight`, buf)
+ FfiConverterUInt.write(value.`initlock`, buf)
+ FfiConverterUInt.write(value.`interval`, buf)
+ FfiConverterSequenceTypeToken.write(value.`tokens`, buf)
+ FfiConverterSequenceTypeActivity.write(value.`activities`, buf)
+ FfiConverterSequenceTypeCoin.write(value.`coins`, buf)
+ FfiConverterTypeSettings.write(value.`settings`, buf)
+ }
+}
+
+@Serializable
+data class WithdrawCompletePayload(
+ @SerialName("statechain_id")
+ var `statechainId`: kotlin.String,
+ @SerialName("signed_statechain_id")
+ var `signedStatechainId`: kotlin.String,
+) {
+ companion object
+}
+
+public object FfiConverterTypeWithdrawCompletePayload : FfiConverterRustBuffer {
+ override fun read(buf: ByteBuffer): WithdrawCompletePayload {
+ return WithdrawCompletePayload(
+ FfiConverterString.read(buf),
+ FfiConverterString.read(buf),
+ )
+ }
+
+ override fun allocationSize(value: WithdrawCompletePayload) =
+ (
+ FfiConverterString.allocationSize(value.`statechainId`) +
+ FfiConverterString.allocationSize(value.`signedStatechainId`)
+ )
+
+ override fun write(
+ value: WithdrawCompletePayload,
+ buf: ByteBuffer,
+ ) {
+ FfiConverterString.write(value.`statechainId`, buf)
+ FfiConverterString.write(value.`signedStatechainId`, buf)
+ }
+}
+
+enum class CoinStatus {
+ INITIALISED,
+ IN_MEMPOOL,
+ UNCONFIRMED,
+ CONFIRMED,
+ IN_TRANSFER,
+ WITHDRAWING,
+ TRANSFERRED,
+ WITHDRAWN,
+ ;
+
+ companion object
+}
+
+public object FfiConverterTypeCoinStatus : FfiConverterRustBuffer {
+ override fun read(buf: ByteBuffer) =
+ try {
+ CoinStatus.values()[buf.getInt() - 1]
+ } catch (e: IndexOutOfBoundsException) {
+ throw RuntimeException("invalid enum value, something is very wrong!!", e)
+ }
+
+ override fun allocationSize(value: CoinStatus) = 4UL
+
+ override fun write(
+ value: CoinStatus,
+ buf: ByteBuffer,
+ ) {
+ buf.putInt(value.ordinal + 1)
+ }
+}
+
+sealed class MercuryException : Exception() {
+ class Bip39Exception() : MercuryException() {
+ override val message
+ get() = ""
+ }
+
+ class Bip32Exception() : MercuryException() {
+ override val message
+ get() = ""
+ }
+
+ class NetworkConversionException() : MercuryException() {
+ override val message
+ get() = ""
+ }
+
+ class Secp256k1UpstreamException() : MercuryException() {
+ override val message
+ get() = ""
+ }
+
+ class KeyException() : MercuryException() {
+ override val message
+ get() = ""
+ }
+
+ class Bech32Exception() : MercuryException() {
+ override val message
+ get() = ""
+ }
+
+ class HexException() : MercuryException() {
+ override val message
+ get() = ""
+ }
+
+ class LocktimeNotBlockHeightException() : MercuryException() {
+ override val message
+ get() = ""
+ }
+
+ class BitcoinConsensusEncodeException() : MercuryException() {
+ override val message
+ get() = ""
+ }
+
+ class MusigNonceGenException() : MercuryException() {
+ override val message
+ get() = ""
+ }
+
+ class InvalidStatechainAddressException() : MercuryException() {
+ override val message
+ get() = ""
+ }
+
+ class InvalidBitcoinAddressException() : MercuryException() {
+ override val message
+ get() = ""
+ }
+
+ class StatechainAddressMismatchNetworkException() : MercuryException() {
+ override val message
+ get() = ""
+ }
+
+ class BitcoinAddressMismatchNetworkException() : MercuryException() {
+ override val message
+ get() = ""
+ }
+
+ class BitcoinAddressException() : MercuryException() {
+ override val message
+ get() = ""
+ }
+
+ class BitcoinAbsoluteException() : MercuryException() {
+ override val message
+ get() = ""
+ }
+
+ class BitcoinHashHexException() : MercuryException() {
+ override val message
+ get() = ""
+ }
+
+ class BitcoinPsbtException() : MercuryException() {
+ override val message
+ get() = ""
+ }
+
+ class SighashTypeParseException() : MercuryException() {
+ override val message
+ get() = ""
+ }
+
+ class BitcoinSighashException() : MercuryException() {
+ override val message
+ get() = ""
+ }
+
+ class ParseException() : MercuryException() {
+ override val message
+ get() = ""
+ }
+
+ class MusigSignException() : MercuryException() {
+ override val message
+ get() = ""
+ }
+
+ class SchnorrSignatureValidationException() : MercuryException() {
+ override val message
+ get() = ""
+ }
+
+ class MoreThanOneInputException() : MercuryException() {
+ override val message
+ get() = ""
+ }
+
+ class UnkownNetwork() : MercuryException() {
+ override val message
+ get() = ""
+ }
+
+ class BackupTransactionDoesNotPayUser() : MercuryException() {
+ override val message
+ get() = ""
+ }
+
+ class FeeTooHigh() : MercuryException() {
+ override val message
+ get() = ""
+ }
+
+ class FeeTooLow() : MercuryException() {
+ override val message
+ get() = ""
+ }
+
+ class OutOfRangeException() : MercuryException() {
+ override val message
+ get() = ""
+ }
+
+ class SerdeJsonException() : MercuryException() {
+ override val message
+ get() = ""
+ }
+
+ class SecpException() : MercuryException() {
+ override val message
+ get() = ""
+ }
+
+ class NoBackupTransactionFound() : MercuryException() {
+ override val message
+ get() = ""
+ }
+
+ class Tx1HasMoreThanOneInput() : MercuryException() {
+ override val message
+ get() = ""
+ }
+
+ class InvalidSignature() : MercuryException() {
+ override val message
+ get() = ""
+ }
+
+ class EmptyWitness() : MercuryException() {
+ override val message
+ get() = ""
+ }
+
+ class EmptyWitnessData() : MercuryException() {
+ override val message
+ get() = ""
+ }
+
+ class IncorrectChallenge() : MercuryException() {
+ override val message
+ get() = ""
+ }
+
+ class InvalidT1() : MercuryException() {
+ override val message
+ get() = ""
+ }
+
+ class IncorrectAggregatedPublicKey() : MercuryException() {
+ override val message
+ get() = ""
+ }
+
+ class T1MustBeExactly32BytesException() : MercuryException() {
+ override val message
+ get() = ""
+ }
+
+ class NoX1Pub() : MercuryException() {
+ override val message
+ get() = ""
+ }
+
+ class NoAggregatedPubkeyException() : MercuryException() {
+ override val message
+ get() = ""
+ }
+
+ class CoinNotFound() : MercuryException() {
+ override val message
+ get() = ""
+ }
+
+ class SignatureSchemeValidationException() : MercuryException() {
+ override val message
+ get() = ""
+ }
+
+ class NoPreviousLockTimeException() : MercuryException() {
+ override val message
+ get() = ""
+ }
+
+ companion object ErrorHandler : UniffiRustCallStatusErrorHandler {
+ override fun lift(error_buf: RustBuffer.ByValue): MercuryException = FfiConverterTypeMercuryError.lift(error_buf)
+ }
+}
+
+public object FfiConverterTypeMercuryError : FfiConverterRustBuffer {
+ override fun read(buf: ByteBuffer): MercuryException {
+ return when (buf.getInt()) {
+ 1 -> MercuryException.Bip39Exception()
+ 2 -> MercuryException.Bip32Exception()
+ 3 -> MercuryException.NetworkConversionException()
+ 4 -> MercuryException.Secp256k1UpstreamException()
+ 5 -> MercuryException.KeyException()
+ 6 -> MercuryException.Bech32Exception()
+ 7 -> MercuryException.HexException()
+ 8 -> MercuryException.LocktimeNotBlockHeightException()
+ 9 -> MercuryException.BitcoinConsensusEncodeException()
+ 10 -> MercuryException.MusigNonceGenException()
+ 11 -> MercuryException.InvalidStatechainAddressException()
+ 12 -> MercuryException.InvalidBitcoinAddressException()
+ 13 -> MercuryException.StatechainAddressMismatchNetworkException()
+ 14 -> MercuryException.BitcoinAddressMismatchNetworkException()
+ 15 -> MercuryException.BitcoinAddressException()
+ 16 -> MercuryException.BitcoinAbsoluteException()
+ 17 -> MercuryException.BitcoinHashHexException()
+ 18 -> MercuryException.BitcoinPsbtException()
+ 19 -> MercuryException.SighashTypeParseException()
+ 20 -> MercuryException.BitcoinSighashException()
+ 21 -> MercuryException.ParseException()
+ 22 -> MercuryException.MusigSignException()
+ 23 -> MercuryException.SchnorrSignatureValidationException()
+ 24 -> MercuryException.MoreThanOneInputException()
+ 25 -> MercuryException.UnkownNetwork()
+ 26 -> MercuryException.BackupTransactionDoesNotPayUser()
+ 27 -> MercuryException.FeeTooHigh()
+ 28 -> MercuryException.FeeTooLow()
+ 29 -> MercuryException.OutOfRangeException()
+ 30 -> MercuryException.SerdeJsonException()
+ 31 -> MercuryException.SecpException()
+ 32 -> MercuryException.NoBackupTransactionFound()
+ 33 -> MercuryException.Tx1HasMoreThanOneInput()
+ 34 -> MercuryException.InvalidSignature()
+ 35 -> MercuryException.EmptyWitness()
+ 36 -> MercuryException.EmptyWitnessData()
+ 37 -> MercuryException.IncorrectChallenge()
+ 38 -> MercuryException.InvalidT1()
+ 39 -> MercuryException.IncorrectAggregatedPublicKey()
+ 40 -> MercuryException.T1MustBeExactly32BytesException()
+ 41 -> MercuryException.NoX1Pub()
+ 42 -> MercuryException.NoAggregatedPubkeyException()
+ 43 -> MercuryException.CoinNotFound()
+ 44 -> MercuryException.SignatureSchemeValidationException()
+ 45 -> MercuryException.NoPreviousLockTimeException()
+ else -> throw RuntimeException("invalid error enum value, something is very wrong!!")
+ }
+ }
+
+ override fun allocationSize(value: MercuryException): ULong {
+ return when (value) {
+ is MercuryException.Bip39Exception -> (
+ // Add the size for the Int that specifies the variant plus the size needed for all fields
+ 4UL
+ )
+ is MercuryException.Bip32Exception -> (
+ // Add the size for the Int that specifies the variant plus the size needed for all fields
+ 4UL
+ )
+ is MercuryException.NetworkConversionException -> (
+ // Add the size for the Int that specifies the variant plus the size needed for all fields
+ 4UL
+ )
+ is MercuryException.Secp256k1UpstreamException -> (
+ // Add the size for the Int that specifies the variant plus the size needed for all fields
+ 4UL
+ )
+ is MercuryException.KeyException -> (
+ // Add the size for the Int that specifies the variant plus the size needed for all fields
+ 4UL
+ )
+ is MercuryException.Bech32Exception -> (
+ // Add the size for the Int that specifies the variant plus the size needed for all fields
+ 4UL
+ )
+ is MercuryException.HexException -> (
+ // Add the size for the Int that specifies the variant plus the size needed for all fields
+ 4UL
+ )
+ is MercuryException.LocktimeNotBlockHeightException -> (
+ // Add the size for the Int that specifies the variant plus the size needed for all fields
+ 4UL
+ )
+ is MercuryException.BitcoinConsensusEncodeException -> (
+ // Add the size for the Int that specifies the variant plus the size needed for all fields
+ 4UL
+ )
+ is MercuryException.MusigNonceGenException -> (
+ // Add the size for the Int that specifies the variant plus the size needed for all fields
+ 4UL
+ )
+ is MercuryException.InvalidStatechainAddressException -> (
+ // Add the size for the Int that specifies the variant plus the size needed for all fields
+ 4UL
+ )
+ is MercuryException.InvalidBitcoinAddressException -> (
+ // Add the size for the Int that specifies the variant plus the size needed for all fields
+ 4UL
+ )
+ is MercuryException.StatechainAddressMismatchNetworkException -> (
+ // Add the size for the Int that specifies the variant plus the size needed for all fields
+ 4UL
+ )
+ is MercuryException.BitcoinAddressMismatchNetworkException -> (
+ // Add the size for the Int that specifies the variant plus the size needed for all fields
+ 4UL
+ )
+ is MercuryException.BitcoinAddressException -> (
+ // Add the size for the Int that specifies the variant plus the size needed for all fields
+ 4UL
+ )
+ is MercuryException.BitcoinAbsoluteException -> (
+ // Add the size for the Int that specifies the variant plus the size needed for all fields
+ 4UL
+ )
+ is MercuryException.BitcoinHashHexException -> (
+ // Add the size for the Int that specifies the variant plus the size needed for all fields
+ 4UL
+ )
+ is MercuryException.BitcoinPsbtException -> (
+ // Add the size for the Int that specifies the variant plus the size needed for all fields
+ 4UL
+ )
+ is MercuryException.SighashTypeParseException -> (
+ // Add the size for the Int that specifies the variant plus the size needed for all fields
+ 4UL
+ )
+ is MercuryException.BitcoinSighashException -> (
+ // Add the size for the Int that specifies the variant plus the size needed for all fields
+ 4UL
+ )
+ is MercuryException.ParseException -> (
+ // Add the size for the Int that specifies the variant plus the size needed for all fields
+ 4UL
+ )
+ is MercuryException.MusigSignException -> (
+ // Add the size for the Int that specifies the variant plus the size needed for all fields
+ 4UL
+ )
+ is MercuryException.SchnorrSignatureValidationException -> (
+ // Add the size for the Int that specifies the variant plus the size needed for all fields
+ 4UL
+ )
+ is MercuryException.MoreThanOneInputException -> (
+ // Add the size for the Int that specifies the variant plus the size needed for all fields
+ 4UL
+ )
+ is MercuryException.UnkownNetwork -> (
+ // Add the size for the Int that specifies the variant plus the size needed for all fields
+ 4UL
+ )
+ is MercuryException.BackupTransactionDoesNotPayUser -> (
+ // Add the size for the Int that specifies the variant plus the size needed for all fields
+ 4UL
+ )
+ is MercuryException.FeeTooHigh -> (
+ // Add the size for the Int that specifies the variant plus the size needed for all fields
+ 4UL
+ )
+ is MercuryException.FeeTooLow -> (
+ // Add the size for the Int that specifies the variant plus the size needed for all fields
+ 4UL
+ )
+ is MercuryException.OutOfRangeException -> (
+ // Add the size for the Int that specifies the variant plus the size needed for all fields
+ 4UL
+ )
+ is MercuryException.SerdeJsonException -> (
+ // Add the size for the Int that specifies the variant plus the size needed for all fields
+ 4UL
+ )
+ is MercuryException.SecpException -> (
+ // Add the size for the Int that specifies the variant plus the size needed for all fields
+ 4UL
+ )
+ is MercuryException.NoBackupTransactionFound -> (
+ // Add the size for the Int that specifies the variant plus the size needed for all fields
+ 4UL
+ )
+ is MercuryException.Tx1HasMoreThanOneInput -> (
+ // Add the size for the Int that specifies the variant plus the size needed for all fields
+ 4UL
+ )
+ is MercuryException.InvalidSignature -> (
+ // Add the size for the Int that specifies the variant plus the size needed for all fields
+ 4UL
+ )
+ is MercuryException.EmptyWitness -> (
+ // Add the size for the Int that specifies the variant plus the size needed for all fields
+ 4UL
+ )
+ is MercuryException.EmptyWitnessData -> (
+ // Add the size for the Int that specifies the variant plus the size needed for all fields
+ 4UL
+ )
+ is MercuryException.IncorrectChallenge -> (
+ // Add the size for the Int that specifies the variant plus the size needed for all fields
+ 4UL
+ )
+ is MercuryException.InvalidT1 -> (
+ // Add the size for the Int that specifies the variant plus the size needed for all fields
+ 4UL
+ )
+ is MercuryException.IncorrectAggregatedPublicKey -> (
+ // Add the size for the Int that specifies the variant plus the size needed for all fields
+ 4UL
+ )
+ is MercuryException.T1MustBeExactly32BytesException -> (
+ // Add the size for the Int that specifies the variant plus the size needed for all fields
+ 4UL
+ )
+ is MercuryException.NoX1Pub -> (
+ // Add the size for the Int that specifies the variant plus the size needed for all fields
+ 4UL
+ )
+ is MercuryException.NoAggregatedPubkeyException -> (
+ // Add the size for the Int that specifies the variant plus the size needed for all fields
+ 4UL
+ )
+ is MercuryException.CoinNotFound -> (
+ // Add the size for the Int that specifies the variant plus the size needed for all fields
+ 4UL
+ )
+ is MercuryException.SignatureSchemeValidationException -> (
+ // Add the size for the Int that specifies the variant plus the size needed for all fields
+ 4UL
+ )
+ is MercuryException.NoPreviousLockTimeException -> (
+ // Add the size for the Int that specifies the variant plus the size needed for all fields
+ 4UL
+ )
+ }
+ }
+
+ override fun write(
+ value: MercuryException,
+ buf: ByteBuffer,
+ ) {
+ when (value) {
+ is MercuryException.Bip39Exception -> {
+ buf.putInt(1)
+ Unit
+ }
+ is MercuryException.Bip32Exception -> {
+ buf.putInt(2)
+ Unit
+ }
+ is MercuryException.NetworkConversionException -> {
+ buf.putInt(3)
+ Unit
+ }
+ is MercuryException.Secp256k1UpstreamException -> {
+ buf.putInt(4)
+ Unit
+ }
+ is MercuryException.KeyException -> {
+ buf.putInt(5)
+ Unit
+ }
+ is MercuryException.Bech32Exception -> {
+ buf.putInt(6)
+ Unit
+ }
+ is MercuryException.HexException -> {
+ buf.putInt(7)
+ Unit
+ }
+ is MercuryException.LocktimeNotBlockHeightException -> {
+ buf.putInt(8)
+ Unit
+ }
+ is MercuryException.BitcoinConsensusEncodeException -> {
+ buf.putInt(9)
+ Unit
+ }
+ is MercuryException.MusigNonceGenException -> {
+ buf.putInt(10)
+ Unit
+ }
+ is MercuryException.InvalidStatechainAddressException -> {
+ buf.putInt(11)
+ Unit
+ }
+ is MercuryException.InvalidBitcoinAddressException -> {
+ buf.putInt(12)
+ Unit
+ }
+ is MercuryException.StatechainAddressMismatchNetworkException -> {
+ buf.putInt(13)
+ Unit
+ }
+ is MercuryException.BitcoinAddressMismatchNetworkException -> {
+ buf.putInt(14)
+ Unit
+ }
+ is MercuryException.BitcoinAddressException -> {
+ buf.putInt(15)
+ Unit
+ }
+ is MercuryException.BitcoinAbsoluteException -> {
+ buf.putInt(16)
+ Unit
+ }
+ is MercuryException.BitcoinHashHexException -> {
+ buf.putInt(17)
+ Unit
+ }
+ is MercuryException.BitcoinPsbtException -> {
+ buf.putInt(18)
+ Unit
+ }
+ is MercuryException.SighashTypeParseException -> {
+ buf.putInt(19)
+ Unit
+ }
+ is MercuryException.BitcoinSighashException -> {
+ buf.putInt(20)
+ Unit
+ }
+ is MercuryException.ParseException -> {
+ buf.putInt(21)
+ Unit
+ }
+ is MercuryException.MusigSignException -> {
+ buf.putInt(22)
+ Unit
+ }
+ is MercuryException.SchnorrSignatureValidationException -> {
+ buf.putInt(23)
+ Unit
+ }
+ is MercuryException.MoreThanOneInputException -> {
+ buf.putInt(24)
+ Unit
+ }
+ is MercuryException.UnkownNetwork -> {
+ buf.putInt(25)
+ Unit
+ }
+ is MercuryException.BackupTransactionDoesNotPayUser -> {
+ buf.putInt(26)
+ Unit
+ }
+ is MercuryException.FeeTooHigh -> {
+ buf.putInt(27)
+ Unit
+ }
+ is MercuryException.FeeTooLow -> {
+ buf.putInt(28)
+ Unit
+ }
+ is MercuryException.OutOfRangeException -> {
+ buf.putInt(29)
+ Unit
+ }
+ is MercuryException.SerdeJsonException -> {
+ buf.putInt(30)
+ Unit
+ }
+ is MercuryException.SecpException -> {
+ buf.putInt(31)
+ Unit
+ }
+ is MercuryException.NoBackupTransactionFound -> {
+ buf.putInt(32)
+ Unit
+ }
+ is MercuryException.Tx1HasMoreThanOneInput -> {
+ buf.putInt(33)
+ Unit
+ }
+ is MercuryException.InvalidSignature -> {
+ buf.putInt(34)
+ Unit
+ }
+ is MercuryException.EmptyWitness -> {
+ buf.putInt(35)
+ Unit
+ }
+ is MercuryException.EmptyWitnessData -> {
+ buf.putInt(36)
+ Unit
+ }
+ is MercuryException.IncorrectChallenge -> {
+ buf.putInt(37)
+ Unit
+ }
+ is MercuryException.InvalidT1 -> {
+ buf.putInt(38)
+ Unit
+ }
+ is MercuryException.IncorrectAggregatedPublicKey -> {
+ buf.putInt(39)
+ Unit
+ }
+ is MercuryException.T1MustBeExactly32BytesException -> {
+ buf.putInt(40)
+ Unit
+ }
+ is MercuryException.NoX1Pub -> {
+ buf.putInt(41)
+ Unit
+ }
+ is MercuryException.NoAggregatedPubkeyException -> {
+ buf.putInt(42)
+ Unit
+ }
+ is MercuryException.CoinNotFound -> {
+ buf.putInt(43)
+ Unit
+ }
+ is MercuryException.SignatureSchemeValidationException -> {
+ buf.putInt(44)
+ Unit
+ }
+ is MercuryException.NoPreviousLockTimeException -> {
+ buf.putInt(45)
+ Unit
+ }
+ }.let { /* this makes the `when` an expression, which ensures it is exhaustive */ }
+ }
+}
+
+@Serializable
+enum class TransferReceiverError {
+ @SerialName("StatecoinBatchLockedError")
+ STATECOIN_BATCH_LOCKED_ERROR,
+ @SerialName("ExpiredBatchTimeError")
+ EXPIRED_BATCH_TIME_ERROR,
+ ;
+
+ companion object
+}
+
+public object FfiConverterTypeTransferReceiverError : FfiConverterRustBuffer {
+ override fun read(buf: ByteBuffer) =
+ try {
+ TransferReceiverError.values()[buf.getInt() - 1]
+ } catch (e: IndexOutOfBoundsException) {
+ throw RuntimeException("invalid enum value, something is very wrong!!", e)
+ }
+
+ override fun allocationSize(value: TransferReceiverError) = 4UL
+
+ override fun write(
+ value: TransferReceiverError,
+ buf: ByteBuffer,
+ ) {
+ buf.putInt(value.ordinal + 1)
+ }
+}
+
+public object FfiConverterOptionalUInt : FfiConverterRustBuffer {
+ override fun read(buf: ByteBuffer): kotlin.UInt? {
+ if (buf.get().toInt() == 0) {
+ return null
+ }
+ return FfiConverterUInt.read(buf)
+ }
+
+ override fun allocationSize(value: kotlin.UInt?): ULong {
+ if (value == null) {
+ return 1UL
+ } else {
+ return 1UL + FfiConverterUInt.allocationSize(value)
+ }
+ }
+
+ override fun write(
+ value: kotlin.UInt?,
+ buf: ByteBuffer,
+ ) {
+ if (value == null) {
+ buf.put(0)
+ } else {
+ buf.put(1)
+ FfiConverterUInt.write(value, buf)
+ }
+ }
+}
+
+public object FfiConverterOptionalString : FfiConverterRustBuffer {
+ override fun read(buf: ByteBuffer): kotlin.String? {
+ if (buf.get().toInt() == 0) {
+ return null
+ }
+ return FfiConverterString.read(buf)
+ }
+
+ override fun allocationSize(value: kotlin.String?): ULong {
+ if (value == null) {
+ return 1UL
+ } else {
+ return 1UL + FfiConverterString.allocationSize(value)
+ }
+ }
+
+ override fun write(
+ value: kotlin.String?,
+ buf: ByteBuffer,
+ ) {
+ if (value == null) {
+ buf.put(0)
+ } else {
+ buf.put(1)
+ FfiConverterString.write(value, buf)
+ }
+ }
+}
+
+public object FfiConverterSequenceString : FfiConverterRustBuffer> {
+ override fun read(buf: ByteBuffer): List {
+ val len = buf.getInt()
+ return List(len) {
+ FfiConverterString.read(buf)
+ }
+ }
+
+ override fun allocationSize(value: List): ULong {
+ val sizeForLength = 4UL
+ val sizeForItems = value.map { FfiConverterString.allocationSize(it) }.sum()
+ return sizeForLength + sizeForItems
+ }
+
+ override fun write(
+ value: List,
+ buf: ByteBuffer,
+ ) {
+ buf.putInt(value.size)
+ value.iterator().forEach {
+ FfiConverterString.write(it, buf)
+ }
+ }
+}
+
+public object FfiConverterSequenceTypeActivity : FfiConverterRustBuffer> {
+ override fun read(buf: ByteBuffer): List {
+ val len = buf.getInt()
+ return List(len) {
+ FfiConverterTypeActivity.read(buf)
+ }
+ }
+
+ override fun allocationSize(value: List): ULong {
+ val sizeForLength = 4UL
+ val sizeForItems = value.map { FfiConverterTypeActivity.allocationSize(it) }.sum()
+ return sizeForLength + sizeForItems
+ }
+
+ override fun write(
+ value: List,
+ buf: ByteBuffer,
+ ) {
+ buf.putInt(value.size)
+ value.iterator().forEach {
+ FfiConverterTypeActivity.write(it, buf)
+ }
+ }
+}
+
+public object FfiConverterSequenceTypeBackupTx : FfiConverterRustBuffer> {
+ override fun read(buf: ByteBuffer): List {
+ val len = buf.getInt()
+ return List(len) {
+ FfiConverterTypeBackupTx.read(buf)
+ }
+ }
+
+ override fun allocationSize(value: List): ULong {
+ val sizeForLength = 4UL
+ val sizeForItems = value.map { FfiConverterTypeBackupTx.allocationSize(it) }.sum()
+ return sizeForLength + sizeForItems
+ }
+
+ override fun write(
+ value: List,
+ buf: ByteBuffer,
+ ) {
+ buf.putInt(value.size)
+ value.iterator().forEach {
+ FfiConverterTypeBackupTx.write(it, buf)
+ }
+ }
+}
+
+public object FfiConverterSequenceTypeCoin : FfiConverterRustBuffer> {
+ override fun read(buf: ByteBuffer): List {
+ val len = buf.getInt()
+ return List(len) {
+ FfiConverterTypeCoin.read(buf)
+ }
+ }
+
+ override fun allocationSize(value: List): ULong {
+ val sizeForLength = 4UL
+ val sizeForItems = value.map { FfiConverterTypeCoin.allocationSize(it) }.sum()
+ return sizeForLength + sizeForItems
+ }
+
+ override fun write(
+ value: List,
+ buf: ByteBuffer,
+ ) {
+ buf.putInt(value.size)
+ value.iterator().forEach {
+ FfiConverterTypeCoin.write(it, buf)
+ }
+ }
+}
+
+public object FfiConverterSequenceTypePubKeyInfo : FfiConverterRustBuffer> {
+ override fun read(buf: ByteBuffer): List {
+ val len = buf.getInt()
+ return List(len) {
+ FfiConverterTypePubKeyInfo.read(buf)
+ }
+ }
+
+ override fun allocationSize(value: List): ULong {
+ val sizeForLength = 4UL
+ val sizeForItems = value.map { FfiConverterTypePubKeyInfo.allocationSize(it) }.sum()
+ return sizeForLength + sizeForItems
+ }
+
+ override fun write(
+ value: List,
+ buf: ByteBuffer,
+ ) {
+ buf.putInt(value.size)
+ value.iterator().forEach {
+ FfiConverterTypePubKeyInfo.write(it, buf)
+ }
+ }
+}
+
+public object FfiConverterSequenceTypeStatechainInfo : FfiConverterRustBuffer> {
+ override fun read(buf: ByteBuffer): List {
+ val len = buf.getInt()
+ return List(len) {
+ FfiConverterTypeStatechainInfo.read(buf)
+ }
+ }
+
+ override fun allocationSize(value: List): ULong {
+ val sizeForLength = 4UL
+ val sizeForItems = value.map { FfiConverterTypeStatechainInfo.allocationSize(it) }.sum()
+ return sizeForLength + sizeForItems
+ }
+
+ override fun write(
+ value: List,
+ buf: ByteBuffer,
+ ) {
+ buf.putInt(value.size)
+ value.iterator().forEach {
+ FfiConverterTypeStatechainInfo.write(it, buf)
+ }
+ }
+}
+
+public object FfiConverterSequenceTypeToken : FfiConverterRustBuffer> {
+ override fun read(buf: ByteBuffer): List {
+ val len = buf.getInt()
+ return List(len) {
+ FfiConverterTypeToken.read(buf)
+ }
+ }
+
+ override fun allocationSize(value: List): ULong {
+ val sizeForLength = 4UL
+ val sizeForItems = value.map { FfiConverterTypeToken.allocationSize(it) }.sum()
+ return sizeForLength + sizeForItems
+ }
+
+ override fun write(
+ value: List,
+ buf: ByteBuffer,
+ ) {
+ buf.putInt(value.size)
+ value.iterator().forEach {
+ FfiConverterTypeToken.write(it, buf)
+ }
+ }
+}
+
+@Throws(MercuryException::class)
+fun `createAggregatedAddress`(
+ `coin`: Coin,
+ `network`: kotlin.String,
+): AggregatedPublicKey {
+ return FfiConverterTypeAggregatedPublicKey.lift(
+ uniffiRustCallWithError(MercuryException) { _status ->
+ UniffiLib.INSTANCE.uniffi_mercurylib_fn_func_create_aggregated_address(
+ FfiConverterTypeCoin.lower(`coin`),
+ FfiConverterString.lower(`network`),
+ _status,
+ )
+ },
+ )
+}
+
+@Throws(MercuryException::class)
+fun `createAndCommitNonces`(`coin`: Coin): CoinNonce {
+ return FfiConverterTypeCoinNonce.lift(
+ uniffiRustCallWithError(MercuryException) { _status ->
+ UniffiLib.INSTANCE.uniffi_mercurylib_fn_func_create_and_commit_nonces(
+ FfiConverterTypeCoin.lower(`coin`),
+ _status,
+ )
+ },
+ )
+}
+
+@Throws(MercuryException::class)
+fun `createCpfpTx`(
+ `backupTx`: BackupTx,
+ `coin`: Coin,
+ `toAddress`: kotlin.String,
+ `feeRateSatsPerByte`: kotlin.ULong,
+ `network`: kotlin.String,
+): kotlin.String {
+ return FfiConverterString.lift(
+ uniffiRustCallWithError(MercuryException) { _status ->
+ UniffiLib.INSTANCE.uniffi_mercurylib_fn_func_create_cpfp_tx(
+ FfiConverterTypeBackupTx.lower(`backupTx`),
+ FfiConverterTypeCoin.lower(`coin`),
+ FfiConverterString.lower(`toAddress`),
+ FfiConverterULong.lower(`feeRateSatsPerByte`),
+ FfiConverterString.lower(`network`),
+ _status,
+ )
+ },
+ )
+}
+
+@Throws(MercuryException::class)
+fun `createDepositMsg1`(
+ `coin`: Coin,
+ `tokenId`: kotlin.String,
+): DepositMsg1 {
+ return FfiConverterTypeDepositMsg1.lift(
+ uniffiRustCallWithError(MercuryException) { _status ->
+ UniffiLib.INSTANCE.uniffi_mercurylib_fn_func_create_deposit_msg1(
+ FfiConverterTypeCoin.lower(`coin`),
+ FfiConverterString.lower(`tokenId`),
+ _status,
+ )
+ },
+ )
+}
+
+@Throws(MercuryException::class)
+fun `createSignature`(
+ `msg`: kotlin.String,
+ `clientPartialSigHex`: kotlin.String,
+ `serverPartialSigHex`: kotlin.String,
+ `sessionHex`: kotlin.String,
+ `outputPubkeyHex`: kotlin.String,
+): kotlin.String {
+ return FfiConverterString.lift(
+ uniffiRustCallWithError(MercuryException) { _status ->
+ UniffiLib.INSTANCE.uniffi_mercurylib_fn_func_create_signature(
+ FfiConverterString.lower(`msg`),
+ FfiConverterString.lower(`clientPartialSigHex`),
+ FfiConverterString.lower(`serverPartialSigHex`),
+ FfiConverterString.lower(`sessionHex`),
+ FfiConverterString.lower(`outputPubkeyHex`),
+ _status,
+ )
+ },
+ )
+}
+
+@Throws(MercuryException::class)
+fun `createTransferSignature`(
+ `recipientAddress`: kotlin.String,
+ `inputTxid`: kotlin.String,
+ `inputVout`: kotlin.UInt,
+ `clientSeckey`: kotlin.String,
+): kotlin.String {
+ return FfiConverterString.lift(
+ uniffiRustCallWithError(MercuryException) { _status ->
+ UniffiLib.INSTANCE.uniffi_mercurylib_fn_func_create_transfer_signature(
+ FfiConverterString.lower(`recipientAddress`),
+ FfiConverterString.lower(`inputTxid`),
+ FfiConverterUInt.lower(`inputVout`),
+ FfiConverterString.lower(`clientSeckey`),
+ _status,
+ )
+ },
+ )
+}
+
+@Throws(MercuryException::class)
+fun `createTransferUpdateMsg`(
+ `x1`: kotlin.String,
+ `recipientAddress`: kotlin.String,
+ `coin`: Coin,
+ `transferSignature`: kotlin.String,
+ `backupTransactions`: List,
+): TransferUpdateMsgRequestPayload {
+ return FfiConverterTypeTransferUpdateMsgRequestPayload.lift(
+ uniffiRustCallWithError(MercuryException) { _status ->
+ UniffiLib.INSTANCE.uniffi_mercurylib_fn_func_create_transfer_update_msg(
+ FfiConverterString.lower(`x1`),
+ FfiConverterString.lower(`recipientAddress`),
+ FfiConverterTypeCoin.lower(`coin`),
+ FfiConverterString.lower(`transferSignature`),
+ FfiConverterSequenceTypeBackupTx.lower(`backupTransactions`),
+ _status,
+ )
+ },
+ )
+}
+
+@Throws(MercuryException::class)
+fun `decodeStatechainAddress`(`scAddress`: kotlin.String): DecodedScAddress {
+ return FfiConverterTypeDecodedSCAddress.lift(
+ uniffiRustCallWithError(MercuryException) { _status ->
+ UniffiLib.INSTANCE.uniffi_mercurylib_fn_func_decode_statechain_address(
+ FfiConverterString.lower(`scAddress`),
+ _status,
+ )
+ },
+ )
+}
+
+@Throws(MercuryException::class)
+fun `duplicateCoinToInitializedState`(
+ `wallet`: Wallet,
+ `authPubkey`: kotlin.String,
+): Coin {
+ return FfiConverterTypeCoin.lift(
+ uniffiRustCallWithError(MercuryException) { _status ->
+ UniffiLib.INSTANCE.uniffi_mercurylib_fn_func_duplicate_coin_to_initialized_state(
+ FfiConverterTypeWallet.lower(`wallet`),
+ FfiConverterString.lower(`authPubkey`),
+ _status,
+ )
+ },
+ )
+}
+
+@Throws(MercuryException::class)
+fun `ffiValidateSignatureScheme`(
+ `ffiTransferMsg`: FfiTransferMsg,
+ `statechainInfo`: StatechainInfoResponsePayload,
+ `tx0Hex`: kotlin.String,
+ `feeRateTolerance`: kotlin.UInt,
+ `currentFeeRateSatsPerByte`: kotlin.UInt,
+ `interval`: kotlin.UInt,
+): kotlin.UInt {
+ return FfiConverterUInt.lift(
+ uniffiRustCallWithError(MercuryException) { _status ->
+ UniffiLib.INSTANCE.uniffi_mercurylib_fn_func_ffi_validate_signature_scheme(
+ FfiConverterTypeFFITransferMsg.lower(`ffiTransferMsg`),
+ FfiConverterTypeStatechainInfoResponsePayload.lower(`statechainInfo`),
+ FfiConverterString.lower(`tx0Hex`),
+ FfiConverterUInt.lower(`feeRateTolerance`),
+ FfiConverterUInt.lower(`currentFeeRateSatsPerByte`),
+ FfiConverterUInt.lower(`interval`),
+ _status,
+ )
+ },
+ )
+}
+
+@Throws(MercuryException::class)
+fun `ffiVerifyTransferSignature`(
+ `newUserPubkey`: kotlin.String,
+ `tx0Outpoint`: TxOutpoint,
+ `ffiTransferMsg`: FfiTransferMsg,
+): kotlin.Boolean {
+ return FfiConverterBoolean.lift(
+ uniffiRustCallWithError(MercuryException) { _status ->
+ UniffiLib.INSTANCE.uniffi_mercurylib_fn_func_ffi_verify_transfer_signature(
+ FfiConverterString.lower(`newUserPubkey`),
+ FfiConverterTypeTxOutpoint.lower(`tx0Outpoint`),
+ FfiConverterTypeFFITransferMsg.lower(`ffiTransferMsg`),
+ _status,
+ )
+ },
+ )
+}
+
+@Throws(MercuryException::class)
+fun `fiiCreateTransferReceiverRequestPayload`(
+ `statechainInfo`: StatechainInfoResponsePayload,
+ `ffiTransferMsg`: FfiTransferMsg,
+ `coin`: Coin,
+): TransferReceiverRequestPayload {
+ return FfiConverterTypeTransferReceiverRequestPayload.lift(
+ uniffiRustCallWithError(MercuryException) { _status ->
+ UniffiLib.INSTANCE.uniffi_mercurylib_fn_func_fii_create_transfer_receiver_request_payload(
+ FfiConverterTypeStatechainInfoResponsePayload.lower(`statechainInfo`),
+ FfiConverterTypeFFITransferMsg.lower(`ffiTransferMsg`),
+ FfiConverterTypeCoin.lower(`coin`),
+ _status,
+ )
+ },
+ )
+}
+
+@Throws(MercuryException::class)
+fun `fiiDecryptTransferMsg`(
+ `encryptedMessage`: kotlin.String,
+ `privateKeyWif`: kotlin.String,
+): FfiTransferMsg {
+ return FfiConverterTypeFFITransferMsg.lift(
+ uniffiRustCallWithError(MercuryException) { _status ->
+ UniffiLib.INSTANCE.uniffi_mercurylib_fn_func_fii_decrypt_transfer_msg(
+ FfiConverterString.lower(`encryptedMessage`),
+ FfiConverterString.lower(`privateKeyWif`),
+ _status,
+ )
+ },
+ )
+}
+
+@Throws(MercuryException::class)
+fun `fiiValidateTx0OutputPubkey`(
+ `enclavePublicKey`: kotlin.String,
+ `ffiTransferMsg`: FfiTransferMsg,
+ `tx0Outpoint`: TxOutpoint,
+ `tx0Hex`: kotlin.String,
+ `network`: kotlin.String,
+): kotlin.Boolean {
+ return FfiConverterBoolean.lift(
+ uniffiRustCallWithError(MercuryException) { _status ->
+ UniffiLib.INSTANCE.uniffi_mercurylib_fn_func_fii_validate_tx0_output_pubkey(
+ FfiConverterString.lower(`enclavePublicKey`),
+ FfiConverterTypeFFITransferMsg.lower(`ffiTransferMsg`),
+ FfiConverterTypeTxOutpoint.lower(`tx0Outpoint`),
+ FfiConverterString.lower(`tx0Hex`),
+ FfiConverterString.lower(`network`),
+ _status,
+ )
+ },
+ )
+}
+
+@Throws(MercuryException::class)
+fun `fiiVerifyLatestBackupTxPaysToUserPubkey`(
+ `ffiTransferMsg`: FfiTransferMsg,
+ `clientPubkeyShare`: kotlin.String,
+ `network`: kotlin.String,
+): kotlin.Boolean {
+ return FfiConverterBoolean.lift(
+ uniffiRustCallWithError(MercuryException) { _status ->
+ UniffiLib.INSTANCE.uniffi_mercurylib_fn_func_fii_verify_latest_backup_tx_pays_to_user_pubkey(
+ FfiConverterTypeFFITransferMsg.lower(`ffiTransferMsg`),
+ FfiConverterString.lower(`clientPubkeyShare`),
+ FfiConverterString.lower(`network`),
+ _status,
+ )
+ },
+ )
+}
+
+@Throws(MercuryException::class)
+fun `generateMnemonic`(): kotlin.String {
+ return FfiConverterString.lift(
+ uniffiRustCallWithError(MercuryException) { _status ->
+ UniffiLib.INSTANCE.uniffi_mercurylib_fn_func_generate_mnemonic(
+ _status,
+ )
+ },
+ )
+}
+
+@Throws(MercuryException::class)
+fun `getBlockheight`(`bkpTx`: BackupTx): kotlin.UInt {
+ return FfiConverterUInt.lift(
+ uniffiRustCallWithError(MercuryException) { _status ->
+ UniffiLib.INSTANCE.uniffi_mercurylib_fn_func_get_blockheight(
+ FfiConverterTypeBackupTx.lower(`bkpTx`),
+ _status,
+ )
+ },
+ )
+}
+
+@Throws(MercuryException::class)
+fun `getNewCoin`(`wallet`: Wallet): Coin {
+ return FfiConverterTypeCoin.lift(
+ uniffiRustCallWithError(MercuryException) { _status ->
+ UniffiLib.INSTANCE.uniffi_mercurylib_fn_func_get_new_coin(
+ FfiConverterTypeWallet.lower(`wallet`),
+ _status,
+ )
+ },
+ )
+}
+
+@Throws(MercuryException::class)
+fun `getNewKeyInfo`(
+ `serverPublicKeyHex`: kotlin.String,
+ `coin`: Coin,
+ `statechainId`: kotlin.String,
+ `tx0Outpoint`: TxOutpoint,
+ `tx0Hex`: kotlin.String,
+ `network`: kotlin.String,
+): NewKeyInfo {
+ return FfiConverterTypeNewKeyInfo.lift(
+ uniffiRustCallWithError(MercuryException) { _status ->
+ UniffiLib.INSTANCE.uniffi_mercurylib_fn_func_get_new_key_info(
+ FfiConverterString.lower(`serverPublicKeyHex`),
+ FfiConverterTypeCoin.lower(`coin`),
+ FfiConverterString.lower(`statechainId`),
+ FfiConverterTypeTxOutpoint.lower(`tx0Outpoint`),
+ FfiConverterString.lower(`tx0Hex`),
+ FfiConverterString.lower(`network`),
+ _status,
+ )
+ },
+ )
+}
+
+@Throws(MercuryException::class)
+fun `getOutputAddressFromTx0`(
+ `tx0Outpoint`: TxOutpoint,
+ `tx0Hex`: kotlin.String,
+ `network`: kotlin.String,
+): kotlin.String {
+ return FfiConverterString.lift(
+ uniffiRustCallWithError(MercuryException) { _status ->
+ UniffiLib.INSTANCE.uniffi_mercurylib_fn_func_get_output_address_from_tx0(
+ FfiConverterTypeTxOutpoint.lower(`tx0Outpoint`),
+ FfiConverterString.lower(`tx0Hex`),
+ FfiConverterString.lower(`network`),
+ _status,
+ )
+ },
+ )
+}
+
+@Throws(MercuryException::class)
+fun `getPartialSigRequest`(
+ `coin`: Coin,
+ `blockHeight`: kotlin.UInt,
+ `initlock`: kotlin.UInt,
+ `interval`: kotlin.UInt,
+ `feeRateSatsPerByte`: kotlin.UInt,
+ `qtBackupTx`: kotlin.UInt,
+ `toAddress`: kotlin.String,
+ `network`: kotlin.String,
+ `isWithdrawal`: kotlin.Boolean,
+): PartialSignatureMsg1 {
+ return FfiConverterTypePartialSignatureMsg1.lift(
+ uniffiRustCallWithError(MercuryException) { _status ->
+ UniffiLib.INSTANCE.uniffi_mercurylib_fn_func_get_partial_sig_request(
+ FfiConverterTypeCoin.lower(`coin`),
+ FfiConverterUInt.lower(`blockHeight`),
+ FfiConverterUInt.lower(`initlock`),
+ FfiConverterUInt.lower(`interval`),
+ FfiConverterUInt.lower(`feeRateSatsPerByte`),
+ FfiConverterUInt.lower(`qtBackupTx`),
+ FfiConverterString.lower(`toAddress`),
+ FfiConverterString.lower(`network`),
+ FfiConverterBoolean.lower(`isWithdrawal`),
+ _status,
+ )
+ },
+ )
+}
+
+@Throws(MercuryException::class)
+fun `getTx0Outpoint`(`backupTransactions`: List): TxOutpoint {
+ return FfiConverterTypeTxOutpoint.lift(
+ uniffiRustCallWithError(MercuryException) { _status ->
+ UniffiLib.INSTANCE.uniffi_mercurylib_fn_func_get_tx0_outpoint(
+ FfiConverterSequenceTypeBackupTx.lower(`backupTransactions`),
+ _status,
+ )
+ },
+ )
+}
+
+@Throws(MercuryException::class)
+fun `getUserBackupAddress`(
+ `coin`: Coin,
+ `network`: kotlin.String,
+): kotlin.String {
+ return FfiConverterString.lift(
+ uniffiRustCallWithError(MercuryException) { _status ->
+ UniffiLib.INSTANCE.uniffi_mercurylib_fn_func_get_user_backup_address(
+ FfiConverterTypeCoin.lower(`coin`),
+ FfiConverterString.lower(`network`),
+ _status,
+ )
+ },
+ )
+}
+
+@Throws(MercuryException::class)
+fun `handleDepositMsg1Response`(
+ `coin`: Coin,
+ `depositMsg1Response`: DepositMsg1Response,
+): DepositInitResult {
+ return FfiConverterTypeDepositInitResult.lift(
+ uniffiRustCallWithError(MercuryException) { _status ->
+ UniffiLib.INSTANCE.uniffi_mercurylib_fn_func_handle_deposit_msg_1_response(
+ FfiConverterTypeCoin.lower(`coin`),
+ FfiConverterTypeDepositMsg1Response.lower(`depositMsg1Response`),
+ _status,
+ )
+ },
+ )
+}
+
+@Throws(MercuryException::class)
+fun `isEnclavePubkeyPartOfCoin`(
+ `coin`: Coin,
+ `enclavePubkey`: kotlin.String,
+): kotlin.Boolean {
+ return FfiConverterBoolean.lift(
+ uniffiRustCallWithError(MercuryException) { _status ->
+ UniffiLib.INSTANCE.uniffi_mercurylib_fn_func_is_enclave_pubkey_part_of_coin(
+ FfiConverterTypeCoin.lower(`coin`),
+ FfiConverterString.lower(`enclavePubkey`),
+ _status,
+ )
+ },
+ )
+}
+
+@Throws(MercuryException::class)
+fun `latestBackupTxPaysToUserPubkey`(
+ `backupTxs`: List,
+ `coin`: Coin,
+ `network`: kotlin.String,
+): BackupTx {
+ return FfiConverterTypeBackupTx.lift(
+ uniffiRustCallWithError(MercuryException) { _status ->
+ UniffiLib.INSTANCE.uniffi_mercurylib_fn_func_latest_backup_tx_pays_to_user_pubkey(
+ FfiConverterSequenceTypeBackupTx.lower(`backupTxs`),
+ FfiConverterTypeCoin.lower(`coin`),
+ FfiConverterString.lower(`network`),
+ _status,
+ )
+ },
+ )
+}
+
+@Throws(MercuryException::class)
+fun `newBackupTransaction`(
+ `encodedUnsignedTx`: kotlin.String,
+ `signatureHex`: kotlin.String,
+): kotlin.String {
+ return FfiConverterString.lift(
+ uniffiRustCallWithError(MercuryException) { _status ->
+ UniffiLib.INSTANCE.uniffi_mercurylib_fn_func_new_backup_transaction(
+ FfiConverterString.lower(`encodedUnsignedTx`),
+ FfiConverterString.lower(`signatureHex`),
+ _status,
+ )
+ },
+ )
+}
+
+@Throws(MercuryException::class)
+fun `signMessage`(
+ `message`: kotlin.String,
+ `coin`: Coin,
+): kotlin.String {
+ return FfiConverterString.lift(
+ uniffiRustCallWithError(MercuryException) { _status ->
+ UniffiLib.INSTANCE.uniffi_mercurylib_fn_func_sign_message(
+ FfiConverterString.lower(`message`),
+ FfiConverterTypeCoin.lower(`coin`),
+ _status,
+ )
+ },
+ )
+}
+
+@Throws(MercuryException::class)
+fun `validateAddress`(
+ `address`: kotlin.String,
+ `network`: kotlin.String,
+): kotlin.Boolean {
+ return FfiConverterBoolean.lift(
+ uniffiRustCallWithError(MercuryException) { _status ->
+ UniffiLib.INSTANCE.uniffi_mercurylib_fn_func_validate_address(
+ FfiConverterString.lower(`address`),
+ FfiConverterString.lower(`network`),
+ _status,
+ )
+ },
+ )
+}
+
+@Throws(MercuryException::class)
+fun `verifyBlindedMusigScheme`(
+ `backupTx`: BackupTx,
+ `tx0Hex`: kotlin.String,
+ `statechainInfo`: StatechainInfo,
+) = uniffiRustCallWithError(MercuryException) { _status ->
+ UniffiLib.INSTANCE.uniffi_mercurylib_fn_func_verify_blinded_musig_scheme(
+ FfiConverterTypeBackupTx.lower(`backupTx`),
+ FfiConverterString.lower(`tx0Hex`),
+ FfiConverterTypeStatechainInfo.lower(`statechainInfo`),
+ _status,
+ )
+}
+
+@Throws(MercuryException::class)
+fun `verifyTransactionSignature`(
+ `txNHex`: kotlin.String,
+ `tx0Hex`: kotlin.String,
+ `feeRateTolerance`: kotlin.UInt,
+ `currentFeeRateSatsPerByte`: kotlin.UInt,
+) = uniffiRustCallWithError(MercuryException) { _status ->
+ UniffiLib.INSTANCE.uniffi_mercurylib_fn_func_verify_transaction_signature(
+ FfiConverterString.lower(`txNHex`),
+ FfiConverterString.lower(`tx0Hex`),
+ FfiConverterUInt.lower(`feeRateTolerance`),
+ FfiConverterUInt.lower(`currentFeeRateSatsPerByte`),
+ _status,
+ )
+}
diff --git a/clients/apps/kotlin/src/main/kotlinotlin b/clients/apps/kotlin/src/main/kotlinotlin
new file mode 100644
index 00000000..41e4238e
--- /dev/null
+++ b/clients/apps/kotlin/src/main/kotlinotlin
@@ -0,0 +1,4611 @@
+// This file was autogenerated by some hot garbage in the `uniffi` crate.
+// Trust me, you don't want to mess with it!
+
+@file:Suppress("NAME_SHADOWING")
+
+
+// Common helper code.
+//
+// Ideally this would live in a separate .kt file where it can be unittested etc
+// in isolation, and perhaps even published as a re-useable package.
+//
+// However, it's important that the details of how this helper code works (e.g. the
+// way that different builtin types are passed across the FFI) exactly match what's
+// expected by the Rust code on the other side of the interface. In practice right
+// now that means coming from the exact some version of `uniffi` that was used to
+// compile the Rust component. The easiest way to ensure this is to bundle the Kotlin
+// helpers directly inline like we're doing here.
+
+import com.sun.jna.Callback
+import com.sun.jna.Library
+import com.sun.jna.Native
+import com.sun.jna.Pointer
+import com.sun.jna.Structure
+import com.sun.jna.ptr.*
+import kotlinx.serialization.Serializable
+import kotlinx.serialization.SerialName
+import java.nio.ByteBuffer
+import java.nio.ByteOrder
+import java.nio.CharBuffer
+import java.nio.charset.CodingErrorAction
+import java.util.concurrent.ConcurrentHashMap
+import java.util.concurrent.atomic.AtomicLong
+
+// This is a helper for safely working with byte buffers returned from the Rust code.
+// A rust-owned buffer is represented by its capacity, its current length, and a
+// pointer to the underlying data.
+
+@Structure.FieldOrder("capacity", "len", "data")
+open class RustBuffer : Structure() {
+ // Note: `capacity` and `len` are actually `ULong` values, but JVM only supports signed values.
+ // When dealing with these fields, make sure to call `toULong()`.
+ @JvmField var capacity: Long = 0
+
+ @JvmField var len: Long = 0
+
+ @JvmField var data: Pointer? = null
+
+ class ByValue : RustBuffer(), Structure.ByValue
+
+ class ByReference : RustBuffer(), Structure.ByReference
+
+ internal fun setValue(other: RustBuffer) {
+ capacity = other.capacity
+ len = other.len
+ data = other.data
+ }
+
+ companion object {
+ internal fun alloc(size: ULong = 0UL) =
+ uniffiRustCall { status ->
+ // Note: need to convert the size to a `Long` value to make this work with JVM.
+ UniffiLib.INSTANCE.ffi_mercurylib_rustbuffer_alloc(size.toLong(), status)
+ }.also {
+ if (it.data == null) {
+ throw RuntimeException("RustBuffer.alloc() returned null data pointer (size=$size)")
+ }
+ }
+
+ internal fun create(
+ capacity: ULong,
+ len: ULong,
+ data: Pointer?,
+ ): RustBuffer.ByValue {
+ var buf = RustBuffer.ByValue()
+ buf.capacity = capacity.toLong()
+ buf.len = len.toLong()
+ buf.data = data
+ return buf
+ }
+
+ internal fun free(buf: RustBuffer.ByValue) =
+ uniffiRustCall { status ->
+ UniffiLib.INSTANCE.ffi_mercurylib_rustbuffer_free(buf, status)
+ }
+ }
+
+ @Suppress("TooGenericExceptionThrown")
+ fun asByteBuffer() =
+ this.data?.getByteBuffer(0, this.len.toLong())?.also {
+ it.order(ByteOrder.BIG_ENDIAN)
+ }
+}
+
+/**
+ * The equivalent of the `*mut RustBuffer` type.
+ * Required for callbacks taking in an out pointer.
+ *
+ * Size is the sum of all values in the struct.
+ */
+class RustBufferByReference : ByReference(16) {
+ /**
+ * Set the pointed-to `RustBuffer` to the given value.
+ */
+ fun setValue(value: RustBuffer.ByValue) {
+ // NOTE: The offsets are as they are in the C-like struct.
+ val pointer = getPointer()
+ pointer.setLong(0, value.capacity)
+ pointer.setLong(8, value.len)
+ pointer.setPointer(16, value.data)
+ }
+
+ /**
+ * Get a `RustBuffer.ByValue` from this reference.
+ */
+ fun getValue(): RustBuffer.ByValue {
+ val pointer = getPointer()
+ val value = RustBuffer.ByValue()
+ value.writeField("capacity", pointer.getLong(0))
+ value.writeField("len", pointer.getLong(8))
+ value.writeField("data", pointer.getLong(16))
+
+ return value
+ }
+}
+
+// This is a helper for safely passing byte references into the rust code.
+// It's not actually used at the moment, because there aren't many things that you
+// can take a direct pointer to in the JVM, and if we're going to copy something
+// then we might as well copy it into a `RustBuffer`. But it's here for API
+// completeness.
+
+@Structure.FieldOrder("len", "data")
+open class ForeignBytes : Structure() {
+ @JvmField var len: Int = 0
+
+ @JvmField var data: Pointer? = null
+
+ class ByValue : ForeignBytes(), Structure.ByValue
+}
+
+// The FfiConverter interface handles converter types to and from the FFI
+//
+// All implementing objects should be public to support external types. When a
+// type is external we need to import it's FfiConverter.
+public interface FfiConverter {
+ // Convert an FFI type to a Kotlin type
+ fun lift(value: FfiType): KotlinType
+
+ // Convert an Kotlin type to an FFI type
+ fun lower(value: KotlinType): FfiType
+
+ // Read a Kotlin type from a `ByteBuffer`
+ fun read(buf: ByteBuffer): KotlinType
+
+ // Calculate bytes to allocate when creating a `RustBuffer`
+ //
+ // This must return at least as many bytes as the write() function will
+ // write. It can return more bytes than needed, for example when writing
+ // Strings we can't know the exact bytes needed until we the UTF-8
+ // encoding, so we pessimistically allocate the largest size possible (3
+ // bytes per codepoint). Allocating extra bytes is not really a big deal
+ // because the `RustBuffer` is short-lived.
+ fun allocationSize(value: KotlinType): ULong
+
+ // Write a Kotlin type to a `ByteBuffer`
+ fun write(
+ value: KotlinType,
+ buf: ByteBuffer,
+ )
+
+ // Lower a value into a `RustBuffer`
+ //
+ // This method lowers a value into a `RustBuffer` rather than the normal
+ // FfiType. It's used by the callback interface code. Callback interface
+ // returns are always serialized into a `RustBuffer` regardless of their
+ // normal FFI type.
+ fun lowerIntoRustBuffer(value: KotlinType): RustBuffer.ByValue {
+ val rbuf = RustBuffer.alloc(allocationSize(value))
+ try {
+ val bbuf =
+ rbuf.data!!.getByteBuffer(0, rbuf.capacity).also {
+ it.order(ByteOrder.BIG_ENDIAN)
+ }
+ write(value, bbuf)
+ rbuf.writeField("len", bbuf.position().toLong())
+ return rbuf
+ } catch (e: Throwable) {
+ RustBuffer.free(rbuf)
+ throw e
+ }
+ }
+
+ // Lift a value from a `RustBuffer`.
+ //
+ // This here mostly because of the symmetry with `lowerIntoRustBuffer()`.
+ // It's currently only used by the `FfiConverterRustBuffer` class below.
+ fun liftFromRustBuffer(rbuf: RustBuffer.ByValue): KotlinType {
+ val byteBuf = rbuf.asByteBuffer()!!
+ try {
+ val item = read(byteBuf)
+ if (byteBuf.hasRemaining()) {
+ throw RuntimeException("junk remaining in buffer after lifting, something is very wrong!!")
+ }
+ return item
+ } finally {
+ RustBuffer.free(rbuf)
+ }
+ }
+}
+
+// FfiConverter that uses `RustBuffer` as the FfiType
+public interface FfiConverterRustBuffer : FfiConverter {
+ override fun lift(value: RustBuffer.ByValue) = liftFromRustBuffer(value)
+
+ override fun lower(value: KotlinType) = lowerIntoRustBuffer(value)
+}
+// A handful of classes and functions to support the generated data structures.
+// This would be a good candidate for isolating in its own ffi-support lib.
+
+internal const val UNIFFI_CALL_SUCCESS = 0.toByte()
+internal const val UNIFFI_CALL_ERROR = 1.toByte()
+internal const val UNIFFI_CALL_UNEXPECTED_ERROR = 2.toByte()
+
+@Structure.FieldOrder("code", "error_buf")
+internal open class UniffiRustCallStatus : Structure() {
+ @JvmField var code: Byte = 0
+
+ @JvmField var error_buf: RustBuffer.ByValue = RustBuffer.ByValue()
+
+ class ByValue : UniffiRustCallStatus(), Structure.ByValue
+
+ fun isSuccess(): Boolean {
+ return code == UNIFFI_CALL_SUCCESS
+ }
+
+ fun isError(): Boolean {
+ return code == UNIFFI_CALL_ERROR
+ }
+
+ fun isPanic(): Boolean {
+ return code == UNIFFI_CALL_UNEXPECTED_ERROR
+ }
+
+ companion object {
+ fun create(
+ code: Byte,
+ errorBuf: RustBuffer.ByValue,
+ ): UniffiRustCallStatus.ByValue {
+ val callStatus = UniffiRustCallStatus.ByValue()
+ callStatus.code = code
+ callStatus.error_buf = errorBuf
+ return callStatus
+ }
+ }
+}
+
+class InternalException(message: String) : Exception(message)
+
+// Each top-level error class has a companion object that can lift the error from the call status's rust buffer
+interface UniffiRustCallStatusErrorHandler {
+ fun lift(error_buf: RustBuffer.ByValue): E
+}
+
+// Helpers for calling Rust
+// In practice we usually need to be synchronized to call this safely, so it doesn't
+// synchronize itself
+
+// Call a rust function that returns a Result<>. Pass in the Error class companion that corresponds to the Err
+private inline fun uniffiRustCallWithError(
+ errorHandler: UniffiRustCallStatusErrorHandler,
+ callback: (UniffiRustCallStatus) -> U,
+): U {
+ var status = UniffiRustCallStatus()
+ val return_value = callback(status)
+ uniffiCheckCallStatus(errorHandler, status)
+ return return_value
+}
+
+// Check UniffiRustCallStatus and throw an error if the call wasn't successful
+private fun uniffiCheckCallStatus(
+ errorHandler: UniffiRustCallStatusErrorHandler,
+ status: UniffiRustCallStatus,
+) {
+ if (status.isSuccess()) {
+ return
+ } else if (status.isError()) {
+ throw errorHandler.lift(status.error_buf)
+ } else if (status.isPanic()) {
+ // when the rust code sees a panic, it tries to construct a rustbuffer
+ // with the message. but if that code panics, then it just sends back
+ // an empty buffer.
+ if (status.error_buf.len > 0) {
+ throw InternalException(FfiConverterString.lift(status.error_buf))
+ } else {
+ throw InternalException("Rust panic")
+ }
+ } else {
+ throw InternalException("Unknown rust call status: $status.code")
+ }
+}
+
+// UniffiRustCallStatusErrorHandler implementation for times when we don't expect a CALL_ERROR
+object UniffiNullRustCallStatusErrorHandler : UniffiRustCallStatusErrorHandler {
+ override fun lift(error_buf: RustBuffer.ByValue): InternalException {
+ RustBuffer.free(error_buf)
+ return InternalException("Unexpected CALL_ERROR")
+ }
+}
+
+// Call a rust function that returns a plain value
+private inline fun uniffiRustCall(callback: (UniffiRustCallStatus) -> U): U {
+ return uniffiRustCallWithError(UniffiNullRustCallStatusErrorHandler, callback)
+}
+
+internal inline fun uniffiTraitInterfaceCall(
+ callStatus: UniffiRustCallStatus,
+ makeCall: () -> T,
+ writeReturn: (T) -> Unit,
+) {
+ try {
+ writeReturn(makeCall())
+ } catch (e: Exception) {
+ callStatus.code = UNIFFI_CALL_UNEXPECTED_ERROR
+ callStatus.error_buf = FfiConverterString.lower(e.toString())
+ }
+}
+
+internal inline fun uniffiTraitInterfaceCallWithError(
+ callStatus: UniffiRustCallStatus,
+ makeCall: () -> T,
+ writeReturn: (T) -> Unit,
+ lowerError: (E) -> RustBuffer.ByValue,
+) {
+ try {
+ writeReturn(makeCall())
+ } catch (e: Exception) {
+ if (e is E) {
+ callStatus.code = UNIFFI_CALL_ERROR
+ callStatus.error_buf = lowerError(e)
+ } else {
+ callStatus.code = UNIFFI_CALL_UNEXPECTED_ERROR
+ callStatus.error_buf = FfiConverterString.lower(e.toString())
+ }
+ }
+}
+
+// Map handles to objects
+//
+// This is used pass an opaque 64-bit handle representing a foreign object to the Rust code.
+internal class UniffiHandleMap {
+ private val map = ConcurrentHashMap()
+ private val counter = java.util.concurrent.atomic.AtomicLong(0)
+
+ val size: Int
+ get() = map.size
+
+ // Insert a new object into the handle map and get a handle for it
+ fun insert(obj: T): Long {
+ val handle = counter.getAndAdd(1)
+ map.put(handle, obj)
+ return handle
+ }
+
+ // Get an object from the handle map
+ fun get(handle: Long): T {
+ return map.get(handle) ?: throw InternalException("UniffiHandleMap.get: Invalid handle")
+ }
+
+ // Remove an entry from the handlemap and get the Kotlin object back
+ fun remove(handle: Long): T {
+ return map.remove(handle) ?: throw InternalException("UniffiHandleMap: Invalid handle")
+ }
+}
+
+// Contains loading, initialization code,
+// and the FFI Function declarations in a com.sun.jna.Library.
+@Synchronized
+private fun findLibraryName(componentName: String): String {
+ val libOverride = System.getProperty("uniffi.component.$componentName.libraryOverride")
+ if (libOverride != null) {
+ return libOverride
+ }
+ return "mercurylib"
+}
+
+private inline fun loadIndirect(componentName: String): Lib {
+ return Native.load(findLibraryName(componentName), Lib::class.java)
+}
+
+// Define FFI callback types
+internal interface UniffiRustFutureContinuationCallback : com.sun.jna.Callback {
+ fun callback(
+ `data`: Long,
+ `pollResult`: Byte,
+ )
+}
+
+internal interface UniffiForeignFutureFree : com.sun.jna.Callback {
+ fun callback(`handle`: Long)
+}
+
+internal interface UniffiCallbackInterfaceFree : com.sun.jna.Callback {
+ fun callback(`handle`: Long)
+}
+
+@Structure.FieldOrder("handle", "free")
+internal open class UniffiForeignFuture(
+ @JvmField internal var `handle`: Long = 0.toLong(),
+ @JvmField internal var `free`: UniffiForeignFutureFree? = null,
+) : Structure() {
+ class UniffiByValue(
+ `handle`: Long = 0.toLong(),
+ `free`: UniffiForeignFutureFree? = null,
+ ) : UniffiForeignFuture(`handle`, `free`), Structure.ByValue
+
+ internal fun uniffiSetValue(other: UniffiForeignFuture) {
+ `handle` = other.`handle`
+ `free` = other.`free`
+ }
+}
+
+@Structure.FieldOrder("returnValue", "callStatus")
+internal open class UniffiForeignFutureStructU8(
+ @JvmField internal var `returnValue`: Byte = 0.toByte(),
+ @JvmField internal var `callStatus`: UniffiRustCallStatus.ByValue = UniffiRustCallStatus.ByValue(),
+) : Structure() {
+ class UniffiByValue(
+ `returnValue`: Byte = 0.toByte(),
+ `callStatus`: UniffiRustCallStatus.ByValue = UniffiRustCallStatus.ByValue(),
+ ) : UniffiForeignFutureStructU8(`returnValue`, `callStatus`), Structure.ByValue
+
+ internal fun uniffiSetValue(other: UniffiForeignFutureStructU8) {
+ `returnValue` = other.`returnValue`
+ `callStatus` = other.`callStatus`
+ }
+}
+
+internal interface UniffiForeignFutureCompleteU8 : com.sun.jna.Callback {
+ fun callback(
+ `callbackData`: Long,
+ `result`: UniffiForeignFutureStructU8.UniffiByValue,
+ )
+}
+
+@Structure.FieldOrder("returnValue", "callStatus")
+internal open class UniffiForeignFutureStructI8(
+ @JvmField internal var `returnValue`: Byte = 0.toByte(),
+ @JvmField internal var `callStatus`: UniffiRustCallStatus.ByValue = UniffiRustCallStatus.ByValue(),
+) : Structure() {
+ class UniffiByValue(
+ `returnValue`: Byte = 0.toByte(),
+ `callStatus`: UniffiRustCallStatus.ByValue = UniffiRustCallStatus.ByValue(),
+ ) : UniffiForeignFutureStructI8(`returnValue`, `callStatus`), Structure.ByValue
+
+ internal fun uniffiSetValue(other: UniffiForeignFutureStructI8) {
+ `returnValue` = other.`returnValue`
+ `callStatus` = other.`callStatus`
+ }
+}
+
+internal interface UniffiForeignFutureCompleteI8 : com.sun.jna.Callback {
+ fun callback(
+ `callbackData`: Long,
+ `result`: UniffiForeignFutureStructI8.UniffiByValue,
+ )
+}
+
+@Structure.FieldOrder("returnValue", "callStatus")
+internal open class UniffiForeignFutureStructU16(
+ @JvmField internal var `returnValue`: Short = 0.toShort(),
+ @JvmField internal var `callStatus`: UniffiRustCallStatus.ByValue = UniffiRustCallStatus.ByValue(),
+) : Structure() {
+ class UniffiByValue(
+ `returnValue`: Short = 0.toShort(),
+ `callStatus`: UniffiRustCallStatus.ByValue = UniffiRustCallStatus.ByValue(),
+ ) : UniffiForeignFutureStructU16(`returnValue`, `callStatus`), Structure.ByValue
+
+ internal fun uniffiSetValue(other: UniffiForeignFutureStructU16) {
+ `returnValue` = other.`returnValue`
+ `callStatus` = other.`callStatus`
+ }
+}
+
+internal interface UniffiForeignFutureCompleteU16 : com.sun.jna.Callback {
+ fun callback(
+ `callbackData`: Long,
+ `result`: UniffiForeignFutureStructU16.UniffiByValue,
+ )
+}
+
+@Structure.FieldOrder("returnValue", "callStatus")
+internal open class UniffiForeignFutureStructI16(
+ @JvmField internal var `returnValue`: Short = 0.toShort(),
+ @JvmField internal var `callStatus`: UniffiRustCallStatus.ByValue = UniffiRustCallStatus.ByValue(),
+) : Structure() {
+ class UniffiByValue(
+ `returnValue`: Short = 0.toShort(),
+ `callStatus`: UniffiRustCallStatus.ByValue = UniffiRustCallStatus.ByValue(),
+ ) : UniffiForeignFutureStructI16(`returnValue`, `callStatus`), Structure.ByValue
+
+ internal fun uniffiSetValue(other: UniffiForeignFutureStructI16) {
+ `returnValue` = other.`returnValue`
+ `callStatus` = other.`callStatus`
+ }
+}
+
+internal interface UniffiForeignFutureCompleteI16 : com.sun.jna.Callback {
+ fun callback(
+ `callbackData`: Long,
+ `result`: UniffiForeignFutureStructI16.UniffiByValue,
+ )
+}
+
+@Structure.FieldOrder("returnValue", "callStatus")
+internal open class UniffiForeignFutureStructU32(
+ @JvmField internal var `returnValue`: Int = 0,
+ @JvmField internal var `callStatus`: UniffiRustCallStatus.ByValue = UniffiRustCallStatus.ByValue(),
+) : Structure() {
+ class UniffiByValue(
+ `returnValue`: Int = 0,
+ `callStatus`: UniffiRustCallStatus.ByValue = UniffiRustCallStatus.ByValue(),
+ ) : UniffiForeignFutureStructU32(`returnValue`, `callStatus`), Structure.ByValue
+
+ internal fun uniffiSetValue(other: UniffiForeignFutureStructU32) {
+ `returnValue` = other.`returnValue`
+ `callStatus` = other.`callStatus`
+ }
+}
+
+internal interface UniffiForeignFutureCompleteU32 : com.sun.jna.Callback {
+ fun callback(
+ `callbackData`: Long,
+ `result`: UniffiForeignFutureStructU32.UniffiByValue,
+ )
+}
+
+@Structure.FieldOrder("returnValue", "callStatus")
+internal open class UniffiForeignFutureStructI32(
+ @JvmField internal var `returnValue`: Int = 0,
+ @JvmField internal var `callStatus`: UniffiRustCallStatus.ByValue = UniffiRustCallStatus.ByValue(),
+) : Structure() {
+ class UniffiByValue(
+ `returnValue`: Int = 0,
+ `callStatus`: UniffiRustCallStatus.ByValue = UniffiRustCallStatus.ByValue(),
+ ) : UniffiForeignFutureStructI32(`returnValue`, `callStatus`), Structure.ByValue
+
+ internal fun uniffiSetValue(other: UniffiForeignFutureStructI32) {
+ `returnValue` = other.`returnValue`
+ `callStatus` = other.`callStatus`
+ }
+}
+
+internal interface UniffiForeignFutureCompleteI32 : com.sun.jna.Callback {
+ fun callback(
+ `callbackData`: Long,
+ `result`: UniffiForeignFutureStructI32.UniffiByValue,
+ )
+}
+
+@Structure.FieldOrder("returnValue", "callStatus")
+internal open class UniffiForeignFutureStructU64(
+ @JvmField internal var `returnValue`: Long = 0.toLong(),
+ @JvmField internal var `callStatus`: UniffiRustCallStatus.ByValue = UniffiRustCallStatus.ByValue(),
+) : Structure() {
+ class UniffiByValue(
+ `returnValue`: Long = 0.toLong(),
+ `callStatus`: UniffiRustCallStatus.ByValue = UniffiRustCallStatus.ByValue(),
+ ) : UniffiForeignFutureStructU64(`returnValue`, `callStatus`), Structure.ByValue
+
+ internal fun uniffiSetValue(other: UniffiForeignFutureStructU64) {
+ `returnValue` = other.`returnValue`
+ `callStatus` = other.`callStatus`
+ }
+}
+
+internal interface UniffiForeignFutureCompleteU64 : com.sun.jna.Callback {
+ fun callback(
+ `callbackData`: Long,
+ `result`: UniffiForeignFutureStructU64.UniffiByValue,
+ )
+}
+
+@Structure.FieldOrder("returnValue", "callStatus")
+internal open class UniffiForeignFutureStructI64(
+ @JvmField internal var `returnValue`: Long = 0.toLong(),
+ @JvmField internal var `callStatus`: UniffiRustCallStatus.ByValue = UniffiRustCallStatus.ByValue(),
+) : Structure() {
+ class UniffiByValue(
+ `returnValue`: Long = 0.toLong(),
+ `callStatus`: UniffiRustCallStatus.ByValue = UniffiRustCallStatus.ByValue(),
+ ) : UniffiForeignFutureStructI64(`returnValue`, `callStatus`), Structure.ByValue
+
+ internal fun uniffiSetValue(other: UniffiForeignFutureStructI64) {
+ `returnValue` = other.`returnValue`
+ `callStatus` = other.`callStatus`
+ }
+}
+
+internal interface UniffiForeignFutureCompleteI64 : com.sun.jna.Callback {
+ fun callback(
+ `callbackData`: Long,
+ `result`: UniffiForeignFutureStructI64.UniffiByValue,
+ )
+}
+
+@Structure.FieldOrder("returnValue", "callStatus")
+internal open class UniffiForeignFutureStructF32(
+ @JvmField internal var `returnValue`: Float = 0.0f,
+ @JvmField internal var `callStatus`: UniffiRustCallStatus.ByValue = UniffiRustCallStatus.ByValue(),
+) : Structure() {
+ class UniffiByValue(
+ `returnValue`: Float = 0.0f,
+ `callStatus`: UniffiRustCallStatus.ByValue = UniffiRustCallStatus.ByValue(),
+ ) : UniffiForeignFutureStructF32(`returnValue`, `callStatus`), Structure.ByValue
+
+ internal fun uniffiSetValue(other: UniffiForeignFutureStructF32) {
+ `returnValue` = other.`returnValue`
+ `callStatus` = other.`callStatus`
+ }
+}
+
+internal interface UniffiForeignFutureCompleteF32 : com.sun.jna.Callback {
+ fun callback(
+ `callbackData`: Long,
+ `result`: UniffiForeignFutureStructF32.UniffiByValue,
+ )
+}
+
+@Structure.FieldOrder("returnValue", "callStatus")
+internal open class UniffiForeignFutureStructF64(
+ @JvmField internal var `returnValue`: Double = 0.0,
+ @JvmField internal var `callStatus`: UniffiRustCallStatus.ByValue = UniffiRustCallStatus.ByValue(),
+) : Structure() {
+ class UniffiByValue(
+ `returnValue`: Double = 0.0,
+ `callStatus`: UniffiRustCallStatus.ByValue = UniffiRustCallStatus.ByValue(),
+ ) : UniffiForeignFutureStructF64(`returnValue`, `callStatus`), Structure.ByValue
+
+ internal fun uniffiSetValue(other: UniffiForeignFutureStructF64) {
+ `returnValue` = other.`returnValue`
+ `callStatus` = other.`callStatus`
+ }
+}
+
+internal interface UniffiForeignFutureCompleteF64 : com.sun.jna.Callback {
+ fun callback(
+ `callbackData`: Long,
+ `result`: UniffiForeignFutureStructF64.UniffiByValue,
+ )
+}
+
+@Structure.FieldOrder("returnValue", "callStatus")
+internal open class UniffiForeignFutureStructPointer(
+ @JvmField internal var `returnValue`: Pointer = Pointer.NULL,
+ @JvmField internal var `callStatus`: UniffiRustCallStatus.ByValue = UniffiRustCallStatus.ByValue(),
+) : Structure() {
+ class UniffiByValue(
+ `returnValue`: Pointer = Pointer.NULL,
+ `callStatus`: UniffiRustCallStatus.ByValue = UniffiRustCallStatus.ByValue(),
+ ) : UniffiForeignFutureStructPointer(`returnValue`, `callStatus`), Structure.ByValue
+
+ internal fun uniffiSetValue(other: UniffiForeignFutureStructPointer) {
+ `returnValue` = other.`returnValue`
+ `callStatus` = other.`callStatus`
+ }
+}
+
+internal interface UniffiForeignFutureCompletePointer : com.sun.jna.Callback {
+ fun callback(
+ `callbackData`: Long,
+ `result`: UniffiForeignFutureStructPointer.UniffiByValue,
+ )
+}
+
+@Structure.FieldOrder("returnValue", "callStatus")
+internal open class UniffiForeignFutureStructRustBuffer(
+ @JvmField internal var `returnValue`: RustBuffer.ByValue = RustBuffer.ByValue(),
+ @JvmField internal var `callStatus`: UniffiRustCallStatus.ByValue = UniffiRustCallStatus.ByValue(),
+) : Structure() {
+ class UniffiByValue(
+ `returnValue`: RustBuffer.ByValue = RustBuffer.ByValue(),
+ `callStatus`: UniffiRustCallStatus.ByValue = UniffiRustCallStatus.ByValue(),
+ ) : UniffiForeignFutureStructRustBuffer(`returnValue`, `callStatus`), Structure.ByValue
+
+ internal fun uniffiSetValue(other: UniffiForeignFutureStructRustBuffer) {
+ `returnValue` = other.`returnValue`
+ `callStatus` = other.`callStatus`
+ }
+}
+
+internal interface UniffiForeignFutureCompleteRustBuffer : com.sun.jna.Callback {
+ fun callback(
+ `callbackData`: Long,
+ `result`: UniffiForeignFutureStructRustBuffer.UniffiByValue,
+ )
+}
+
+@Structure.FieldOrder("callStatus")
+internal open class UniffiForeignFutureStructVoid(
+ @JvmField internal var `callStatus`: UniffiRustCallStatus.ByValue = UniffiRustCallStatus.ByValue(),
+) : Structure() {
+ class UniffiByValue(
+ `callStatus`: UniffiRustCallStatus.ByValue = UniffiRustCallStatus.ByValue(),
+ ) : UniffiForeignFutureStructVoid(`callStatus`), Structure.ByValue
+
+ internal fun uniffiSetValue(other: UniffiForeignFutureStructVoid) {
+ `callStatus` = other.`callStatus`
+ }
+}
+
+internal interface UniffiForeignFutureCompleteVoid : com.sun.jna.Callback {
+ fun callback(
+ `callbackData`: Long,
+ `result`: UniffiForeignFutureStructVoid.UniffiByValue,
+ )
+}
+
+// A JNA Library to expose the extern-C FFI definitions.
+// This is an implementation detail which will be called internally by the public API.
+
+internal interface UniffiLib : Library {
+ companion object {
+ internal val INSTANCE: UniffiLib by lazy {
+ loadIndirect(componentName = "mercurylib")
+ .also { lib: UniffiLib ->
+ uniffiCheckContractApiVersion(lib)
+ uniffiCheckApiChecksums(lib)
+ }
+ }
+ }
+
+ fun uniffi_mercurylib_fn_func_create_aggregated_address(
+ `coin`: RustBuffer.ByValue,
+ `network`: RustBuffer.ByValue,
+ uniffi_out_err: UniffiRustCallStatus,
+ ): RustBuffer.ByValue
+
+ fun uniffi_mercurylib_fn_func_create_and_commit_nonces(
+ `coin`: RustBuffer.ByValue,
+ uniffi_out_err: UniffiRustCallStatus,
+ ): RustBuffer.ByValue
+
+ fun uniffi_mercurylib_fn_func_create_cpfp_tx(
+ `backupTx`: RustBuffer.ByValue,
+ `coin`: RustBuffer.ByValue,
+ `toAddress`: RustBuffer.ByValue,
+ `feeRateSatsPerByte`: Long,
+ `network`: RustBuffer.ByValue,
+ uniffi_out_err: UniffiRustCallStatus,
+ ): RustBuffer.ByValue
+
+ fun uniffi_mercurylib_fn_func_create_deposit_msg1(
+ `coin`: RustBuffer.ByValue,
+ `tokenId`: RustBuffer.ByValue,
+ uniffi_out_err: UniffiRustCallStatus,
+ ): RustBuffer.ByValue
+
+ fun uniffi_mercurylib_fn_func_create_signature(
+ `msg`: RustBuffer.ByValue,
+ `clientPartialSigHex`: RustBuffer.ByValue,
+ `serverPartialSigHex`: RustBuffer.ByValue,
+ `sessionHex`: RustBuffer.ByValue,
+ `outputPubkeyHex`: RustBuffer.ByValue,
+ uniffi_out_err: UniffiRustCallStatus,
+ ): RustBuffer.ByValue
+
+ fun uniffi_mercurylib_fn_func_create_transfer_signature(
+ `recipientAddress`: RustBuffer.ByValue,
+ `inputTxid`: RustBuffer.ByValue,
+ `inputVout`: Int,
+ `clientSeckey`: RustBuffer.ByValue,
+ uniffi_out_err: UniffiRustCallStatus,
+ ): RustBuffer.ByValue
+
+ fun uniffi_mercurylib_fn_func_create_transfer_update_msg(
+ `x1`: RustBuffer.ByValue,
+ `recipientAddress`: RustBuffer.ByValue,
+ `coin`: RustBuffer.ByValue,
+ `transferSignature`: RustBuffer.ByValue,
+ `backupTransactions`: RustBuffer.ByValue,
+ uniffi_out_err: UniffiRustCallStatus,
+ ): RustBuffer.ByValue
+
+ fun uniffi_mercurylib_fn_func_decode_statechain_address(
+ `scAddress`: RustBuffer.ByValue,
+ uniffi_out_err: UniffiRustCallStatus,
+ ): RustBuffer.ByValue
+
+ fun uniffi_mercurylib_fn_func_duplicate_coin_to_initialized_state(
+ `wallet`: RustBuffer.ByValue,
+ `authPubkey`: RustBuffer.ByValue,
+ uniffi_out_err: UniffiRustCallStatus,
+ ): RustBuffer.ByValue
+
+ fun uniffi_mercurylib_fn_func_ffi_validate_signature_scheme(
+ `ffiTransferMsg`: RustBuffer.ByValue,
+ `statechainInfo`: RustBuffer.ByValue,
+ `tx0Hex`: RustBuffer.ByValue,
+ `feeRateTolerance`: Int,
+ `currentFeeRateSatsPerByte`: Int,
+ `interval`: Int,
+ uniffi_out_err: UniffiRustCallStatus,
+ ): Int
+
+ fun uniffi_mercurylib_fn_func_ffi_verify_transfer_signature(
+ `newUserPubkey`: RustBuffer.ByValue,
+ `tx0Outpoint`: RustBuffer.ByValue,
+ `ffiTransferMsg`: RustBuffer.ByValue,
+ uniffi_out_err: UniffiRustCallStatus,
+ ): Byte
+
+ fun uniffi_mercurylib_fn_func_fii_create_transfer_receiver_request_payload(
+ `statechainInfo`: RustBuffer.ByValue,
+ `ffiTransferMsg`: RustBuffer.ByValue,
+ `coin`: RustBuffer.ByValue,
+ uniffi_out_err: UniffiRustCallStatus,
+ ): RustBuffer.ByValue
+
+ fun uniffi_mercurylib_fn_func_fii_decrypt_transfer_msg(
+ `encryptedMessage`: RustBuffer.ByValue,
+ `privateKeyWif`: RustBuffer.ByValue,
+ uniffi_out_err: UniffiRustCallStatus,
+ ): RustBuffer.ByValue
+
+ fun uniffi_mercurylib_fn_func_fii_validate_tx0_output_pubkey(
+ `enclavePublicKey`: RustBuffer.ByValue,
+ `ffiTransferMsg`: RustBuffer.ByValue,
+ `tx0Outpoint`: RustBuffer.ByValue,
+ `tx0Hex`: RustBuffer.ByValue,
+ `network`: RustBuffer.ByValue,
+ uniffi_out_err: UniffiRustCallStatus,
+ ): Byte
+
+ fun uniffi_mercurylib_fn_func_fii_verify_latest_backup_tx_pays_to_user_pubkey(
+ `ffiTransferMsg`: RustBuffer.ByValue,
+ `clientPubkeyShare`: RustBuffer.ByValue,
+ `network`: RustBuffer.ByValue,
+ uniffi_out_err: UniffiRustCallStatus,
+ ): Byte
+
+ fun uniffi_mercurylib_fn_func_generate_mnemonic(uniffi_out_err: UniffiRustCallStatus): RustBuffer.ByValue
+
+ fun uniffi_mercurylib_fn_func_get_blockheight(
+ `bkpTx`: RustBuffer.ByValue,
+ uniffi_out_err: UniffiRustCallStatus,
+ ): Int
+
+ fun uniffi_mercurylib_fn_func_get_new_coin(
+ `wallet`: RustBuffer.ByValue,
+ uniffi_out_err: UniffiRustCallStatus,
+ ): RustBuffer.ByValue
+
+ fun uniffi_mercurylib_fn_func_get_new_key_info(
+ `serverPublicKeyHex`: RustBuffer.ByValue,
+ `coin`: RustBuffer.ByValue,
+ `statechainId`: RustBuffer.ByValue,
+ `tx0Outpoint`: RustBuffer.ByValue,
+ `tx0Hex`: RustBuffer.ByValue,
+ `network`: RustBuffer.ByValue,
+ uniffi_out_err: UniffiRustCallStatus,
+ ): RustBuffer.ByValue
+
+ fun uniffi_mercurylib_fn_func_get_output_address_from_tx0(
+ `tx0Outpoint`: RustBuffer.ByValue,
+ `tx0Hex`: RustBuffer.ByValue,
+ `network`: RustBuffer.ByValue,
+ uniffi_out_err: UniffiRustCallStatus,
+ ): RustBuffer.ByValue
+
+ fun uniffi_mercurylib_fn_func_get_partial_sig_request(
+ `coin`: RustBuffer.ByValue,
+ `blockHeight`: Int,
+ `initlock`: Int,
+ `interval`: Int,
+ `feeRateSatsPerByte`: Int,
+ `qtBackupTx`: Int,
+ `toAddress`: RustBuffer.ByValue,
+ `network`: RustBuffer.ByValue,
+ `isWithdrawal`: Byte,
+ uniffi_out_err: UniffiRustCallStatus,
+ ): RustBuffer.ByValue
+
+ fun uniffi_mercurylib_fn_func_get_tx0_outpoint(
+ `backupTransactions`: RustBuffer.ByValue,
+ uniffi_out_err: UniffiRustCallStatus,
+ ): RustBuffer.ByValue
+
+ fun uniffi_mercurylib_fn_func_get_user_backup_address(
+ `coin`: RustBuffer.ByValue,
+ `network`: RustBuffer.ByValue,
+ uniffi_out_err: UniffiRustCallStatus,
+ ): RustBuffer.ByValue
+
+ fun uniffi_mercurylib_fn_func_handle_deposit_msg_1_response(
+ `coin`: RustBuffer.ByValue,
+ `depositMsg1Response`: RustBuffer.ByValue,
+ uniffi_out_err: UniffiRustCallStatus,
+ ): RustBuffer.ByValue
+
+ fun uniffi_mercurylib_fn_func_is_enclave_pubkey_part_of_coin(
+ `coin`: RustBuffer.ByValue,
+ `enclavePubkey`: RustBuffer.ByValue,
+ uniffi_out_err: UniffiRustCallStatus,
+ ): Byte
+
+ fun uniffi_mercurylib_fn_func_latest_backup_tx_pays_to_user_pubkey(
+ `backupTxs`: RustBuffer.ByValue,
+ `coin`: RustBuffer.ByValue,
+ `network`: RustBuffer.ByValue,
+ uniffi_out_err: UniffiRustCallStatus,
+ ): RustBuffer.ByValue
+
+ fun uniffi_mercurylib_fn_func_new_backup_transaction(
+ `encodedUnsignedTx`: RustBuffer.ByValue,
+ `signatureHex`: RustBuffer.ByValue,
+ uniffi_out_err: UniffiRustCallStatus,
+ ): RustBuffer.ByValue
+
+ fun uniffi_mercurylib_fn_func_sign_message(
+ `message`: RustBuffer.ByValue,
+ `coin`: RustBuffer.ByValue,
+ uniffi_out_err: UniffiRustCallStatus,
+ ): RustBuffer.ByValue
+
+ fun uniffi_mercurylib_fn_func_validate_address(
+ `address`: RustBuffer.ByValue,
+ `network`: RustBuffer.ByValue,
+ uniffi_out_err: UniffiRustCallStatus,
+ ): Byte
+
+ fun uniffi_mercurylib_fn_func_verify_blinded_musig_scheme(
+ `backupTx`: RustBuffer.ByValue,
+ `tx0Hex`: RustBuffer.ByValue,
+ `statechainInfo`: RustBuffer.ByValue,
+ uniffi_out_err: UniffiRustCallStatus,
+ ): Unit
+
+ fun uniffi_mercurylib_fn_func_verify_transaction_signature(
+ `txNHex`: RustBuffer.ByValue,
+ `tx0Hex`: RustBuffer.ByValue,
+ `feeRateTolerance`: Int,
+ `currentFeeRateSatsPerByte`: Int,
+ uniffi_out_err: UniffiRustCallStatus,
+ ): Unit
+
+ fun ffi_mercurylib_rustbuffer_alloc(
+ `size`: Long,
+ uniffi_out_err: UniffiRustCallStatus,
+ ): RustBuffer.ByValue
+
+ fun ffi_mercurylib_rustbuffer_from_bytes(
+ `bytes`: ForeignBytes.ByValue,
+ uniffi_out_err: UniffiRustCallStatus,
+ ): RustBuffer.ByValue
+
+ fun ffi_mercurylib_rustbuffer_free(
+ `buf`: RustBuffer.ByValue,
+ uniffi_out_err: UniffiRustCallStatus,
+ ): Unit
+
+ fun ffi_mercurylib_rustbuffer_reserve(
+ `buf`: RustBuffer.ByValue,
+ `additional`: Long,
+ uniffi_out_err: UniffiRustCallStatus,
+ ): RustBuffer.ByValue
+
+ fun ffi_mercurylib_rust_future_poll_u8(
+ `handle`: Long,
+ `callback`: UniffiRustFutureContinuationCallback,
+ `callbackData`: Long,
+ ): Unit
+
+ fun ffi_mercurylib_rust_future_cancel_u8(`handle`: Long): Unit
+
+ fun ffi_mercurylib_rust_future_free_u8(`handle`: Long): Unit
+
+ fun ffi_mercurylib_rust_future_complete_u8(
+ `handle`: Long,
+ uniffi_out_err: UniffiRustCallStatus,
+ ): Byte
+
+ fun ffi_mercurylib_rust_future_poll_i8(
+ `handle`: Long,
+ `callback`: UniffiRustFutureContinuationCallback,
+ `callbackData`: Long,
+ ): Unit
+
+ fun ffi_mercurylib_rust_future_cancel_i8(`handle`: Long): Unit
+
+ fun ffi_mercurylib_rust_future_free_i8(`handle`: Long): Unit
+
+ fun ffi_mercurylib_rust_future_complete_i8(
+ `handle`: Long,
+ uniffi_out_err: UniffiRustCallStatus,
+ ): Byte
+
+ fun ffi_mercurylib_rust_future_poll_u16(
+ `handle`: Long,
+ `callback`: UniffiRustFutureContinuationCallback,
+ `callbackData`: Long,
+ ): Unit
+
+ fun ffi_mercurylib_rust_future_cancel_u16(`handle`: Long): Unit
+
+ fun ffi_mercurylib_rust_future_free_u16(`handle`: Long): Unit
+
+ fun ffi_mercurylib_rust_future_complete_u16(
+ `handle`: Long,
+ uniffi_out_err: UniffiRustCallStatus,
+ ): Short
+
+ fun ffi_mercurylib_rust_future_poll_i16(
+ `handle`: Long,
+ `callback`: UniffiRustFutureContinuationCallback,
+ `callbackData`: Long,
+ ): Unit
+
+ fun ffi_mercurylib_rust_future_cancel_i16(`handle`: Long): Unit
+
+ fun ffi_mercurylib_rust_future_free_i16(`handle`: Long): Unit
+
+ fun ffi_mercurylib_rust_future_complete_i16(
+ `handle`: Long,
+ uniffi_out_err: UniffiRustCallStatus,
+ ): Short
+
+ fun ffi_mercurylib_rust_future_poll_u32(
+ `handle`: Long,
+ `callback`: UniffiRustFutureContinuationCallback,
+ `callbackData`: Long,
+ ): Unit
+
+ fun ffi_mercurylib_rust_future_cancel_u32(`handle`: Long): Unit
+
+ fun ffi_mercurylib_rust_future_free_u32(`handle`: Long): Unit
+
+ fun ffi_mercurylib_rust_future_complete_u32(
+ `handle`: Long,
+ uniffi_out_err: UniffiRustCallStatus,
+ ): Int
+
+ fun ffi_mercurylib_rust_future_poll_i32(
+ `handle`: Long,
+ `callback`: UniffiRustFutureContinuationCallback,
+ `callbackData`: Long,
+ ): Unit
+
+ fun ffi_mercurylib_rust_future_cancel_i32(`handle`: Long): Unit
+
+ fun ffi_mercurylib_rust_future_free_i32(`handle`: Long): Unit
+
+ fun ffi_mercurylib_rust_future_complete_i32(
+ `handle`: Long,
+ uniffi_out_err: UniffiRustCallStatus,
+ ): Int
+
+ fun ffi_mercurylib_rust_future_poll_u64(
+ `handle`: Long,
+ `callback`: UniffiRustFutureContinuationCallback,
+ `callbackData`: Long,
+ ): Unit
+
+ fun ffi_mercurylib_rust_future_cancel_u64(`handle`: Long): Unit
+
+ fun ffi_mercurylib_rust_future_free_u64(`handle`: Long): Unit
+
+ fun ffi_mercurylib_rust_future_complete_u64(
+ `handle`: Long,
+ uniffi_out_err: UniffiRustCallStatus,
+ ): Long
+
+ fun ffi_mercurylib_rust_future_poll_i64(
+ `handle`: Long,
+ `callback`: UniffiRustFutureContinuationCallback,
+ `callbackData`: Long,
+ ): Unit
+
+ fun ffi_mercurylib_rust_future_cancel_i64(`handle`: Long): Unit
+
+ fun ffi_mercurylib_rust_future_free_i64(`handle`: Long): Unit
+
+ fun ffi_mercurylib_rust_future_complete_i64(
+ `handle`: Long,
+ uniffi_out_err: UniffiRustCallStatus,
+ ): Long
+
+ fun ffi_mercurylib_rust_future_poll_f32(
+ `handle`: Long,
+ `callback`: UniffiRustFutureContinuationCallback,
+ `callbackData`: Long,
+ ): Unit
+
+ fun ffi_mercurylib_rust_future_cancel_f32(`handle`: Long): Unit
+
+ fun ffi_mercurylib_rust_future_free_f32(`handle`: Long): Unit
+
+ fun ffi_mercurylib_rust_future_complete_f32(
+ `handle`: Long,
+ uniffi_out_err: UniffiRustCallStatus,
+ ): Float
+
+ fun ffi_mercurylib_rust_future_poll_f64(
+ `handle`: Long,
+ `callback`: UniffiRustFutureContinuationCallback,
+ `callbackData`: Long,
+ ): Unit
+
+ fun ffi_mercurylib_rust_future_cancel_f64(`handle`: Long): Unit
+
+ fun ffi_mercurylib_rust_future_free_f64(`handle`: Long): Unit
+
+ fun ffi_mercurylib_rust_future_complete_f64(
+ `handle`: Long,
+ uniffi_out_err: UniffiRustCallStatus,
+ ): Double
+
+ fun ffi_mercurylib_rust_future_poll_pointer(
+ `handle`: Long,
+ `callback`: UniffiRustFutureContinuationCallback,
+ `callbackData`: Long,
+ ): Unit
+
+ fun ffi_mercurylib_rust_future_cancel_pointer(`handle`: Long): Unit
+
+ fun ffi_mercurylib_rust_future_free_pointer(`handle`: Long): Unit
+
+ fun ffi_mercurylib_rust_future_complete_pointer(
+ `handle`: Long,
+ uniffi_out_err: UniffiRustCallStatus,
+ ): Pointer
+
+ fun ffi_mercurylib_rust_future_poll_rust_buffer(
+ `handle`: Long,
+ `callback`: UniffiRustFutureContinuationCallback,
+ `callbackData`: Long,
+ ): Unit
+
+ fun ffi_mercurylib_rust_future_cancel_rust_buffer(`handle`: Long): Unit
+
+ fun ffi_mercurylib_rust_future_free_rust_buffer(`handle`: Long): Unit
+
+ fun ffi_mercurylib_rust_future_complete_rust_buffer(
+ `handle`: Long,
+ uniffi_out_err: UniffiRustCallStatus,
+ ): RustBuffer.ByValue
+
+ fun ffi_mercurylib_rust_future_poll_void(
+ `handle`: Long,
+ `callback`: UniffiRustFutureContinuationCallback,
+ `callbackData`: Long,
+ ): Unit
+
+ fun ffi_mercurylib_rust_future_cancel_void(`handle`: Long): Unit
+
+ fun ffi_mercurylib_rust_future_free_void(`handle`: Long): Unit
+
+ fun ffi_mercurylib_rust_future_complete_void(
+ `handle`: Long,
+ uniffi_out_err: UniffiRustCallStatus,
+ ): Unit
+
+ fun uniffi_mercurylib_checksum_func_create_aggregated_address(): Short
+
+ fun uniffi_mercurylib_checksum_func_create_and_commit_nonces(): Short
+
+ fun uniffi_mercurylib_checksum_func_create_cpfp_tx(): Short
+
+ fun uniffi_mercurylib_checksum_func_create_deposit_msg1(): Short
+
+ fun uniffi_mercurylib_checksum_func_create_signature(): Short
+
+ fun uniffi_mercurylib_checksum_func_create_transfer_signature(): Short
+
+ fun uniffi_mercurylib_checksum_func_create_transfer_update_msg(): Short
+
+ fun uniffi_mercurylib_checksum_func_decode_statechain_address(): Short
+
+ fun uniffi_mercurylib_checksum_func_duplicate_coin_to_initialized_state(): Short
+
+ fun uniffi_mercurylib_checksum_func_ffi_validate_signature_scheme(): Short
+
+ fun uniffi_mercurylib_checksum_func_ffi_verify_transfer_signature(): Short
+
+ fun uniffi_mercurylib_checksum_func_fii_create_transfer_receiver_request_payload(): Short
+
+ fun uniffi_mercurylib_checksum_func_fii_decrypt_transfer_msg(): Short
+
+ fun uniffi_mercurylib_checksum_func_fii_validate_tx0_output_pubkey(): Short
+
+ fun uniffi_mercurylib_checksum_func_fii_verify_latest_backup_tx_pays_to_user_pubkey(): Short
+
+ fun uniffi_mercurylib_checksum_func_generate_mnemonic(): Short
+
+ fun uniffi_mercurylib_checksum_func_get_blockheight(): Short
+
+ fun uniffi_mercurylib_checksum_func_get_new_coin(): Short
+
+ fun uniffi_mercurylib_checksum_func_get_new_key_info(): Short
+
+ fun uniffi_mercurylib_checksum_func_get_output_address_from_tx0(): Short
+
+ fun uniffi_mercurylib_checksum_func_get_partial_sig_request(): Short
+
+ fun uniffi_mercurylib_checksum_func_get_tx0_outpoint(): Short
+
+ fun uniffi_mercurylib_checksum_func_get_user_backup_address(): Short
+
+ fun uniffi_mercurylib_checksum_func_handle_deposit_msg_1_response(): Short
+
+ fun uniffi_mercurylib_checksum_func_is_enclave_pubkey_part_of_coin(): Short
+
+ fun uniffi_mercurylib_checksum_func_latest_backup_tx_pays_to_user_pubkey(): Short
+
+ fun uniffi_mercurylib_checksum_func_new_backup_transaction(): Short
+
+ fun uniffi_mercurylib_checksum_func_sign_message(): Short
+
+ fun uniffi_mercurylib_checksum_func_validate_address(): Short
+
+ fun uniffi_mercurylib_checksum_func_verify_blinded_musig_scheme(): Short
+
+ fun uniffi_mercurylib_checksum_func_verify_transaction_signature(): Short
+
+ fun ffi_mercurylib_uniffi_contract_version(): Int
+}
+
+private fun uniffiCheckContractApiVersion(lib: UniffiLib) {
+ // Get the bindings contract version from our ComponentInterface
+ val bindings_contract_version = 26
+ // Get the scaffolding contract version by calling the into the dylib
+ val scaffolding_contract_version = lib.ffi_mercurylib_uniffi_contract_version()
+ if (bindings_contract_version != scaffolding_contract_version) {
+ throw RuntimeException("UniFFI contract version mismatch: try cleaning and rebuilding your project")
+ }
+}
+
+@Suppress("UNUSED_PARAMETER")
+private fun uniffiCheckApiChecksums(lib: UniffiLib) {
+ if (lib.uniffi_mercurylib_checksum_func_create_aggregated_address() != 44269.toShort()) {
+ throw RuntimeException("UniFFI API checksum mismatch: try cleaning and rebuilding your project")
+ }
+ if (lib.uniffi_mercurylib_checksum_func_create_and_commit_nonces() != 16584.toShort()) {
+ throw RuntimeException("UniFFI API checksum mismatch: try cleaning and rebuilding your project")
+ }
+ if (lib.uniffi_mercurylib_checksum_func_create_cpfp_tx() != 63811.toShort()) {
+ throw RuntimeException("UniFFI API checksum mismatch: try cleaning and rebuilding your project")
+ }
+ if (lib.uniffi_mercurylib_checksum_func_create_deposit_msg1() != 9767.toShort()) {
+ throw RuntimeException("UniFFI API checksum mismatch: try cleaning and rebuilding your project")
+ }
+ if (lib.uniffi_mercurylib_checksum_func_create_signature() != 53021.toShort()) {
+ throw RuntimeException("UniFFI API checksum mismatch: try cleaning and rebuilding your project")
+ }
+ if (lib.uniffi_mercurylib_checksum_func_create_transfer_signature() != 61677.toShort()) {
+ throw RuntimeException("UniFFI API checksum mismatch: try cleaning and rebuilding your project")
+ }
+ if (lib.uniffi_mercurylib_checksum_func_create_transfer_update_msg() != 6918.toShort()) {
+ throw RuntimeException("UniFFI API checksum mismatch: try cleaning and rebuilding your project")
+ }
+ if (lib.uniffi_mercurylib_checksum_func_decode_statechain_address() != 7125.toShort()) {
+ throw RuntimeException("UniFFI API checksum mismatch: try cleaning and rebuilding your project")
+ }
+ if (lib.uniffi_mercurylib_checksum_func_duplicate_coin_to_initialized_state() != 30591.toShort()) {
+ throw RuntimeException("UniFFI API checksum mismatch: try cleaning and rebuilding your project")
+ }
+ if (lib.uniffi_mercurylib_checksum_func_ffi_validate_signature_scheme() != 26248.toShort()) {
+ throw RuntimeException("UniFFI API checksum mismatch: try cleaning and rebuilding your project")
+ }
+ if (lib.uniffi_mercurylib_checksum_func_ffi_verify_transfer_signature() != 18534.toShort()) {
+ throw RuntimeException("UniFFI API checksum mismatch: try cleaning and rebuilding your project")
+ }
+ if (lib.uniffi_mercurylib_checksum_func_fii_create_transfer_receiver_request_payload() != 58308.toShort()) {
+ throw RuntimeException("UniFFI API checksum mismatch: try cleaning and rebuilding your project")
+ }
+ if (lib.uniffi_mercurylib_checksum_func_fii_decrypt_transfer_msg() != 44515.toShort()) {
+ throw RuntimeException("UniFFI API checksum mismatch: try cleaning and rebuilding your project")
+ }
+ if (lib.uniffi_mercurylib_checksum_func_fii_validate_tx0_output_pubkey() != 51706.toShort()) {
+ throw RuntimeException("UniFFI API checksum mismatch: try cleaning and rebuilding your project")
+ }
+ if (lib.uniffi_mercurylib_checksum_func_fii_verify_latest_backup_tx_pays_to_user_pubkey() != 46083.toShort()) {
+ throw RuntimeException("UniFFI API checksum mismatch: try cleaning and rebuilding your project")
+ }
+ if (lib.uniffi_mercurylib_checksum_func_generate_mnemonic() != 62910.toShort()) {
+ throw RuntimeException("UniFFI API checksum mismatch: try cleaning and rebuilding your project")
+ }
+ if (lib.uniffi_mercurylib_checksum_func_get_blockheight() != 5222.toShort()) {
+ throw RuntimeException("UniFFI API checksum mismatch: try cleaning and rebuilding your project")
+ }
+ if (lib.uniffi_mercurylib_checksum_func_get_new_coin() != 45841.toShort()) {
+ throw RuntimeException("UniFFI API checksum mismatch: try cleaning and rebuilding your project")
+ }
+ if (lib.uniffi_mercurylib_checksum_func_get_new_key_info() != 64987.toShort()) {
+ throw RuntimeException("UniFFI API checksum mismatch: try cleaning and rebuilding your project")
+ }
+ if (lib.uniffi_mercurylib_checksum_func_get_output_address_from_tx0() != 62309.toShort()) {
+ throw RuntimeException("UniFFI API checksum mismatch: try cleaning and rebuilding your project")
+ }
+ if (lib.uniffi_mercurylib_checksum_func_get_partial_sig_request() != 13111.toShort()) {
+ throw RuntimeException("UniFFI API checksum mismatch: try cleaning and rebuilding your project")
+ }
+ if (lib.uniffi_mercurylib_checksum_func_get_tx0_outpoint() != 21467.toShort()) {
+ throw RuntimeException("UniFFI API checksum mismatch: try cleaning and rebuilding your project")
+ }
+ if (lib.uniffi_mercurylib_checksum_func_get_user_backup_address() != 29075.toShort()) {
+ throw RuntimeException("UniFFI API checksum mismatch: try cleaning and rebuilding your project")
+ }
+ if (lib.uniffi_mercurylib_checksum_func_handle_deposit_msg_1_response() != 64110.toShort()) {
+ throw RuntimeException("UniFFI API checksum mismatch: try cleaning and rebuilding your project")
+ }
+ if (lib.uniffi_mercurylib_checksum_func_is_enclave_pubkey_part_of_coin() != 37041.toShort()) {
+ throw RuntimeException("UniFFI API checksum mismatch: try cleaning and rebuilding your project")
+ }
+ if (lib.uniffi_mercurylib_checksum_func_latest_backup_tx_pays_to_user_pubkey() != 19689.toShort()) {
+ throw RuntimeException("UniFFI API checksum mismatch: try cleaning and rebuilding your project")
+ }
+ if (lib.uniffi_mercurylib_checksum_func_new_backup_transaction() != 56642.toShort()) {
+ throw RuntimeException("UniFFI API checksum mismatch: try cleaning and rebuilding your project")
+ }
+ if (lib.uniffi_mercurylib_checksum_func_sign_message() != 9994.toShort()) {
+ throw RuntimeException("UniFFI API checksum mismatch: try cleaning and rebuilding your project")
+ }
+ if (lib.uniffi_mercurylib_checksum_func_validate_address() != 16334.toShort()) {
+ throw RuntimeException("UniFFI API checksum mismatch: try cleaning and rebuilding your project")
+ }
+ if (lib.uniffi_mercurylib_checksum_func_verify_blinded_musig_scheme() != 42963.toShort()) {
+ throw RuntimeException("UniFFI API checksum mismatch: try cleaning and rebuilding your project")
+ }
+ if (lib.uniffi_mercurylib_checksum_func_verify_transaction_signature() != 32006.toShort()) {
+ throw RuntimeException("UniFFI API checksum mismatch: try cleaning and rebuilding your project")
+ }
+}
+
+// Async support
+
+// Public interface members begin here.
+
+// Interface implemented by anything that can contain an object reference.
+//
+// Such types expose a `destroy()` method that must be called to cleanly
+// dispose of the contained objects. Failure to call this method may result
+// in memory leaks.
+//
+// The easiest way to ensure this method is called is to use the `.use`
+// helper method to execute a block and destroy the object at the end.
+interface Disposable {
+ fun destroy()
+
+ companion object {
+ fun destroy(vararg args: Any?) {
+ args.filterIsInstance()
+ .forEach(Disposable::destroy)
+ }
+ }
+}
+
+inline fun T.use(block: (T) -> R) =
+ try {
+ block(this)
+ } finally {
+ try {
+ // N.B. our implementation is on the nullable type `Disposable?`.
+ this?.destroy()
+ } catch (e: Throwable) {
+ // swallow
+ }
+ }
+
+/** Used to instantiate an interface without an actual pointer, for fakes in tests, mostly. */
+object NoPointer
+
+public object FfiConverterUByte : FfiConverter {
+ override fun lift(value: Byte): UByte {
+ return value.toUByte()
+ }
+
+ override fun read(buf: ByteBuffer): UByte {
+ return lift(buf.get())
+ }
+
+ override fun lower(value: UByte): Byte {
+ return value.toByte()
+ }
+
+ override fun allocationSize(value: UByte) = 1UL
+
+ override fun write(
+ value: UByte,
+ buf: ByteBuffer,
+ ) {
+ buf.put(value.toByte())
+ }
+}
+
+public object FfiConverterUInt : FfiConverter {
+ override fun lift(value: Int): UInt {
+ return value.toUInt()
+ }
+
+ override fun read(buf: ByteBuffer): UInt {
+ return lift(buf.getInt())
+ }
+
+ override fun lower(value: UInt): Int {
+ return value.toInt()
+ }
+
+ override fun allocationSize(value: UInt) = 4UL
+
+ override fun write(
+ value: UInt,
+ buf: ByteBuffer,
+ ) {
+ buf.putInt(value.toInt())
+ }
+}
+
+public object FfiConverterULong : FfiConverter {
+ override fun lift(value: Long): ULong {
+ return value.toULong()
+ }
+
+ override fun read(buf: ByteBuffer): ULong {
+ return lift(buf.getLong())
+ }
+
+ override fun lower(value: ULong): Long {
+ return value.toLong()
+ }
+
+ override fun allocationSize(value: ULong) = 8UL
+
+ override fun write(
+ value: ULong,
+ buf: ByteBuffer,
+ ) {
+ buf.putLong(value.toLong())
+ }
+}
+
+public object FfiConverterBoolean : FfiConverter {
+ override fun lift(value: Byte): Boolean {
+ return value.toInt() != 0
+ }
+
+ override fun read(buf: ByteBuffer): Boolean {
+ return lift(buf.get())
+ }
+
+ override fun lower(value: Boolean): Byte {
+ return if (value) 1.toByte() else 0.toByte()
+ }
+
+ override fun allocationSize(value: Boolean) = 1UL
+
+ override fun write(
+ value: Boolean,
+ buf: ByteBuffer,
+ ) {
+ buf.put(lower(value))
+ }
+}
+
+public object FfiConverterString : FfiConverter {
+ // Note: we don't inherit from FfiConverterRustBuffer, because we use a
+ // special encoding when lowering/lifting. We can use `RustBuffer.len` to
+ // store our length and avoid writing it out to the buffer.
+ override fun lift(value: RustBuffer.ByValue): String {
+ try {
+ val byteArr = ByteArray(value.len.toInt())
+ value.asByteBuffer()!!.get(byteArr)
+ return byteArr.toString(Charsets.UTF_8)
+ } finally {
+ RustBuffer.free(value)
+ }
+ }
+
+ override fun read(buf: ByteBuffer): String {
+ val len = buf.getInt()
+ val byteArr = ByteArray(len)
+ buf.get(byteArr)
+ return byteArr.toString(Charsets.UTF_8)
+ }
+
+ fun toUtf8(value: String): ByteBuffer {
+ // Make sure we don't have invalid UTF-16, check for lone surrogates.
+ return Charsets.UTF_8.newEncoder().run {
+ onMalformedInput(CodingErrorAction.REPORT)
+ encode(CharBuffer.wrap(value))
+ }
+ }
+
+ override fun lower(value: String): RustBuffer.ByValue {
+ val byteBuf = toUtf8(value)
+ // Ideally we'd pass these bytes to `ffi_bytebuffer_from_bytes`, but doing so would require us
+ // to copy them into a JNA `Memory`. So we might as well directly copy them into a `RustBuffer`.
+ val rbuf = RustBuffer.alloc(byteBuf.limit().toULong())
+ rbuf.asByteBuffer()!!.put(byteBuf)
+ return rbuf
+ }
+
+ // We aren't sure exactly how many bytes our string will be once it's UTF-8
+ // encoded. Allocate 3 bytes per UTF-16 code unit which will always be
+ // enough.
+ override fun allocationSize(value: String): ULong {
+ val sizeForLength = 4UL
+ val sizeForString = value.length.toULong() * 3UL
+ return sizeForLength + sizeForString
+ }
+
+ override fun write(
+ value: String,
+ buf: ByteBuffer,
+ ) {
+ val byteBuf = toUtf8(value)
+ buf.putInt(byteBuf.limit())
+ buf.put(byteBuf)
+ }
+}
+
+public object FfiConverterByteArray : FfiConverterRustBuffer {
+ override fun read(buf: ByteBuffer): ByteArray {
+ val len = buf.getInt()
+ val byteArr = ByteArray(len)
+ buf.get(byteArr)
+ return byteArr
+ }
+
+ override fun allocationSize(value: ByteArray): ULong {
+ return 4UL + value.size.toULong()
+ }
+
+ override fun write(
+ value: ByteArray,
+ buf: ByteBuffer,
+ ) {
+ buf.putInt(value.size)
+ buf.put(value)
+ }
+}
+
+@Serializable
+data class Activity(
+ var `utxo`: kotlin.String,
+ var `amount`: kotlin.UInt,
+ var `action`: kotlin.String,
+ var `date`: kotlin.String,
+) {
+ companion object
+}
+
+public object FfiConverterTypeActivity : FfiConverterRustBuffer {
+ override fun read(buf: ByteBuffer): Activity {
+ return Activity(
+ FfiConverterString.read(buf),
+ FfiConverterUInt.read(buf),
+ FfiConverterString.read(buf),
+ FfiConverterString.read(buf),
+ )
+ }
+
+ override fun allocationSize(value: Activity) =
+ (
+ FfiConverterString.allocationSize(value.`utxo`) +
+ FfiConverterUInt.allocationSize(value.`amount`) +
+ FfiConverterString.allocationSize(value.`action`) +
+ FfiConverterString.allocationSize(value.`date`)
+ )
+
+ override fun write(
+ value: Activity,
+ buf: ByteBuffer,
+ ) {
+ FfiConverterString.write(value.`utxo`, buf)
+ FfiConverterUInt.write(value.`amount`, buf)
+ FfiConverterString.write(value.`action`, buf)
+ FfiConverterString.write(value.`date`, buf)
+ }
+}
+
+@Serializable
+data class AggregatedPublicKey(
+ var `aggregatePubkey`: kotlin.String,
+ var `aggregateAddress`: kotlin.String,
+) {
+ companion object
+}
+
+public object FfiConverterTypeAggregatedPublicKey : FfiConverterRustBuffer {
+ override fun read(buf: ByteBuffer): AggregatedPublicKey {
+ return AggregatedPublicKey(
+ FfiConverterString.read(buf),
+ FfiConverterString.read(buf),
+ )
+ }
+
+ override fun allocationSize(value: AggregatedPublicKey) =
+ (
+ FfiConverterString.allocationSize(value.`aggregatePubkey`) +
+ FfiConverterString.allocationSize(value.`aggregateAddress`)
+ )
+
+ override fun write(
+ value: AggregatedPublicKey,
+ buf: ByteBuffer,
+ ) {
+ FfiConverterString.write(value.`aggregatePubkey`, buf)
+ FfiConverterString.write(value.`aggregateAddress`, buf)
+ }
+}
+
+@Serializable
+data class BackupTx(
+ var `txN`: kotlin.UInt,
+ var `tx`: kotlin.String,
+ var `clientPublicNonce`: kotlin.String,
+ var `serverPublicNonce`: kotlin.String,
+ var `clientPublicKey`: kotlin.String,
+ var `serverPublicKey`: kotlin.String,
+ var `blindingFactor`: kotlin.String,
+) {
+ companion object
+}
+
+public object FfiConverterTypeBackupTx : FfiConverterRustBuffer {
+ override fun read(buf: ByteBuffer): BackupTx {
+ return BackupTx(
+ FfiConverterUInt.read(buf),
+ FfiConverterString.read(buf),
+ FfiConverterString.read(buf),
+ FfiConverterString.read(buf),
+ FfiConverterString.read(buf),
+ FfiConverterString.read(buf),
+ FfiConverterString.read(buf),
+ )
+ }
+
+ override fun allocationSize(value: BackupTx) =
+ (
+ FfiConverterUInt.allocationSize(value.`txN`) +
+ FfiConverterString.allocationSize(value.`tx`) +
+ FfiConverterString.allocationSize(value.`clientPublicNonce`) +
+ FfiConverterString.allocationSize(value.`serverPublicNonce`) +
+ FfiConverterString.allocationSize(value.`clientPublicKey`) +
+ FfiConverterString.allocationSize(value.`serverPublicKey`) +
+ FfiConverterString.allocationSize(value.`blindingFactor`)
+ )
+
+ override fun write(
+ value: BackupTx,
+ buf: ByteBuffer,
+ ) {
+ FfiConverterUInt.write(value.`txN`, buf)
+ FfiConverterString.write(value.`tx`, buf)
+ FfiConverterString.write(value.`clientPublicNonce`, buf)
+ FfiConverterString.write(value.`serverPublicNonce`, buf)
+ FfiConverterString.write(value.`clientPublicKey`, buf)
+ FfiConverterString.write(value.`serverPublicKey`, buf)
+ FfiConverterString.write(value.`blindingFactor`, buf)
+ }
+}
+
+@Serializable
+data class Coin(
+ var `index`: kotlin.UInt,
+ var `userPrivkey`: kotlin.String,
+ var `userPubkey`: kotlin.String,
+ var `authPrivkey`: kotlin.String,
+ var `authPubkey`: kotlin.String,
+ var `derivationPath`: kotlin.String,
+ var `fingerprint`: kotlin.String,
+ /**
+ * The coin address is the user_pubkey || auth_pubkey
+ * Used to transfer the coin to another wallet
+ */
+ var `address`: kotlin.String,
+ /**
+ * The backup address is the address used in backup transactions
+ * The backup address is the p2tr address of the user_pubkey
+ */
+ var `backupAddress`: kotlin.String,
+ var `serverPubkey`: kotlin.String?,
+ var `aggregatedPubkey`: kotlin.String?,
+ /**
+ * The aggregated address is the P2TR address from aggregated_pubkey
+ */
+ var `aggregatedAddress`: kotlin.String?,
+ var `utxoTxid`: kotlin.String?,
+ var `utxoVout`: kotlin.UInt?,
+ var `amount`: kotlin.UInt?,
+ var `statechainId`: kotlin.String?,
+ var `signedStatechainId`: kotlin.String?,
+ var `locktime`: kotlin.UInt?,
+ var `secretNonce`: kotlin.String?,
+ var `publicNonce`: kotlin.String?,
+ var `blindingFactor`: kotlin.String?,
+ var `serverPublicNonce`: kotlin.String?,
+ var `txCpfp`: kotlin.String?,
+ var `txWithdraw`: kotlin.String?,
+ var `withdrawalAddress`: kotlin.String?,
+ var `status`: CoinStatus,
+) {
+ companion object
+}
+
+public object FfiConverterTypeCoin : FfiConverterRustBuffer {
+ override fun read(buf: ByteBuffer): Coin {
+ return Coin(
+ FfiConverterUInt.read(buf),
+ FfiConverterString.read(buf),
+ FfiConverterString.read(buf),
+ FfiConverterString.read(buf),
+ FfiConverterString.read(buf),
+ FfiConverterString.read(buf),
+ FfiConverterString.read(buf),
+ FfiConverterString.read(buf),
+ FfiConverterString.read(buf),
+ FfiConverterOptionalString.read(buf),
+ FfiConverterOptionalString.read(buf),
+ FfiConverterOptionalString.read(buf),
+ FfiConverterOptionalString.read(buf),
+ FfiConverterOptionalUInt.read(buf),
+ FfiConverterOptionalUInt.read(buf),
+ FfiConverterOptionalString.read(buf),
+ FfiConverterOptionalString.read(buf),
+ FfiConverterOptionalUInt.read(buf),
+ FfiConverterOptionalString.read(buf),
+ FfiConverterOptionalString.read(buf),
+ FfiConverterOptionalString.read(buf),
+ FfiConverterOptionalString.read(buf),
+ FfiConverterOptionalString.read(buf),
+ FfiConverterOptionalString.read(buf),
+ FfiConverterOptionalString.read(buf),
+ FfiConverterTypeCoinStatus.read(buf),
+ )
+ }
+
+ override fun allocationSize(value: Coin) =
+ (
+ FfiConverterUInt.allocationSize(value.`index`) +
+ FfiConverterString.allocationSize(value.`userPrivkey`) +
+ FfiConverterString.allocationSize(value.`userPubkey`) +
+ FfiConverterString.allocationSize(value.`authPrivkey`) +
+ FfiConverterString.allocationSize(value.`authPubkey`) +
+ FfiConverterString.allocationSize(value.`derivationPath`) +
+ FfiConverterString.allocationSize(value.`fingerprint`) +
+ FfiConverterString.allocationSize(value.`address`) +
+ FfiConverterString.allocationSize(value.`backupAddress`) +
+ FfiConverterOptionalString.allocationSize(value.`serverPubkey`) +
+ FfiConverterOptionalString.allocationSize(value.`aggregatedPubkey`) +
+ FfiConverterOptionalString.allocationSize(value.`aggregatedAddress`) +
+ FfiConverterOptionalString.allocationSize(value.`utxoTxid`) +
+ FfiConverterOptionalUInt.allocationSize(value.`utxoVout`) +
+ FfiConverterOptionalUInt.allocationSize(value.`amount`) +
+ FfiConverterOptionalString.allocationSize(value.`statechainId`) +
+ FfiConverterOptionalString.allocationSize(value.`signedStatechainId`) +
+ FfiConverterOptionalUInt.allocationSize(value.`locktime`) +
+ FfiConverterOptionalString.allocationSize(value.`secretNonce`) +
+ FfiConverterOptionalString.allocationSize(value.`publicNonce`) +
+ FfiConverterOptionalString.allocationSize(value.`blindingFactor`) +
+ FfiConverterOptionalString.allocationSize(value.`serverPublicNonce`) +
+ FfiConverterOptionalString.allocationSize(value.`txCpfp`) +
+ FfiConverterOptionalString.allocationSize(value.`txWithdraw`) +
+ FfiConverterOptionalString.allocationSize(value.`withdrawalAddress`) +
+ FfiConverterTypeCoinStatus.allocationSize(value.`status`)
+ )
+
+ override fun write(
+ value: Coin,
+ buf: ByteBuffer,
+ ) {
+ FfiConverterUInt.write(value.`index`, buf)
+ FfiConverterString.write(value.`userPrivkey`, buf)
+ FfiConverterString.write(value.`userPubkey`, buf)
+ FfiConverterString.write(value.`authPrivkey`, buf)
+ FfiConverterString.write(value.`authPubkey`, buf)
+ FfiConverterString.write(value.`derivationPath`, buf)
+ FfiConverterString.write(value.`fingerprint`, buf)
+ FfiConverterString.write(value.`address`, buf)
+ FfiConverterString.write(value.`backupAddress`, buf)
+ FfiConverterOptionalString.write(value.`serverPubkey`, buf)
+ FfiConverterOptionalString.write(value.`aggregatedPubkey`, buf)
+ FfiConverterOptionalString.write(value.`aggregatedAddress`, buf)
+ FfiConverterOptionalString.write(value.`utxoTxid`, buf)
+ FfiConverterOptionalUInt.write(value.`utxoVout`, buf)
+ FfiConverterOptionalUInt.write(value.`amount`, buf)
+ FfiConverterOptionalString.write(value.`statechainId`, buf)
+ FfiConverterOptionalString.write(value.`signedStatechainId`, buf)
+ FfiConverterOptionalUInt.write(value.`locktime`, buf)
+ FfiConverterOptionalString.write(value.`secretNonce`, buf)
+ FfiConverterOptionalString.write(value.`publicNonce`, buf)
+ FfiConverterOptionalString.write(value.`blindingFactor`, buf)
+ FfiConverterOptionalString.write(value.`serverPublicNonce`, buf)
+ FfiConverterOptionalString.write(value.`txCpfp`, buf)
+ FfiConverterOptionalString.write(value.`txWithdraw`, buf)
+ FfiConverterOptionalString.write(value.`withdrawalAddress`, buf)
+ FfiConverterTypeCoinStatus.write(value.`status`, buf)
+ }
+}
+
+data class CoinNonce(
+ var `secretNonce`: kotlin.String,
+ var `publicNonce`: kotlin.String,
+ var `blindingFactor`: kotlin.String,
+ var `signFirstRequestPayload`: SignFirstRequestPayload,
+) {
+ companion object
+}
+
+public object FfiConverterTypeCoinNonce : FfiConverterRustBuffer {
+ override fun read(buf: ByteBuffer): CoinNonce {
+ return CoinNonce(
+ FfiConverterString.read(buf),
+ FfiConverterString.read(buf),
+ FfiConverterString.read(buf),
+ FfiConverterTypeSignFirstRequestPayload.read(buf),
+ )
+ }
+
+ override fun allocationSize(value: CoinNonce) =
+ (
+ FfiConverterString.allocationSize(value.`secretNonce`) +
+ FfiConverterString.allocationSize(value.`publicNonce`) +
+ FfiConverterString.allocationSize(value.`blindingFactor`) +
+ FfiConverterTypeSignFirstRequestPayload.allocationSize(value.`signFirstRequestPayload`)
+ )
+
+ override fun write(
+ value: CoinNonce,
+ buf: ByteBuffer,
+ ) {
+ FfiConverterString.write(value.`secretNonce`, buf)
+ FfiConverterString.write(value.`publicNonce`, buf)
+ FfiConverterString.write(value.`blindingFactor`, buf)
+ FfiConverterTypeSignFirstRequestPayload.write(value.`signFirstRequestPayload`, buf)
+ }
+}
+
+class CoinStatusParseError {
+ override fun equals(other: Any?): Boolean {
+ return other is CoinStatusParseError
+ }
+
+ override fun hashCode(): Int {
+ return javaClass.hashCode()
+ }
+
+ companion object
+}
+
+public object FfiConverterTypeCoinStatusParseError : FfiConverterRustBuffer {
+ override fun read(buf: ByteBuffer): CoinStatusParseError {
+ return CoinStatusParseError()
+ }
+
+ override fun allocationSize(value: CoinStatusParseError) = 0UL
+
+ override fun write(
+ value: CoinStatusParseError,
+ buf: ByteBuffer,
+ ) {
+ }
+}
+
+data class DecodedScAddress(
+ var `version`: kotlin.UByte,
+ var `userPubkey`: kotlin.String,
+ var `authPubkey`: kotlin.String,
+) {
+ companion object
+}
+
+public object FfiConverterTypeDecodedSCAddress : FfiConverterRustBuffer {
+ override fun read(buf: ByteBuffer): DecodedScAddress {
+ return DecodedScAddress(
+ FfiConverterUByte.read(buf),
+ FfiConverterString.read(buf),
+ FfiConverterString.read(buf),
+ )
+ }
+
+ override fun allocationSize(value: DecodedScAddress) =
+ (
+ FfiConverterUByte.allocationSize(value.`version`) +
+ FfiConverterString.allocationSize(value.`userPubkey`) +
+ FfiConverterString.allocationSize(value.`authPubkey`)
+ )
+
+ override fun write(
+ value: DecodedScAddress,
+ buf: ByteBuffer,
+ ) {
+ FfiConverterUByte.write(value.`version`, buf)
+ FfiConverterString.write(value.`userPubkey`, buf)
+ FfiConverterString.write(value.`authPubkey`, buf)
+ }
+}
+
+@Serializable
+data class DepositInitResult(
+ var `serverPubkey`: kotlin.String,
+ var `statechainId`: kotlin.String,
+ var `signedStatechainId`: kotlin.String,
+) {
+ companion object
+}
+
+public object FfiConverterTypeDepositInitResult : FfiConverterRustBuffer {
+ override fun read(buf: ByteBuffer): DepositInitResult {
+ return DepositInitResult(
+ FfiConverterString.read(buf),
+ FfiConverterString.read(buf),
+ FfiConverterString.read(buf),
+ )
+ }
+
+ override fun allocationSize(value: DepositInitResult) =
+ (
+ FfiConverterString.allocationSize(value.`serverPubkey`) +
+ FfiConverterString.allocationSize(value.`statechainId`) +
+ FfiConverterString.allocationSize(value.`signedStatechainId`)
+ )
+
+ override fun write(
+ value: DepositInitResult,
+ buf: ByteBuffer,
+ ) {
+ FfiConverterString.write(value.`serverPubkey`, buf)
+ FfiConverterString.write(value.`statechainId`, buf)
+ FfiConverterString.write(value.`signedStatechainId`, buf)
+ }
+}
+
+@Serializable
+data class DepositMsg1(
+ @SerialName("auth_key")
+ var `authKey`: kotlin.String,
+ @SerialName("token_id")
+ var `tokenId`: kotlin.String,
+ @SerialName("signed_token_id")
+ var `signedTokenId`: kotlin.String,
+) {
+ companion object
+}
+
+public object FfiConverterTypeDepositMsg1 : FfiConverterRustBuffer {
+ override fun read(buf: ByteBuffer): DepositMsg1 {
+ return DepositMsg1(
+ FfiConverterString.read(buf),
+ FfiConverterString.read(buf),
+ FfiConverterString.read(buf),
+ )
+ }
+
+ override fun allocationSize(value: DepositMsg1) =
+ (
+ FfiConverterString.allocationSize(value.`authKey`) +
+ FfiConverterString.allocationSize(value.`tokenId`) +
+ FfiConverterString.allocationSize(value.`signedTokenId`)
+ )
+
+ override fun write(
+ value: DepositMsg1,
+ buf: ByteBuffer,
+ ) {
+ FfiConverterString.write(value.`authKey`, buf)
+ FfiConverterString.write(value.`tokenId`, buf)
+ FfiConverterString.write(value.`signedTokenId`, buf)
+ }
+}
+
+@Serializable
+data class DepositMsg1Response(
+ @SerialName("server_pubkey")
+ var `serverPubkey`: kotlin.String,
+ @SerialName("statechain_id")
+ var `statechainId`: kotlin.String,
+) {
+ companion object
+}
+
+public object FfiConverterTypeDepositMsg1Response : FfiConverterRustBuffer {
+ override fun read(buf: ByteBuffer): DepositMsg1Response {
+ return DepositMsg1Response(
+ FfiConverterString.read(buf),
+ FfiConverterString.read(buf),
+ )
+ }
+
+ override fun allocationSize(value: DepositMsg1Response) =
+ (
+ FfiConverterString.allocationSize(value.`serverPubkey`) +
+ FfiConverterString.allocationSize(value.`statechainId`)
+ )
+
+ override fun write(
+ value: DepositMsg1Response,
+ buf: ByteBuffer,
+ ) {
+ FfiConverterString.write(value.`serverPubkey`, buf)
+ FfiConverterString.write(value.`statechainId`, buf)
+ }
+}
+
+data class FfiTransferMsg(
+ var `statechainId`: kotlin.String,
+ var `transferSignature`: kotlin.String,
+ var `backupTransactions`: List,
+ var `t1`: kotlin.ByteArray,
+ var `userPublicKey`: kotlin.String,
+) {
+ companion object
+}
+
+public object FfiConverterTypeFFITransferMsg : FfiConverterRustBuffer {
+ override fun read(buf: ByteBuffer): FfiTransferMsg {
+ return FfiTransferMsg(
+ FfiConverterString.read(buf),
+ FfiConverterString.read(buf),
+ FfiConverterSequenceTypeBackupTx.read(buf),
+ FfiConverterByteArray.read(buf),
+ FfiConverterString.read(buf),
+ )
+ }
+
+ override fun allocationSize(value: FfiTransferMsg) =
+ (
+ FfiConverterString.allocationSize(value.`statechainId`) +
+ FfiConverterString.allocationSize(value.`transferSignature`) +
+ FfiConverterSequenceTypeBackupTx.allocationSize(value.`backupTransactions`) +
+ FfiConverterByteArray.allocationSize(value.`t1`) +
+ FfiConverterString.allocationSize(value.`userPublicKey`)
+ )
+
+ override fun write(
+ value: FfiTransferMsg,
+ buf: ByteBuffer,
+ ) {
+ FfiConverterString.write(value.`statechainId`, buf)
+ FfiConverterString.write(value.`transferSignature`, buf)
+ FfiConverterSequenceTypeBackupTx.write(value.`backupTransactions`, buf)
+ FfiConverterByteArray.write(value.`t1`, buf)
+ FfiConverterString.write(value.`userPublicKey`, buf)
+ }
+}
+
+@Serializable
+data class GetMsgAddrResponsePayload(
+ @SerialName("list_enc_transfer_msg")
+ var `listEncTransferMsg`: List,
+) {
+ companion object
+}
+
+public object FfiConverterTypeGetMsgAddrResponsePayload : FfiConverterRustBuffer {
+ override fun read(buf: ByteBuffer): GetMsgAddrResponsePayload {
+ return GetMsgAddrResponsePayload(
+ FfiConverterSequenceString.read(buf),
+ )
+ }
+
+ override fun allocationSize(value: GetMsgAddrResponsePayload) =
+ (
+ FfiConverterSequenceString.allocationSize(value.`listEncTransferMsg`)
+ )
+
+ override fun write(
+ value: GetMsgAddrResponsePayload,
+ buf: ByteBuffer,
+ ) {
+ FfiConverterSequenceString.write(value.`listEncTransferMsg`, buf)
+ }
+}
+
+data class InfoConfig(
+ var `initlock`: kotlin.UInt,
+ var `interval`: kotlin.UInt,
+ var `feeRateSatsPerByte`: kotlin.ULong,
+) {
+ companion object
+}
+
+public object FfiConverterTypeInfoConfig : FfiConverterRustBuffer {
+ override fun read(buf: ByteBuffer): InfoConfig {
+ return InfoConfig(
+ FfiConverterUInt.read(buf),
+ FfiConverterUInt.read(buf),
+ FfiConverterULong.read(buf),
+ )
+ }
+
+ override fun allocationSize(value: InfoConfig) =
+ (
+ FfiConverterUInt.allocationSize(value.`initlock`) +
+ FfiConverterUInt.allocationSize(value.`interval`) +
+ FfiConverterULong.allocationSize(value.`feeRateSatsPerByte`)
+ )
+
+ override fun write(
+ value: InfoConfig,
+ buf: ByteBuffer,
+ ) {
+ FfiConverterUInt.write(value.`initlock`, buf)
+ FfiConverterUInt.write(value.`interval`, buf)
+ FfiConverterULong.write(value.`feeRateSatsPerByte`, buf)
+ }
+}
+
+data class KeyListResponsePayload(
+ var `listKeyinfo`: List,
+) {
+ companion object
+}
+
+public object FfiConverterTypeKeyListResponsePayload : FfiConverterRustBuffer {
+ override fun read(buf: ByteBuffer): KeyListResponsePayload {
+ return KeyListResponsePayload(
+ FfiConverterSequenceTypePubKeyInfo.read(buf),
+ )
+ }
+
+ override fun allocationSize(value: KeyListResponsePayload) =
+ (
+ FfiConverterSequenceTypePubKeyInfo.allocationSize(value.`listKeyinfo`)
+ )
+
+ override fun write(
+ value: KeyListResponsePayload,
+ buf: ByteBuffer,
+ ) {
+ FfiConverterSequenceTypePubKeyInfo.write(value.`listKeyinfo`, buf)
+ }
+}
+
+@Serializable
+data class KeyUpdateResponsePayload(
+ @SerialName("statechain_id")
+ var `statechainId`: kotlin.String,
+ var `t2`: kotlin.String,
+ var `x1`: kotlin.String,
+) {
+ companion object
+}
+
+public object FfiConverterTypeKeyUpdateResponsePayload : FfiConverterRustBuffer {
+ override fun read(buf: ByteBuffer): KeyUpdateResponsePayload {
+ return KeyUpdateResponsePayload(
+ FfiConverterString.read(buf),
+ FfiConverterString.read(buf),
+ FfiConverterString.read(buf),
+ )
+ }
+
+ override fun allocationSize(value: KeyUpdateResponsePayload) =
+ (
+ FfiConverterString.allocationSize(value.`statechainId`) +
+ FfiConverterString.allocationSize(value.`t2`) +
+ FfiConverterString.allocationSize(value.`x1`)
+ )
+
+ override fun write(
+ value: KeyUpdateResponsePayload,
+ buf: ByteBuffer,
+ ) {
+ FfiConverterString.write(value.`statechainId`, buf)
+ FfiConverterString.write(value.`t2`, buf)
+ FfiConverterString.write(value.`x1`, buf)
+ }
+}
+
+data class NewKeyInfo(
+ var `aggregatePubkey`: kotlin.String,
+ var `aggregateAddress`: kotlin.String,
+ var `signedStatechainId`: kotlin.String,
+ var `amount`: kotlin.UInt,
+) {
+ companion object
+}
+
+public object FfiConverterTypeNewKeyInfo : FfiConverterRustBuffer {
+ override fun read(buf: ByteBuffer): NewKeyInfo {
+ return NewKeyInfo(
+ FfiConverterString.read(buf),
+ FfiConverterString.read(buf),
+ FfiConverterString.read(buf),
+ FfiConverterUInt.read(buf),
+ )
+ }
+
+ override fun allocationSize(value: NewKeyInfo) =
+ (
+ FfiConverterString.allocationSize(value.`aggregatePubkey`) +
+ FfiConverterString.allocationSize(value.`aggregateAddress`) +
+ FfiConverterString.allocationSize(value.`signedStatechainId`) +
+ FfiConverterUInt.allocationSize(value.`amount`)
+ )
+
+ override fun write(
+ value: NewKeyInfo,
+ buf: ByteBuffer,
+ ) {
+ FfiConverterString.write(value.`aggregatePubkey`, buf)
+ FfiConverterString.write(value.`aggregateAddress`, buf)
+ FfiConverterString.write(value.`signedStatechainId`, buf)
+ FfiConverterUInt.write(value.`amount`, buf)
+ }
+}
+
+data class PartialSignatureMsg1(
+ var `msg`: kotlin.String,
+ var `outputPubkey`: kotlin.String,
+ var `clientPartialSig`: kotlin.String,
+ var `encodedSession`: kotlin.String,
+ var `encodedUnsignedTx`: kotlin.String,
+ var `partialSignatureRequestPayload`: PartialSignatureRequestPayload,
+) {
+ companion object
+}
+
+public object FfiConverterTypePartialSignatureMsg1 : FfiConverterRustBuffer {
+ override fun read(buf: ByteBuffer): PartialSignatureMsg1 {
+ return PartialSignatureMsg1(
+ FfiConverterString.read(buf),
+ FfiConverterString.read(buf),
+ FfiConverterString.read(buf),
+ FfiConverterString.read(buf),
+ FfiConverterString.read(buf),
+ FfiConverterTypePartialSignatureRequestPayload.read(buf),
+ )
+ }
+
+ override fun allocationSize(value: PartialSignatureMsg1) =
+ (
+ FfiConverterString.allocationSize(value.`msg`) +
+ FfiConverterString.allocationSize(value.`outputPubkey`) +
+ FfiConverterString.allocationSize(value.`clientPartialSig`) +
+ FfiConverterString.allocationSize(value.`encodedSession`) +
+ FfiConverterString.allocationSize(value.`encodedUnsignedTx`) +
+ FfiConverterTypePartialSignatureRequestPayload.allocationSize(value.`partialSignatureRequestPayload`)
+ )
+
+ override fun write(
+ value: PartialSignatureMsg1,
+ buf: ByteBuffer,
+ ) {
+ FfiConverterString.write(value.`msg`, buf)
+ FfiConverterString.write(value.`outputPubkey`, buf)
+ FfiConverterString.write(value.`clientPartialSig`, buf)
+ FfiConverterString.write(value.`encodedSession`, buf)
+ FfiConverterString.write(value.`encodedUnsignedTx`, buf)
+ FfiConverterTypePartialSignatureRequestPayload.write(value.`partialSignatureRequestPayload`, buf)
+ }
+}
+
+@Serializable
+data class PartialSignatureRequestPayload(
+ @SerialName("statechain_id")
+ var `statechainId`: kotlin.String,
+ @SerialName("negate_seckey")
+ var `negateSeckey`: kotlin.UByte,
+ var `session`: kotlin.String,
+ @SerialName("signed_statechain_id")
+ var `signedStatechainId`: kotlin.String,
+ @SerialName("server_pub_nonce")
+ var `serverPubNonce`: kotlin.String,
+) {
+ companion object
+}
+
+public object FfiConverterTypePartialSignatureRequestPayload : FfiConverterRustBuffer {
+ override fun read(buf: ByteBuffer): PartialSignatureRequestPayload {
+ return PartialSignatureRequestPayload(
+ FfiConverterString.read(buf),
+ FfiConverterUByte.read(buf),
+ FfiConverterString.read(buf),
+ FfiConverterString.read(buf),
+ FfiConverterString.read(buf),
+ )
+ }
+
+ override fun allocationSize(value: PartialSignatureRequestPayload) =
+ (
+ FfiConverterString.allocationSize(value.`statechainId`) +
+ FfiConverterUByte.allocationSize(value.`negateSeckey`) +
+ FfiConverterString.allocationSize(value.`session`) +
+ FfiConverterString.allocationSize(value.`signedStatechainId`) +
+ FfiConverterString.allocationSize(value.`serverPubNonce`)
+ )
+
+ override fun write(
+ value: PartialSignatureRequestPayload,
+ buf: ByteBuffer,
+ ) {
+ FfiConverterString.write(value.`statechainId`, buf)
+ FfiConverterUByte.write(value.`negateSeckey`, buf)
+ FfiConverterString.write(value.`session`, buf)
+ FfiConverterString.write(value.`signedStatechainId`, buf)
+ FfiConverterString.write(value.`serverPubNonce`, buf)
+ }
+}
+
+@Serializable
+data class PartialSignatureResponsePayload(
+ @SerialName("partial_sig")
+ var `partialSig`: kotlin.String,
+) {
+ companion object
+}
+
+public object FfiConverterTypePartialSignatureResponsePayload : FfiConverterRustBuffer {
+ override fun read(buf: ByteBuffer): PartialSignatureResponsePayload {
+ return PartialSignatureResponsePayload(
+ FfiConverterString.read(buf),
+ )
+ }
+
+ override fun allocationSize(value: PartialSignatureResponsePayload) =
+ (
+ FfiConverterString.allocationSize(value.`partialSig`)
+ )
+
+ override fun write(
+ value: PartialSignatureResponsePayload,
+ buf: ByteBuffer,
+ ) {
+ FfiConverterString.write(value.`partialSig`, buf)
+ }
+}
+
+data class PubKeyInfo(
+ var `serverPubkey`: kotlin.String,
+ var `txN`: kotlin.UInt,
+ var `updatedAt`: kotlin.String,
+) {
+ companion object
+}
+
+public object FfiConverterTypePubKeyInfo : FfiConverterRustBuffer {
+ override fun read(buf: ByteBuffer): PubKeyInfo {
+ return PubKeyInfo(
+ FfiConverterString.read(buf),
+ FfiConverterUInt.read(buf),
+ FfiConverterString.read(buf),
+ )
+ }
+
+ override fun allocationSize(value: PubKeyInfo) =
+ (
+ FfiConverterString.allocationSize(value.`serverPubkey`) +
+ FfiConverterUInt.allocationSize(value.`txN`) +
+ FfiConverterString.allocationSize(value.`updatedAt`)
+ )
+
+ override fun write(
+ value: PubKeyInfo,
+ buf: ByteBuffer,
+ ) {
+ FfiConverterString.write(value.`serverPubkey`, buf)
+ FfiConverterUInt.write(value.`txN`, buf)
+ FfiConverterString.write(value.`updatedAt`, buf)
+ }
+}
+
+@Serializable
+data class ServerConfig(
+ var `initlock`: kotlin.UInt,
+ var `interval`: kotlin.UInt,
+) {
+ companion object
+}
+
+public object FfiConverterTypeServerConfig : FfiConverterRustBuffer {
+ override fun read(buf: ByteBuffer): ServerConfig {
+ return ServerConfig(
+ FfiConverterUInt.read(buf),
+ FfiConverterUInt.read(buf),
+ )
+ }
+
+ override fun allocationSize(value: ServerConfig) =
+ (
+ FfiConverterUInt.allocationSize(value.`initlock`) +
+ FfiConverterUInt.allocationSize(value.`interval`)
+ )
+
+ override fun write(
+ value: ServerConfig,
+ buf: ByteBuffer,
+ ) {
+ FfiConverterUInt.write(value.`initlock`, buf)
+ FfiConverterUInt.write(value.`interval`, buf)
+ }
+}
+
+data class ServerPublicNonceResponsePayload(
+ var `serverPubnonce`: kotlin.String,
+) {
+ companion object
+}
+
+public object FfiConverterTypeServerPublicNonceResponsePayload : FfiConverterRustBuffer {
+ override fun read(buf: ByteBuffer): ServerPublicNonceResponsePayload {
+ return ServerPublicNonceResponsePayload(
+ FfiConverterString.read(buf),
+ )
+ }
+
+ override fun allocationSize(value: ServerPublicNonceResponsePayload) =
+ (
+ FfiConverterString.allocationSize(value.`serverPubnonce`)
+ )
+
+ override fun write(
+ value: ServerPublicNonceResponsePayload,
+ buf: ByteBuffer,
+ ) {
+ FfiConverterString.write(value.`serverPubnonce`, buf)
+ }
+}
+
+@Serializable
+data class Settings(
+ var `network`: kotlin.String,
+ var `blockExplorerUrl`: kotlin.String?,
+ var `torProxyHost`: kotlin.String?,
+ var `torProxyPort`: kotlin.String?,
+ var `torProxyControlPassword`: kotlin.String?,
+ var `torProxyControlPort`: kotlin.String?,
+ var `statechainEntityApi`: kotlin.String,
+ var `torStatechainEntityApi`: kotlin.String?,
+ var `electrumProtocol`: kotlin.String,
+ var `electrumHost`: kotlin.String,
+ var `electrumPort`: kotlin.String,
+ var `electrumType`: kotlin.String,
+ var `notifications`: kotlin.Boolean,
+ var `tutorials`: kotlin.Boolean,
+) {
+ companion object
+}
+
+public object FfiConverterTypeSettings : FfiConverterRustBuffer {
+ override fun read(buf: ByteBuffer): Settings {
+ return Settings(
+ FfiConverterString.read(buf),
+ FfiConverterOptionalString.read(buf),
+ FfiConverterOptionalString.read(buf),
+ FfiConverterOptionalString.read(buf),
+ FfiConverterOptionalString.read(buf),
+ FfiConverterOptionalString.read(buf),
+ FfiConverterString.read(buf),
+ FfiConverterOptionalString.read(buf),
+ FfiConverterString.read(buf),
+ FfiConverterString.read(buf),
+ FfiConverterString.read(buf),
+ FfiConverterString.read(buf),
+ FfiConverterBoolean.read(buf),
+ FfiConverterBoolean.read(buf),
+ )
+ }
+
+ override fun allocationSize(value: Settings) =
+ (
+ FfiConverterString.allocationSize(value.`network`) +
+ FfiConverterOptionalString.allocationSize(value.`blockExplorerUrl`) +
+ FfiConverterOptionalString.allocationSize(value.`torProxyHost`) +
+ FfiConverterOptionalString.allocationSize(value.`torProxyPort`) +
+ FfiConverterOptionalString.allocationSize(value.`torProxyControlPassword`) +
+ FfiConverterOptionalString.allocationSize(value.`torProxyControlPort`) +
+ FfiConverterString.allocationSize(value.`statechainEntityApi`) +
+ FfiConverterOptionalString.allocationSize(value.`torStatechainEntityApi`) +
+ FfiConverterString.allocationSize(value.`electrumProtocol`) +
+ FfiConverterString.allocationSize(value.`electrumHost`) +
+ FfiConverterString.allocationSize(value.`electrumPort`) +
+ FfiConverterString.allocationSize(value.`electrumType`) +
+ FfiConverterBoolean.allocationSize(value.`notifications`) +
+ FfiConverterBoolean.allocationSize(value.`tutorials`)
+ )
+
+ override fun write(
+ value: Settings,
+ buf: ByteBuffer,
+ ) {
+ FfiConverterString.write(value.`network`, buf)
+ FfiConverterOptionalString.write(value.`blockExplorerUrl`, buf)
+ FfiConverterOptionalString.write(value.`torProxyHost`, buf)
+ FfiConverterOptionalString.write(value.`torProxyPort`, buf)
+ FfiConverterOptionalString.write(value.`torProxyControlPassword`, buf)
+ FfiConverterOptionalString.write(value.`torProxyControlPort`, buf)
+ FfiConverterString.write(value.`statechainEntityApi`, buf)
+ FfiConverterOptionalString.write(value.`torStatechainEntityApi`, buf)
+ FfiConverterString.write(value.`electrumProtocol`, buf)
+ FfiConverterString.write(value.`electrumHost`, buf)
+ FfiConverterString.write(value.`electrumPort`, buf)
+ FfiConverterString.write(value.`electrumType`, buf)
+ FfiConverterBoolean.write(value.`notifications`, buf)
+ FfiConverterBoolean.write(value.`tutorials`, buf)
+ }
+}
+
+@Serializable
+data class SignFirstRequestPayload(
+ @SerialName("statechain_id")
+ var `statechainId`: kotlin.String,
+ @SerialName("signed_statechain_id")
+ var `signedStatechainId`: kotlin.String,
+) {
+ companion object
+}
+
+public object FfiConverterTypeSignFirstRequestPayload : FfiConverterRustBuffer {
+ override fun read(buf: ByteBuffer): SignFirstRequestPayload {
+ return SignFirstRequestPayload(
+ FfiConverterString.read(buf),
+ FfiConverterString.read(buf),
+ )
+ }
+
+ override fun allocationSize(value: SignFirstRequestPayload) =
+ (
+ FfiConverterString.allocationSize(value.`statechainId`) +
+ FfiConverterString.allocationSize(value.`signedStatechainId`)
+ )
+
+ override fun write(
+ value: SignFirstRequestPayload,
+ buf: ByteBuffer,
+ ) {
+ FfiConverterString.write(value.`statechainId`, buf)
+ FfiConverterString.write(value.`signedStatechainId`, buf)
+ }
+}
+
+@Serializable
+data class SignFirstResponsePayload(
+ @SerialName("server_pubnonce")
+ var `serverPubnonce`: kotlin.String,
+) {
+ companion object
+}
+
+public object FfiConverterTypeSignFirstResponsePayload : FfiConverterRustBuffer {
+ override fun read(buf: ByteBuffer): SignFirstResponsePayload {
+ return SignFirstResponsePayload(
+ FfiConverterString.read(buf),
+ )
+ }
+
+ override fun allocationSize(value: SignFirstResponsePayload) =
+ (
+ FfiConverterString.allocationSize(value.`serverPubnonce`)
+ )
+
+ override fun write(
+ value: SignFirstResponsePayload,
+ buf: ByteBuffer,
+ ) {
+ FfiConverterString.write(value.`serverPubnonce`, buf)
+ }
+}
+
+data class StatechainBackupTxs(
+ var `statechainId`: kotlin.String,
+ var `backupTxs`: List,
+) {
+ companion object
+}
+
+public object FfiConverterTypeStatechainBackupTxs : FfiConverterRustBuffer {
+ override fun read(buf: ByteBuffer): StatechainBackupTxs {
+ return StatechainBackupTxs(
+ FfiConverterString.read(buf),
+ FfiConverterSequenceTypeBackupTx.read(buf),
+ )
+ }
+
+ override fun allocationSize(value: StatechainBackupTxs) =
+ (
+ FfiConverterString.allocationSize(value.`statechainId`) +
+ FfiConverterSequenceTypeBackupTx.allocationSize(value.`backupTxs`)
+ )
+
+ override fun write(
+ value: StatechainBackupTxs,
+ buf: ByteBuffer,
+ ) {
+ FfiConverterString.write(value.`statechainId`, buf)
+ FfiConverterSequenceTypeBackupTx.write(value.`backupTxs`, buf)
+ }
+}
+
+@Serializable
+data class StatechainInfo(
+ @SerialName("statechain_id")
+ var `statechainId`: kotlin.String,
+ @SerialName("server_pubnonce")
+ var `serverPubnonce`: kotlin.String,
+ var `challenge`: kotlin.String,
+ @SerialName("tx_n")
+ var `txN`: kotlin.UInt,
+) {
+ companion object
+}
+
+public object FfiConverterTypeStatechainInfo : FfiConverterRustBuffer {
+ override fun read(buf: ByteBuffer): StatechainInfo {
+ return StatechainInfo(
+ FfiConverterString.read(buf),
+ FfiConverterString.read(buf),
+ FfiConverterString.read(buf),
+ FfiConverterUInt.read(buf),
+ )
+ }
+
+ override fun allocationSize(value: StatechainInfo) =
+ (
+ FfiConverterString.allocationSize(value.`statechainId`) +
+ FfiConverterString.allocationSize(value.`serverPubnonce`) +
+ FfiConverterString.allocationSize(value.`challenge`) +
+ FfiConverterUInt.allocationSize(value.`txN`)
+ )
+
+ override fun write(
+ value: StatechainInfo,
+ buf: ByteBuffer,
+ ) {
+ FfiConverterString.write(value.`statechainId`, buf)
+ FfiConverterString.write(value.`serverPubnonce`, buf)
+ FfiConverterString.write(value.`challenge`, buf)
+ FfiConverterUInt.write(value.`txN`, buf)
+ }
+}
+
+@Serializable
+data class StatechainInfoResponsePayload(
+ @SerialName("enclave_public_key")
+ var `enclavePublicKey`: kotlin.String,
+ @SerialName("num_sigs")
+ var `numSigs`: kotlin.UInt,
+ @SerialName("statechain_info")
+ var `statechainInfo`: List,
+ @SerialName("x1_pub")
+ var `x1Pub`: kotlin.String?,
+) {
+ companion object
+}
+
+public object FfiConverterTypeStatechainInfoResponsePayload : FfiConverterRustBuffer {
+ override fun read(buf: ByteBuffer): StatechainInfoResponsePayload {
+ return StatechainInfoResponsePayload(
+ FfiConverterString.read(buf),
+ FfiConverterUInt.read(buf),
+ FfiConverterSequenceTypeStatechainInfo.read(buf),
+ FfiConverterOptionalString.read(buf),
+ )
+ }
+
+ override fun allocationSize(value: StatechainInfoResponsePayload) =
+ (
+ FfiConverterString.allocationSize(value.`enclavePublicKey`) +
+ FfiConverterUInt.allocationSize(value.`numSigs`) +
+ FfiConverterSequenceTypeStatechainInfo.allocationSize(value.`statechainInfo`) +
+ FfiConverterOptionalString.allocationSize(value.`x1Pub`)
+ )
+
+ override fun write(
+ value: StatechainInfoResponsePayload,
+ buf: ByteBuffer,
+ ) {
+ FfiConverterString.write(value.`enclavePublicKey`, buf)
+ FfiConverterUInt.write(value.`numSigs`, buf)
+ FfiConverterSequenceTypeStatechainInfo.write(value.`statechainInfo`, buf)
+ FfiConverterOptionalString.write(value.`x1Pub`, buf)
+ }
+}
+
+@Serializable
+data class Token(
+ @SerialName("btc_payment_address")
+ var `btcPaymentAddress`: kotlin.String,
+ var `fee`: kotlin.String,
+ @SerialName("lightning_invoice")
+ var `lightningInvoice`: kotlin.String,
+ @SerialName("processor_id")
+ var `processorId`: kotlin.String,
+ @SerialName("token_id")
+ var `tokenId`: kotlin.String,
+ var `confirmed`: kotlin.Boolean,
+ var `spent`: kotlin.Boolean,
+ var `expiry`: kotlin.String,
+) {
+ companion object
+}
+
+public object FfiConverterTypeToken : FfiConverterRustBuffer {
+ override fun read(buf: ByteBuffer): Token {
+ return Token(
+ FfiConverterString.read(buf),
+ FfiConverterString.read(buf),
+ FfiConverterString.read(buf),
+ FfiConverterString.read(buf),
+ FfiConverterString.read(buf),
+ FfiConverterBoolean.read(buf),
+ FfiConverterBoolean.read(buf),
+ FfiConverterString.read(buf),
+ )
+ }
+
+ override fun allocationSize(value: Token) =
+ (
+ FfiConverterString.allocationSize(value.`btcPaymentAddress`) +
+ FfiConverterString.allocationSize(value.`fee`) +
+ FfiConverterString.allocationSize(value.`lightningInvoice`) +
+ FfiConverterString.allocationSize(value.`processorId`) +
+ FfiConverterString.allocationSize(value.`tokenId`) +
+ FfiConverterBoolean.allocationSize(value.`confirmed`) +
+ FfiConverterBoolean.allocationSize(value.`spent`) +
+ FfiConverterString.allocationSize(value.`expiry`)
+ )
+
+ override fun write(
+ value: Token,
+ buf: ByteBuffer,
+ ) {
+ FfiConverterString.write(value.`btcPaymentAddress`, buf)
+ FfiConverterString.write(value.`fee`, buf)
+ FfiConverterString.write(value.`lightningInvoice`, buf)
+ FfiConverterString.write(value.`processorId`, buf)
+ FfiConverterString.write(value.`tokenId`, buf)
+ FfiConverterBoolean.write(value.`confirmed`, buf)
+ FfiConverterBoolean.write(value.`spent`, buf)
+ FfiConverterString.write(value.`expiry`, buf)
+ }
+}
+
+@Serializable
+data class TransferReceiverErrorResponsePayload(
+ var `code`: TransferReceiverError,
+ var `message`: kotlin.String,
+) {
+ companion object
+}
+
+public object FfiConverterTypeTransferReceiverErrorResponsePayload : FfiConverterRustBuffer {
+ override fun read(buf: ByteBuffer): TransferReceiverErrorResponsePayload {
+ return TransferReceiverErrorResponsePayload(
+ FfiConverterTypeTransferReceiverError.read(buf),
+ FfiConverterString.read(buf),
+ )
+ }
+
+ override fun allocationSize(value: TransferReceiverErrorResponsePayload) =
+ (
+ FfiConverterTypeTransferReceiverError.allocationSize(value.`code`) +
+ FfiConverterString.allocationSize(value.`message`)
+ )
+
+ override fun write(
+ value: TransferReceiverErrorResponsePayload,
+ buf: ByteBuffer,
+ ) {
+ FfiConverterTypeTransferReceiverError.write(value.`code`, buf)
+ FfiConverterString.write(value.`message`, buf)
+ }
+}
+
+@Serializable
+data class TransferReceiverPostResponsePayload(
+ @SerialName("server_pubkey")
+ var `serverPubkey`: kotlin.String,
+) {
+ companion object
+}
+
+public object FfiConverterTypeTransferReceiverPostResponsePayload : FfiConverterRustBuffer {
+ override fun read(buf: ByteBuffer): TransferReceiverPostResponsePayload {
+ return TransferReceiverPostResponsePayload(
+ FfiConverterString.read(buf),
+ )
+ }
+
+ override fun allocationSize(value: TransferReceiverPostResponsePayload) =
+ (
+ FfiConverterString.allocationSize(value.`serverPubkey`)
+ )
+
+ override fun write(
+ value: TransferReceiverPostResponsePayload,
+ buf: ByteBuffer,
+ ) {
+ FfiConverterString.write(value.`serverPubkey`, buf)
+ }
+}
+
+@Serializable
+data class TransferReceiverRequestPayload(
+ @SerialName("statechain_id")
+ var `statechainId`: kotlin.String,
+ @SerialName("batch_data")
+ var `batchData`: kotlin.String?,
+ var `t2`: kotlin.String,
+ @SerialName("auth_sig")
+ var `authSig`: kotlin.String,
+) {
+ companion object
+}
+
+public object FfiConverterTypeTransferReceiverRequestPayload : FfiConverterRustBuffer {
+ override fun read(buf: ByteBuffer): TransferReceiverRequestPayload {
+ return TransferReceiverRequestPayload(
+ FfiConverterString.read(buf),
+ FfiConverterOptionalString.read(buf),
+ FfiConverterString.read(buf),
+ FfiConverterString.read(buf),
+ )
+ }
+
+ override fun allocationSize(value: TransferReceiverRequestPayload) =
+ (
+ FfiConverterString.allocationSize(value.`statechainId`) +
+ FfiConverterOptionalString.allocationSize(value.`batchData`) +
+ FfiConverterString.allocationSize(value.`t2`) +
+ FfiConverterString.allocationSize(value.`authSig`)
+ )
+
+ override fun write(
+ value: TransferReceiverRequestPayload,
+ buf: ByteBuffer,
+ ) {
+ FfiConverterString.write(value.`statechainId`, buf)
+ FfiConverterOptionalString.write(value.`batchData`, buf)
+ FfiConverterString.write(value.`t2`, buf)
+ FfiConverterString.write(value.`authSig`, buf)
+ }
+}
+
+@Serializable
+data class TransferSenderRequestPayload(
+ @SerialName("statechain_id")
+ var `statechainId`: kotlin.String,
+ @SerialName("auth_sig")
+ var `authSig`: kotlin.String,
+ @SerialName("new_user_auth_key")
+ var `newUserAuthKey`: kotlin.String,
+ @SerialName("batch_id")
+ var `batchId`: kotlin.String?,
+) {
+ companion object
+}
+
+public object FfiConverterTypeTransferSenderRequestPayload : FfiConverterRustBuffer {
+ override fun read(buf: ByteBuffer): TransferSenderRequestPayload {
+ return TransferSenderRequestPayload(
+ FfiConverterString.read(buf),
+ FfiConverterString.read(buf),
+ FfiConverterString.read(buf),
+ FfiConverterOptionalString.read(buf),
+ )
+ }
+
+ override fun allocationSize(value: TransferSenderRequestPayload) =
+ (
+ FfiConverterString.allocationSize(value.`statechainId`) +
+ FfiConverterString.allocationSize(value.`authSig`) +
+ FfiConverterString.allocationSize(value.`newUserAuthKey`) +
+ FfiConverterOptionalString.allocationSize(value.`batchId`)
+ )
+
+ override fun write(
+ value: TransferSenderRequestPayload,
+ buf: ByteBuffer,
+ ) {
+ FfiConverterString.write(value.`statechainId`, buf)
+ FfiConverterString.write(value.`authSig`, buf)
+ FfiConverterString.write(value.`newUserAuthKey`, buf)
+ FfiConverterOptionalString.write(value.`batchId`, buf)
+ }
+}
+
+@Serializable
+data class TransferSenderResponsePayload(
+ var `x1`: kotlin.String,
+) {
+ companion object
+}
+
+public object FfiConverterTypeTransferSenderResponsePayload : FfiConverterRustBuffer {
+ override fun read(buf: ByteBuffer): TransferSenderResponsePayload {
+ return TransferSenderResponsePayload(
+ FfiConverterString.read(buf),
+ )
+ }
+
+ override fun allocationSize(value: TransferSenderResponsePayload) =
+ (
+ FfiConverterString.allocationSize(value.`x1`)
+ )
+
+ override fun write(
+ value: TransferSenderResponsePayload,
+ buf: ByteBuffer,
+ ) {
+ FfiConverterString.write(value.`x1`, buf)
+ }
+}
+
+@Serializable
+data class TransferUnlockRequestPayload(
+ @SerialName("statechain_id")
+ var `statechainId`: kotlin.String,
+ @SerialName("auth_sig")
+ var `authSig`: kotlin.String,
+ @SerialName("auth_pub_key")
+ var `authPubKey`: kotlin.String,
+) {
+ companion object
+}
+
+public object FfiConverterTypeTransferUnlockRequestPayload : FfiConverterRustBuffer {
+ override fun read(buf: ByteBuffer): TransferUnlockRequestPayload {
+ return TransferUnlockRequestPayload(
+ FfiConverterString.read(buf),
+ FfiConverterString.read(buf),
+ FfiConverterString.read(buf),
+ )
+ }
+
+ override fun allocationSize(value: TransferUnlockRequestPayload) =
+ (
+ FfiConverterString.allocationSize(value.`statechainId`) +
+ FfiConverterString.allocationSize(value.`authSig`) +
+ FfiConverterString.allocationSize(value.`authPubKey`)
+ )
+
+ override fun write(
+ value: TransferUnlockRequestPayload,
+ buf: ByteBuffer,
+ ) {
+ FfiConverterString.write(value.`statechainId`, buf)
+ FfiConverterString.write(value.`authSig`, buf)
+ FfiConverterString.write(value.`authPubKey`, buf)
+ }
+}
+
+@Serializable
+data class TransferUpdateMsgRequestPayload(
+ @SerialName("statechain_id")
+ var `statechainId`: kotlin.String,
+ @SerialName("auth_sig")
+ var `authSig`: kotlin.String,
+ @SerialName("new_user_auth_key")
+ var `newUserAuthKey`: kotlin.String,
+ @SerialName("enc_transfer_msg")
+ var `encTransferMsg`: kotlin.String,
+) {
+ companion object
+}
+
+public object FfiConverterTypeTransferUpdateMsgRequestPayload : FfiConverterRustBuffer {
+ override fun read(buf: ByteBuffer): TransferUpdateMsgRequestPayload {
+ return TransferUpdateMsgRequestPayload(
+ FfiConverterString.read(buf),
+ FfiConverterString.read(buf),
+ FfiConverterString.read(buf),
+ FfiConverterString.read(buf),
+ )
+ }
+
+ override fun allocationSize(value: TransferUpdateMsgRequestPayload) =
+ (
+ FfiConverterString.allocationSize(value.`statechainId`) +
+ FfiConverterString.allocationSize(value.`authSig`) +
+ FfiConverterString.allocationSize(value.`newUserAuthKey`) +
+ FfiConverterString.allocationSize(value.`encTransferMsg`)
+ )
+
+ override fun write(
+ value: TransferUpdateMsgRequestPayload,
+ buf: ByteBuffer,
+ ) {
+ FfiConverterString.write(value.`statechainId`, buf)
+ FfiConverterString.write(value.`authSig`, buf)
+ FfiConverterString.write(value.`newUserAuthKey`, buf)
+ FfiConverterString.write(value.`encTransferMsg`, buf)
+ }
+}
+
+data class TxOutpoint(
+ var `txid`: kotlin.String,
+ var `vout`: kotlin.UInt,
+) {
+ companion object
+}
+
+public object FfiConverterTypeTxOutpoint : FfiConverterRustBuffer {
+ override fun read(buf: ByteBuffer): TxOutpoint {
+ return TxOutpoint(
+ FfiConverterString.read(buf),
+ FfiConverterUInt.read(buf),
+ )
+ }
+
+ override fun allocationSize(value: TxOutpoint) =
+ (
+ FfiConverterString.allocationSize(value.`txid`) +
+ FfiConverterUInt.allocationSize(value.`vout`)
+ )
+
+ override fun write(
+ value: TxOutpoint,
+ buf: ByteBuffer,
+ ) {
+ FfiConverterString.write(value.`txid`, buf)
+ FfiConverterUInt.write(value.`vout`, buf)
+ }
+}
+
+@Serializable
+data class Wallet(
+ var `name`: kotlin.String,
+ var `mnemonic`: kotlin.String,
+ var `version`: kotlin.String,
+ var `stateEntityEndpoint`: kotlin.String,
+ var `electrumEndpoint`: kotlin.String,
+ var `network`: kotlin.String,
+ var `blockheight`: kotlin.UInt,
+ var `initlock`: kotlin.UInt,
+ var `interval`: kotlin.UInt,
+ var `tokens`: List,
+ var `activities`: List,
+ var `coins`: List,
+ var `settings`: Settings,
+) {
+ companion object
+}
+
+public object FfiConverterTypeWallet : FfiConverterRustBuffer {
+ override fun read(buf: ByteBuffer): Wallet {
+ return Wallet(
+ FfiConverterString.read(buf),
+ FfiConverterString.read(buf),
+ FfiConverterString.read(buf),
+ FfiConverterString.read(buf),
+ FfiConverterString.read(buf),
+ FfiConverterString.read(buf),
+ FfiConverterUInt.read(buf),
+ FfiConverterUInt.read(buf),
+ FfiConverterUInt.read(buf),
+ FfiConverterSequenceTypeToken.read(buf),
+ FfiConverterSequenceTypeActivity.read(buf),
+ FfiConverterSequenceTypeCoin.read(buf),
+ FfiConverterTypeSettings.read(buf),
+ )
+ }
+
+ override fun allocationSize(value: Wallet) =
+ (
+ FfiConverterString.allocationSize(value.`name`) +
+ FfiConverterString.allocationSize(value.`mnemonic`) +
+ FfiConverterString.allocationSize(value.`version`) +
+ FfiConverterString.allocationSize(value.`stateEntityEndpoint`) +
+ FfiConverterString.allocationSize(value.`electrumEndpoint`) +
+ FfiConverterString.allocationSize(value.`network`) +
+ FfiConverterUInt.allocationSize(value.`blockheight`) +
+ FfiConverterUInt.allocationSize(value.`initlock`) +
+ FfiConverterUInt.allocationSize(value.`interval`) +
+ FfiConverterSequenceTypeToken.allocationSize(value.`tokens`) +
+ FfiConverterSequenceTypeActivity.allocationSize(value.`activities`) +
+ FfiConverterSequenceTypeCoin.allocationSize(value.`coins`) +
+ FfiConverterTypeSettings.allocationSize(value.`settings`)
+ )
+
+ override fun write(
+ value: Wallet,
+ buf: ByteBuffer,
+ ) {
+ FfiConverterString.write(value.`name`, buf)
+ FfiConverterString.write(value.`mnemonic`, buf)
+ FfiConverterString.write(value.`version`, buf)
+ FfiConverterString.write(value.`stateEntityEndpoint`, buf)
+ FfiConverterString.write(value.`electrumEndpoint`, buf)
+ FfiConverterString.write(value.`network`, buf)
+ FfiConverterUInt.write(value.`blockheight`, buf)
+ FfiConverterUInt.write(value.`initlock`, buf)
+ FfiConverterUInt.write(value.`interval`, buf)
+ FfiConverterSequenceTypeToken.write(value.`tokens`, buf)
+ FfiConverterSequenceTypeActivity.write(value.`activities`, buf)
+ FfiConverterSequenceTypeCoin.write(value.`coins`, buf)
+ FfiConverterTypeSettings.write(value.`settings`, buf)
+ }
+}
+
+@Serializable
+data class WithdrawCompletePayload(
+ @SerialName("statechain_id")
+ var `statechainId`: kotlin.String,
+ @SerialName("signed_statechain_id")
+ var `signedStatechainId`: kotlin.String,
+) {
+ companion object
+}
+
+public object FfiConverterTypeWithdrawCompletePayload : FfiConverterRustBuffer {
+ override fun read(buf: ByteBuffer): WithdrawCompletePayload {
+ return WithdrawCompletePayload(
+ FfiConverterString.read(buf),
+ FfiConverterString.read(buf),
+ )
+ }
+
+ override fun allocationSize(value: WithdrawCompletePayload) =
+ (
+ FfiConverterString.allocationSize(value.`statechainId`) +
+ FfiConverterString.allocationSize(value.`signedStatechainId`)
+ )
+
+ override fun write(
+ value: WithdrawCompletePayload,
+ buf: ByteBuffer,
+ ) {
+ FfiConverterString.write(value.`statechainId`, buf)
+ FfiConverterString.write(value.`signedStatechainId`, buf)
+ }
+}
+
+enum class CoinStatus {
+ INITIALISED,
+ IN_MEMPOOL,
+ UNCONFIRMED,
+ CONFIRMED,
+ IN_TRANSFER,
+ WITHDRAWING,
+ TRANSFERRED,
+ WITHDRAWN,
+ ;
+
+ companion object
+}
+
+public object FfiConverterTypeCoinStatus : FfiConverterRustBuffer {
+ override fun read(buf: ByteBuffer) =
+ try {
+ CoinStatus.values()[buf.getInt() - 1]
+ } catch (e: IndexOutOfBoundsException) {
+ throw RuntimeException("invalid enum value, something is very wrong!!", e)
+ }
+
+ override fun allocationSize(value: CoinStatus) = 4UL
+
+ override fun write(
+ value: CoinStatus,
+ buf: ByteBuffer,
+ ) {
+ buf.putInt(value.ordinal + 1)
+ }
+}
+
+sealed class MercuryException : Exception() {
+ class Bip39Exception() : MercuryException() {
+ override val message
+ get() = ""
+ }
+
+ class Bip32Exception() : MercuryException() {
+ override val message
+ get() = ""
+ }
+
+ class NetworkConversionException() : MercuryException() {
+ override val message
+ get() = ""
+ }
+
+ class Secp256k1UpstreamException() : MercuryException() {
+ override val message
+ get() = ""
+ }
+
+ class KeyException() : MercuryException() {
+ override val message
+ get() = ""
+ }
+
+ class Bech32Exception() : MercuryException() {
+ override val message
+ get() = ""
+ }
+
+ class HexException() : MercuryException() {
+ override val message
+ get() = ""
+ }
+
+ class LocktimeNotBlockHeightException() : MercuryException() {
+ override val message
+ get() = ""
+ }
+
+ class BitcoinConsensusEncodeException() : MercuryException() {
+ override val message
+ get() = ""
+ }
+
+ class MusigNonceGenException() : MercuryException() {
+ override val message
+ get() = ""
+ }
+
+ class InvalidStatechainAddressException() : MercuryException() {
+ override val message
+ get() = ""
+ }
+
+ class InvalidBitcoinAddressException() : MercuryException() {
+ override val message
+ get() = ""
+ }
+
+ class StatechainAddressMismatchNetworkException() : MercuryException() {
+ override val message
+ get() = ""
+ }
+
+ class BitcoinAddressMismatchNetworkException() : MercuryException() {
+ override val message
+ get() = ""
+ }
+
+ class BitcoinAddressException() : MercuryException() {
+ override val message
+ get() = ""
+ }
+
+ class BitcoinAbsoluteException() : MercuryException() {
+ override val message
+ get() = ""
+ }
+
+ class BitcoinHashHexException() : MercuryException() {
+ override val message
+ get() = ""
+ }
+
+ class BitcoinPsbtException() : MercuryException() {
+ override val message
+ get() = ""
+ }
+
+ class SighashTypeParseException() : MercuryException() {
+ override val message
+ get() = ""
+ }
+
+ class BitcoinSighashException() : MercuryException() {
+ override val message
+ get() = ""
+ }
+
+ class ParseException() : MercuryException() {
+ override val message
+ get() = ""
+ }
+
+ class MusigSignException() : MercuryException() {
+ override val message
+ get() = ""
+ }
+
+ class SchnorrSignatureValidationException() : MercuryException() {
+ override val message
+ get() = ""
+ }
+
+ class MoreThanOneInputException() : MercuryException() {
+ override val message
+ get() = ""
+ }
+
+ class UnkownNetwork() : MercuryException() {
+ override val message
+ get() = ""
+ }
+
+ class BackupTransactionDoesNotPayUser() : MercuryException() {
+ override val message
+ get() = ""
+ }
+
+ class FeeTooHigh() : MercuryException() {
+ override val message
+ get() = ""
+ }
+
+ class FeeTooLow() : MercuryException() {
+ override val message
+ get() = ""
+ }
+
+ class OutOfRangeException() : MercuryException() {
+ override val message
+ get() = ""
+ }
+
+ class SerdeJsonException() : MercuryException() {
+ override val message
+ get() = ""
+ }
+
+ class SecpException() : MercuryException() {
+ override val message
+ get() = ""
+ }
+
+ class NoBackupTransactionFound() : MercuryException() {
+ override val message
+ get() = ""
+ }
+
+ class Tx1HasMoreThanOneInput() : MercuryException() {
+ override val message
+ get() = ""
+ }
+
+ class InvalidSignature() : MercuryException() {
+ override val message
+ get() = ""
+ }
+
+ class EmptyWitness() : MercuryException() {
+ override val message
+ get() = ""
+ }
+
+ class EmptyWitnessData() : MercuryException() {
+ override val message
+ get() = ""
+ }
+
+ class IncorrectChallenge() : MercuryException() {
+ override val message
+ get() = ""
+ }
+
+ class InvalidT1() : MercuryException() {
+ override val message
+ get() = ""
+ }
+
+ class IncorrectAggregatedPublicKey() : MercuryException() {
+ override val message
+ get() = ""
+ }
+
+ class T1MustBeExactly32BytesException() : MercuryException() {
+ override val message
+ get() = ""
+ }
+
+ class NoX1Pub() : MercuryException() {
+ override val message
+ get() = ""
+ }
+
+ class NoAggregatedPubkeyException() : MercuryException() {
+ override val message
+ get() = ""
+ }
+
+ class CoinNotFound() : MercuryException() {
+ override val message
+ get() = ""
+ }
+
+ class SignatureSchemeValidationException() : MercuryException() {
+ override val message
+ get() = ""
+ }
+
+ class NoPreviousLockTimeException() : MercuryException() {
+ override val message
+ get() = ""
+ }
+
+ companion object ErrorHandler : UniffiRustCallStatusErrorHandler {
+ override fun lift(error_buf: RustBuffer.ByValue): MercuryException = FfiConverterTypeMercuryError.lift(error_buf)
+ }
+}
+
+public object FfiConverterTypeMercuryError : FfiConverterRustBuffer {
+ override fun read(buf: ByteBuffer): MercuryException {
+ return when (buf.getInt()) {
+ 1 -> MercuryException.Bip39Exception()
+ 2 -> MercuryException.Bip32Exception()
+ 3 -> MercuryException.NetworkConversionException()
+ 4 -> MercuryException.Secp256k1UpstreamException()
+ 5 -> MercuryException.KeyException()
+ 6 -> MercuryException.Bech32Exception()
+ 7 -> MercuryException.HexException()
+ 8 -> MercuryException.LocktimeNotBlockHeightException()
+ 9 -> MercuryException.BitcoinConsensusEncodeException()
+ 10 -> MercuryException.MusigNonceGenException()
+ 11 -> MercuryException.InvalidStatechainAddressException()
+ 12 -> MercuryException.InvalidBitcoinAddressException()
+ 13 -> MercuryException.StatechainAddressMismatchNetworkException()
+ 14 -> MercuryException.BitcoinAddressMismatchNetworkException()
+ 15 -> MercuryException.BitcoinAddressException()
+ 16 -> MercuryException.BitcoinAbsoluteException()
+ 17 -> MercuryException.BitcoinHashHexException()
+ 18 -> MercuryException.BitcoinPsbtException()
+ 19 -> MercuryException.SighashTypeParseException()
+ 20 -> MercuryException.BitcoinSighashException()
+ 21 -> MercuryException.ParseException()
+ 22 -> MercuryException.MusigSignException()
+ 23 -> MercuryException.SchnorrSignatureValidationException()
+ 24 -> MercuryException.MoreThanOneInputException()
+ 25 -> MercuryException.UnkownNetwork()
+ 26 -> MercuryException.BackupTransactionDoesNotPayUser()
+ 27 -> MercuryException.FeeTooHigh()
+ 28 -> MercuryException.FeeTooLow()
+ 29 -> MercuryException.OutOfRangeException()
+ 30 -> MercuryException.SerdeJsonException()
+ 31 -> MercuryException.SecpException()
+ 32 -> MercuryException.NoBackupTransactionFound()
+ 33 -> MercuryException.Tx1HasMoreThanOneInput()
+ 34 -> MercuryException.InvalidSignature()
+ 35 -> MercuryException.EmptyWitness()
+ 36 -> MercuryException.EmptyWitnessData()
+ 37 -> MercuryException.IncorrectChallenge()
+ 38 -> MercuryException.InvalidT1()
+ 39 -> MercuryException.IncorrectAggregatedPublicKey()
+ 40 -> MercuryException.T1MustBeExactly32BytesException()
+ 41 -> MercuryException.NoX1Pub()
+ 42 -> MercuryException.NoAggregatedPubkeyException()
+ 43 -> MercuryException.CoinNotFound()
+ 44 -> MercuryException.SignatureSchemeValidationException()
+ 45 -> MercuryException.NoPreviousLockTimeException()
+ else -> throw RuntimeException("invalid error enum value, something is very wrong!!")
+ }
+ }
+
+ override fun allocationSize(value: MercuryException): ULong {
+ return when (value) {
+ is MercuryException.Bip39Exception -> (
+ // Add the size for the Int that specifies the variant plus the size needed for all fields
+ 4UL
+ )
+ is MercuryException.Bip32Exception -> (
+ // Add the size for the Int that specifies the variant plus the size needed for all fields
+ 4UL
+ )
+ is MercuryException.NetworkConversionException -> (
+ // Add the size for the Int that specifies the variant plus the size needed for all fields
+ 4UL
+ )
+ is MercuryException.Secp256k1UpstreamException -> (
+ // Add the size for the Int that specifies the variant plus the size needed for all fields
+ 4UL
+ )
+ is MercuryException.KeyException -> (
+ // Add the size for the Int that specifies the variant plus the size needed for all fields
+ 4UL
+ )
+ is MercuryException.Bech32Exception -> (
+ // Add the size for the Int that specifies the variant plus the size needed for all fields
+ 4UL
+ )
+ is MercuryException.HexException -> (
+ // Add the size for the Int that specifies the variant plus the size needed for all fields
+ 4UL
+ )
+ is MercuryException.LocktimeNotBlockHeightException -> (
+ // Add the size for the Int that specifies the variant plus the size needed for all fields
+ 4UL
+ )
+ is MercuryException.BitcoinConsensusEncodeException -> (
+ // Add the size for the Int that specifies the variant plus the size needed for all fields
+ 4UL
+ )
+ is MercuryException.MusigNonceGenException -> (
+ // Add the size for the Int that specifies the variant plus the size needed for all fields
+ 4UL
+ )
+ is MercuryException.InvalidStatechainAddressException -> (
+ // Add the size for the Int that specifies the variant plus the size needed for all fields
+ 4UL
+ )
+ is MercuryException.InvalidBitcoinAddressException -> (
+ // Add the size for the Int that specifies the variant plus the size needed for all fields
+ 4UL
+ )
+ is MercuryException.StatechainAddressMismatchNetworkException -> (
+ // Add the size for the Int that specifies the variant plus the size needed for all fields
+ 4UL
+ )
+ is MercuryException.BitcoinAddressMismatchNetworkException -> (
+ // Add the size for the Int that specifies the variant plus the size needed for all fields
+ 4UL
+ )
+ is MercuryException.BitcoinAddressException -> (
+ // Add the size for the Int that specifies the variant plus the size needed for all fields
+ 4UL
+ )
+ is MercuryException.BitcoinAbsoluteException -> (
+ // Add the size for the Int that specifies the variant plus the size needed for all fields
+ 4UL
+ )
+ is MercuryException.BitcoinHashHexException -> (
+ // Add the size for the Int that specifies the variant plus the size needed for all fields
+ 4UL
+ )
+ is MercuryException.BitcoinPsbtException -> (
+ // Add the size for the Int that specifies the variant plus the size needed for all fields
+ 4UL
+ )
+ is MercuryException.SighashTypeParseException -> (
+ // Add the size for the Int that specifies the variant plus the size needed for all fields
+ 4UL
+ )
+ is MercuryException.BitcoinSighashException -> (
+ // Add the size for the Int that specifies the variant plus the size needed for all fields
+ 4UL
+ )
+ is MercuryException.ParseException -> (
+ // Add the size for the Int that specifies the variant plus the size needed for all fields
+ 4UL
+ )
+ is MercuryException.MusigSignException -> (
+ // Add the size for the Int that specifies the variant plus the size needed for all fields
+ 4UL
+ )
+ is MercuryException.SchnorrSignatureValidationException -> (
+ // Add the size for the Int that specifies the variant plus the size needed for all fields
+ 4UL
+ )
+ is MercuryException.MoreThanOneInputException -> (
+ // Add the size for the Int that specifies the variant plus the size needed for all fields
+ 4UL
+ )
+ is MercuryException.UnkownNetwork -> (
+ // Add the size for the Int that specifies the variant plus the size needed for all fields
+ 4UL
+ )
+ is MercuryException.BackupTransactionDoesNotPayUser -> (
+ // Add the size for the Int that specifies the variant plus the size needed for all fields
+ 4UL
+ )
+ is MercuryException.FeeTooHigh -> (
+ // Add the size for the Int that specifies the variant plus the size needed for all fields
+ 4UL
+ )
+ is MercuryException.FeeTooLow -> (
+ // Add the size for the Int that specifies the variant plus the size needed for all fields
+ 4UL
+ )
+ is MercuryException.OutOfRangeException -> (
+ // Add the size for the Int that specifies the variant plus the size needed for all fields
+ 4UL
+ )
+ is MercuryException.SerdeJsonException -> (
+ // Add the size for the Int that specifies the variant plus the size needed for all fields
+ 4UL
+ )
+ is MercuryException.SecpException -> (
+ // Add the size for the Int that specifies the variant plus the size needed for all fields
+ 4UL
+ )
+ is MercuryException.NoBackupTransactionFound -> (
+ // Add the size for the Int that specifies the variant plus the size needed for all fields
+ 4UL
+ )
+ is MercuryException.Tx1HasMoreThanOneInput -> (
+ // Add the size for the Int that specifies the variant plus the size needed for all fields
+ 4UL
+ )
+ is MercuryException.InvalidSignature -> (
+ // Add the size for the Int that specifies the variant plus the size needed for all fields
+ 4UL
+ )
+ is MercuryException.EmptyWitness -> (
+ // Add the size for the Int that specifies the variant plus the size needed for all fields
+ 4UL
+ )
+ is MercuryException.EmptyWitnessData -> (
+ // Add the size for the Int that specifies the variant plus the size needed for all fields
+ 4UL
+ )
+ is MercuryException.IncorrectChallenge -> (
+ // Add the size for the Int that specifies the variant plus the size needed for all fields
+ 4UL
+ )
+ is MercuryException.InvalidT1 -> (
+ // Add the size for the Int that specifies the variant plus the size needed for all fields
+ 4UL
+ )
+ is MercuryException.IncorrectAggregatedPublicKey -> (
+ // Add the size for the Int that specifies the variant plus the size needed for all fields
+ 4UL
+ )
+ is MercuryException.T1MustBeExactly32BytesException -> (
+ // Add the size for the Int that specifies the variant plus the size needed for all fields
+ 4UL
+ )
+ is MercuryException.NoX1Pub -> (
+ // Add the size for the Int that specifies the variant plus the size needed for all fields
+ 4UL
+ )
+ is MercuryException.NoAggregatedPubkeyException -> (
+ // Add the size for the Int that specifies the variant plus the size needed for all fields
+ 4UL
+ )
+ is MercuryException.CoinNotFound -> (
+ // Add the size for the Int that specifies the variant plus the size needed for all fields
+ 4UL
+ )
+ is MercuryException.SignatureSchemeValidationException -> (
+ // Add the size for the Int that specifies the variant plus the size needed for all fields
+ 4UL
+ )
+ is MercuryException.NoPreviousLockTimeException -> (
+ // Add the size for the Int that specifies the variant plus the size needed for all fields
+ 4UL
+ )
+ }
+ }
+
+ override fun write(
+ value: MercuryException,
+ buf: ByteBuffer,
+ ) {
+ when (value) {
+ is MercuryException.Bip39Exception -> {
+ buf.putInt(1)
+ Unit
+ }
+ is MercuryException.Bip32Exception -> {
+ buf.putInt(2)
+ Unit
+ }
+ is MercuryException.NetworkConversionException -> {
+ buf.putInt(3)
+ Unit
+ }
+ is MercuryException.Secp256k1UpstreamException -> {
+ buf.putInt(4)
+ Unit
+ }
+ is MercuryException.KeyException -> {
+ buf.putInt(5)
+ Unit
+ }
+ is MercuryException.Bech32Exception -> {
+ buf.putInt(6)
+ Unit
+ }
+ is MercuryException.HexException -> {
+ buf.putInt(7)
+ Unit
+ }
+ is MercuryException.LocktimeNotBlockHeightException -> {
+ buf.putInt(8)
+ Unit
+ }
+ is MercuryException.BitcoinConsensusEncodeException -> {
+ buf.putInt(9)
+ Unit
+ }
+ is MercuryException.MusigNonceGenException -> {
+ buf.putInt(10)
+ Unit
+ }
+ is MercuryException.InvalidStatechainAddressException -> {
+ buf.putInt(11)
+ Unit
+ }
+ is MercuryException.InvalidBitcoinAddressException -> {
+ buf.putInt(12)
+ Unit
+ }
+ is MercuryException.StatechainAddressMismatchNetworkException -> {
+ buf.putInt(13)
+ Unit
+ }
+ is MercuryException.BitcoinAddressMismatchNetworkException -> {
+ buf.putInt(14)
+ Unit
+ }
+ is MercuryException.BitcoinAddressException -> {
+ buf.putInt(15)
+ Unit
+ }
+ is MercuryException.BitcoinAbsoluteException -> {
+ buf.putInt(16)
+ Unit
+ }
+ is MercuryException.BitcoinHashHexException -> {
+ buf.putInt(17)
+ Unit
+ }
+ is MercuryException.BitcoinPsbtException -> {
+ buf.putInt(18)
+ Unit
+ }
+ is MercuryException.SighashTypeParseException -> {
+ buf.putInt(19)
+ Unit
+ }
+ is MercuryException.BitcoinSighashException -> {
+ buf.putInt(20)
+ Unit
+ }
+ is MercuryException.ParseException -> {
+ buf.putInt(21)
+ Unit
+ }
+ is MercuryException.MusigSignException -> {
+ buf.putInt(22)
+ Unit
+ }
+ is MercuryException.SchnorrSignatureValidationException -> {
+ buf.putInt(23)
+ Unit
+ }
+ is MercuryException.MoreThanOneInputException -> {
+ buf.putInt(24)
+ Unit
+ }
+ is MercuryException.UnkownNetwork -> {
+ buf.putInt(25)
+ Unit
+ }
+ is MercuryException.BackupTransactionDoesNotPayUser -> {
+ buf.putInt(26)
+ Unit
+ }
+ is MercuryException.FeeTooHigh -> {
+ buf.putInt(27)
+ Unit
+ }
+ is MercuryException.FeeTooLow -> {
+ buf.putInt(28)
+ Unit
+ }
+ is MercuryException.OutOfRangeException -> {
+ buf.putInt(29)
+ Unit
+ }
+ is MercuryException.SerdeJsonException -> {
+ buf.putInt(30)
+ Unit
+ }
+ is MercuryException.SecpException -> {
+ buf.putInt(31)
+ Unit
+ }
+ is MercuryException.NoBackupTransactionFound -> {
+ buf.putInt(32)
+ Unit
+ }
+ is MercuryException.Tx1HasMoreThanOneInput -> {
+ buf.putInt(33)
+ Unit
+ }
+ is MercuryException.InvalidSignature -> {
+ buf.putInt(34)
+ Unit
+ }
+ is MercuryException.EmptyWitness -> {
+ buf.putInt(35)
+ Unit
+ }
+ is MercuryException.EmptyWitnessData -> {
+ buf.putInt(36)
+ Unit
+ }
+ is MercuryException.IncorrectChallenge -> {
+ buf.putInt(37)
+ Unit
+ }
+ is MercuryException.InvalidT1 -> {
+ buf.putInt(38)
+ Unit
+ }
+ is MercuryException.IncorrectAggregatedPublicKey -> {
+ buf.putInt(39)
+ Unit
+ }
+ is MercuryException.T1MustBeExactly32BytesException -> {
+ buf.putInt(40)
+ Unit
+ }
+ is MercuryException.NoX1Pub -> {
+ buf.putInt(41)
+ Unit
+ }
+ is MercuryException.NoAggregatedPubkeyException -> {
+ buf.putInt(42)
+ Unit
+ }
+ is MercuryException.CoinNotFound -> {
+ buf.putInt(43)
+ Unit
+ }
+ is MercuryException.SignatureSchemeValidationException -> {
+ buf.putInt(44)
+ Unit
+ }
+ is MercuryException.NoPreviousLockTimeException -> {
+ buf.putInt(45)
+ Unit
+ }
+ }.let { /* this makes the `when` an expression, which ensures it is exhaustive */ }
+ }
+}
+
+@Serializable
+enum class TransferReceiverError {
+ @SerialName("StatecoinBatchLockedError")
+ STATECOIN_BATCH_LOCKED_ERROR,
+ @SerialName("ExpiredBatchTimeError")
+ EXPIRED_BATCH_TIME_ERROR,
+ ;
+
+ companion object
+}
+
+public object FfiConverterTypeTransferReceiverError : FfiConverterRustBuffer {
+ override fun read(buf: ByteBuffer) =
+ try {
+ TransferReceiverError.values()[buf.getInt() - 1]
+ } catch (e: IndexOutOfBoundsException) {
+ throw RuntimeException("invalid enum value, something is very wrong!!", e)
+ }
+
+ override fun allocationSize(value: TransferReceiverError) = 4UL
+
+ override fun write(
+ value: TransferReceiverError,
+ buf: ByteBuffer,
+ ) {
+ buf.putInt(value.ordinal + 1)
+ }
+}
+
+public object FfiConverterOptionalUInt : FfiConverterRustBuffer {
+ override fun read(buf: ByteBuffer): kotlin.UInt? {
+ if (buf.get().toInt() == 0) {
+ return null
+ }
+ return FfiConverterUInt.read(buf)
+ }
+
+ override fun allocationSize(value: kotlin.UInt?): ULong {
+ if (value == null) {
+ return 1UL
+ } else {
+ return 1UL + FfiConverterUInt.allocationSize(value)
+ }
+ }
+
+ override fun write(
+ value: kotlin.UInt?,
+ buf: ByteBuffer,
+ ) {
+ if (value == null) {
+ buf.put(0)
+ } else {
+ buf.put(1)
+ FfiConverterUInt.write(value, buf)
+ }
+ }
+}
+
+public object FfiConverterOptionalString : FfiConverterRustBuffer {
+ override fun read(buf: ByteBuffer): kotlin.String? {
+ if (buf.get().toInt() == 0) {
+ return null
+ }
+ return FfiConverterString.read(buf)
+ }
+
+ override fun allocationSize(value: kotlin.String?): ULong {
+ if (value == null) {
+ return 1UL
+ } else {
+ return 1UL + FfiConverterString.allocationSize(value)
+ }
+ }
+
+ override fun write(
+ value: kotlin.String?,
+ buf: ByteBuffer,
+ ) {
+ if (value == null) {
+ buf.put(0)
+ } else {
+ buf.put(1)
+ FfiConverterString.write(value, buf)
+ }
+ }
+}
+
+public object FfiConverterSequenceString : FfiConverterRustBuffer> {
+ override fun read(buf: ByteBuffer): List {
+ val len = buf.getInt()
+ return List(len) {
+ FfiConverterString.read(buf)
+ }
+ }
+
+ override fun allocationSize(value: List): ULong {
+ val sizeForLength = 4UL
+ val sizeForItems = value.map { FfiConverterString.allocationSize(it) }.sum()
+ return sizeForLength + sizeForItems
+ }
+
+ override fun write(
+ value: List,
+ buf: ByteBuffer,
+ ) {
+ buf.putInt(value.size)
+ value.iterator().forEach {
+ FfiConverterString.write(it, buf)
+ }
+ }
+}
+
+public object FfiConverterSequenceTypeActivity : FfiConverterRustBuffer> {
+ override fun read(buf: ByteBuffer): List {
+ val len = buf.getInt()
+ return List(len) {
+ FfiConverterTypeActivity.read(buf)
+ }
+ }
+
+ override fun allocationSize(value: List): ULong {
+ val sizeForLength = 4UL
+ val sizeForItems = value.map { FfiConverterTypeActivity.allocationSize(it) }.sum()
+ return sizeForLength + sizeForItems
+ }
+
+ override fun write(
+ value: List,
+ buf: ByteBuffer,
+ ) {
+ buf.putInt(value.size)
+ value.iterator().forEach {
+ FfiConverterTypeActivity.write(it, buf)
+ }
+ }
+}
+
+public object FfiConverterSequenceTypeBackupTx : FfiConverterRustBuffer> {
+ override fun read(buf: ByteBuffer): List {
+ val len = buf.getInt()
+ return List(len) {
+ FfiConverterTypeBackupTx.read(buf)
+ }
+ }
+
+ override fun allocationSize(value: List): ULong {
+ val sizeForLength = 4UL
+ val sizeForItems = value.map { FfiConverterTypeBackupTx.allocationSize(it) }.sum()
+ return sizeForLength + sizeForItems
+ }
+
+ override fun write(
+ value: List,
+ buf: ByteBuffer,
+ ) {
+ buf.putInt(value.size)
+ value.iterator().forEach {
+ FfiConverterTypeBackupTx.write(it, buf)
+ }
+ }
+}
+
+public object FfiConverterSequenceTypeCoin : FfiConverterRustBuffer> {
+ override fun read(buf: ByteBuffer): List {
+ val len = buf.getInt()
+ return List(len) {
+ FfiConverterTypeCoin.read(buf)
+ }
+ }
+
+ override fun allocationSize(value: List): ULong {
+ val sizeForLength = 4UL
+ val sizeForItems = value.map { FfiConverterTypeCoin.allocationSize(it) }.sum()
+ return sizeForLength + sizeForItems
+ }
+
+ override fun write(
+ value: List,
+ buf: ByteBuffer,
+ ) {
+ buf.putInt(value.size)
+ value.iterator().forEach {
+ FfiConverterTypeCoin.write(it, buf)
+ }
+ }
+}
+
+public object FfiConverterSequenceTypePubKeyInfo : FfiConverterRustBuffer> {
+ override fun read(buf: ByteBuffer): List {
+ val len = buf.getInt()
+ return List(len) {
+ FfiConverterTypePubKeyInfo.read(buf)
+ }
+ }
+
+ override fun allocationSize(value: List