diff --git a/Cargo.lock b/Cargo.lock index dd265f37..fb1f54c7 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -165,6 +165,47 @@ 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" @@ -184,7 +225,7 @@ checksum = "16e62a023e7c117e27523144c5d2459f4397fcc3cab0085af8e2224f643a0193" dependencies = [ "proc-macro2", "quote", - "syn 2.0.38", + "syn 2.0.60", ] [[package]] @@ -195,7 +236,7 @@ checksum = "a66537f1bb974b254c98ed142ff995236e81b9d0fe4db0575f46612cb15eb0f9" dependencies = [ "proc-macro2", "quote", - "syn 2.0.38", + "syn 2.0.60", ] [[package]] @@ -261,6 +302,15 @@ 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" @@ -273,6 +323,15 @@ 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" @@ -381,6 +440,38 @@ 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" @@ -451,7 +542,7 @@ dependencies = [ "heck", "proc-macro2", "quote", - "syn 2.0.38", + "syn 2.0.60", ] [[package]] @@ -668,7 +759,7 @@ dependencies = [ "proc-macro2", "proc-macro2-diagnostics", "quote", - "syn 2.0.38", + "syn 2.0.60", ] [[package]] @@ -865,6 +956,15 @@ 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" @@ -1010,6 +1110,17 @@ 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" @@ -1502,7 +1613,6 @@ dependencies = [ name = "mercurylib" version = "0.1.0" dependencies = [ - "anyhow", "bech32", "bip39", "bitcoin", @@ -1511,6 +1621,8 @@ dependencies = [ "secp256k1-zkp", "serde", "serde_json", + "thiserror", + "uniffi", ] [[package]] @@ -1519,6 +1631,16 @@ 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" @@ -1676,6 +1798,12 @@ version = "1.18.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "dd8b5dd2ae5ed71462c540258bedcb51965123ad7e7ccf4b9a8cafaa4a63576d" +[[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" @@ -1705,7 +1833,7 @@ checksum = "a948666b637a0f465e8564c73e89d4dde00d72d4d473cc972f390fc3dcee7d9c" dependencies = [ "proc-macro2", "quote", - "syn 2.0.38", + "syn 2.0.60", ] [[package]] @@ -1797,7 +1925,7 @@ dependencies = [ "proc-macro2", "proc-macro2-diagnostics", "quote", - "syn 2.0.38", + "syn 2.0.60", ] [[package]] @@ -1846,7 +1974,7 @@ dependencies = [ "pest_meta", "proc-macro2", "quote", - "syn 2.0.38", + "syn 2.0.60", ] [[package]] @@ -1899,6 +2027,12 @@ 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" @@ -1919,9 +2053,9 @@ checksum = "5b40af805b3121feab8a3c29f04d8ad262fa8e0561883e7653e024ae4479e6de" [[package]] name = "proc-macro2" -version = "1.0.69" +version = "1.0.81" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "134c189feb4956b20f6f547d2cf727d4c0fe06722b20a0eec87ed445a97f92da" +checksum = "3d1597b0c024618f09a9c3b8655b7e430397a36d23fdafec26d6965e9eec3eba" dependencies = [ "unicode-ident", ] @@ -1934,16 +2068,16 @@ checksum = "af066a9c399a26e020ada66a034357a868728e72cd426f3adcd35f80d88d88c8" dependencies = [ "proc-macro2", "quote", - "syn 2.0.38", + "syn 2.0.60", "version_check", "yansi", ] [[package]] name = "quote" -version = "1.0.33" +version = "1.0.36" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5267fca4496028628a95160fc423a33e8b2e6af8a5302579e322e4b520293cae" +checksum = "0fa76aaf39101c457836aec0ce2316dbdc3ab723cdda1c6bd4e6ad4208acaca7" dependencies = [ "proc-macro2", ] @@ -2010,7 +2144,7 @@ checksum = "7f7473c2cfcf90008193dd0e3e16599455cb601a9fce322b5bb55de799664925" dependencies = [ "proc-macro2", "quote", - "syn 2.0.38", + "syn 2.0.60", ] [[package]] @@ -2175,7 +2309,7 @@ dependencies = [ "proc-macro2", "quote", "rocket_http", - "syn 2.0.38", + "syn 2.0.60", "unicode-xid", "version_check", ] @@ -2350,6 +2484,26 @@ 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" @@ -2424,11 +2578,20 @@ dependencies = [ "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.188" +version = "1.0.199" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "cf9e0fcba69a370eed61bcf2b728575f726b50b55cba78064753d708ddc7549e" +checksum = "0c9f6e76df036c77cd94996771fb40db98187f096dd0b9af39c6c6e452ba966a" dependencies = [ "serde_derive", ] @@ -2446,13 +2609,13 @@ dependencies = [ [[package]] name = "serde_derive" -version = "1.0.188" +version = "1.0.199" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4eca7ac642d82aa35b60049a6eccb4be6be75e599bd2e9adb5f875a737654af2" +checksum = "11bd257a6541e141e42ca6d24ae26f7714887b47e89aa739099104c7e4d3b7fc" dependencies = [ "proc-macro2", "quote", - "syn 2.0.38", + "syn 2.0.60", ] [[package]] @@ -2548,6 +2711,12 @@ dependencies = [ "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" @@ -2572,6 +2741,12 @@ 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" @@ -2849,6 +3024,12 @@ 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" @@ -2885,9 +3066,9 @@ dependencies = [ [[package]] name = "syn" -version = "2.0.38" +version = "2.0.60" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e96b79aaa137db8f61e26363a0c9b47d8b4ec75da28b7d1d614c2303e232408b" +checksum = "909518bc7b1c9b779f1bbf07f2929d35af9f0f37e47c6e9ef7f9dddc1e1821f3" dependencies = [ "proc-macro2", "quote", @@ -2928,24 +3109,35 @@ dependencies = [ "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.49" +version = "1.0.59" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1177e8c6d7ede7afde3585fd2513e611227efd6481bd78d2e82ba1ce16557ed4" +checksum = "f0126ad08bff79f29fc3ae6a55cc72352056dfff61e3ff8bb7129476d44b23aa" dependencies = [ "thiserror-impl", ] [[package]] name = "thiserror-impl" -version = "1.0.49" +version = "1.0.59" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "10712f02019e9288794769fba95cd6847df9874d49d871d062172f9dd41bc4cc" +checksum = "d1cd413b5d558b4c5bf3680e324a6fa5014e7b7c067a51e69dbdf47eb7148b66" dependencies = [ "proc-macro2", "quote", - "syn 2.0.38", + "syn 2.0.60", ] [[package]] @@ -3029,7 +3221,7 @@ checksum = "630bdcf245f78637c13ec01ffae6187cca34625e8c63150d424b59e55af2675e" dependencies = [ "proc-macro2", "quote", - "syn 2.0.38", + "syn 2.0.60", ] [[package]] @@ -3149,7 +3341,7 @@ checksum = "5f4f31f56159e98206da9efd823404b79b6ef3143b4a7ab76e67b1751b25a4ab" dependencies = [ "proc-macro2", "quote", - "syn 2.0.38", + "syn 2.0.60", ] [[package]] @@ -3228,6 +3420,15 @@ dependencies = [ "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" @@ -3240,6 +3441,12 @@ 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" @@ -3255,6 +3462,12 @@ 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" @@ -3267,6 +3480,127 @@ 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" @@ -3376,7 +3710,7 @@ dependencies = [ "once_cell", "proc-macro2", "quote", - "syn 2.0.38", + "syn 2.0.60", "wasm-bindgen-shared", ] @@ -3410,7 +3744,7 @@ checksum = "54681b18a46765f095758388f2d0cf16eb8d4169b639ab575a8f5693af210c7b" dependencies = [ "proc-macro2", "quote", - "syn 2.0.38", + "syn 2.0.60", "wasm-bindgen-backend", "wasm-bindgen-shared", ] @@ -3474,6 +3808,15 @@ dependencies = [ "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" diff --git a/clients/rust/src/broadcast_backup_tx.rs b/clients/rust/src/broadcast_backup_tx.rs index 9680bd0c..0a58c1b8 100644 --- a/clients/rust/src/broadcast_backup_tx.rs +++ b/clients/rust/src/broadcast_backup_tx.rs @@ -55,7 +55,7 @@ pub async fn execute(client_config: &ClientConfig, wallet_name: &str, statechain }, }; - let cpfp_tx = cpfp_tx::create(&backup_tx, &coin, to_address, fee_rate, &wallet.network)?; + let cpfp_tx = cpfp_tx::create_cpfp_tx(&backup_tx, &coin, to_address, fee_rate, &wallet.network)?; let tx_bytes = hex::decode(&backup_tx.tx)?; let txid = client_config.electrum_client.transaction_broadcast_raw(&tx_bytes)?; diff --git a/lib/Cargo.toml b/lib/Cargo.toml index 6b0282af..0cfd68e7 100644 --- a/lib/Cargo.toml +++ b/lib/Cargo.toml @@ -3,7 +3,14 @@ name = "mercurylib" version = "0.1.0" edition = "2021" -# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html +[lib] +crate-type = ["cdylib", "staticlib", "lib"] +name = "mercurylib" + +[[bin]] +name = "uniffi-bindgen" +path = "uniffi-bindgen.rs" +required-features = ["bindings"] [dependencies] bitcoin = { version = "0.30.1", features = ["serde", "base64", "rand-std", "std"], default-features = false } @@ -16,4 +23,9 @@ hex = "0.4.3" serde = { version = "1.0.163", features = ["derive"] } serde_json = "1.0.96" secp256k1-zkp = { git = "https://github.com/ssantos21/rust-secp256k1-zkp.git", branch = "blinded-musig-scheme", features = [ "rand-std", "bitcoin_hashes", "std" ] } -anyhow = "1.0" +uniffi = { version = "0.27.1", features = [ "cli" ], optional = true } +thiserror = "1.0.59" + +[features] +default = [] +bindings = ["uniffi", "uniffi/cli"] diff --git a/lib/modify_sh/modify_all.sh b/lib/modify_sh/modify_all.sh new file mode 100755 index 00000000..643ee346 --- /dev/null +++ b/lib/modify_sh/modify_all.sh @@ -0,0 +1,17 @@ +./modify_sh/modify_kt_file.sh +./modify_sh/modify_token.sh +./modify_sh/modify_deposit_msg1.sh +./modify_sh/modify_deposit_msg_response.sh +./modify_sh/modify_sign_first_request_payload.sh +./modify_sh/modify_sign_first_response_payload.sh +./modify_sh/modify_partial_signature_request_payload.sh +./modify_sh/modify_partial_signature_response_payload.sh +./modify_sh/modify_transfer_sender_request_payload.sh +./modify_sh/modify_transfer_update_msg_request_payload.sh +./modify_sh/modify_get_msg_addr_response_payload.sh +./modify_sh/modify_key_update_response_payload.sh +./modify_sh/modify_statechain_info.sh +./modify_sh/modify_statechainInfo_response_payload.sh +./modify_sh/modify_transfer_receiver_request_payload.sh +./modify_sh/modify_transfer_receiver_response_payload.sh +./modify_sh/modify_transfer_receiver_get_response_payload.sh \ No newline at end of file diff --git a/lib/modify_sh/modify_deposit_msg1.sh b/lib/modify_sh/modify_deposit_msg1.sh new file mode 100755 index 00000000..8451cf1b --- /dev/null +++ b/lib/modify_sh/modify_deposit_msg1.sh @@ -0,0 +1,39 @@ +#!/bin/bash + +# Directory where Kotlin files are located +SEARCH_DIR="out-kotlin/com/mercurylayer" + +# File pattern to search for (assuming all Kotlin files end with .kt) +FILE_PATTERN="*.kt" + +# awk script to add @SerialName within data class Token +add_serial_name() { + local file_path="$1" # Path to the file being processed + + awk ' + BEGIN { in_data_class = 0 } + + /data class DepositMsg1\(/ { in_data_class = 1 } + /^}/ { if (in_data_class) in_data_class = 0 } + + in_data_class && /var `authKey`:/ { + print "\t@SerialName(\"auth_key\")" + } + in_data_class && /var `tokenId`:/ { + print "\t@SerialName(\"token_id\")" + } + in_data_class && /var `signedTokenId`:/ { + print "\t@SerialName(\"signed_token_id\")" + } + + { print } + ' "$file_path" > tmp && mv tmp "$file_path" +} + +# Export the function so it's available to the subshell spawned by find +export -f add_serial_name + +# Use find to locate Kotlin files and process them with the add_serial_name function +find "$SEARCH_DIR" -type f -name "$FILE_PATTERN" -exec bash -c 'add_serial_name "$0"' {} \; + +echo "@SerialName annotations added to DepositMsg1 successfully." diff --git a/lib/modify_sh/modify_deposit_msg_response.sh b/lib/modify_sh/modify_deposit_msg_response.sh new file mode 100755 index 00000000..b539cd18 --- /dev/null +++ b/lib/modify_sh/modify_deposit_msg_response.sh @@ -0,0 +1,36 @@ +#!/bin/bash + +# Directory where Kotlin files are located +SEARCH_DIR="out-kotlin/com/mercurylayer" + +# File pattern to search for (assuming all Kotlin files end with .kt) +FILE_PATTERN="*.kt" + +# awk script to add @SerialName within data class Token +add_serial_name() { + local file_path="$1" # Path to the file being processed + + awk ' + BEGIN { in_data_class = 0 } + + /data class DepositMsg1Response\(/ { in_data_class = 1 } + /^}/ { if (in_data_class) in_data_class = 0 } + + in_data_class && /var `serverPubkey`:/ { + print "\t@SerialName(\"server_pubkey\")" + } + in_data_class && /var `statechainId`:/ { + print "\t@SerialName(\"statechain_id\")" + } + + { print } + ' "$file_path" > tmp && mv tmp "$file_path" +} + +# Export the function so it's available to the subshell spawned by find +export -f add_serial_name + +# Use find to locate Kotlin files and process them with the add_serial_name function +find "$SEARCH_DIR" -type f -name "$FILE_PATTERN" -exec bash -c 'add_serial_name "$0"' {} \; + +echo "@SerialName annotations added to DepositMsg1Response successfully." diff --git a/lib/modify_sh/modify_get_msg_addr_response_payload.sh b/lib/modify_sh/modify_get_msg_addr_response_payload.sh new file mode 100755 index 00000000..ee5f7348 --- /dev/null +++ b/lib/modify_sh/modify_get_msg_addr_response_payload.sh @@ -0,0 +1,33 @@ +#!/bin/bash + +# Directory where Kotlin files are located +SEARCH_DIR="out-kotlin/com/mercurylayer" + +# File pattern to search for (assuming all Kotlin files end with .kt) +FILE_PATTERN="*.kt" + +# awk script to add @SerialName within data class Token +add_serial_name() { + local file_path="$1" # Path to the file being processed + + awk ' + BEGIN { in_data_class = 0 } + + /data class GetMsgAddrResponsePayload\(/ { in_data_class = 1 } + /^}/ { if (in_data_class) in_data_class = 0 } + + in_data_class && /var `listEncTransferMsg`:/ { + print "\t@SerialName(\"list_enc_transfer_msg\")" + } + + { print } + ' "$file_path" > tmp && mv tmp "$file_path" +} + +# Export the function so it's available to the subshell spawned by find +export -f add_serial_name + +# Use find to locate Kotlin files and process them with the add_serial_name function +find "$SEARCH_DIR" -type f -name "$FILE_PATTERN" -exec bash -c 'add_serial_name "$0"' {} \; + +echo "@SerialName annotations added to GetMsgAddrResponsePayload successfully." diff --git a/lib/modify_sh/modify_key_update_response_payload.sh b/lib/modify_sh/modify_key_update_response_payload.sh new file mode 100755 index 00000000..19759032 --- /dev/null +++ b/lib/modify_sh/modify_key_update_response_payload.sh @@ -0,0 +1,33 @@ +#!/bin/bash + +# Directory where Kotlin files are located +SEARCH_DIR="out-kotlin/com/mercurylayer" + +# File pattern to search for (assuming all Kotlin files end with .kt) +FILE_PATTERN="*.kt" + +# awk script to add @SerialName within data class Token +add_serial_name() { + local file_path="$1" # Path to the file being processed + + awk ' + BEGIN { in_data_class = 0 } + + /data class KeyUpdateResponsePayload\(/ { in_data_class = 1 } + /^}/ { if (in_data_class) in_data_class = 0 } + + in_data_class && /var `statechainId`:/ { + print "\t@SerialName(\"statechain_id\")" + } + + { print } + ' "$file_path" > tmp && mv tmp "$file_path" +} + +# Export the function so it's available to the subshell spawned by find +export -f add_serial_name + +# Use find to locate Kotlin files and process them with the add_serial_name function +find "$SEARCH_DIR" -type f -name "$FILE_PATTERN" -exec bash -c 'add_serial_name "$0"' {} \; + +echo "@SerialName annotations added to KeyUpdateResponsePayload successfully." diff --git a/lib/modify_sh/modify_kt_file.sh b/lib/modify_sh/modify_kt_file.sh new file mode 100755 index 00000000..c21479dc --- /dev/null +++ b/lib/modify_sh/modify_kt_file.sh @@ -0,0 +1,83 @@ +#!/bin/bash + +# Directory where the files are located +SEARCH_DIR="out-kotlin/com/mercurylayer" + +# File pattern to search for (e.g., all Kotlin files) +FILE_PATTERN="*.kt" + +# The text to find for adding @Serializable +FIND_TEXT_SERVER_CONFIG="data class ServerConfig(" +FIND_TEXT_WALLET="data class Wallet(" +FIND_TEXT_TOKEN="data class Token(" +FIND_TEXT_ACTIVITY="data class Activity(" +FIND_TEXT_COIN="data class Coin(" +FIND_TEXT_SETTINGS="data class Settings(" +FIND_TEXT_DEPOSIT_MSG1="data class DepositMsg1(" +FIND_TEXT_DEPOSIT_MSG1_RESPONSE="data class DepositMsg1Response(" +FIND_TEXT_DEPOSIT_INIT_RESULT="data class DepositInitResult(" +FIND_TEXT_AGGREGATED_PUBLIC_KEY="data class AggregatedPublicKey(" +FIND_TEXT_SIGN_FIRST_REQUEST_PAYLOAD="data class SignFirstRequestPayload(" +FIND_TEXT_SIGN_FIRST_RESPONSE_PAYLOAD="data class SignFirstResponsePayload(" +FIND_TEXT_PARTIAL_SIGNATURE_REQUEST_PAYLOAD="data class PartialSignatureRequestPayload(" +FIND_TEXT_PARTIAL_SIGNATURE_RESPONSE_PAYLOAD="data class PartialSignatureResponsePayload(" +FIND_TEXT_BACKUP_TX="data class BackupTx(" +FIND_TEXT_TRANSFER_SENDER_REQUEST_PAYLOAD="data class TransferSenderRequestPayload(" +FIND_TEXT_TRANSFER_SENDER_RESPONSE_PAYLOAD="data class TransferSenderResponsePayload(" +FIND_TEXT_TRANSFER_UPDATE_MSG_REQUEST_PAYLOAD="data class TransferUpdateMsgRequestPayload(" +FIND_TEXT_TRANSFER_GET_MSG_ADDR_RESPONSE_PAYLOAD="data class GetMsgAddrResponsePayload(" +FIND_TEXT_TRANSFER_KEY_UPDATE_RESPONSE_PAYLOAD="data class KeyUpdateResponsePayload(" +FIND_TEXT_TRANSFER_STATECHAIN_INFO="data class StatechainInfo(" +FIND_TEXT_TRANSFER_STATECHAIN_INFO_RESPONSE_PAYLOAD="data class StatechainInfoResponsePayload(" +FIND_TEXT_TRANSFER_RECEIVER_REQUEST_PAYLOAD="data class TransferReceiverRequestPayload(" +FIND_TEXT_TRANSFER_RECEIVER_RESPONSE_PAYLOAD="data class TransferReceiverResponsePayload(" +FIND_TEXT_TRANSFER_GET_RECEIVER_RESPONSE_PAYLOAD="data class TransferReceiverGetResponsePayload(" + +# The text to add @Serializable +ADD_TEXT="@Serializable" + +# Text to find for modifying imports +IMPORT_FIND_TEXT="import com.sun.jna.ptr.*" + +# New import text to add +IMPORT_ADD_SERIALIZABLE="import kotlinx.serialization.Serializable" +IMPORT_ADD_SERIALNAME="import kotlinx.serialization.SerialName" + +# Import text to remove. This should be disabled when the folder struct is fixed +PACKAGE_REMOVE_TEXT="package com.mercurylayer" + +# Using find to locate Kotlin files and sed to modify them +find "$SEARCH_DIR" -type f -name "$FILE_PATTERN" -exec sed -i \ + -e "/$FIND_TEXT_SERVER_CONFIG/i $ADD_TEXT" \ + -e "/$FIND_TEXT_WALLET/i $ADD_TEXT" \ + -e "/$FIND_TEXT_TOKEN/i $ADD_TEXT" \ + -e "/$FIND_TEXT_ACTIVITY/i $ADD_TEXT" \ + -e "/$FIND_TEXT_COIN/i $ADD_TEXT" \ + -e "/$FIND_TEXT_SETTINGS/i $ADD_TEXT" \ + -e "/$FIND_TEXT_DEPOSIT_MSG1/i $ADD_TEXT" \ + -e "/$FIND_TEXT_DEPOSIT_MSG1_RESPONSE/i $ADD_TEXT" \ + -e "/$FIND_TEXT_DEPOSIT_INIT_RESULT/i $ADD_TEXT" \ + -e "/$FIND_TEXT_AGGREGATED_PUBLIC_KEY/i $ADD_TEXT" \ + -e "/$FIND_TEXT_SIGN_FIRST_REQUEST_PAYLOAD/i $ADD_TEXT" \ + -e "/$FIND_TEXT_SIGN_FIRST_RESPONSE_PAYLOAD/i $ADD_TEXT" \ + -e "/$FIND_TEXT_PARTIAL_SIGNATURE_REQUEST_PAYLOAD/i $ADD_TEXT" \ + -e "/$FIND_TEXT_PARTIAL_SIGNATURE_RESPONSE_PAYLOAD/i $ADD_TEXT" \ + -e "/$FIND_TEXT_BACKUP_TX/i $ADD_TEXT" \ + -e "/$FIND_TEXT_TRANSFER_SENDER_REQUEST_PAYLOAD/i $ADD_TEXT" \ + -e "/$FIND_TEXT_TRANSFER_SENDER_RESPONSE_PAYLOAD/i $ADD_TEXT" \ + -e "/$FIND_TEXT_TRANSFER_UPDATE_MSG_REQUEST_PAYLOAD/i $ADD_TEXT" \ + -e "/$FIND_TEXT_TRANSFER_GET_MSG_ADDR_RESPONSE_PAYLOAD/i $ADD_TEXT" \ + -e "/$FIND_TEXT_TRANSFER_KEY_UPDATE_RESPONSE_PAYLOAD/i $ADD_TEXT" \ + -e "/$FIND_TEXT_TRANSFER_STATECHAIN_INFO/i $ADD_TEXT" \ + -e "/$FIND_TEXT_TRANSFER_STATECHAIN_INFO_RESPONSE_PAYLOAD/i $ADD_TEXT" \ + -e "/$FIND_TEXT_TRANSFER_RECEIVER_REQUEST_PAYLOAD/i $ADD_TEXT" \ + -e "/$FIND_TEXT_TRANSFER_RECEIVER_RESPONSE_PAYLOAD/i $ADD_TEXT" \ + -e "/$FIND_TEXT_TRANSFER_GET_RECEIVER_RESPONSE_PAYLOAD/i $ADD_TEXT" \ + -e "/$IMPORT_FIND_TEXT$/ { + n; + /$IMPORT_ADD_SERIALIZABLE/!i $IMPORT_ADD_SERIALIZABLE + /$IMPORT_ADD_SERIALNAME/!i $IMPORT_ADD_SERIALNAME + }" \ + -e "/$PACKAGE_REMOVE_TEXT/d" {} + + +echo "@Serializable annotations added successfully." diff --git a/lib/modify_sh/modify_partial_signature_request_payload.sh b/lib/modify_sh/modify_partial_signature_request_payload.sh new file mode 100755 index 00000000..6484d362 --- /dev/null +++ b/lib/modify_sh/modify_partial_signature_request_payload.sh @@ -0,0 +1,42 @@ +#!/bin/bash + +# Directory where Kotlin files are located +SEARCH_DIR="out-kotlin/com/mercurylayer" + +# File pattern to search for (assuming all Kotlin files end with .kt) +FILE_PATTERN="*.kt" + +# awk script to add @SerialName within data class Token +add_serial_name() { + local file_path="$1" # Path to the file being processed + + awk ' + BEGIN { in_data_class = 0 } + + /data class PartialSignatureRequestPayload\(/ { in_data_class = 1 } + /^}/ { if (in_data_class) in_data_class = 0 } + + in_data_class && /var `statechainId`:/ { + print "\t@SerialName(\"statechain_id\")" + } + in_data_class && /var `negateSeckey`:/ { + print "\t@SerialName(\"negate_seckey\")" + } + in_data_class && /var `signedStatechainId`:/ { + print "\t@SerialName(\"signed_statechain_id\")" + } + in_data_class && /var `serverPubNonce`:/ { + print "\t@SerialName(\"server_pub_nonce\")" + } + + { print } + ' "$file_path" > tmp && mv tmp "$file_path" +} + +# Export the function so it's available to the subshell spawned by find +export -f add_serial_name + +# Use find to locate Kotlin files and process them with the add_serial_name function +find "$SEARCH_DIR" -type f -name "$FILE_PATTERN" -exec bash -c 'add_serial_name "$0"' {} \; + +echo "@SerialName annotations added to PartialSignatureRequestPayload successfully." diff --git a/lib/modify_sh/modify_partial_signature_response_payload.sh b/lib/modify_sh/modify_partial_signature_response_payload.sh new file mode 100755 index 00000000..56f378dd --- /dev/null +++ b/lib/modify_sh/modify_partial_signature_response_payload.sh @@ -0,0 +1,33 @@ +#!/bin/bash + +# Directory where Kotlin files are located +SEARCH_DIR="out-kotlin/com/mercurylayer" + +# File pattern to search for (assuming all Kotlin files end with .kt) +FILE_PATTERN="*.kt" + +# awk script to add @SerialName within data class Token +add_serial_name() { + local file_path="$1" # Path to the file being processed + + awk ' + BEGIN { in_data_class = 0 } + + /data class PartialSignatureResponsePayload\(/ { in_data_class = 1 } + /^}/ { if (in_data_class) in_data_class = 0 } + + in_data_class && /var `partialSig`:/ { + print "\t@SerialName(\"partial_sig\")" + } + + { print } + ' "$file_path" > tmp && mv tmp "$file_path" +} + +# Export the function so it's available to the subshell spawned by find +export -f add_serial_name + +# Use find to locate Kotlin files and process them with the add_serial_name function +find "$SEARCH_DIR" -type f -name "$FILE_PATTERN" -exec bash -c 'add_serial_name "$0"' {} \; + +echo "@SerialName annotations added to PartialSignatureResponsePayload successfully." diff --git a/lib/modify_sh/modify_sign_first_request_payload.sh b/lib/modify_sh/modify_sign_first_request_payload.sh new file mode 100755 index 00000000..b7601cbf --- /dev/null +++ b/lib/modify_sh/modify_sign_first_request_payload.sh @@ -0,0 +1,36 @@ +#!/bin/bash + +# Directory where Kotlin files are located +SEARCH_DIR="out-kotlin/com/mercurylayer" + +# File pattern to search for (assuming all Kotlin files end with .kt) +FILE_PATTERN="*.kt" + +# awk script to add @SerialName within data class Token +add_serial_name() { + local file_path="$1" # Path to the file being processed + + awk ' + BEGIN { in_data_class = 0 } + + /data class SignFirstRequestPayload\(/ { in_data_class = 1 } + /^}/ { if (in_data_class) in_data_class = 0 } + + in_data_class && /var `statechainId`:/ { + print "\t@SerialName(\"statechain_id\")" + } + in_data_class && /var `signedStatechainId`:/ { + print "\t@SerialName(\"signed_statechain_id\")" + } + + { print } + ' "$file_path" > tmp && mv tmp "$file_path" +} + +# Export the function so it's available to the subshell spawned by find +export -f add_serial_name + +# Use find to locate Kotlin files and process them with the add_serial_name function +find "$SEARCH_DIR" -type f -name "$FILE_PATTERN" -exec bash -c 'add_serial_name "$0"' {} \; + +echo "@SerialName annotations added to SignFirstRequestPayload successfully." diff --git a/lib/modify_sh/modify_sign_first_response_payload.sh b/lib/modify_sh/modify_sign_first_response_payload.sh new file mode 100755 index 00000000..f56e4a7e --- /dev/null +++ b/lib/modify_sh/modify_sign_first_response_payload.sh @@ -0,0 +1,33 @@ +#!/bin/bash + +# Directory where Kotlin files are located +SEARCH_DIR="out-kotlin/com/mercurylayer" + +# File pattern to search for (assuming all Kotlin files end with .kt) +FILE_PATTERN="*.kt" + +# awk script to add @SerialName within data class Token +add_serial_name() { + local file_path="$1" # Path to the file being processed + + awk ' + BEGIN { in_data_class = 0 } + + /data class SignFirstResponsePayload\(/ { in_data_class = 1 } + /^}/ { if (in_data_class) in_data_class = 0 } + + in_data_class && /var `serverPubnonce`:/ { + print "\t@SerialName(\"server_pubnonce\")" + } + + { print } + ' "$file_path" > tmp && mv tmp "$file_path" +} + +# Export the function so it's available to the subshell spawned by find +export -f add_serial_name + +# Use find to locate Kotlin files and process them with the add_serial_name function +find "$SEARCH_DIR" -type f -name "$FILE_PATTERN" -exec bash -c 'add_serial_name "$0"' {} \; + +echo "@SerialName annotations added to SignFirstResponsePayload successfully." diff --git a/lib/modify_sh/modify_statechainInfo_response_payload.sh b/lib/modify_sh/modify_statechainInfo_response_payload.sh new file mode 100755 index 00000000..6c821cd4 --- /dev/null +++ b/lib/modify_sh/modify_statechainInfo_response_payload.sh @@ -0,0 +1,42 @@ +#!/bin/bash + +# Directory where Kotlin files are located +SEARCH_DIR="out-kotlin/com/mercurylayer" + +# File pattern to search for (assuming all Kotlin files end with .kt) +FILE_PATTERN="*.kt" + +# awk script to add @SerialName within data class Token +add_serial_name() { + local file_path="$1" # Path to the file being processed + + awk ' + BEGIN { in_data_class = 0 } + + /data class StatechainInfoResponsePayload\(/ { in_data_class = 1 } + /^}/ { if (in_data_class) in_data_class = 0 } + + in_data_class && /var `enclavePublicKey`:/ { + print "\t@SerialName(\"enclave_public_key\")" + } + in_data_class && /var `numSigs`:/ { + print "\t@SerialName(\"num_sigs\")" + } + in_data_class && /var `statechainInfo`:/ { + print "\t@SerialName(\"statechain_info\")" + } + in_data_class && /var `x1Pub`:/ { + print "\t@SerialName(\"x1_pub\")" + } + + { print } + ' "$file_path" > tmp && mv tmp "$file_path" +} + +# Export the function so it's available to the subshell spawned by find +export -f add_serial_name + +# Use find to locate Kotlin files and process them with the add_serial_name function +find "$SEARCH_DIR" -type f -name "$FILE_PATTERN" -exec bash -c 'add_serial_name "$0"' {} \; + +echo "@SerialName annotations added to StatechainInfoResponsePayload successfully." diff --git a/lib/modify_sh/modify_statechain_info.sh b/lib/modify_sh/modify_statechain_info.sh new file mode 100755 index 00000000..77a8f38a --- /dev/null +++ b/lib/modify_sh/modify_statechain_info.sh @@ -0,0 +1,39 @@ +#!/bin/bash + +# Directory where Kotlin files are located +SEARCH_DIR="out-kotlin/com/mercurylayer" + +# File pattern to search for (assuming all Kotlin files end with .kt) +FILE_PATTERN="*.kt" + +# awk script to add @SerialName within data class Token +add_serial_name() { + local file_path="$1" # Path to the file being processed + + awk ' + BEGIN { in_data_class = 0 } + + /data class StatechainInfo\(/ { in_data_class = 1 } + /^}/ { if (in_data_class) in_data_class = 0 } + + in_data_class && /var `statechainId`:/ { + print "\t@SerialName(\"statechain_id\")" + } + in_data_class && /var `serverPubnonce`:/ { + print "\t@SerialName(\"server_pubnonce\")" + } + in_data_class && /var `txN`:/ { + print "\t@SerialName(\"tx_n\")" + } + + { print } + ' "$file_path" > tmp && mv tmp "$file_path" +} + +# Export the function so it's available to the subshell spawned by find +export -f add_serial_name + +# Use find to locate Kotlin files and process them with the add_serial_name function +find "$SEARCH_DIR" -type f -name "$FILE_PATTERN" -exec bash -c 'add_serial_name "$0"' {} \; + +echo "@SerialName annotations added to StatechainInfo successfully." diff --git a/lib/modify_sh/modify_token.sh b/lib/modify_sh/modify_token.sh new file mode 100755 index 00000000..c3c2b0ef --- /dev/null +++ b/lib/modify_sh/modify_token.sh @@ -0,0 +1,71 @@ +#!/bin/bash + +# # Directory where Kotlin files are located +# SEARCH_DIR="/path/to/kotlin/files" + +# # File pattern to search for (assuming all Kotlin files end with .kt) +# FILE_PATTERN="*.kt" + +# # Function to prepend @SerialName to fields in data class Token +# add_serial_name() { +# local file_path="$1" # Path to the file being processed + +# # Use sed to insert @SerialName annotations +# sed -i '' \ +# -e '/var `btcPaymentAddress`:/i @SerialName("btc_payment_address")' \ +# -e '/var `lightningInvoice`:/i @SerialName("lightning_invoice")' \ +# -e '/var `processorId`:/i @SerialName("processor_id")' \ +# -e '/var `tokenId`:/i @SerialName("token_id")' \ +# "$file_path" +# } + +# # Export the function so it's available to the subshell spawned by find +# export -f add_serial_name + +# # Use find to locate Kotlin files and process them with the add_serial_name function +# find "$SEARCH_DIR" -type f -name "$FILE_PATTERN" -exec bash -c 'add_serial_name "$0"' {} \; + +# echo "Annotation modification complete." + +#!/bin/bash + +# Directory where Kotlin files are located +SEARCH_DIR="out-kotlin/com/mercurylayer" + +# File pattern to search for (assuming all Kotlin files end with .kt) +FILE_PATTERN="*.kt" + +# awk script to add @SerialName within data class Token +add_serial_name() { + local file_path="$1" # Path to the file being processed + + awk ' + BEGIN { in_data_class = 0 } + + /data class Token\(/ { in_data_class = 1 } + /^}/ { if (in_data_class) in_data_class = 0 } + + in_data_class && /var `btcPaymentAddress`:/ { + print "\t@SerialName(\"btc_payment_address\")" + } + in_data_class && /var `lightningInvoice`:/ { + print "\t@SerialName(\"lightning_invoice\")" + } + in_data_class && /var `processorId`:/ { + print "\t@SerialName(\"processor_id\")" + } + in_data_class && /var `tokenId`:/ { + print "\t@SerialName(\"token_id\")" + } + + { print } + ' "$file_path" > tmp && mv tmp "$file_path" +} + +# Export the function so it's available to the subshell spawned by find +export -f add_serial_name + +# Use find to locate Kotlin files and process them with the add_serial_name function +find "$SEARCH_DIR" -type f -name "$FILE_PATTERN" -exec bash -c 'add_serial_name "$0"' {} \; + +echo "@SerialName annotations added to Token successfully." diff --git a/lib/modify_sh/modify_transfer_receiver_get_response_payload.sh b/lib/modify_sh/modify_transfer_receiver_get_response_payload.sh new file mode 100755 index 00000000..045a501a --- /dev/null +++ b/lib/modify_sh/modify_transfer_receiver_get_response_payload.sh @@ -0,0 +1,33 @@ +#!/bin/bash + +# Directory where Kotlin files are located +SEARCH_DIR="out-kotlin/com/mercurylayer" + +# File pattern to search for (assuming all Kotlin files end with .kt) +FILE_PATTERN="*.kt" + +# awk script to add @SerialName within data class Token +add_serial_name() { + local file_path="$1" # Path to the file being processed + + awk ' + BEGIN { in_data_class = 0 } + + /data class TransferReceiverGetResponsePayload\(/ { in_data_class = 1 } + /^}/ { if (in_data_class) in_data_class = 0 } + + in_data_class && /var `transferComplete`:/ { + print "\t@SerialName(\"transfer_complete\")" + } + + { print } + ' "$file_path" > tmp && mv tmp "$file_path" +} + +# Export the function so it's available to the subshell spawned by find +export -f add_serial_name + +# Use find to locate Kotlin files and process them with the add_serial_name function +find "$SEARCH_DIR" -type f -name "$FILE_PATTERN" -exec bash -c 'add_serial_name "$0"' {} \; + +echo "@SerialName annotations added to TransferReceiverGetResponsePayload successfully." diff --git a/lib/modify_sh/modify_transfer_receiver_request_payload.sh b/lib/modify_sh/modify_transfer_receiver_request_payload.sh new file mode 100755 index 00000000..d112b8fd --- /dev/null +++ b/lib/modify_sh/modify_transfer_receiver_request_payload.sh @@ -0,0 +1,39 @@ +#!/bin/bash + +# Directory where Kotlin files are located +SEARCH_DIR="out-kotlin/com/mercurylayer" + +# File pattern to search for (assuming all Kotlin files end with .kt) +FILE_PATTERN="*.kt" + +# awk script to add @SerialName within data class Token +add_serial_name() { + local file_path="$1" # Path to the file being processed + + awk ' + BEGIN { in_data_class = 0 } + + /data class TransferReceiverRequestPayload\(/ { in_data_class = 1 } + /^}/ { if (in_data_class) in_data_class = 0 } + + in_data_class && /var `statechainId`:/ { + print "\t@SerialName(\"statechain_id\")" + } + in_data_class && /var `batchData`:/ { + print "\t@SerialName(\"batch_data\")" + } + in_data_class && /var `authSig`:/ { + print "\t@SerialName(\"auth_sig\")" + } + + { print } + ' "$file_path" > tmp && mv tmp "$file_path" +} + +# Export the function so it's available to the subshell spawned by find +export -f add_serial_name + +# Use find to locate Kotlin files and process them with the add_serial_name function +find "$SEARCH_DIR" -type f -name "$FILE_PATTERN" -exec bash -c 'add_serial_name "$0"' {} \; + +echo "@SerialName annotations added to TransferReceiverRequestPayload successfully." diff --git a/lib/modify_sh/modify_transfer_receiver_response_payload.sh b/lib/modify_sh/modify_transfer_receiver_response_payload.sh new file mode 100755 index 00000000..04437733 --- /dev/null +++ b/lib/modify_sh/modify_transfer_receiver_response_payload.sh @@ -0,0 +1,33 @@ +#!/bin/bash + +# Directory where Kotlin files are located +SEARCH_DIR="out-kotlin/com/mercurylayer" + +# File pattern to search for (assuming all Kotlin files end with .kt) +FILE_PATTERN="*.kt" + +# awk script to add @SerialName within data class Token +add_serial_name() { + local file_path="$1" # Path to the file being processed + + awk ' + BEGIN { in_data_class = 0 } + + /data class TransferReceiverResponsePayload\(/ { in_data_class = 1 } + /^}/ { if (in_data_class) in_data_class = 0 } + + in_data_class && /var `serverPubkey`:/ { + print "\t@SerialName(\"server_pubkey\")" + } + + { print } + ' "$file_path" > tmp && mv tmp "$file_path" +} + +# Export the function so it's available to the subshell spawned by find +export -f add_serial_name + +# Use find to locate Kotlin files and process them with the add_serial_name function +find "$SEARCH_DIR" -type f -name "$FILE_PATTERN" -exec bash -c 'add_serial_name "$0"' {} \; + +echo "@SerialName annotations added to TransferReceiverResponsePayload successfully." diff --git a/lib/modify_sh/modify_transfer_sender_request_payload.sh b/lib/modify_sh/modify_transfer_sender_request_payload.sh new file mode 100755 index 00000000..75cd172a --- /dev/null +++ b/lib/modify_sh/modify_transfer_sender_request_payload.sh @@ -0,0 +1,42 @@ +#!/bin/bash + +# Directory where Kotlin files are located +SEARCH_DIR="out-kotlin/com/mercurylayer" + +# File pattern to search for (assuming all Kotlin files end with .kt) +FILE_PATTERN="*.kt" + +# awk script to add @SerialName within data class Token +add_serial_name() { + local file_path="$1" # Path to the file being processed + + awk ' + BEGIN { in_data_class = 0 } + + /data class TransferSenderRequestPayload\(/ { in_data_class = 1 } + /^}/ { if (in_data_class) in_data_class = 0 } + + in_data_class && /var `statechainId`:/ { + print "\t@SerialName(\"statechain_id\")" + } + in_data_class && /var `authSig`:/ { + print "\t@SerialName(\"auth_sig\")" + } + in_data_class && /var `newUserAuthKey`:/ { + print "\t@SerialName(\"new_user_auth_key\")" + } + in_data_class && /var `batchId`:/ { + print "\t@SerialName(\"batch_id\")" + } + + { print } + ' "$file_path" > tmp && mv tmp "$file_path" +} + +# Export the function so it's available to the subshell spawned by find +export -f add_serial_name + +# Use find to locate Kotlin files and process them with the add_serial_name function +find "$SEARCH_DIR" -type f -name "$FILE_PATTERN" -exec bash -c 'add_serial_name "$0"' {} \; + +echo "@SerialName annotations added to TransferSenderRequestPayload successfully." diff --git a/lib/modify_sh/modify_transfer_update_msg_request_payload.sh b/lib/modify_sh/modify_transfer_update_msg_request_payload.sh new file mode 100755 index 00000000..b73e2dfe --- /dev/null +++ b/lib/modify_sh/modify_transfer_update_msg_request_payload.sh @@ -0,0 +1,42 @@ +#!/bin/bash + +# Directory where Kotlin files are located +SEARCH_DIR="out-kotlin/com/mercurylayer" + +# File pattern to search for (assuming all Kotlin files end with .kt) +FILE_PATTERN="*.kt" + +# awk script to add @SerialName within data class Token +add_serial_name() { + local file_path="$1" # Path to the file being processed + + awk ' + BEGIN { in_data_class = 0 } + + /data class TransferUpdateMsgRequestPayload\(/ { in_data_class = 1 } + /^}/ { if (in_data_class) in_data_class = 0 } + + in_data_class && /var `statechainId`:/ { + print "\t@SerialName(\"statechain_id\")" + } + in_data_class && /var `authSig`:/ { + print "\t@SerialName(\"auth_sig\")" + } + in_data_class && /var `newUserAuthKey`:/ { + print "\t@SerialName(\"new_user_auth_key\")" + } + in_data_class && /var `encTransferMsg`:/ { + print "\t@SerialName(\"enc_transfer_msg\")" + } + + { print } + ' "$file_path" > tmp && mv tmp "$file_path" +} + +# Export the function so it's available to the subshell spawned by find +export -f add_serial_name + +# Use find to locate Kotlin files and process them with the add_serial_name function +find "$SEARCH_DIR" -type f -name "$FILE_PATTERN" -exec bash -c 'add_serial_name "$0"' {} \; + +echo "@SerialName annotations added to TransferUpdateMsgRequestPayload successfully." diff --git a/lib/out-kotlin/com/mercurylayer/mercurylib.kt b/lib/out-kotlin/com/mercurylayer/mercurylib.kt new file mode 100644 index 00000000..fc7bdb9c --- /dev/null +++ b/lib/out-kotlin/com/mercurylayer/mercurylib.kt @@ -0,0 +1,4288 @@ +// 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_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_new_backup_transaction( + `encodedUnsignedTx`: RustBuffer.ByValue, + `signatureHex`: 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_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_new_backup_transaction(): 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_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_new_backup_transaction() != 56642.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), + FfiConverterString.read(buf), + ) + } + + override fun allocationSize(value: StatechainInfoResponsePayload) = + ( + FfiConverterString.allocationSize(value.`enclavePublicKey`) + + FfiConverterUInt.allocationSize(value.`numSigs`) + + FfiConverterSequenceTypeStatechainInfo.allocationSize(value.`statechainInfo`) + + FfiConverterString.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) + FfiConverterString.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 TransferReceiverGetResponsePayload( + @SerialName("transfer_complete") + var `transferComplete`: kotlin.Boolean, +) { + companion object +} + +public object FfiConverterTypeTransferReceiverGetResponsePayload : FfiConverterRustBuffer { + override fun read(buf: ByteBuffer): TransferReceiverGetResponsePayload { + return TransferReceiverGetResponsePayload( + FfiConverterBoolean.read(buf), + ) + } + + override fun allocationSize(value: TransferReceiverGetResponsePayload) = + ( + FfiConverterBoolean.allocationSize(value.`transferComplete`) + ) + + override fun write( + value: TransferReceiverGetResponsePayload, + buf: ByteBuffer, + ) { + FfiConverterBoolean.write(value.`transferComplete`, 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 TransferReceiverResponsePayload( + @SerialName("server_pubkey") + var `serverPubkey`: kotlin.String, +) { + companion object +} + +public object FfiConverterTypeTransferReceiverResponsePayload : FfiConverterRustBuffer { + override fun read(buf: ByteBuffer): TransferReceiverResponsePayload { + return TransferReceiverResponsePayload( + FfiConverterString.read(buf), + ) + } + + override fun allocationSize(value: TransferReceiverResponsePayload) = + ( + FfiConverterString.allocationSize(value.`serverPubkey`) + ) + + override fun write( + value: TransferReceiverResponsePayload, + buf: ByteBuffer, + ) { + FfiConverterString.write(value.`serverPubkey`, 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 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) + } +} + +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() = "" + } + + 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() + 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 + ) + } + } + + 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 + } + }.let { /* this makes the `when` an expression, which ensures it is exhaustive */ } + } +} + +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 `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 `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 `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/lib/rust-toolchain.toml b/lib/rust-toolchain.toml new file mode 100644 index 00000000..624eb0ea --- /dev/null +++ b/lib/rust-toolchain.toml @@ -0,0 +1,2 @@ +[toolchain] +channel = "1.76.0" diff --git a/lib/src/deposit/mod.rs b/lib/src/deposit/mod.rs index ae7b9ae0..57191a61 100644 --- a/lib/src/deposit/mod.rs +++ b/lib/src/deposit/mod.rs @@ -1,7 +1,6 @@ use std::str::FromStr; -use crate::{wallet::Coin, utils::get_network}; -use anyhow::Result; +use crate::{error::MercuryError, utils::get_network, wallet::Coin}; use bitcoin::{hashes::sha256, PrivateKey, secp256k1, Address}; use secp256k1_zkp::{Message, Secp256k1, PublicKey}; use serde::{Serialize, Deserialize}; @@ -12,6 +11,7 @@ pub struct TokenID { } #[derive(Debug, Serialize, Deserialize)] +#[cfg_attr(feature = "bindings", derive(uniffi::Record))] pub struct DepositMsg1 { pub auth_key: String, pub token_id: String, @@ -19,12 +19,14 @@ pub struct DepositMsg1 { } #[derive(Debug, Serialize, Deserialize)] +#[cfg_attr(feature = "bindings", derive(uniffi::Record))] pub struct DepositMsg1Response { pub server_pubkey: String, pub statechain_id: String, } #[derive(Debug, Serialize, Deserialize)] +#[cfg_attr(feature = "bindings", derive(uniffi::Record))] pub struct DepositInitResult { pub server_pubkey: String, pub statechain_id: String, @@ -32,12 +34,14 @@ pub struct DepositInitResult { } #[derive(Debug, Serialize, Deserialize)] +#[cfg_attr(feature = "bindings", derive(uniffi::Record))] pub struct AggregatedPublicKey { pub aggregate_pubkey: String, pub aggregate_address: String, } -pub fn create_deposit_msg1(coin: &Coin, token_id: &str) -> Result{ +#[cfg_attr(feature = "bindings", uniffi::export)] +pub fn create_deposit_msg1(coin: &Coin, token_id: &str) -> Result{ let msg = Message::from_hashed_data::(token_id.to_string().as_bytes()); let secp = Secp256k1::new(); @@ -56,7 +60,8 @@ pub fn create_deposit_msg1(coin: &Coin, token_id: &str) -> Result{ Ok(deposit_msg_1) } -pub fn handle_deposit_msg_1_response(coin: &Coin, deposit_msg_1_response: &DepositMsg1Response) -> Result { +#[cfg_attr(feature = "bindings", uniffi::export)] +pub fn handle_deposit_msg_1_response(coin: &Coin, deposit_msg_1_response: &DepositMsg1Response) -> Result { let secp = Secp256k1::new(); @@ -77,7 +82,8 @@ pub fn handle_deposit_msg_1_response(coin: &Coin, deposit_msg_1_response: &Depos }) } -pub fn create_aggregated_address(coin: &Coin, network: String) -> Result { +#[cfg_attr(feature = "bindings", uniffi::export)] +pub fn create_aggregated_address(coin: &Coin, network: String) -> Result { let network = get_network(&network)?; diff --git a/lib/src/error.rs b/lib/src/error.rs new file mode 100644 index 00000000..a16baacb --- /dev/null +++ b/lib/src/error.rs @@ -0,0 +1,199 @@ +/* +The simplified struct below cannot be used because the errors from other libs are not compatible with uniffi. +TODO: Look for a way to make the errors compatible with uniffi. + +#[derive(Debug, thiserror::Error)] +#[cfg_attr(feature = "bindings", derive(uniffi::Error))] +pub enum MercuryError { + #[error("BIP39 Error: {0}")] + Bip39Error(#[from] bip39::Error), + + #[error("BIP32 Error: {0}")] + Bip32Error(#[from] bip32::Error), + + #[error("Invalid bitcoin network: `{0}`")] + NetworkConversionError(String), + + #[error("Secp256k1UpstreamError Error: {0}")] + Secp256k1UpstreamError(#[from] UpstreamError), + + #[error("KeyError Error: {0}")] + KeyError(#[from] bitcoin::key::Error), + + #[error("Bech32Error Error: {0}")] + Bech32Error(#[from] bech32::Error), +} + */ + +use bitcoin::{bip32, sighash::SighashTypeParseError}; +use ecies::SecpError; +use secp256k1_zkp::{musig::{MusigNonceGenError, MusigSignError, ParseError}, scalar::OutOfRangeError, UpstreamError}; + +// TODO: UniFFI apparently does not support adding fields to the error enum variants. +// For example, NetworkConversionError(String) is not supported. +// This makes it impossible to detail the error message. Look into this issue. + +#[derive(Debug, thiserror::Error)] +#[cfg_attr(feature = "bindings", derive(uniffi::Error))] +pub enum MercuryError { + Bip39Error, + Bip32Error, + NetworkConversionError, + Secp256k1UpstreamError, + KeyError, + Bech32Error, + HexError, + LocktimeNotBlockHeightError, + BitcoinConsensusEncodeError, + MusigNonceGenError, + InvalidStatechainAddressError, + InvalidBitcoinAddressError, + StatechainAddressMismatchNetworkError, + BitcoinAddressMismatchNetworkError, + BitcoinAddressError, + BitcoinAbsoluteError, + BitcoinHashHexError, + BitcoinPsbtError, + SighashTypeParseError, + BitcoinSighashError, + ParseError, + MusigSignError, + SchnorrSignatureValidationError, + MoreThanOneInputError, + UnkownNetwork, + BackupTransactionDoesNotPayUser, + FeeTooHigh, + FeeTooLow, + OutOfRangeError, + SerdeJsonError, + SecpError, + NoBackupTransactionFound, + Tx1HasMoreThanOneInput, + InvalidSignature, + EmptyWitness, + EmptyWitnessData, + IncorrectChallenge, + InvalidT1, + IncorrectAggregatedPublicKey, + T1MustBeExactly32BytesError, +} + +impl core::fmt::Display for MercuryError { + fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { + f.write_fmt(format_args!("{:?}", self)) + } +} + +impl From for MercuryError { + fn from(_: bip39::Error) -> Self { + MercuryError::Bip39Error + } +} + +impl From for MercuryError { + fn from(_: bip32::Error) -> Self { + MercuryError::Bip32Error + } +} + +impl From for MercuryError { + fn from(_: UpstreamError) -> Self { + MercuryError::Secp256k1UpstreamError + } +} + +impl From for MercuryError { + fn from(_: bitcoin::key::Error) -> Self { + MercuryError::KeyError + } +} + +impl From for MercuryError { + fn from(_: bech32::Error) -> Self { + MercuryError::Bech32Error + } +} + +impl From for MercuryError { + fn from(_: hex::FromHexError) -> Self { + MercuryError::HexError + } +} + +impl From for MercuryError { + fn from(_: bitcoin::consensus::encode::Error) -> Self { + MercuryError::BitcoinConsensusEncodeError + } +} + +impl From for MercuryError { + fn from(_: MusigNonceGenError) -> Self { + MercuryError::MusigNonceGenError + } +} + +impl From for MercuryError { + fn from(_: bitcoin::address::Error) -> Self { + MercuryError::BitcoinAddressError + } +} + +impl From for MercuryError { + fn from(_: bitcoin::absolute::Error) -> Self { + MercuryError::BitcoinAbsoluteError + } +} + +impl From for MercuryError { + fn from(_: bitcoin::hashes::hex::Error) -> Self { + MercuryError::BitcoinHashHexError + } +} + +impl From for MercuryError { + fn from(_: bitcoin::psbt::Error) -> Self { + MercuryError::BitcoinPsbtError + } +} + +impl From for MercuryError { + fn from(_: SighashTypeParseError) -> Self { + MercuryError::SighashTypeParseError + } +} + +impl From for MercuryError { + fn from(_: bitcoin::sighash::Error) -> Self { + MercuryError::BitcoinSighashError + } +} + +impl From for MercuryError { + fn from(_: ParseError) -> Self { + MercuryError::ParseError + } +} + +impl From for MercuryError { + fn from(_: MusigSignError) -> Self { + MercuryError::MusigSignError + } +} + +impl From for MercuryError { + fn from(_: OutOfRangeError) -> Self { + MercuryError::OutOfRangeError + } +} + +impl From for MercuryError { + fn from(_: serde_json::Error) -> Self { + MercuryError::SerdeJsonError + } +} + +impl From for MercuryError { + fn from(_: SecpError) -> Self { + MercuryError::SecpError + } +} diff --git a/lib/src/lib.rs b/lib/src/lib.rs index e2f0b07a..54047a91 100644 --- a/lib/src/lib.rs +++ b/lib/src/lib.rs @@ -4,6 +4,8 @@ pub mod withdraw; pub mod wallet; pub mod utils; pub mod transaction; +pub mod unifii_interface; +pub mod error; use std::str::FromStr; @@ -11,12 +13,15 @@ use bech32::{Variant, ToBase32, FromBase32}; use bip39::Mnemonic; use bitcoin::{bip32::{ChildNumber, DerivationPath, ExtendedPrivKey}, secp256k1::{ffi::types::AlignedType, AllPreallocated, PublicKey, Secp256k1, SecretKey}, Address}; -use anyhow::{anyhow, Result}; +use error::MercuryError; + +#[cfg(feature = "bindings")] +uniffi::setup_scaffolding!(); const MAINNET_HRP : &str = "ml"; const TESTNET_HRP : &str = "tml"; -pub fn encode_sc_address(user_pubkey: &PublicKey, auth_pubkey: &PublicKey, network: bitcoin::Network) -> Result { +pub fn encode_sc_address(user_pubkey: &PublicKey, auth_pubkey: &PublicKey, network: bitcoin::Network) -> core::result::Result { let mut hrp = TESTNET_HRP; @@ -36,15 +41,15 @@ pub fn encode_sc_address(user_pubkey: &PublicKey, auth_pubkey: &PublicKey, netwo Ok(encoded) } -pub fn decode_transfer_address(sc_address: &str) -> Result<(u8, PublicKey, PublicKey)> { +pub fn decode_transfer_address(sc_address: &str) -> core::result::Result<(u8, PublicKey, PublicKey), MercuryError> { let (hrp, data, variant) = bech32::decode(sc_address)?; if hrp != MAINNET_HRP && hrp != TESTNET_HRP { - return Err(anyhow!("Invalid SC address".to_string())); + return Err(MercuryError::InvalidStatechainAddressError); } if variant != Variant::Bech32m { - return Err(anyhow!("Invalid address".to_string())); + return Err(MercuryError::InvalidBitcoinAddressError); } let decoded_data = Vec::::from_base32(&data)?; @@ -56,7 +61,7 @@ pub fn decode_transfer_address(sc_address: &str) -> Result<(u8, PublicKey, Publi Ok((version, user_pubkey, auth_pubkey)) } -fn get_key(secp: &Secp256k1>, root: ExtendedPrivKey, derivation_path: &str, change_index: u32, address_index:u32) -> Result { +fn get_key(secp: &Secp256k1>, root: ExtendedPrivKey, derivation_path: &str, change_index: u32, address_index:u32) -> core::result::Result { // derive child xpub let path = DerivationPath::from_str(derivation_path)?; let child = root.derive_priv(&secp, &path)?; @@ -70,7 +75,7 @@ fn get_key(secp: &Secp256k1>, root: ExtendedPrivKey, derivat Ok(secret_key) } -pub fn get_sc_address(mnemonic: &str, index: u32, network: &str) -> Result { +pub fn get_sc_address(mnemonic: &str, index: u32, network: &str) -> core::result::Result { let network = utils::get_network(network)?; @@ -99,22 +104,23 @@ pub fn get_sc_address(mnemonic: &str, index: u32, network: &str) -> Result Result { +#[cfg_attr(feature = "bindings", uniffi::export)] +pub fn validate_address(address: &str, network: &str) -> core::result::Result { let network = utils::get_network(network)?; if address.starts_with(MAINNET_HRP) || address.starts_with(TESTNET_HRP) { if address.starts_with(MAINNET_HRP) && network != bitcoin::Network::Bitcoin { - return Err(anyhow!("Statechain address does not match the network")); + return Err(MercuryError::StatechainAddressMismatchNetworkError); } if address.starts_with(TESTNET_HRP) && network == bitcoin::Network::Bitcoin { - return Err(anyhow!("Statechain address does not match the network")); + return Err(MercuryError::StatechainAddressMismatchNetworkError); } match decode_transfer_address(address) { Ok(_) => Ok(true), - Err(_) => Err(anyhow::anyhow!("Invalid statechain address")), + Err(_) => Err(MercuryError::InvalidStatechainAddressError), } } else { @@ -123,10 +129,10 @@ pub fn validate_address(address: &str, network: &str) -> Result { match addr.require_network(network) { Ok(_) => Ok(true), - Err(_) => Err(anyhow::anyhow!("Bitcoin address does not match the network")), + Err(_) => Err(MercuryError::BitcoinAddressMismatchNetworkError), } }, - Err(_) => Err(anyhow::anyhow!("Invalid bitcoin address")), + Err(_) => Err(MercuryError::InvalidBitcoinAddressError), } } diff --git a/lib/src/transaction.rs b/lib/src/transaction.rs index c10c0652..a1b0124a 100644 --- a/lib/src/transaction.rs +++ b/lib/src/transaction.rs @@ -4,17 +4,17 @@ use bitcoin::{Txid, ScriptBuf, Transaction, absolute, TxIn, OutPoint, Witness, T use secp256k1_zkp::{SecretKey, PublicKey, Secp256k1, schnorr::Signature, Message, musig::{MusigSessionId, MusigPubNonce, BlindingFactor, MusigSession, MusigPartialSignature, blinded_musig_pubkey_xonly_tweak_add, blinded_musig_negate_seckey, MusigAggNonce, MusigSecNonce}, new_musig_nonce_pair, KeyPair, rand::{self, Rng}}; use serde::{Serialize, Deserialize}; -use anyhow::{anyhow, Result}; - -use crate::{wallet::Coin, utils::{self, get_network}, decode_transfer_address}; +use crate::{decode_transfer_address, error::MercuryError, utils::{self, get_network}, wallet::Coin}; #[derive(Serialize, Deserialize, Debug)] +#[cfg_attr(feature = "bindings", derive(uniffi::Record))] pub struct SignFirstRequestPayload { pub statechain_id: String, pub signed_statechain_id: String, } #[derive(Serialize, Deserialize)] +#[cfg_attr(feature = "bindings", derive(uniffi::Record))] pub struct CoinNonce { pub secret_nonce: String, pub public_nonce: String, @@ -23,11 +23,13 @@ pub struct CoinNonce { } #[derive(Serialize, Deserialize, Debug, Clone)] +#[cfg_attr(feature = "bindings", derive(uniffi::Record))] pub struct SignFirstResponsePayload { pub server_pubnonce: String, } #[derive(Serialize, Deserialize, Debug, Clone)] +#[cfg_attr(feature = "bindings", derive(uniffi::Record))] pub struct PartialSignatureMsg1 { pub msg: String, pub output_pubkey: String, // the tweaked pubkey @@ -38,6 +40,7 @@ pub struct PartialSignatureMsg1 { } #[derive(Serialize, Deserialize, Debug, Clone)] +#[cfg_attr(feature = "bindings", derive(uniffi::Record))] pub struct PartialSignatureRequestPayload { pub statechain_id: String, pub negate_seckey: u8, @@ -47,17 +50,19 @@ pub struct PartialSignatureRequestPayload { } #[derive(Serialize, Deserialize, Debug, Clone)] -pub struct ServerPublicNonceResponsePayload<'r> { - pub server_pubnonce: &'r str, +#[cfg_attr(feature = "bindings", derive(uniffi::Record))] +pub struct ServerPublicNonceResponsePayload { + pub server_pubnonce: String, } #[derive(Serialize, Deserialize, Debug, Clone)] -pub struct PartialSignatureResponsePayload<'r> { - pub partial_sig: &'r str, +#[cfg_attr(feature = "bindings", derive(uniffi::Record))] +pub struct PartialSignatureResponsePayload { + pub partial_sig: String, } - -pub fn create_and_commit_nonces(coin: &Coin) -> Result{ +#[cfg_attr(feature = "bindings", uniffi::export)] +pub fn create_and_commit_nonces(coin: &Coin) -> core::result::Result{ let secp = Secp256k1::new(); @@ -66,7 +71,7 @@ pub fn create_and_commit_nonces(coin: &Coin) -> Result{ let client_seckey = PrivateKey::from_wif(&coin.user_privkey)?.inner; let client_pubkey = PublicKey::from_str(&coin.user_pubkey)?; - let (client_sec_nonce, client_pub_nonce) = new_musig_nonce_pair(&secp, client_session_id, None, Some(client_seckey), client_pubkey, None, None).unwrap(); + let (client_sec_nonce, client_pub_nonce) = new_musig_nonce_pair(&secp, client_session_id, None, Some(client_seckey), client_pubkey, None, None)?; let blinding_factor = BlindingFactor::new(&mut rand::thread_rng()); @@ -106,7 +111,7 @@ pub fn create_tx_out( fee_rate_sats_per_byte: u64, to_address: &str, network: Network, -) -> Result +) -> core::result::Result { const BACKUP_TX_SIZE: u64 = 112; // virtual size one input P2TR and one output P2TR // 163 is the real size one input P2TR and one output P2TR @@ -134,7 +139,7 @@ pub fn calculate_block_height( initlock: u32, interval: u32, qt_backup_tx: u32, - is_withdrawal: bool) -> Result + is_withdrawal: bool) -> core::result::Result { // if qt_backup_tx == 0, it means this is the first backup transaction (Tx0) // In this case, the block_height is equal to the current block height @@ -146,7 +151,8 @@ pub fn calculate_block_height( Ok(block_height) } -pub fn get_user_backup_address(coin: &Coin, network: String) -> Result { +#[cfg_attr(feature = "bindings", uniffi::export)] +pub fn get_user_backup_address(coin: &Coin, network: String) -> core::result::Result { let network = get_network(&network)?; @@ -155,6 +161,7 @@ pub fn get_user_backup_address(coin: &Coin, network: String) -> Result { Ok(to_address.to_string()) } +#[cfg_attr(feature = "bindings", uniffi::export)] pub fn get_partial_sig_request( coin: &Coin, block_height: u32, @@ -164,7 +171,7 @@ pub fn get_partial_sig_request( qt_backup_tx: u32, to_address: String, network: String, - is_withdrawal: bool) -> Result + is_withdrawal: bool) -> core::result::Result { let network = utils::get_network(&network)?; @@ -191,7 +198,7 @@ pub fn get_musig_session( coin: &Coin, block_height: u32, output: &TxOut, - network: Network) -> Result + network: Network) -> core::result::Result { let input_pubkey = PublicKey::from_str(&coin.aggregated_pubkey.as_ref().unwrap())?; let input_xonly_pubkey = input_pubkey.x_only_public_key().0; @@ -268,7 +275,7 @@ pub fn get_musig_session( pub fn calculate_musig_session( coin: &Coin, hash: TapSighash, - encoded_unsigned_tx: String,) -> Result + encoded_unsigned_tx: String,) -> core::result::Result { let secp = Secp256k1::new(); @@ -360,12 +367,13 @@ pub fn calculate_musig_session( }) } +#[cfg_attr(feature = "bindings", uniffi::export)] pub fn create_signature( msg: String, client_partial_sig_hex: String, server_partial_sig_hex: String, session_hex: String, - output_pubkey_hex: String) -> Result + output_pubkey_hex: String) -> core::result::Result { let secp = Secp256k1::new(); @@ -387,16 +395,17 @@ pub fn create_signature( let x_only_key_tweaked = output_pubkey.x_only_public_key().0; if !secp.verify_schnorr(&sig, &msg, &x_only_key_tweaked).is_ok() { - return Err(anyhow!("Unkown network")); + return Err(MercuryError::SchnorrSignatureValidationError); } Ok(sig.to_string()) } +#[cfg_attr(feature = "bindings", uniffi::export)] pub fn new_backup_transaction( encoded_unsigned_tx: String, signature_hex: String, -) -> Result { +) -> core::result::Result { let tx_bytes = hex::decode(encoded_unsigned_tx)?; let tx: Transaction = bitcoin::consensus::encode::deserialize(&tx_bytes)?; @@ -404,7 +413,7 @@ pub fn new_backup_transaction( let mut psbt = Psbt::from_unsigned_tx(tx)?; if psbt.inputs.len() != 1 { - return Err(anyhow!("There must be only one input")); + return Err(MercuryError::MoreThanOneInputError); } let vout = 0; diff --git a/lib/src/transfer/mod.rs b/lib/src/transfer/mod.rs index 927efde5..03be674d 100644 --- a/lib/src/transfer/mod.rs +++ b/lib/src/transfer/mod.rs @@ -97,4 +97,4 @@ pub struct TransferMsg { pub backup_transactions: Vec, pub t1: [u8; 32], pub user_public_key: String, -} \ No newline at end of file +} diff --git a/lib/src/transfer/receiver.rs b/lib/src/transfer/receiver.rs index a12bf6d0..15cbbabb 100644 --- a/lib/src/transfer/receiver.rs +++ b/lib/src/transfer/receiver.rs @@ -3,13 +3,13 @@ use std::str::FromStr; use bitcoin::{PrivateKey, Transaction, hashes::{sha256, Hash}, Txid, Address, sighash::{TapSighashType, SighashCache, self}, TxOut, taproot::TapTweakHash}; use secp256k1_zkp::{PublicKey, schnorr::Signature, Secp256k1, Message, XOnlyPublicKey, musig::{MusigPubNonce, BlindingFactor, blinded_musig_pubkey_xonly_tweak_add, MusigAggNonce, MusigSession}, SecretKey, Scalar, KeyPair}; use serde::{Serialize, Deserialize}; -use anyhow::{Result, anyhow}; -use crate::{wallet::{BackupTx, Coin}, utils::get_network}; +use crate::{error::MercuryError, utils::get_network, wallet::{BackupTx, Coin}}; use super::TransferMsg; #[derive(Debug, Serialize, Deserialize)] +#[cfg_attr(feature = "bindings", derive(uniffi::Record))] pub struct TransferReceiverRequestPayload { pub statechain_id: String, pub batch_data: Option, @@ -17,7 +17,20 @@ pub struct TransferReceiverRequestPayload { pub auth_sig: String, } +#[derive(Serialize, Deserialize)] +#[cfg_attr(feature = "bindings", derive(uniffi::Record))] +pub struct TransferReceiverResponsePayload { + pub server_pubkey: String, +} + +#[derive(Serialize, Deserialize)] +#[cfg_attr(feature = "bindings", derive(uniffi::Record))] +pub struct TransferReceiverGetResponsePayload { + pub transfer_complete: bool, +} + #[derive(Debug, Serialize, Deserialize)] +#[cfg_attr(feature = "bindings", derive(uniffi::Record))] pub struct KeyUpdateResponsePayload { pub statechain_id: String, pub t2: String, @@ -25,11 +38,13 @@ pub struct KeyUpdateResponsePayload { } #[derive(Debug, Serialize, Deserialize)] +#[cfg_attr(feature = "bindings", derive(uniffi::Record))] pub struct GetMsgAddrResponsePayload { pub list_enc_transfer_msg: Vec, } #[derive(Debug, Serialize, Deserialize)] +#[cfg_attr(feature = "bindings", derive(uniffi::Record))] pub struct StatechainInfo { pub statechain_id: String, pub server_pubnonce: String, @@ -38,6 +53,7 @@ pub struct StatechainInfo { } #[derive(Debug, Serialize, Deserialize)] +#[cfg_attr(feature = "bindings", derive(uniffi::Record))] pub struct StatechainInfoResponsePayload { pub enclave_public_key: String, pub num_sigs: u32, @@ -46,12 +62,14 @@ pub struct StatechainInfoResponsePayload { } #[derive(Debug, Serialize, Deserialize)] +#[cfg_attr(feature = "bindings", derive(uniffi::Record))] pub struct TxOutpoint { pub txid: String, pub vout: u32, } #[derive(Debug, Serialize, Deserialize)] +#[cfg_attr(feature = "bindings", derive(uniffi::Record))] pub struct NewKeyInfo { pub aggregate_pubkey: String, pub aggregate_address: String, @@ -59,7 +77,7 @@ pub struct NewKeyInfo { pub amount: u32, } -pub fn decrypt_transfer_msg(encrypted_message: &str, private_key_wif: &str) -> Result { +pub fn decrypt_transfer_msg(encrypted_message: &str, private_key_wif: &str) -> Result { let client_auth_key = PrivateKey::from_wif(private_key_wif)?.inner; @@ -74,22 +92,23 @@ pub fn decrypt_transfer_msg(encrypted_message: &str, private_key_wif: &str) -> R Ok(transfer_msg) } -pub fn get_tx0_outpoint(backup_transactions: &Vec) -> Result { +#[cfg_attr(feature = "bindings", uniffi::export)] +pub fn get_tx0_outpoint(backup_transactions: &Vec) -> Result { let mut backup_transactions = backup_transactions.clone(); backup_transactions.sort_by(|a, b| a.tx_n.cmp(&b.tx_n)); - let bkp_tx1 = backup_transactions.first().ok_or(anyhow!("No backup transaction found"))?; + let bkp_tx1 = backup_transactions.first().ok_or(MercuryError::NoBackupTransactionFound)?; let tx1: Transaction = bitcoin::consensus::encode::deserialize(&hex::decode(&bkp_tx1.tx)?)?; if tx1.input.len() > 1 { - return Err(anyhow!("tx1 has more than one input")); + return Err(MercuryError::Tx1HasMoreThanOneInput); } if tx1.output.len() > 1 { - return Err(anyhow!("tx1 has more than one output")); + return Err(MercuryError::Tx1HasMoreThanOneInput); } let tx0_txid = tx1.input[0].previous_output.txid; @@ -98,7 +117,7 @@ pub fn get_tx0_outpoint(backup_transactions: &Vec) -> Result Result { +pub fn verify_transfer_signature(new_user_pubkey: &str, tx0_outpoint: &TxOutpoint, transfer_msg: &TransferMsg) -> Result { let new_user_pubkey = PublicKey::from_str(new_user_pubkey)?; let sender_public_key = PublicKey::from_str(&transfer_msg.user_public_key)?.x_only_public_key().0; @@ -120,7 +139,7 @@ pub fn verify_transfer_signature(new_user_pubkey: &str, tx0_outpoint: &TxOutpoin Ok(secp.verify_schnorr(&signature, &msg, &sender_public_key).is_ok()) } -pub fn validate_tx0_output_pubkey(enclave_public_key: &str, transfer_msg: &TransferMsg, tx0_outpoint: &TxOutpoint, tx0_hex: &str, network: &str) -> Result { +pub fn validate_tx0_output_pubkey(enclave_public_key: &str, transfer_msg: &TransferMsg, tx0_outpoint: &TxOutpoint, tx0_hex: &str, network: &str) -> Result { let network = get_network(&network)?; @@ -145,7 +164,7 @@ pub fn validate_tx0_output_pubkey(enclave_public_key: &str, transfer_msg: &Trans Ok(transfer_aggregate_xonly_pubkey == tx0_output_xonly_pubkey) } -pub fn verify_latest_backup_tx_pays_to_user_pubkey(transfer_msg: &TransferMsg, client_pubkey_share: &str, network: &str) -> Result { +pub fn verify_latest_backup_tx_pays_to_user_pubkey(transfer_msg: &TransferMsg, client_pubkey_share: &str, network: &str) -> Result { let client_pubkey_share = PublicKey::from_str(&client_pubkey_share)?; @@ -154,7 +173,7 @@ pub fn verify_latest_backup_tx_pays_to_user_pubkey(transfer_msg: &TransferMsg, c let last_bkp_tx = transfer_msg.backup_transactions.last(); if last_bkp_tx.is_none() { - return Err(anyhow!("No backup transaction found")); + return Err(MercuryError::NoBackupTransactionFound); } let last_bkp_tx = last_bkp_tx.unwrap(); @@ -168,7 +187,8 @@ pub fn verify_latest_backup_tx_pays_to_user_pubkey(transfer_msg: &TransferMsg, c Ok(output.script_pubkey == aggregate_address.script_pubkey()) } -pub fn get_output_address_from_tx0(tx0_outpoint: &TxOutpoint, tx0_hex: &str, network: &str) -> Result { +#[cfg_attr(feature = "bindings", uniffi::export)] +pub fn get_output_address_from_tx0(tx0_outpoint: &TxOutpoint, tx0_hex: &str, network: &str) -> Result { let network = get_network(&network)?; @@ -183,7 +203,8 @@ pub fn get_output_address_from_tx0(tx0_outpoint: &TxOutpoint, tx0_hex: &str, net Ok(address.to_string()) } -pub fn verify_transaction_signature(tx_n_hex: &str, tx0_hex: &str, fee_rate_tolerance: u32, current_fee_rate_sats_per_byte: u32) -> Result<()> { +#[cfg_attr(feature = "bindings", uniffi::export)] +pub fn verify_transaction_signature(tx_n_hex: &str, tx0_hex: &str, fee_rate_tolerance: u32, current_fee_rate_sats_per_byte: u32) -> Result<(), MercuryError> { let tx_n: Transaction = bitcoin::consensus::encode::deserialize(&hex::decode(&tx_n_hex)?)?; @@ -221,27 +242,28 @@ pub fn verify_transaction_signature(tx_n_hex: &str, tx0_hex: &str, fee_rate_tole let fee_rate = fee / tx_n.vsize() as u64; if (fee_rate as i64 + fee_rate_tolerance as i64) < current_fee_rate_sats_per_byte as i64 { - return Err(anyhow!("Fee rate too low".to_string())); + return Err(MercuryError::FeeTooLow); } if (fee_rate as i64 - fee_rate_tolerance as i64) > current_fee_rate_sats_per_byte as i64 { - return Err(anyhow!("Fee rate too high".to_string())); + return Err(MercuryError::FeeTooHigh); } if !Secp256k1::new().verify_schnorr(&signature, &msg, &xonly_pubkey).is_ok() { - return Err(anyhow!("Invalid signature".to_string())); + return Err(MercuryError::InvalidSignature); } Ok(()) } -fn get_tx_hash(tx_0: &Transaction, tx_n: &Transaction) -> Result { + +fn get_tx_hash(tx_0: &Transaction, tx_n: &Transaction) -> Result { let witness = tx_n.input[0].witness.clone(); if witness.nth(0).is_none() { - return Err(anyhow!("Empty witness")); + return Err(MercuryError::EmptyWitness); } let witness_data = witness.nth(0).unwrap(); @@ -251,7 +273,7 @@ fn get_tx_hash(tx_0: &Transaction, tx_n: &Transaction) -> Result { let tx_0_output = tx_0.output[vout].clone(); if witness_data.last().is_none() { - return Err(anyhow!("Empty witness data")); + return Err(MercuryError::EmptyWitnessData); } let sighash_type = TapSighashType::from_consensus_u8(witness_data.last().unwrap().to_owned())?; @@ -270,7 +292,8 @@ fn get_tx_hash(tx_0: &Transaction, tx_n: &Transaction) -> Result { Ok(msg) } -pub fn verify_blinded_musig_scheme(backup_tx: &BackupTx, tx0_hex: &str, statechain_info: &StatechainInfo) -> Result<()> { +#[cfg_attr(feature = "bindings", uniffi::export)] +pub fn verify_blinded_musig_scheme(backup_tx: &BackupTx, tx0_hex: &str, statechain_info: &StatechainInfo) -> Result<(), MercuryError> { let client_public_nonce = MusigPubNonce::from_slice(hex::decode(&backup_tx.client_public_nonce)?.as_slice())?; @@ -316,13 +339,13 @@ pub fn verify_blinded_musig_scheme(backup_tx: &BackupTx, tx0_hex: &str, statecha let challenge = hex::encode(challenge); if statechain_info.challenge != challenge { - return Err(anyhow!("challenge is not correct".to_string())); + return Err(MercuryError::IncorrectChallenge); } Ok(()) } -fn validate_t1pub(t1: &[u8; 32], x1_pub: &PublicKey, sender_public_key: &PublicKey) -> Result { +fn validate_t1pub(t1: &[u8; 32], x1_pub: &PublicKey, sender_public_key: &PublicKey) -> Result { let secret_t1 = SecretKey::from_slice(t1)?; let public_t1 = secret_t1.public_key(&Secp256k1::new()); @@ -332,7 +355,7 @@ fn validate_t1pub(t1: &[u8; 32], x1_pub: &PublicKey, sender_public_key: &PublicK Ok(result_pubkey == public_t1) } -fn calculate_t2(transfer_msg: &TransferMsg, client_seckey_share: &SecretKey,) -> Result { +fn calculate_t2(transfer_msg: &TransferMsg, client_seckey_share: &SecretKey,) -> Result { let t1 = Scalar::from_be_bytes(transfer_msg.t1)?; @@ -343,7 +366,7 @@ fn calculate_t2(transfer_msg: &TransferMsg, client_seckey_share: &SecretKey,) -> Ok(t2) } -pub fn create_transfer_receiver_request_payload(statechain_info: &StatechainInfoResponsePayload, transfer_msg: &TransferMsg, coin: &Coin) -> Result { +pub fn create_transfer_receiver_request_payload(statechain_info: &StatechainInfoResponsePayload, transfer_msg: &TransferMsg, coin: &Coin) -> Result { let x1_pub = PublicKey::from_str(&statechain_info.x1_pub)?; @@ -354,7 +377,7 @@ pub fn create_transfer_receiver_request_payload(statechain_info: &StatechainInfo let client_auth_key = PrivateKey::from_wif(&coin.auth_privkey)?.inner; if !validate_t1pub(&transfer_msg.t1, &x1_pub, &sender_public_key)? { - return Err(anyhow!("Invalid t1")); + return Err(MercuryError::InvalidT1); } let t2 = calculate_t2(&transfer_msg, &client_seckey_share)?; @@ -378,7 +401,8 @@ pub fn create_transfer_receiver_request_payload(statechain_info: &StatechainInfo } -pub fn get_new_key_info(server_public_key_hex: &str, coin: &Coin, statechain_id: &str, tx0_outpoint: &TxOutpoint, tx0_hex: &str, network: &str) -> Result { +#[cfg_attr(feature = "bindings", uniffi::export)] +pub fn get_new_key_info(server_public_key_hex: &str, coin: &Coin, statechain_id: &str, tx0_outpoint: &TxOutpoint, tx0_hex: &str, network: &str) -> Result { let network = get_network(&network)?; @@ -405,7 +429,7 @@ pub fn get_new_key_info(server_public_key_hex: &str, coin: &Coin, statechain_id: let tx0_output_xonly_pubkey = XOnlyPublicKey::from_slice(tx0_output.script_pubkey[2..].as_bytes()).unwrap(); if tx0_output_xonly_pubkey != xonly_pubkey { - return Err(anyhow!("Aggregated public key is not correct".to_string())); + return Err(MercuryError::IncorrectAggregatedPublicKey); } let p2tr_agg_address = Address::p2tr(&secp, aggregated_xonly_pubkey, None, network); diff --git a/lib/src/transfer/sender.rs b/lib/src/transfer/sender.rs index f7d8afc3..5e1e4b46 100644 --- a/lib/src/transfer/sender.rs +++ b/lib/src/transfer/sender.rs @@ -3,14 +3,14 @@ use std::str::FromStr; use bitcoin::{secp256k1, hashes::sha256, Txid, PrivateKey}; use secp256k1_zkp::{Secp256k1, Message, Scalar}; use serde::{Serialize, Deserialize}; -use anyhow::Result; use serde_json::json; -use crate::{decode_transfer_address, wallet::{Coin, BackupTx}}; +use crate::{decode_transfer_address, error::MercuryError, wallet::{BackupTx, Coin}}; use super::TransferMsg; #[derive(Serialize, Deserialize)] +#[cfg_attr(feature = "bindings", derive(uniffi::Record))] pub struct TransferSenderRequestPayload { pub statechain_id: String, pub auth_sig: String, // signed_statechain_id @@ -19,11 +19,13 @@ pub struct TransferSenderRequestPayload { } #[derive(Serialize, Deserialize)] +#[cfg_attr(feature = "bindings", derive(uniffi::Record))] pub struct TransferSenderResponsePayload { pub x1: String, } #[derive(Debug, Serialize, Deserialize, Clone)] +#[cfg_attr(feature = "bindings", derive(uniffi::Record))] pub struct TransferUpdateMsgRequestPayload { pub statechain_id: String, pub auth_sig: String, // signed_statechain_id @@ -32,7 +34,8 @@ pub struct TransferUpdateMsgRequestPayload { } // Step 7. Owner 1 then concatinates the Tx0 outpoint with the Owner 2 public key (O2) and signs it with their key o1 to generate SC_sig_1. -pub fn create_transfer_signature(recipient_address: &str, input_txid: &str, input_vout: u32, client_seckey: &str) -> Result { +#[cfg_attr(feature = "bindings", uniffi::export)] +pub fn create_transfer_signature(recipient_address: &str, input_txid: &str, input_vout: u32, client_seckey: &str) -> Result { // new_user_pubkey: PublicKey, input_txid: &Txid, input_vout: u32, client_seckey: &SecretKey @@ -55,7 +58,8 @@ pub fn create_transfer_signature(recipient_address: &str, input_txid: &str, inpu Ok(signature.to_string()) } -pub fn create_transfer_update_msg(x1: &str, recipient_address: &str, coin: &Coin, transfer_signature: &str, backup_transactions: &Vec) -> Result { +#[cfg_attr(feature = "bindings", uniffi::export)] +pub fn create_transfer_update_msg(x1: &str, recipient_address: &str, coin: &Coin, transfer_signature: &str, backup_transactions: &Vec) -> Result { let (_, _, recipient_auth_pubkey) = decode_transfer_address(recipient_address)?; diff --git a/lib/src/unifii_interface.rs b/lib/src/unifii_interface.rs new file mode 100644 index 00000000..66ee4e8d --- /dev/null +++ b/lib/src/unifii_interface.rs @@ -0,0 +1,98 @@ +// the functions in this file are called by the unifii library +// They were created because we would need to expose to the unifii library some low level functions and struct that are not part of the wallet API +// TODO: 1. verify if they can also be used with WASM, unifyify both interface +// 2. use these same function in Rust client + +use serde::{Deserialize, Serialize}; + +use crate::{decode_transfer_address, transfer::{receiver::{StatechainInfoResponsePayload, TransferReceiverRequestPayload, TxOutpoint}, TransferMsg}, wallet::{BackupTx, Coin, Wallet}, MercuryError}; + +#[derive(Debug, Serialize, Deserialize, Clone)] +#[cfg_attr(feature = "bindings", derive(uniffi::Record))] +pub struct DecodedSCAddress { + version: u8, + user_pubkey: String, + auth_pubkey: String, +} + +#[derive(Clone, Debug, Deserialize, Serialize)] +#[cfg_attr(feature = "bindings", derive(uniffi::Record))] +pub struct FFITransferMsg { + pub statechain_id: String, + pub transfer_signature: String, + pub backup_transactions: Vec, + pub t1: Vec, + pub user_public_key: String, +} + +#[cfg_attr(feature = "bindings", uniffi::export)] +pub fn get_new_coin(wallet: &Wallet) -> Result { + wallet.get_new_coin() +} + +#[cfg_attr(feature = "bindings", uniffi::export)] +pub fn decode_statechain_address(sc_address: String) -> Result { + + let (version, user_pubkey, auth_pubkey) = decode_transfer_address(&sc_address)?; + + Ok(DecodedSCAddress { + version, + user_pubkey: user_pubkey.to_string(), + auth_pubkey: auth_pubkey.to_string(), + }) +} + +fn ffi_to_transfer_msg(ffi_msg: FFITransferMsg) -> Result { + if ffi_msg.t1.len() != 32 { + return Err(MercuryError::T1MustBeExactly32BytesError); + } + let mut t1_array = [0u8; 32]; + t1_array.copy_from_slice(&ffi_msg.t1); + Ok(TransferMsg { + statechain_id: ffi_msg.statechain_id, + transfer_signature: ffi_msg.transfer_signature, + backup_transactions: ffi_msg.backup_transactions, + t1: t1_array, + user_public_key: ffi_msg.user_public_key, + }) +} + +fn transfer_to_ffi_msg(transfer_msg: TransferMsg) -> FFITransferMsg { + FFITransferMsg { + statechain_id: transfer_msg.statechain_id, + transfer_signature: transfer_msg.transfer_signature, + backup_transactions: transfer_msg.backup_transactions, + t1: Vec::from(transfer_msg.t1), + user_public_key: transfer_msg.user_public_key, + } +} + +#[cfg_attr(feature = "bindings", uniffi::export)] +pub fn fii_decrypt_transfer_msg(encrypted_message: &str, private_key_wif: &str) -> Result { + let transfer_msg = crate::transfer::receiver::decrypt_transfer_msg(encrypted_message, private_key_wif)?; + Ok(transfer_to_ffi_msg(transfer_msg)) +} + +#[cfg_attr(feature = "bindings", uniffi::export)] +pub fn ffi_verify_transfer_signature(new_user_pubkey: &str, tx0_outpoint: &TxOutpoint, ffi_transfer_msg: &FFITransferMsg) -> Result { + let transfer_msg = ffi_to_transfer_msg(ffi_transfer_msg.clone())?; + crate::transfer::receiver::verify_transfer_signature(new_user_pubkey, tx0_outpoint, &transfer_msg) +} + +#[cfg_attr(feature = "bindings", uniffi::export)] +pub fn fii_validate_tx0_output_pubkey(enclave_public_key: &str, ffi_transfer_msg: &FFITransferMsg, tx0_outpoint: &TxOutpoint, tx0_hex: &str, network: &str) -> Result { + let transfer_msg = ffi_to_transfer_msg(ffi_transfer_msg.clone())?; + crate::transfer::receiver::validate_tx0_output_pubkey(enclave_public_key, &transfer_msg, tx0_outpoint, tx0_hex, network) +} + +#[cfg_attr(feature = "bindings", uniffi::export)] +pub fn fii_verify_latest_backup_tx_pays_to_user_pubkey(ffi_transfer_msg: &FFITransferMsg, client_pubkey_share: &str, network: &str) -> Result { + let transfer_msg = ffi_to_transfer_msg(ffi_transfer_msg.clone())?; + crate::transfer::receiver::verify_latest_backup_tx_pays_to_user_pubkey(&transfer_msg, client_pubkey_share, network) +} + +#[cfg_attr(feature = "bindings", uniffi::export)] +pub fn fii_create_transfer_receiver_request_payload(statechain_info: &StatechainInfoResponsePayload, ffi_transfer_msg: &FFITransferMsg, coin: &Coin) -> Result { + let transfer_msg = ffi_to_transfer_msg(ffi_transfer_msg.clone())?; + crate::transfer::receiver::create_transfer_receiver_request_payload(statechain_info, &transfer_msg, coin) +} diff --git a/lib/src/utils.rs b/lib/src/utils.rs index b9af25dc..2ae85673 100644 --- a/lib/src/utils.rs +++ b/lib/src/utils.rs @@ -1,15 +1,17 @@ use bitcoin::Transaction; use serde::{Serialize, Deserialize}; -use anyhow::{anyhow, Result}; -use crate::wallet::BackupTx; +use crate::{wallet::BackupTx, MercuryError}; -#[derive(Serialize, Deserialize)] +#[derive(Debug, Serialize, Deserialize)] +#[cfg_attr(feature = "bindings", derive(uniffi::Record))] pub struct ServerConfig { pub initlock: u32, pub interval: u32, } +#[derive(Debug, Serialize, Deserialize)] +#[cfg_attr(feature = "bindings", derive(uniffi::Record))] pub struct InfoConfig { pub initlock: u32, pub interval: u32, @@ -17,6 +19,7 @@ pub struct InfoConfig { } #[derive(Debug, Serialize, Deserialize)] +#[cfg_attr(feature = "bindings", derive(uniffi::Record))] pub struct PubKeyInfo { pub server_pubkey: String, pub tx_n: u32, @@ -24,27 +27,29 @@ pub struct PubKeyInfo { } #[derive(Debug, Serialize, Deserialize)] +#[cfg_attr(feature = "bindings", derive(uniffi::Record))] pub struct KeyListResponsePayload { pub list_keyinfo: Vec, } -pub fn get_network(network: &str) -> Result { +pub fn get_network(network: &str) -> Result { match network { "signet" => Ok(bitcoin::Network::Signet), "testnet" => Ok(bitcoin::Network::Testnet), "regtest" => Ok(bitcoin::Network::Regtest), "mainnet" => Ok(bitcoin::Network::Bitcoin), - _ => Err(anyhow!("Unkown network")) + _ => Err(MercuryError::NetworkConversionError) } } -pub fn get_blockheight(bkp_tx: &BackupTx) -> Result { +#[cfg_attr(feature = "bindings", uniffi::export)] +pub fn get_blockheight(bkp_tx: &BackupTx) -> Result { let tx_bytes = hex::decode(&bkp_tx.tx)?; - let tx1 = bitcoin::consensus::deserialize::(&tx_bytes).unwrap(); + let tx1 = bitcoin::consensus::deserialize::(&tx_bytes)?; let lock_time = tx1.lock_time; if !(lock_time.is_block_height()) { - return Err(anyhow!("Locktime is not block height")); + return Err(MercuryError::LocktimeNotBlockHeightError); } let block_height = lock_time.to_consensus_u32(); diff --git a/lib/src/wallet/cpfp_tx.rs b/lib/src/wallet/cpfp_tx.rs index 55e03a2e..8e136397 100644 --- a/lib/src/wallet/cpfp_tx.rs +++ b/lib/src/wallet/cpfp_tx.rs @@ -1,13 +1,13 @@ use std::{str::FromStr, collections::BTreeMap}; -use crate::utils::get_network; +use crate::{error::MercuryError, utils::get_network}; use super::{BackupTx, Coin}; -use anyhow::{anyhow, Result}; use bitcoin::{Transaction, Address, TxOut, Txid, OutPoint, TxIn, ScriptBuf, Witness, absolute, psbt::{Psbt, Input, PsbtSighashType, self}, bip32::{Fingerprint, DerivationPath}, Amount, Network, sighash::{TapSighashType, SighashCache, self, TapSighash}, taproot::{TapLeafHash, self}, secp256k1, key::TapTweak, PrivateKey}; use secp256k1_zkp::{Secp256k1, SecretKey, PublicKey, XOnlyPublicKey}; -pub fn create(backup_tx: &BackupTx, coin: &Coin, to_address: &str, fee_rate_sats_per_byte: u64, network: &str) -> Result { +#[cfg_attr(feature = "bindings", uniffi::export)] +pub fn create_cpfp_tx(backup_tx: &BackupTx, coin: &Coin, to_address: &str, fee_rate_sats_per_byte: u64, network: &str) -> Result { let network = get_network(network)?; @@ -15,7 +15,7 @@ pub fn create(backup_tx: &BackupTx, coin: &Coin, to_address: &str, fee_rate_sats let tx: Transaction = bitcoin::consensus::deserialize(&tx_bytes)?; if tx.output.len() != 1 { - return Err(anyhow!("Unkown network")); + return Err(MercuryError::UnkownNetwork); } let output: &TxOut = tx.output.get(0).unwrap(); @@ -23,7 +23,7 @@ pub fn create(backup_tx: &BackupTx, coin: &Coin, to_address: &str, fee_rate_sats let backup_address = Address::from_str(coin.backup_address.as_str())?.require_network(network)?; if backup_address.script_pubkey() != output.script_pubkey { - return Err(anyhow!("Backup transaction does not pay user")); + return Err(MercuryError::BackupTransactionDoesNotPayUser); } let input_tx_hash = tx.txid(); @@ -44,7 +44,7 @@ pub fn create(backup_tx: &BackupTx, coin: &Coin, to_address: &str, fee_rate_sats let amount_out = input_amount as i64 - absolute_fee as i64; if amount_out < 0 { - return Err(anyhow!("Fee is too high")); + return Err(MercuryError::FeeTooHigh); } let outputs = vec![ @@ -59,7 +59,7 @@ pub fn create(backup_tx: &BackupTx, coin: &Coin, to_address: &str, fee_rate_sats Ok(encoded_signed_tx) } -fn create_transaction(input_tx_hash: &Txid, input_vout: u32, coin: &Coin, input_amount: u64, outputs: &Vec, network: Network) -> Result { +fn create_transaction(input_tx_hash: &Txid, input_vout: u32, coin: &Coin, input_amount: u64, outputs: &Vec, network: Network) -> Result { let secp = Secp256k1::new(); diff --git a/lib/src/wallet/key_derivation.rs b/lib/src/wallet/key_derivation.rs index 22f6e16d..da119eca 100644 --- a/lib/src/wallet/key_derivation.rs +++ b/lib/src/wallet/key_derivation.rs @@ -1,11 +1,10 @@ use std::str::FromStr; -use anyhow::Result; use bip39::Mnemonic; use bitcoin::{bip32::{ExtendedPrivKey, DerivationPath, ExtendedPubKey, ChildNumber}, Address, PrivateKey}; use secp256k1_zkp::{SecretKey, PublicKey, ffi::types::AlignedType, Secp256k1}; -use crate::{wallet::{Wallet, Coin, CoinStatus}, encode_sc_address, utils::get_network}; +use crate::{encode_sc_address, error::MercuryError, utils::get_network, wallet::{Coin, CoinStatus, Wallet}}; pub struct KeyData { pub secret_key: SecretKey, @@ -18,7 +17,7 @@ pub struct KeyData { impl Wallet { - fn get_seed(&self) -> Result<[u8; 64]> { + fn get_seed(&self) -> Result<[u8; 64], MercuryError> { let seed: [u8; 64] = Mnemonic::from_str(&self.mnemonic)?.to_seed(""); Ok(seed) } @@ -33,7 +32,7 @@ impl Wallet { } } - pub fn generate_new_key(&self, derivation_path: &str, change_index: u32, address_index:u32) -> Result { + pub fn generate_new_key(&self, derivation_path: &str, change_index: u32, address_index:u32) -> Result { let seed= self.get_seed()?; let network = get_network(&self.network)?; @@ -71,7 +70,7 @@ impl Wallet { }) } - pub fn get_new_coin(&self) -> Result { + pub fn get_new_coin(&self) -> Result { let network = get_network(&self.network)?; diff --git a/lib/src/wallet/mod.rs b/lib/src/wallet/mod.rs index 9140bbb3..840c304d 100644 --- a/lib/src/wallet/mod.rs +++ b/lib/src/wallet/mod.rs @@ -6,11 +6,11 @@ use std::{fmt, str::FromStr}; use bip39::{Mnemonic, Language}; use secp256k1_zkp::rand::{self, Rng}; use serde::{Serialize, Deserialize}; -use anyhow::Result; -use crate::utils::ServerConfig; +use crate::{utils::ServerConfig, MercuryError}; #[derive(Debug, Serialize, Deserialize, Clone)] +#[cfg_attr(feature = "bindings", derive(uniffi::Record))] pub struct Wallet { pub name: String, pub mnemonic: String, @@ -29,6 +29,7 @@ pub struct Wallet { #[allow(non_snake_case)] #[derive(Debug, Serialize, Deserialize, Clone)] +#[cfg_attr(feature = "bindings", derive(uniffi::Record))] pub struct Settings { pub network: String, pub block_explorerURL: Option, @@ -46,6 +47,7 @@ pub struct Settings { pub tutorials: bool } #[derive(Debug, Serialize, Deserialize, Clone)] +#[cfg_attr(feature = "bindings", derive(uniffi::Record))] pub struct Token { pub btc_payment_address: String, pub fee: String, @@ -58,6 +60,7 @@ pub struct Token { } #[derive(Debug, Serialize, Deserialize, Clone)] +#[cfg_attr(feature = "bindings", derive(uniffi::Record))] pub struct Activity { pub utxo: String, pub amount: u32, @@ -66,6 +69,7 @@ pub struct Activity { } #[derive(Debug, Serialize, Deserialize, Clone)] +#[cfg_attr(feature = "bindings", derive(uniffi::Record))] pub struct Coin { pub index: u32, @@ -103,6 +107,7 @@ pub struct Coin { } #[derive(Debug, Serialize, Deserialize, Clone, PartialEq)] +#[cfg_attr(feature = "bindings", derive(uniffi::Enum))] #[allow(non_camel_case_types)] pub enum CoinStatus { INITIALISED, // address generated but no Tx0 yet @@ -132,6 +137,7 @@ impl fmt::Display for CoinStatus { } #[derive(Debug, Clone, PartialEq, Eq)] +#[cfg_attr(feature = "bindings", derive(uniffi::Record))] pub struct CoinStatusParseError; impl fmt::Display for CoinStatusParseError { @@ -160,12 +166,14 @@ impl FromStr for CoinStatus { } } #[derive(Debug, Serialize, Deserialize, Clone)] +#[cfg_attr(feature = "bindings", derive(uniffi::Record))] pub struct StatechainBackupTxs { pub statechain_id: String, pub backup_txs: Vec } #[derive(Debug, Serialize, Deserialize, Clone)] +#[cfg_attr(feature = "bindings", derive(uniffi::Record))] pub struct BackupTx { pub tx_n: u32, pub tx: String, @@ -181,7 +189,8 @@ pub fn set_config(wallet: &mut Wallet, config: &ServerConfig) { wallet.interval = config.interval; } -pub fn generate_mnemonic() -> Result { +#[cfg_attr(feature = "bindings", uniffi::export)] +pub fn generate_mnemonic() -> core::result::Result { let mut rng = rand::thread_rng(); let entropy = (0..16).map(|_| rng.gen::()).collect::>(); // 16 bytes of entropy for 12 words let mnemonic = Mnemonic::from_entropy_in(Language::English, &entropy)?; diff --git a/lib/uniffi-bindgen.rs b/lib/uniffi-bindgen.rs new file mode 100644 index 00000000..d96eac70 --- /dev/null +++ b/lib/uniffi-bindgen.rs @@ -0,0 +1,3 @@ +fn main() { + uniffi::uniffi_bindgen_main() +} \ No newline at end of file diff --git a/lib/uniffi.toml b/lib/uniffi.toml new file mode 100644 index 00000000..f247e307 --- /dev/null +++ b/lib/uniffi.toml @@ -0,0 +1,3 @@ +[bindings.kotlin] +package_name = "com.mercurylayer" +android = false diff --git a/server/src/endpoints/deposit.rs b/server/src/endpoints/deposit.rs index 221cadb6..70cbe071 100644 --- a/server/src/endpoints/deposit.rs +++ b/server/src/endpoints/deposit.rs @@ -112,6 +112,45 @@ pub async fn get_token(statechain_entity: &State) -> status::C return status::Custom(Status::Ok, Json(response_body)); } +#[get("/tokens/token_init")] +pub async fn token_init(statechain_entity: &State) -> status::Custom> { + + if statechain_entity.config.network == "mainnet" { + let response_body = json!({ + "error": "Internal Server Error", + "message": "Token generation not supported on mainnet." + }); + + return status::Custom(Status::InternalServerError, Json(response_body)); + } + + let btc_payment_address = String::from("tb1qdgjdmmsdp5hkrhwl6cxd3uvt6hvjvlmmzucdca"); + let fee = String::from("0.0001"); + let lightning_invoice = String::from("lnbc10u1pj3knpdsp5k9f25s2wpzewkf9c78pftkgnkuuz82erkcjml7zkgsp7znyhs5yspp5rxz3tkc7ydgln3u7ez6duhp0g6jpzgtnn7ph5xrjy6muh9xm07wqdp2f9h8vmmfvdjjqen0wgsy6ctfdeehgcteyp6x76m9dcxqyjw5qcqpj9qyysgq6z9whs8am75r6mzcgt76vlwgk5g9yq5g8xefdxx6few6d5why7fs7h5g2dx9hk7s60ywtnkyc0f3p0cha4a9kmgkq5jvu5e7hvsaawqpjtf8p4"); + let processor_id = uuid::Uuid::new_v4().to_string(); + let token_id = uuid::Uuid::new_v4().to_string(); + let confirmed = false; + let spent = false; + let expiry = String::from("2024-12-26T17:29:50.013Z"); + + insert_new_token(&statechain_entity.pool, &token_id).await; + + let token = mercurylib::wallet::Token { + btc_payment_address, + fee, + lightning_invoice, + processor_id, + token_id, + confirmed, + spent, + expiry + }; + + let response_body = json!(token); + + return status::Custom(Status::Ok, Json(response_body)); +} + #[post("/deposit/init/pod", format = "json", data = "")] pub async fn post_deposit(statechain_entity: &State, deposit_msg1: Json) -> status::Custom> { diff --git a/server/src/endpoints/transfer_receiver.rs b/server/src/endpoints/transfer_receiver.rs index bd167ed4..35a13371 100644 --- a/server/src/endpoints/transfer_receiver.rs +++ b/server/src/endpoints/transfer_receiver.rs @@ -1,7 +1,7 @@ use std::str::FromStr; use bitcoin::hashes::sha256; -use mercurylib::transfer::receiver::{GetMsgAddrResponsePayload, StatechainInfo}; +use mercurylib::transfer::receiver::{GetMsgAddrResponsePayload, StatechainInfo, TransferReceiverResponsePayload}; use rocket::{State, response::status, serde::json::Json, http::Status}; use secp256k1_zkp::{PublicKey, schnorr::Signature, Message, Secp256k1, XOnlyPublicKey, SecretKey}; use serde::{Serialize, Deserialize}; @@ -282,14 +282,9 @@ pub async fn transfer_receiver(statechain_entity: &State, tran }, }; - #[derive(Serialize, Deserialize)] - pub struct TransferReceiverResponsePayload<'r> { - server_pubkey: &'r str, - } - let response: TransferReceiverResponsePayload = serde_json::from_str(value.as_str()).expect(&format!("failed to parse: {}", value.as_str())); - let mut server_pubkey_hex = response.server_pubkey.to_string(); + let mut server_pubkey_hex = response.server_pubkey.clone(); if server_pubkey_hex.starts_with("0x") { server_pubkey_hex = server_pubkey_hex[2..].to_string(); diff --git a/server/src/main.rs b/server/src/main.rs index 2db95b9c..e500268e 100644 --- a/server/src/main.rs +++ b/server/src/main.rs @@ -41,6 +41,7 @@ async fn main() { .mount("/", routes![ endpoints::deposit::post_deposit, endpoints::deposit::get_token, + endpoints::deposit::token_init, endpoints::sign::sign_first, endpoints::sign::sign_second, endpoints::transfer_sender::transfer_sender, diff --git a/wasm/src/lib.rs b/wasm/src/lib.rs index 7908e684..3787f43f 100644 --- a/wasm/src/lib.rs +++ b/wasm/src/lib.rs @@ -255,7 +255,7 @@ pub fn createCpfpTx(backup_tx_json: JsValue, coin_json: JsValue, to_address: Str let coin: Coin = serde_wasm_bindgen::from_value(coin_json).unwrap(); let backup_tx: BackupTx = serde_wasm_bindgen::from_value(backup_tx_json).unwrap(); - let backup_tx = mercurylib::wallet::cpfp_tx::create(&backup_tx, &coin, &to_address, fee_rate_sats_per_byte as u64, &network).unwrap(); + let backup_tx = mercurylib::wallet::cpfp_tx::create_cpfp_tx(&backup_tx, &coin, &to_address, fee_rate_sats_per_byte as u64, &network).unwrap(); backup_tx // "".to_string() }